Пример #1
0
        //[NonSerialized]
        //private static IEventSourcedHandlerProvider _eventHandlerProvider = ObjectContainer.Instance.Resolve<IEventSourcedHandlerProvider>();
        private void ApplyEvent(IVersionedEvent @event, Type eventType)
        {
            if (@event.Version == 1 && this.Id.Equals(default(TIdentify)))
            {
                this.Id = TypeConvert.To <TIdentify>(@event.SourceId);
            }

            if (@event.Version > 1 && this.Id.ToString() != @event.SourceId)
            {
                throw new EventSourcedException(@event.SourceId, this.Id.ToString());
            }

            if (@event.Version != this.Version + 1)
            {
                throw new EventSourcedException(@event.Version, this.Version);
            }

            //this.handlers[@event.GetType()].Invoke(@event);
            //var aggregateType = this.GetType();
            var handler = this.handlers[eventType];

            if (handler == null)
            {
                throw new EventSourcedException(this.GetType(), eventType);
            }
            handler(@event);
        }
        public void Project(IVersionedEvent e, Action <T> doProjectionOrRebuild)
        {
            if (isLiveProjection)
            {
                using (var context = this.liveContextFactory.Invoke())
                {
                    if (context
                        .ReadModelingEvents
                        .Where(log =>
                               log.SourceId == e.SourceId &&
                               log.SourceType == e.SourceType &&
                               log.Version >= e.Version)
                        .Any())
                    {
                        tracer.TraceAsync("Read model is up to date for event type: " + e.GetType().ToString());
                        return;
                    }

                    doProjectionOrRebuild(context);

                    // Mark as projected in the the subscription log
                    context.ReadModelingEvents.Add(this.BuildProjectedEventEntity(e));

                    context.SaveChanges();
                }
            }
            else
            {
                doProjectionOrRebuild(this.rebuildContext as T);

                this.rebuildContext.AddToUnityOfWork(this.BuildProjectedEventEntity(e));
            }
        }
Пример #3
0
        public TEventType AddEvent <TEventType>(Guid id, IVersionedEvent <Guid> eventItem) where TEventType : EventContainer
        {
            EventContainer result;

            using (var session = documentStore.OpenSession())
            {
                result = session.Load <TEventType>(typeof(TEventType).Name + "/" + id);

                if (result == null)
                {
                    result = _typeActivator.Instance <TEventType>();

                    result.Init(id);
                    result.AddEvent(eventItem);
                    session.Store(result);
                }
                else
                {
                    result.AddEvent(eventItem);
                }

                session.SaveChanges();
            }

            return((TEventType)result);
        }
Пример #4
0
        public virtual void ApplyUpdate(IVersionedEvent versionedEvent)
        {
            if (!_isUpdateHandlersRegistered)
            {
                RegisterUpdateHandlers();
                _isUpdateHandlersRegistered = true;
            }

            if (_handlers.TryGetValue(versionedEvent.GetType(), out var eventHandler))
            {
                eventHandler(versionedEvent);
            }

            var eventSourcedEntities = GetChildEntities();

            if (!eventSourcedEntities.Any())
            {
                return;
            }

            eventSourcedEntities.ToList().ForEach(eventSourcedEntity =>
            {
                eventSourcedEntity.ApplyUpdate(versionedEvent);
            });
        }
Пример #5
0
        public void when_reading_entity_then_rehydrates()
        {
            var newEvents = new IVersionedEvent[] {
                new TestEvent {
                    SourceId = id, Version = 2, Foo = "Baz"
                }
            };
            var serialized = newEvents.Select(x => new EventData {
                Version = x.Version, Payload = Serialize(x)
            });

            id = Guid.NewGuid();
            var eventStore = new Mock <IEventStore>();

            memento = Mock.Of <IMemento>(x => x.Version == 1);
            var cache = new MemoryCache(Guid.NewGuid().ToString());

            cache.Add("TestOriginatorEntity_" + id, new Tuple <IMemento, DateTime?>(memento, null), DateTimeOffset.UtcNow.AddMinutes(10));

            eventStore.Setup(x => x.Load(It.IsAny <string>(), 2)).Returns(serialized);
            var sut = new AzureEventSourcedRepository <TestOriginatorEntity>(eventStore.Object, Mock.Of <IEventStoreBusPublisher>(), new JsonTextSerializer(), new StandardMetadataProvider(), cache);

            var entity = sut.Find(id);

            Assert.NotNull(entity);
            Assert.Equal(id, entity.Id);
            Assert.Equal(memento, entity.Memento);
            Assert.Equal(newEvents, entity.History, new TestEventComparer());
        }
