DispatchDomainEvents(IEventSourced <TAggregateId> aggregate, TransportMessage <TRequest, TAggregateId> transRequest
                             )
        {
            var hasError = false;
            var results  = new Dictionary <DomainEvent <TAggregateId>, DomainResult>();

            foreach (var @event in aggregate.ReleaseEvents())
            {
                if (!hasError)
                {
                    var result = await this.eventsDispatcher.DispatchEvent(
                        new TransportMessage <DomainEvent <TAggregateId>, TAggregateId>(
                            @event, transRequest.CorrelationId, transRequest.UserId, transRequest.RequestTimestamp));

                    results.Add(@event, result);
                    if (result.HasError)
                    {
                        hasError = true;
                    }
                }
                else
                {
                    results.Add(@event, DomainResult.Skipped);
                }
            }
            return(results);
        }
Exemplo n.º 2
0
        public IStream GetOrAdd(IEventSourced es)
        {
            var key    = Key(es);
            var stream = new Stream(key, es.Version, es.GetType());

            return(_streams.GetOrAdd(key, stream));
        }
        public static string BuildParentsString(this IEventSourced parent)
        {
            var parents = parent.Stream.Parents.ToList();

            parents.Add(parent.Id);
            return(parents.BuildParentsString());
        }
Exemplo n.º 4
0
        public static IEventSourced AndOne <TEvent>(this IEventSourced aggregate)
            where TEvent : IEvent
        {
            var singleEvent = aggregate.PendingEvents.OfType <TEvent>().Single();

            return(aggregate);
        }
        public static IEnumerable <Id> BuildParents(this IEventSourced parent)
        {
            var parents = parent.Stream.Parents.ToList();

            parents.Add(parent.Id);
            return(parents);
        }
 protected override Task <Dictionary <DomainEvent <PublicSchemeId>, DomainResult> > DispatchDomainEvents(
     IEventSourced <PublicSchemeId> aggregate, TransportMessage <DomainRequest <PublicSchemeId>, PublicSchemeId> transRequest)
 {
     aggregate.Should().BeSameAs(this.testScheme);
     this.dispatchDomainEvents_CallCount++;
     return(base.DispatchDomainEvents(aggregate, transRequest));
 }
 internal static void SetAggregate(
     this IEvent @event,
     IEventSourced aggregate) =>
 @event.IfTypeIs <IHaveExtensibleMetada>()
 .ThenDo(e => ((object)e.Metadata)
         .IfTypeIs <IDictionary <string, object> >()
         .ThenDo(metadata => { metadata["Aggregate"] = aggregate; }));
Exemplo n.º 8
0
 public virtual void OfAggregate(IEventSourced <TStreamId> aggregate)
 {
     if (aggregate.StreamId.Equals(default(TStreamId)) || !aggregate.StreamId.Equals(StreamId))
     {
         throw AggregateIdNotMatchException.GetAggregateIdNotMatchExceptionFromAggregateAndEvent(aggregate, this);
     }
     EventVersion = aggregate.CurrentVersion;
 }
Exemplo n.º 9
0
 public static IEventSourced AndNotAny <TEvent>(this IEventSourced aggregate)
     where TEvent : IEvent
 {
     if (aggregate.PendingEvents.OfType <TEvent>().Any())
     {
         throw new InvalidOperationException($"Not expected any '{typeof(TEvent).Name}' event type but there is/are {aggregate.PendingEvents.OfType<TEvent>().Count()} event/s of that type.");
     }
     return(aggregate);
 }
