diff --git a/src/core/Akka.Persistence.Tests/Journal/MemoryEventAdaptersSpec.cs b/src/core/Akka.Persistence.Tests/Journal/MemoryEventAdaptersSpec.cs index 22cbf9508f7..fcc3bb996fd 100644 --- a/src/core/Akka.Persistence.Tests/Journal/MemoryEventAdaptersSpec.cs +++ b/src/core/Akka.Persistence.Tests/Journal/MemoryEventAdaptersSpec.cs @@ -51,6 +51,7 @@ public MemoryEventAdaptersSpec() """ + typeof (ReadMeEvent).FullName + @", Akka.Persistence.Tests"" = reader """ + typeof (WriteMeEvent).FullName + @", Akka.Persistence.Tests"" = writer """ + typeof(ReadMeTwiceEvent).FullName + @", Akka.Persistence.Tests"" = [reader, another-reader] + """ + typeof(ReadWriteEvent).FullName + @", Akka.Persistence.Tests"" = [reader, another-reader, writer] } } }").WithFallback(ConfigurationFactory.Default()); @@ -130,6 +131,19 @@ public void EventAdapters_should_allow_combining_only_the_readside_CombinedReadE .Should() .BeEquivalentTo("from-ReadMeTwiceEvent()", "again-ReadMeTwiceEvent()"); } + + [Fact] + public void EventAdapters_should_allow_read_write_ReadWriteEventAdapter() + { + var adapters = EventAdapters.Create(_extendedActorSystem, _memoryConfig); + + var readWriteAdapter = adapters.Get(); + var events = readWriteAdapter.FromJournal(readWriteAdapter.ToJournal(new ReadWriteEvent()), "").Events + .Select(c => c.ToString()) + .Should() + .BeEquivalentTo("from-to-ReadWriteEvent()", "again-to-ReadWriteEvent()"); + } + } public abstract class BaseTestAdapter : IEventAdapter @@ -170,6 +184,14 @@ public override string ToString() } } + public class ReadWriteEvent + { + public override string ToString() + { + return "ReadWriteEvent()"; + } + } + public class ReaderAdapter : IReadEventAdapter { public IEventSequence FromJournal(object evt, string manifest) diff --git a/src/core/Akka.Persistence/Journal/EventAdapters.cs b/src/core/Akka.Persistence/Journal/EventAdapters.cs index b17cfc42728..0d544d8b10c 100644 --- a/src/core/Akka.Persistence/Journal/EventAdapters.cs +++ b/src/core/Akka.Persistence/Journal/EventAdapters.cs @@ -230,6 +230,34 @@ public IEventSequence FromJournal(object evt, string manifest) } } + [Serializable] + internal class ReadWriteEventAdapter : IEventAdapter + { + private readonly IWriteEventAdapter _writeEventAdapter; + private readonly IReadEventAdapter _readEventAdapter; + + public ReadWriteEventAdapter(IReadEventAdapter readEventAdapter, IWriteEventAdapter writeEventAdapter) + { + _readEventAdapter = readEventAdapter; + _writeEventAdapter = writeEventAdapter; + } + + public string Manifest(object evt) + { + return _writeEventAdapter.Manifest(evt); + } + + public object ToJournal(object evt) + { + return _writeEventAdapter.ToJournal(evt); + } + + public IEventSequence FromJournal(object evt, string manifest) + { + return _readEventAdapter.FromJournal(evt, manifest); + } + } + /// /// TBD /// @@ -302,7 +330,7 @@ private static EventAdapters Create(ExtendedActorSystem system, IDictionary handlers[h]))); + : CombineAdapters(kv.Value.Select(h => handlers[h])); return new KeyValuePair(type, adapter); }).ToList()); @@ -332,6 +360,16 @@ private static List> Sort(List adapters) + { + var writeAdapters = adapters.Where(a => a is NoopReadEventAdapter); + if (writeAdapters.Count() == 0) + return new NoopWriteEventAdapter(new CombinedReadEventAdapter(adapters)); + else if (writeAdapters.Count() == 1) + return new ReadWriteEventAdapter(new CombinedReadEventAdapter(adapters.Where(a => a is NoopWriteEventAdapter)), writeAdapters.First()); + throw new IllegalStateException("Cannot have multiple write adapters for a single adapter binding"); + } + private static int IndexWhere(IList list, Predicate predicate) { for (int i = 0; i < list.Count; i++)