Пример #6
0
        public void when_reading_entity_then_rehydrates()
        {
            var events = new IVersionedEvent[] {
                new TestEvent {
                    SourceId = id, Version = 1, Foo = "Bar"
                },
                new TestEvent {
                    SourceId = id, Version = 2, Foo = "Baz"
                }
            };
            var serialized = events.Select(x => new EventData {
                Version = x.Version, Payload = Serialize(x)
            });

            id = Guid.NewGuid();
            var eventStore = new Mock <IEventStore>();

            eventStore.Setup(x => x.Load(It.IsAny <string>(), It.IsAny <int>())).Returns(serialized);
            var sut = new AzureEventSourcedRepository <TestEntity>(eventStore.Object, Mock.Of <IEventStoreBusPublisher>(), new JsonTextSerializer(), new StandardMetadataProvider(), null);

            var entity = sut.Find(id);

            Assert.NotNull(entity);
            Assert.Equal(id, entity.Id);
            Assert.Equal(events, entity.History, new TestEventComparer());
        }
Пример #7
0
        protected Event Serialize(IVersionedEvent e)
        {
            Event serialized;

            using (var writer = new StringWriter())
            {
                this.serializer.Serialize(writer, e);
                serialized = new Event
                {
                    SourceId       = e.SourceId,
                    SourceType     = _sourceType,
                    Version        = e.Version,
                    Payload        = writer.ToString(),
                    CorrelationId  = e.CorrelationId,
                    EventType      = e.GetType().Name,
                    CreationDate   = e.CreationDate,
                    LastUpdateTime = dateTime.Now
                };
            }

            var projectable = e as IProjectableEvent;

            if (projectable != null)
            {
                serialized.IsProjectable = true;
            }
            else
            {
                serialized.IsProjectable = false;
            }

            return(serialized);
        }
Пример #8
0
        private EventData ToEventData(IVersionedEvent versionedEvent)
        {
            var eventType = versionedEvent.GetType().Name;

            var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(versionedEvent, _serializerSettings));

            return(new EventData(versionedEvent.EventId, eventType, true, body, new byte[0]));
        }
Пример #9
0
 public void Update(IVersionedEvent versionedEvent)
 {
     versionedEvent.SourceId = entity.Id;
     versionedEvent.Version  = Version + 1;
     this.handlers[versionedEvent.GetType()].Invoke(versionedEvent);
     Version = versionedEvent.Version;
     this.events.Enqueue(versionedEvent);
 }
Пример #10
0
        public async Task SaveEvent(IVersionedEvent versionedEvent, ITextSerializer textSerializer)
        {
            if (versionedEvent == null)
            {
                throw new ArgumentNullException(nameof(versionedEvent));
            }

            await SaveAllEvents(new[] { versionedEvent }, textSerializer);
        }
Пример #11
0
 private StoredEvent ToStoredEvent(IVersionedEvent versionedEvent)
 {
     return(new StoredEvent(
                versionedEvent.SourceId,
                _aggregateType,
                JsonConvert.SerializeObject(versionedEvent, _serializerSettings),
                versionedEvent.Version,
                versionedEvent.GetType().Name,
                null));
 }