Exemplo n.º 10
0
        public void Save(IEventSourced eventSourced, Envelope <ICommand> command)
        {
            Assertions.NotNull(eventSourced, "eventSourced");
            Assertions.NotNull(command, "command");

            var eventSourcedType = eventSourced.GetType();
            var sourceInfo       = new SourceInfo(eventSourced.Id, eventSourcedType);
            var changedEvents    = eventSourced.GetChanges();

            var saved = false;

            try
            {
                if (_eventStore.Save(sourceInfo, changedEvents, command.MessageId))
                {
                    if (LogManager.Default.IsDebugEnabled)
                    {
                        LogManager.Default.DebugFormat(
                            "Persistent domain events successfully. aggregateRootType:{0},aggregateRootId:{1},version:{2}~{3}.",
                            eventSourcedType.FullName, eventSourced.Id, changedEvents.Min(p => p.Version), changedEvents.Max(p => p.Version));
                    }
                    saved = true;
                }
            }
            catch (Exception ex)
            {
                LogManager.Default.Error(ex,
                                         "Persistent domain events failed. aggregateRootType:{0},aggregateRootId:{1},version:{2}~{3}.",
                                         eventSourcedType.FullName, eventSourced.Id, changedEvents.Min(p => p.Version), changedEvents.Max(p => p.Version));
                throw ex;
            }

            if (!saved)
            {
                //由该命令产生的事件如果已保存,则取出之前的事件重新发送
                changedEvents = _eventStore.Find(sourceInfo, command.MessageId);

                _eventBus.Publish(sourceInfo, changedEvents, command);
                return;
            }

            try
            {
                _cacheProvider.GetCache(GetCacheRegion(eventSourcedType)).Put(GetCacheKey(eventSourcedType, eventSourced.Id), eventSourced);
            }
            catch (Exception ex)
            {
                LogManager.Default.Warn(ex,
                                        "Failed to refresh aggregate root to memory cache. aggregateRootType:{0},aggregateRootId:{1}.",
                                        eventSourcedType.FullName, eventSourced.Id);
            }

            _eventBus.Publish(sourceInfo, changedEvents, command);
        }
Exemplo n.º 11
0
        public bool ShouldCreateSnapshot(IEventSourced eventSourced)
        {
            var isShould = false;

            if ((eventSourced.Version + 1) % snapshotIntervalInEvents == 0)
            {
                isShould = true;
            }

            return(isShould);
        }
Exemplo n.º 12
0
        public async Task Handle(ConflictingEvents conflicts, IMessageHandlerContext ctx)
        {
            // Hydrate the entity, include all his parents
            IEventSourced parentBase = null;

            foreach (var parent in conflicts.Parents)
            {
                parentBase = await GetBase(conflicts.Bucket, parent.Item1, parent.Item2, parentBase).ConfigureAwait(false);
            }

            var target = await GetBase(conflicts.Bucket, conflicts.EntityType, conflicts.StreamId, parentBase).ConfigureAwait(false);

            var stream = target.Stream;

            Logger.Write(LogLevel.Info,
                         () => $"Weakly resolving {conflicts.Events.Count()} conflicts on stream [{conflicts.StreamId}] type [{target.GetType().FullName}] bucket [{target.Stream.Bucket}]");

            // No need to pull from the delayed channel or hydrate as below because this is called from the Delayed system which means
            // the conflict is not in delayed cache and GetBase above pulls the latest stream

            Logger.Write(LogLevel.Debug, () => $"Merging {conflicts.Events.Count()} conflicted events");
            try
            {
                foreach (var u in conflicts.Events)
                {
                    target.Conflict(u.Event as IEvent,
                                    metadata:
                                    new Dictionary <string, string>
                    {
                        { "ConflictResolution", ConcurrencyConflict.ResolveWeakly.ToString() }
                    });
                }
            }
            catch (NoRouteException e)
            {
                Logger.Write(LogLevel.Info, () => $"Failed to resolve conflict: {e.Message}");
                throw new ConflictResolutionFailedException("Failed to resolve conflict", e);
            }

            Logger.Write(LogLevel.Info, () => "Successfully merged conflicted events");

            if (stream.StreamVersion != stream.CommitVersion && target is ISnapshotting &&
                ((ISnapshotting)target).ShouldTakeSnapshot())
            {
                Logger.Write(LogLevel.Debug,
                             () => $"Taking snapshot of [{target.GetType().FullName}] id [{target.Id}] version {stream.StreamVersion}");
                var memento = ((ISnapshotting)target).TakeSnapshot();
                stream.AddSnapshot(memento);
            }
            // Dont call stream.Commit we are inside a UOW in this method it will do the commit for us
        }
Exemplo n.º 13
0
        public static IEventSourced AndAtLeastOne <TEvent>(this IEventSourced aggregate)
            where TEvent : IEvent
        {
            var hasEvents = aggregate.PendingEvents.OfType <TEvent>().Any();

            if (hasEvents)
            {
                return(aggregate);
            }
            else
            {
                throw new InvalidOperationException($"Aggregate of type {aggregate.GetType().Name} does not generated any event of type {typeof(TEvent).Name} so far.");
            }
        }