Пример #12
0
        private void WriteEvent(IVersionedEvent e)
        {
            var command = _sqlConnection.CreateCommand();

            command.CommandText = @"INSERT INTO [TodoItem] ([Id], [Version], [EventName], [EventData]) VALUES (@id, @version, @eventName, @eventData)";
            command.Parameters.AddWithValue("@id", e.SourceId);
            command.Parameters.AddWithValue("@version", e.Version);
            command.Parameters.AddWithValue("@eventName", e.GetType().Name);
            command.Parameters.AddWithValue("@eventData", JsonConvert.SerializeObject(e));
            command.ExecuteNonQuery();
        }
 private ProjectedEvent BuildProjectedEventEntity(IVersionedEvent e)
 {
     return(new ProjectedEvent
     {
         SourceId = e.SourceId,
         SourceType = e.SourceType,
         Version = e.Version,
         EventType = ((object)e).GetType().FullName,
         CorrelationId = e.CorrelationId
     });
 }
 private Log BuildConsumedEventEntity <Log>(IVersionedEvent e)
     where Log : class, IProcessedEvent, new()
 {
     return(new Log
     {
         SourceId = e.SourceId,
         SourceType = e.SourceType,
         Version = e.Version,
         EventType = e.GetType().Name,
         CorrelationId = e.CorrelationId
     });
 }
Пример #15
0
        protected void Raise(IVersionedEvent @event)
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }

            @event.SourceId = Id;
            @event.Version  = Version + 1;

            Raise(@event, true);
        }
        static EventData Serialize(IVersionedEvent @event, string correlationId)
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }
            var json     = JsonSerializer.SerializeToString(@event);
            var metadata = new Dictionary <string, object> {
                { "correlationId", correlationId }
            };

            return(new EventData(Guid.NewGuid(), @event.GetType().FullName, true, json.ToUtf8Bytes(), metadata.ToJson().ToUtf8Bytes()));
        }
Пример #17
0
        private EventEntity Serialize(IVersionedEvent e, string correlationId)
        {
            var payload    = this.serializer.SerializeToString(e);
            var serialized = new EventEntity
            {
                AggregateId   = e.SourceId,
                AggregateType = sourceType,
                Version       = e.Version,
                Payload       = payload,
                CorrelationId = correlationId
            };

            return(serialized);
        }
Пример #18
0
        private EventStore GetSerializedEvent(IVersionedEvent versionedEvent, ITextSerializer textSerializer)
        {
            var serializedEvent = new EventStore
            {
                CorrelationId    = versionedEvent.CorrelationId,
                Version          = (int)versionedEvent.Version,
                AggregateType    = versionedEvent.AggregateRootType,
                AggregateId      = versionedEvent.AggregateRootId,
                Payload          = textSerializer.Serialize(versionedEvent),
                OccurredDateTime = DateTime.UtcNow
            };

            return(serializedEvent);
        }
Пример #19
0
        private static Envelope <IEvent> Convert(IVersionedEvent @event, SourceInfo sourceInfo,
                                                 Envelope <ICommand> command)
        {
            var envelope = new Envelope <IEvent>(@event,
                                                 MD5(string.Format("{0}&{1}", sourceInfo.Id, command.MessageId)));

            if (command.Items.ContainsKey(StandardMetadata.TraceInfo))
            {
                envelope.Items[StandardMetadata.TraceInfo] = command.Items[StandardMetadata.TraceInfo];
            }
            envelope.Items[StandardMetadata.SourceInfo]  = sourceInfo;
            envelope.Items[StandardMetadata.CommandInfo] = new SourceInfo(command.MessageId, command.Body.GetType());

            return(envelope);
        }
Пример #20
0
        private void WriteTodoListItemView(IVersionedEvent e, TodoItem item)
        {
            var command = _sqlConnection.CreateCommand();

            command.CommandText = @"MERGE [TodoListItem] AS Target
                                    USING (SELECT @id AS [Id], @name AS [Name], @done AS [Done]) AS Source
                                        ON Target.Id = Source.Id
                                    WHEN NOT MATCHED THEN
                                        INSERT([Id], [Name], [Done]) VALUES(Source.[Id], Source.[Name], Source.[Done])
                                    WHEN MATCHED THEN
                                        UPDATE SET Target.[Name] = Source.[Name], Target.[Done] = Source.[Done];";
            command.Parameters.AddWithValue("@id", item.Id);
            command.Parameters.AddWithValue("@name", item.Name);
            command.Parameters.AddWithValue("@done", item.Done);
            command.ExecuteNonQuery();
        }