Exemplo n.º 14
0
        public static IEventSourced ThenExpectSingle <TEvent>(this IEventSourced aggregate)
        {
            var count = aggregate.PendingEvents.OfType <TEvent>().Count();

            if (count <= 0)
            {
                throw new InvalidOperationException($"There was expected to find a single event of type '{typeof(TEvent).Name}' but none were found.");
            }

            else if (count == 1)
            {
                return(aggregate);
            }

            throw new InvalidOperationException($"There was expected to find a single event of type '{typeof(TEvent).Name}' but there where found {count} events of that type.");
        }
        public async Task SaveAsync(TAggregate aggregate)
        {
            try
            {
                IEventSourced <TAggregateId> aggregateEventSourcedView = aggregate;

                foreach (var evt in aggregateEventSourcedView.UncommittedEvents)
                {
                    await _eventStore.AddEventAsync(evt).ConfigureAwait(false);

                    // TODO : create PublishEventAsync method to make this call async
                    PublishEvent(evt);
                }
                aggregateEventSourcedView.ClearUncommittedEvents();
            }
            catch (EventStoreNotReachableException ex)
            {
                throw new RepositoryException(CommunicationImpossibleWithPersistenceBackend, ex);
            }
        }
 public void Save(TAggregate aggregate)
 {
     try
     {
         IEventSourced <TAggregateId> aggregateEventSourcedView = aggregate;
         var  versionFromStore = _eventStore.GetNextExpectedVersion(aggregate.AggregateId);
         long count            = 0;
         foreach (var evt in aggregateEventSourcedView.UncommittedEvents)
         {
             VersionGuard(versionFromStore, evt);
             versionFromStore = _eventStore.AddEvent(evt);
             PublishEvent(evt);
             count++;
         }
         aggregateEventSourcedView.ClearUncommittedEvents();
     }
     catch (EventStoreNotReachableException ex)
     {
         throw new RepositoryException(CommunicationImpossibleWithPersistenceBackend, ex);
     }
 }
        public async Task <TAggregate> GetByIdAsync(TAggregateId id)
        {
            try
            {
                var aggregate = _emptyAggregateFactory.GetEmptyAggregate();
                IEventSourced <TAggregateId> aggregateEventSourcedView = aggregate;

                foreach (var evt in await _eventStore.ReadEventsAsync(id))
                {
                    aggregateEventSourcedView.ProcessEvent(evt.DomainEvent, evt.Version);
                }
                return(aggregate);
            }
            catch (AggregateNotFoundEventStoreException)
            {
                return(null);
            }
            catch (EventStoreNotReachableException ex)
            {
                throw new RepositoryException(CommunicationImpossibleWithPersistenceBackend, ex);
            }
        }
        public TAggregate GetById(TAggregateId id)
        {
            try
            {
                var aggregate = _emptyAggregateFactory.GetEmptyAggregate();
                IEventSourced <TAggregateId> aggregateEventSourcedView = aggregate;

                foreach (var evt in _eventStore.ReadEvents(id))
                {
                    //aggregate.RaiseEvent(evt.DomainEvent);
                    aggregateEventSourcedView.ProcessEvent(evt.DomainEvent, evt.Version);
                }
                aggregateEventSourcedView.ClearUncommittedEvents();
                return(aggregate);
            }
            catch (AggregateNotFoundEventStoreException)
            {
                return(null);
            }
            catch (EventStoreNotReachableException ex)
            {
                throw new RepositoryException(CommunicationImpossibleWithPersistenceBackend, ex);
            }
        }
Exemplo n.º 19
0
 /// <summary>
 /// 删除该聚合根下的溯源事件
 /// </summary>
 public void Delete(IEventSourced aggregateRoot)
 {
     this.Delete(aggregateRoot.GetType(), aggregateRoot.Id);
 }
Exemplo n.º 20
0
        /// <summary>
        /// 保存聚合事件。
        /// </summary>
        public void Save(IEventSourced aggregateRoot, string correlationId)
        {
            if (string.IsNullOrWhiteSpace(correlationId)) {
                if (_logger.IsWarnEnabled)
                    _logger.Warn("Not use command to modify the state of the aggregate root.");
            }

            var aggregateRootType = aggregateRoot.GetType();
            var aggregateRootId = aggregateRoot.Id;
            var events = aggregateRoot.GetEvents();
            var key = new SourceKey(aggregateRootId, aggregateRootType);

            if (_eventStore.Save(key, correlationId, () => events.Select(Serialize))) {
                if (_logger.IsDebugEnabled)
                    _logger.DebugFormat("Domain events persistent completed. aggregateRootId:{0}, aggregateRootType:{1}, commandId:{2}.",
                        aggregateRootId, aggregateRootType.FullName, correlationId);

                _cache.Set(aggregateRoot, aggregateRoot.Id);
            }
            else {
                events = _eventStore.FindAll(key, correlationId).Select(Deserialize).OfType<IVersionedEvent>().OrderBy(p => p.Version);

                if (_logger.IsDebugEnabled)
                    _logger.DebugFormat("The command generates events have been saved, load from storage. aggregateRootId:{0}, aggregateRootType:{1}, commandId:{2}.",
                        aggregateRootId, aggregateRootType.FullName, correlationId);
            }

            List<IEvent> pendingEvents = new List<IEvent>();
            if (string.IsNullOrWhiteSpace(correlationId)) {
                pendingEvents.AddRange(events);
            }
            else {
                pendingEvents.Add(Convert(key, correlationId, events));
            }

            var eventPublisher = aggregateRoot as IEventPublisher;
            if (eventPublisher != null) {
                var otherEvents = eventPublisher.Events.Where(p => !(p is IVersionedEvent));
                pendingEvents.AddRange(otherEvents);
            }
            _eventBus.Publish(pendingEvents);

            var snapshot = Serialize(key, aggregateRoot);
            if (!_snapshotPolicy.ShouldbeCreateSnapshot(snapshot))
                return;

            try {
                if (_snapshotStore.Save(snapshot) && _logger.IsDebugEnabled)
                    _logger.DebugFormat("make snapshot completed. aggregateRootId:{0},aggregateRootType:{1},version:{2}.",
                       aggregateRootId, aggregateRootType.FullName, aggregateRoot.Version);
            }
            catch (Exception ex) {
                if (_logger.IsWarnEnabled)
                    _logger.Warn(ex,
                        "snapshot persistent failed. aggregateRootId:{0},aggregateRootType:{1},version:{2}.",
                        aggregateRootId, aggregateRootType.FullName, aggregateRoot.Version);
            }
        }
Exemplo n.º 21
0
 public static IEnumerable <TEvent> EventsOfType <TEvent>(this IEventSourced aggregate)
     where TEvent : IEvent
 {
     return(aggregate.PendingEvents.OfType <TEvent>().AsEnumerable());
 }
Exemplo n.º 22
0
 public void OfAggregate(IEventSourced <int> aggregate)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 23
0
 private static string GetStandardizedErrorMessage <TAggregateId>(IEventSourced <TAggregateId> aggregate, DomainEventBase <TAggregateId> evt)
 => $"The StreamId {aggregate.StreamId} of the aggregate don't match the recorded StreamId {evt.StreamId} of the Event.";
Exemplo n.º 24
0
 public static AggregateIdNotMatchException GetAggregateIdNotMatchExceptionFromAggregateAndEvent <TAggregateId>(IEventSourced <TAggregateId> aggregate,
                                                                                                                DomainEventBase <TAggregateId> evt,
                                                                                                                Exception inner)
 => new AggregateIdNotMatchException(GetStandardizedErrorMessage(aggregate, evt), inner);
Exemplo n.º 25
0
 public static TEvent SingleEvent <TEvent>(this IEventSourced aggregate)
     where TEvent : IEvent
 {
     return((TEvent)aggregate.Events.Single());
 }
Exemplo n.º 26
0
 internal static IEnumerable <string> ETags(this IEventSourced eventSourced)
 {
     return(eventSourced.IfTypeIs <EventSourcedAggregate>()
            .Then(a => a.ETags())
            .Else(() => new string[0]));
 }