Пример #21
0
        public virtual void AddEvent(IVersionedEvent versionedEvent)
        {
            if (!AggregateRoot.Active)
            {
                throw new InvalidOperationException("No changes can be made to this aggregate, since it is not active");
            }

            if (!versionedEvent.IsInitialized)
            {
                versionedEvent.Initialize(Key.ToString(), GetType().Name, ++Version,
                                          AggregateRoot.Key.ToString(), AggregateRoot.GetType().Name);
            }

            ApplyUpdate(versionedEvent);
            UnCommittedEvents.Enqueue(versionedEvent);
        }
Пример #22
0
        private void Raise(IVersionedEvent @event, bool isNew)
        {
            Action <IVersionedEvent> handler;

            if (_handlers.TryGetValue(@event.GetType(), out handler))
            {
                handler(@event);
            }

            Version = @event.Version;

            if (isNew)
            {
                _uncommittedEvents.Add(@event);
            }
        }
Пример #23
0
        private Event Serialize(IVersionedEvent e, string correlationId)
        {
            Event serialized;

            using (var writer = new StringWriter()) {
                serializer.Serialize(writer, e);
                serialized = new Event {
                    AggregateId   = e.SourceId,
                    AggregateType = sourceType,
                    Version       = e.Version,
                    Payload       = writer.ToString(),
                    CorrelationId = correlationId
                };
            }
            return(serialized);
        }
Пример #24
0
        private EventData Serialize(IVersionedEvent e, string correlationId)
        {
            EventData serialized;

            string s = this.serializer.Serialize <IVersionedEvent>(e);

            serialized = new EventData
            {
                AggregateId   = e.SourceId,
                AggregateType = sourceType,
                Version       = e.Version,
                Payload       = s,
                CorrelationId = correlationId
            };

            return(serialized);
        }
Пример #25
0
        public void AddEvent(IVersionedEvent <Guid> eventItem)
        {
            var list = new List <IVersionedEvent <Guid> >();

            if (Events != null)
            {
                list.AddRange(Events);
            }

            var version = list.Any() ? list.Count + 1 : 1;

            eventItem.Version = version;

            list.Add(eventItem);

            Events = list.ToArray();
        }