Exemplo n.º 27
0
        /// <summary>
        /// 保存聚合事件。
        /// </summary>
        public void Save(IEventSourced aggregateRoot, string correlationId)
        {
            if (string.IsNullOrWhiteSpace(correlationId)) {
                if (_logger.IsWarnEnabled)
                    _logger.Warn("Not use command to modify the state of the aggregate root.");
            }

            var aggregateRootType = aggregateRoot.GetType();
            var aggregateRootId = aggregateRoot.Id;
            var events = aggregateRoot.GetEvents();
            var key = new SourceKey(aggregateRootId, aggregateRootType);            

            if (!_eventStore.EventPersisted(key, correlationId)) {
                _eventStore.Save(key, correlationId, events.Select(Serialize));

                if (_logger.IsInfoEnabled)
                    _logger.InfoFormat("sourcing events persistent completed. aggregateRootId:{0},aggregateRootType:{1}.",
                        aggregateRootId, aggregateRootType.FullName);
            }
            else {
                events = _eventStore.FindAll(key, correlationId).Select(Deserialize).OfType<IVersionedEvent>().OrderBy(p => p.Version);

                if (_logger.IsInfoEnabled)
                    _logger.InfoFormat("the command generates events have been saved, load from storage. command id:{0}", 
                        correlationId);
            }

            if (string.IsNullOrWhiteSpace(correlationId)) {
                _eventBus.Publish(events);
            }
            else {
                _eventBus.Publish(Convert(key, correlationId, events));
            }

            var eventPublisher = aggregateRoot as IEventPublisher;
            if (eventPublisher != null) {
                eventPublisher.Events.ForEach(item => {
                    if (item is IVersionedEvent)
                        return;
                });
            }

            //if (_logger.IsInfoEnabled)
            //    _logger.InfoFormat("publish all events. event:{0}", _textSerializer.Serialize(events));

            _cache.Set(aggregateRoot, aggregateRoot.Id);

            var snapshot = Serialize(key, aggregateRoot);
            if (!_snapshotPolicy.ShouldbeCreateSnapshot(snapshot))
                return;

            try {
                if (_snapshotStore.Save(snapshot) && _logger.IsInfoEnabled)
                    _logger.InfoFormat("make snapshot completed. aggregateRootId:{0},aggregateRootType:{1},version:{2}.",
                       aggregateRootId, aggregateRootType.FullName, aggregateRoot.Version);
            }
            catch (Exception ex) {
                if (_logger.IsWarnEnabled)
                    _logger.Warn(ex,
                        "snapshot persistent failed. aggregateRootId:{0},aggregateRootType:{1},version:{2}.",
                        aggregateRootId, aggregateRootType.FullName, aggregateRoot.Version);
            }
        }
Exemplo n.º 28
0
 private Stream Serialize(SourceKey sourceKey, IEventSourced aggregateRoot)
 {
     return new Stream() {
         Key = sourceKey,
         Version = aggregateRoot.Version,
         Payload = _binarySerializer.Serialize(aggregateRoot)
     };
 }
Exemplo n.º 29
0
 public override void OfAggregate(IEventSourced <int> aggregate) => EventVersion = aggregate.CurrentVersion;
Exemplo n.º 30
0
 public static TEvent OneEventOfType <TEvent>(this IEventSourced aggregate)
     where TEvent : IEvent
 {
     return(aggregate.PendingEvents.OfType <TEvent>().Single());
 }
Exemplo n.º 31
0
Arquivo: Stream.cs Projeto: zedr0n/ZES
 /// <summary>
 /// Initializes a new instance of the <see cref="Stream"/> class.
 /// </summary>
 /// <param name="es">Event sourced instance</param>
 /// <param name="timeline">Target timeline</param>
 public Stream(IEventSourced es, string timeline = "")
     : this(es.Id, es.GetType().Name, ExpectedVersion.NoStream, timeline)
 {
 }
Exemplo n.º 32
0
 public Guid Key(IEventSourced es)
 {
     return(es.Id);
 }
Exemplo n.º 33
0
 public static string GetEventStoreStream <TKey>(this IEventSourced <TKey> aggregate)
 {
     return(string.Format("{0}-{1}", aggregate.GetType().Name, aggregate.Id));
 }
Exemplo n.º 34
0
 public bool ShouldCreateSnapshot(IEventSourced eventSourced)
 {
     return(false);
 }