Пример #26
0
        private void UpdateAvailableQuantity(IVersionedEvent @event, IEnumerable <AnchorQuantity> anchors)
        {
            using (var repository = this.contextFactory.Create())
            {
                var anchorDtos = DbContext.Set <AnchorType>().Where(x => x.WorkshopID == @event.SourceId).ToList();
                if (anchorDtos.Count > 0)
                {
                    // This check assumes events might be received more than once, but not out of order
                    var maxAnchorsAvailabilityVersion = anchorDtos.Max(x => x.AnchorsAvailabilityVersion);
                    if (maxAnchorsAvailabilityVersion >= @event.Version)
                    {
                        logger.LogWarning(
                            "Ignoring availability update message with version {1} for anchor types with conference id {0}, last known version {2}.",
                            @event.SourceId,
                            @event.Version,
                            maxAnchorsAvailabilityVersion);
                        return;
                    }

                    foreach (var anchor in anchors)
                    {
                        var anchorDto = anchorDtos.FirstOrDefault(x => x.ID == anchor.AnchorType);
                        if (anchorDto != null)
                        {
                            anchorDto.AvailableQuantity         += anchor.Quantity;
                            anchorDto.AnchorsAvailabilityVersion = @event.Version;
                        }
                        else
                        {
                            // TODO should reject the entire update?
                            logger.LogWarning(
                                "Failed to locate Anchor Type read model being updated with id {0}.", anchor.AnchorType);
                        }
                    }

                    repository.SaveChanges();
                }
                else
                {
                    logger.LogWarning(
                        "Failed to locate Anchor Types read model for updated anchor availability, with conference id {0}.",
                        @event.SourceId);
                }
            }
        }
        private void UpdateAvailableQuantity(IVersionedEvent @event, IEnumerable <SeatQuantity> seats)
        {
            using (var repository = this.contextFactory.Invoke())
            {
                var seatDtos = repository.Set <SeatType>().Where(x => x.ConferenceId == @event.SourceId).ToList();
                if (seatDtos.Count > 0)
                {
                    // This check assumes events might be received more than once, but not out of order
                    var maxSeatsAvailabilityVersion = seatDtos.Max(x => x.SeatsAvailabilityVersion);
                    if (maxSeatsAvailabilityVersion >= @event.Version)
                    {
                        Trace.TraceWarning(
                            "Ignoring availability update message with version {1} for seat types with conference id {0}, last known version {2}.",
                            @event.SourceId,
                            @event.Version,
                            maxSeatsAvailabilityVersion);
                        return;
                    }

                    foreach (var seat in seats)
                    {
                        var seatDto = seatDtos.FirstOrDefault(x => x.Id == seat.SeatType);
                        if (seatDto != null)
                        {
                            seatDto.AvailableQuantity       += seat.Quantity;
                            seatDto.SeatsAvailabilityVersion = @event.Version;
                        }
                        else
                        {
                            // TODO should reject the entire update?
                            Trace.TraceError(
                                "Failed to locate Seat Type read model being updated with id {0}.", seat.SeatType);
                        }
                    }

                    repository.SaveChanges();
                }
                else
                {
                    Trace.TraceError(
                        "Failed to locate Seat Types read model for updated seat availability, with conference id {0}.",
                        @event.SourceId);
                }
            }
        }
        public bool TryProcessWithGuaranteedIdempotency(IVersionedEvent @event)
        {
            var eventKey     = this.GetEventKey(@event);
            var eventVersion = @event.Version;

            var lastProcessedEventVersion = this.lastProcessedEvents.TryGetValue(eventKey);

            if (eventVersion <= lastProcessedEventVersion)
            {
                // el evento ya fue procesado.
                return(false);
            }
            else if (lastProcessedEventVersion == eventVersion - 1)
            {
                // el evento vino en el orden correcto
                ((dynamic)this).Process((dynamic)@event);
                base.Update(new CorrelatedEventProcessed
                {
                    CorrelatedEventTypeName = eventKey,
                    CorrelatedEventVersion  = eventVersion
                });

                this.ProcessEarlyEventsIfApplicable();
            }
            else
            {
                // verificando que no se agregue el mismo evento con la misma version varias veces
                if (this.earlyReceivedEvents
                    .Where(e => e.Version == eventVersion &&
                           this.GetEventKey(e) == eventKey)
                    .Any())
                {
                    return(false);
                }

                // el evento vino prematuramente, se almacena para procesarlo en el orden correcto
                this.Update(new EarlyEventReceived
                {
                    Event = @event
                });
            }
            // El caso cuando el evento es muy nuevo todavia y falta otro anterior.
            return(true);
        }
 private EventData Serialize(IVersionedEvent e, string correlationId)
 {
     using (var writer = new StringWriter()) {
         serializer.Serialize(writer, e);
         var metadata = metadataProvider.GetMetadata(e);
         return(new EventData {
             Version = e.Version,
             SourceId = e.SourceId.ToString(),
             Payload = writer.ToString(),
             SourceType = sourceType,
             CorrelationId = correlationId,
             // Standard metadata
             AssemblyName = metadata.TryGetValue(StandardMetadata.AssemblyName),
             Namespace = metadata.TryGetValue(StandardMetadata.Namespace),
             TypeName = metadata.TryGetValue(StandardMetadata.TypeName),
             FullName = metadata.TryGetValue(StandardMetadata.FullName)
         });
     }
 }
Пример #30
0
        private void UpdateAvailableQuantity(IVersionedEvent @event, IEnumerable <SeatQuantity> seats)
        {
            using (var context = this._contextFactory.Invoke()) {
                var seatDtos = context.Set <SeatType>().Where(x => x.ConferenceId == @event.SourceId).ToList();

                if (seatDtos.Count > 0)
                {
                    var maxSeatsAvailabilityVersion = seatDtos.Max(x => x.SeatsAvailabilityVersion);

                    if (maxSeatsAvailabilityVersion >= @event.Version)
                    {
                        Trace.TraceWarning(
                            "Ignoring availability update message with version {1} for seat types with conference id {0}, last known version {2}",
                            @event.SourceId, @event.Version, maxSeatsAvailabilityVersion);

                        return;
                    }

                    foreach (var seat in seats)
                    {
                        var seatDto = seatDtos.FirstOrDefault(x => x.Id == seat.SeatType);

                        if (seatDto != null)
                        {
                            seatDto.AvailableQuantity       += seat.Quantity;
                            seatDto.SeatsAvailabilityVersion = @event.Version;
                        }
                        else
                        {
                            Trace.TraceError("Failed to locate Seat Type read model being updated with id {0}.", seat.SeatType);
                        }
                    }

                    context.SaveChanges();
                }
                else
                {
                    Trace.TraceError(
                        "Failed to locate Seat Types read model for updated seat availability, with conference id {0}.",
                        @event.SourceId);
                }
            }
        }
        public void when_reading_entity_then_rehydrates()
        {
            var newEvents = new IVersionedEvent[]
                             {
                                 new TestEvent { SourceId = id, Version = 2, Foo = "Baz" }                              
                             };
            var serialized = newEvents.Select(x => new EventData { Version = x.Version, Payload = Serialize(x) });
            this.id = Guid.NewGuid();
            var eventStore = new Mock<IEventStore>();
            this.memento = Mock.Of<IMemento>(x => x.Version == 1);
            var cache = new MemoryCache(Guid.NewGuid().ToString());
            cache.Add("TestOriginatorEntity_" + id.ToString(), new Tuple<IMemento, DateTime?>(this.memento, null), DateTimeOffset.UtcNow.AddMinutes(10));

            eventStore.Setup(x => x.Load(It.IsAny<string>(), 2)).Returns(serialized);
            var sut = new AzureEventSourcedRepository<TestOriginatorEntity>(eventStore.Object, Mock.Of<IEventStoreBusPublisher>(), new JsonTextSerializer(), new StandardMetadataProvider(), cache);

            var entity = sut.Find(id);

            Assert.NotNull(entity);
            Assert.Equal(id, entity.Id);
            Assert.Equal(memento, entity.Memento);
            Assert.Equal(newEvents, entity.History, new TestEventComparer());
        }
        public void when_reading_entity_then_rehydrates()
        {
            var events = new IVersionedEvent[]
                             {
                                 new TestEvent { SourceId = id, Version = 1, Foo = "Bar" },
                                 new TestEvent { SourceId = id, Version = 2, Foo = "Baz" }                              
                             };
            var serialized = events.Select(x => new EventData { Version = x.Version, Payload = Serialize(x) });
            this.id = Guid.NewGuid();
            var eventStore = new Mock<IEventStore>();
            eventStore.Setup(x => x.Load(It.IsAny<string>(), It.IsAny<int>())).Returns(serialized);
            var sut = new AzureEventSourcedRepository<TestEntity>(eventStore.Object, Mock.Of<IEventStoreBusPublisher>(), new JsonTextSerializer(), new StandardMetadataProvider(), null);

            var entity = sut.Find(id);

            Assert.NotNull(entity);
            Assert.Equal(id, entity.Id);
            Assert.Equal(events, entity.History, new TestEventComparer());
        }
Пример #33
0
 private Stream Serialize(IVersionedEvent @event)
 {
     return new Stream() {
         Key = new SourceKey(@event.Id, @event.GetType()),
         Version = @event.Version,
         Payload = _binarySerializer.Serialize(@event)
     };
 }
Пример #34
0
 private string SerializeToString(IVersionedEvent @event)
 {
     return _textSerializer.Serialize(@event);
 }