Пример #1
0
        public async Task ChooseSkill(Guid playerId, LevelUpPlayerComand levelUpCommand)
        {
            var eventStoreResult = await _eventStore.LoadAsync <Player>(playerId);

            var player      = eventStoreResult.Value;
            var skillResult = await _readModelRepository.LoadAsync <SkillReadModel>(levelUpCommand.SkillId);

            var result = player.ChooseSkill(skillResult.Value);

            (await _eventStore.AppendAsync(result.DomainEvents, eventStoreResult.Version)).Check();
        }
Пример #2
0
        public async Task StartSeason(StartSeasonCommand command)
        {
            var eventStoreResult = await _eventStore.LoadAsync <Season>(command.SeasonId);

            var season       = eventStoreResult.Value;
            var domainResult = season.StartSeason();
            var domainEvents = domainResult.DomainEvents.ToList();
            var result       = await _eventStore.AppendAsync(domainEvents, eventStoreResult.Version);

            result.Check();
        }
Пример #3
0
        public async Task FinishMatch(FinishMatchCommand command)
        {
            var eventStoreResult = await _eventStore.LoadAsync <Matchup>(command.MatchId);

            var match        = eventStoreResult.Value;
            var domainResult = match.Finish();

            domainResult.EnsureSucces();
            var storeResult = await _eventStore.AppendAsync(domainResult.DomainEvents, eventStoreResult.Version);

            storeResult.Check();
        }
Пример #4
0
        public async Task <string> CreateTeam(CreateTeamCommand createTeamCommand)
        {
            var readModelResult = await _readModelRepository.LoadAsync <RaceReadModel>(createTeamCommand.RaceId);

            var race         = readModelResult.Value;
            var domainResult = Team.Draft(
                race.RaceConfigId,
                createTeamCommand.TeamName,
                createTeamCommand.TrainerName, race.AllowedPlayers);
            await _eventStore.AppendAsync(domainResult.DomainEvents, 0);

            return(domainResult.DomainEvents.First().EntityId);
        }
Пример #5
0
        public async Task <ActionResult> WriteEvent()
        {
            var appendAsync = await _eventStore.LoadAsync <EntityTest>(_entityId);

            if (appendAsync.Is <NotFound>())
            {
                (await _eventStore.AppendAsync(new Event2(_entityId, "jeah"), 0)).Check();
            }
            else
            {
                (await _eventStore.AppendAsync(new Event2(_entityId, "jeah"), appendAsync.Version)).Check();
            }
            return(Ok());
        }
Пример #6
0
        public async Task AppendAsync(AggregateCommit aggregateCommit)
        {
            AggregateCommit transformedAggregateCommit = aggregateCommit;

            try
            {
                transformedAggregateCommit = aggregateCommitTransformer.Transform(aggregateCommit);
                await eventStore.AppendAsync(transformedAggregateCommit).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                logger.ErrorException(ex, () => $"Failed to append aggregate with id = {transformedAggregateCommit.AggregateRootId}. \n Exception: {ex.Message}");
                throw;
            }
        }
        public void SaveChanges()
        {
            var batch = _uncommittedEvents.ToArray();

            _eventStore.AppendAsync(batch).GetAwaiter().GetResult();
            _uncommittedEvents.Clear();
        }
Пример #8
0
        public async Task WriteEventsAsync(IEnumerable <Envelope <IEvent> > events)
        {
            Guard.NotNull(events, nameof(events));

            var eventArray = events.ToArray();

            if (eventArray.Length > 0)
            {
                var expectedVersion = UseEventSourcing() ? version : EtagVersion.Any;

                var commitId = Guid.NewGuid();

                foreach (var @event in eventArray)
                {
                    eventEnricher.Enrich(@event, ownerKey);
                }

                var eventStream = GetStreamName();
                var eventData   = GetEventData(eventArray, commitId);

                try
                {
                    await eventStore.AppendAsync(commitId, eventStream, expectedVersion, eventData);
                }
                catch (WrongEventVersionException ex)
                {
                    throw new InconsistentStateException(ex.CurrentVersion, ex.ExpectedVersion, ex);
                }

                versionEvents += eventArray.Length;
            }

            UpdateVersion();
        }
Пример #9
0
        public async Task WriteEventsAsync(IEnumerable <Envelope <IEvent> > events)
        {
            Guard.NotNull(events, nameof(@events));

            var eventArray = events.ToArray();

            if (eventArray.Length > 0)
            {
                var expectedVersion = UseEventSourcing() ? version : EtagVersion.Any;

                var commitId = Guid.NewGuid();

                var eventStream = GetStreamName();
                var eventData   = GetEventData(eventArray, commitId);

                try
                {
                    await eventStore.AppendAsync(commitId, GetStreamName(), expectedVersion, eventData);
                }
                catch (WrongEventVersionException ex)
                {
                    throw new DomainObjectVersionException(ownerKey.ToString(), ownerType, ex.CurrentVersion, ex.ExpectedVersion);
                }

                versionEvents += eventArray.Length;
            }

            UpdateVersion();
        }
Пример #10
0
        public async Task HandleAsync(MatchFinished domainEvent)
        {
            foreach (var playerProgression in domainEvent.PlayerProgressions)
            {
                var domainResults = new List <DomainResult>();
                var result        = await _eventStore.LoadAsync <Player>(playerProgression.PlayerId);

                var player = result.Value;

                switch (playerProgression.ProgressionEvent)
                {
                case ProgressionEvent.PlayerPassed:
                    domainResults.Add(player.Pass());
                    break;

                case ProgressionEvent.PlayerMadeCasualty:
                    domainResults.Add(player.Block());
                    break;

                case ProgressionEvent.PlayerMadeTouchdown:
                    domainResults.Add(player.Move());
                    break;

                case ProgressionEvent.NominatedMostValuablePlayer:
                    domainResults.Add(player.NominateForMostValuablePlayer());
                    break;
                }

                var domainEvents = domainResults.SelectMany(res => res.DomainEvents);

                var resultStore = await _eventStore.AppendAsync(domainEvents, result.Version);

                resultStore.Check();
            }
        }
Пример #11
0
        public async Task HandleAsync(SeasonStarted domainEvent)
        {
            var matchCreatedEvents = new List <IDomainEvent>();

            foreach (var gameDay in domainEvent.GameDays)
            {
                foreach (var matchup in gameDay.Matchups)
                {
                    var guestTeam = await _readModelRepository.LoadAsync <TeamReadModel>(matchup.TeamAsGuest);

                    var homeTeam = await _readModelRepository.LoadAsync <TeamReadModel>(matchup.TeamAtHome);

                    var domainEvents = Matchup.Create(
                        matchup.MatchId,
                        homeTeam.Value,
                        guestTeam.Value)
                                       .DomainEvents;
                    matchCreatedEvents.Add(domainEvents.Single());
                }
            }

            foreach (var createdEvent in matchCreatedEvents)
            {
                var result = await _eventStore.AppendAsync(createdEvent, 0);

                result.Check();
            }
        }
Пример #12
0
        public CommentsGrainTests()
        {
            A.CallTo(() => eventStore.AppendAsync(A <Guid> ._, A <string> ._, A <long> ._, A <ICollection <EventData> > ._))
            .Invokes(x => LastEvents = sut.GetUncommittedEvents().Select(x => x.To <IEvent>()).ToList());

            sut = new CommentsGrain(eventStore, eventDataFormatter);
            sut.ActivateAsync(Id).Wait();
        }
        public async Task Should_write_to_store_with_previous_position()
        {
            SetupEventStore(3);

            var actualObject = await sut.GetSingleAsync <MyStatefulObject>(key);

            Assert.Same(statefulObject, actualObject);

            await statefulObject.WriteEventsAsync(new MyEvent(), new MyEvent());

            await statefulObject.WriteEventsAsync(new MyEvent(), new MyEvent());

            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 2, A <ICollection <EventData> > .That.Matches(x => x.Count == 2)))
            .MustHaveHappened();
            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 4, A <ICollection <EventData> > .That.Matches(x => x.Count == 2)))
            .MustHaveHappened();
        }
        public async Task Should_write_to_store_with_previous_position()
        {
            SetupEventStore(3);

            var persistedEvents = new List <IEvent>();
            var persistence     = sut.WithEventSourcing <object, string>(key, x => persistedEvents.Add(x.Payload));

            await persistence.ReadAsync();

            await persistence.WriteEventsAsync(new[] { new MyEvent(), new MyEvent() }.Select(Envelope.Create));

            await persistence.WriteEventsAsync(new[] { new MyEvent(), new MyEvent() }.Select(Envelope.Create));

            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 2, A <ICollection <EventData> > .That.Matches(x => x.Count == 2)))
            .MustHaveHappened();
            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 4, A <ICollection <EventData> > .That.Matches(x => x.Count == 2)))
            .MustHaveHappened();
        }
Пример #15
0
        private void PersistEventAsync(EventCommittingContext context, int retryTimes)
        {
            _ioHelper.TryAsyncActionRecursively("PersistEventAsync",
                                                () => _eventStore.AppendAsync(context.EventStream),
                                                currentRetryTimes => PersistEventAsync(context, currentRetryTimes),
                                                result =>
            {
                if (result.Data == EventAppendResult.Success)
                {
                    if (_logger.IsDebugEnabled)
                    {
                        _logger.DebugFormat("Persist event success, {0}", context.EventStream);
                    }

                    Task.Factory.StartNew(x =>
                    {
                        var currentContext = x as EventCommittingContext;
                        PublishDomainEventAsync(currentContext.ProcessingCommand, currentContext.EventStream);
                    }, context);

                    if (context.Next != null)
                    {
                        PersistEventAsync(context.Next, 0);
                    }
                    else
                    {
                        context.MailBox.TryRun(true);
                    }
                }
                else if (result.Data == EventAppendResult.DuplicateEvent)
                {
                    if (context.EventStream.Version == 1)
                    {
                        HandleFirstEventDuplicationAsync(context, 0);
                    }
                    else
                    {
                        _logger.WarnFormat("Persist event has concurrent version conflict, eventStream: {0}", context.EventStream);
                        ResetCommandMailBoxConsumingSequence(context, context.ProcessingCommand.Sequence).ContinueWith(t => { }).ConfigureAwait(false);
                    }
                }
                else if (result.Data == EventAppendResult.DuplicateCommand)
                {
                    _logger.WarnFormat("Persist event has duplicate command, eventStream: {0}", context.EventStream);
                    ResetCommandMailBoxConsumingSequence(context, context.ProcessingCommand.Sequence + 1).ContinueWith(t => { }).ConfigureAwait(false);
                    TryToRepublishEventAsync(context, 0);
                }
            },
                                                () => string.Format("[eventStream:{0}]", context.EventStream),
                                                errorMessage =>
            {
                _logger.Fatal(string.Format("Persist event has unknown exception, the code should not be run to here, errorMessage: {0}", errorMessage));
            },
                                                retryTimes, true);
        }
Пример #16
0
        public async Task Should_write_to_store_with_previous_position()
        {
            SetupEventStore(3);

            var persistedEvents = new List <IEvent>();
            var persistence     = sut.WithEventSourcing(None.Type, key, x => persistedEvents.Add(x.Payload));

            await persistence.ReadAsync();

            await persistence.WriteEventAsync(Envelope.Create(new MyEvent()));

            await persistence.WriteEventAsync(Envelope.Create(new MyEvent()));

            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 2, A <ICollection <EventData> > .That.Matches(x => x.Count == 1)))
            .MustHaveHappened();
            A.CallTo(() => eventStore.AppendAsync(A <Guid> .Ignored, key, 3, A <ICollection <EventData> > .That.Matches(x => x.Count == 1)))
            .MustHaveHappened();
            A.CallTo(() => eventEnricher.Enrich(A <Envelope <IEvent> > .Ignored, key))
            .MustHaveHappenedTwiceExactly();
        }
        public void Run([EventHubTrigger("vs-eventsourcing-eventhub", Connection = "EventHubConnectionString")] string[] messages, FunctionContext context)
        {
            var logger = context.GetLogger("EventStorage");

            foreach (var message in messages)
            {
                logger.LogDebug($"C# Kafka trigger function processed a message: {message}");

                _eventStore.AppendAsync(message.To <Message <Guid, EventBase> >().Value).GetAwaiter().GetResult();
            }
        }
Пример #18
0
        public async Task Should_write_events_to_store()
        {
            SetupEventStore(3);

            var persistedEvents = Save.Events();
            var persistence     = sut.WithEventSourcing(None.Type, key, persistedEvents.Write);

            await persistence.ReadAsync();

            await persistence.WriteEventAsync(Envelope.Create(new MyEvent()));

            await persistence.WriteEventAsync(Envelope.Create(new MyEvent()));

            A.CallTo(() => eventStore.AppendAsync(A <Guid> ._, key, 2, A <ICollection <EventData> > .That.Matches(x => x.Count == 1)))
            .MustHaveHappened();
            A.CallTo(() => eventStore.AppendAsync(A <Guid> ._, key, 3, A <ICollection <EventData> > .That.Matches(x => x.Count == 1)))
            .MustHaveHappened();

            A.CallTo(() => snapshotStore.WriteAsync(A <string> ._, A <int> ._, A <long> ._, A <long> ._))
            .MustNotHaveHappened();
        }
        public async Task Should_Append_EventStream()
        {
            //Arrange
            var eventStream = GetTestDomainEventStream();

            //Act
            await _store.AppendAsync(eventStream);

            //Assert
            var result = await _store.FindAsync(eventStream.AggregateRootId, eventStream.Version);

            result.Status.ShouldBe(AsyncTaskStatus.Success);
            result.Data.AggregateRootId.ShouldBe(eventStream.AggregateRootId);
            result.Data.AggregateRootTypeName.ShouldBe(eventStream.AggregateRootTypeName);
            result.Data.Version.ShouldBe(eventStream.Version);
            foreach (var @event in result.Data.Events)
            {
                eventStream.Events.ToList().Select(e => e.AggregateRootStringId).ShouldContain(@event.AggregateRootStringId);
            }
            result.Data.CommandId.ShouldBe(eventStream.CommandId);
            result.ShouldNotBeNull();
        }
Пример #20
0
        private void PersistEventAsync(EventCommittingContext context, int retryTimes)
        {
            _ioHelper.TryAsyncActionRecursively("PersistEventAsync",
                                                () => _eventStore.AppendAsync(context.EventStream),
                                                currentRetryTimes => PersistEventAsync(context, currentRetryTimes),
                                                result =>
            {
                if (result.Data == EventAppendResult.Success)
                {
                    if (_logger.IsDebugEnabled)
                    {
                        _logger.DebugFormat("Persist event success, {0}", context.EventStream);
                    }

                    Task.Factory.StartNew(x =>
                    {
                        var currentContext = x as EventCommittingContext;
                        PublishDomainEventAsync(currentContext.ProcessingCommand, currentContext.EventStream);
                    }, context);

                    TryProcessNextContext(context);
                }
                else if (result.Data == EventAppendResult.DuplicateEvent)
                {
                    //如果是当前事件的版本号为1,则认为是在创建重复的聚合根
                    if (context.EventStream.Version == 1)
                    {
                        HandleFirstEventDuplicationAsync(context, 0);
                    }
                    //如果事件的版本大于1,则认为是更新聚合根时遇到并发冲突了,则需要进行重试;
                    else
                    {
                        _logger.WarnFormat("Persist event has concurrent version conflict, eventStream: {0}", context.EventStream);
                        ResetCommandMailBoxConsumingSequence(context, context.ProcessingCommand.Sequence);
                    }
                }
                else if (result.Data == EventAppendResult.DuplicateCommand)
                {
                    _logger.WarnFormat("Persist event has duplicate command, eventStream: {0}", context.EventStream);
                    ResetCommandMailBoxConsumingSequence(context, context.ProcessingCommand.Sequence + 1);
                    TryToRepublishEventAsync(context, 0);
                    context.EventMailBox.RegisterForExecution(true);
                }
            },
                                                () => string.Format("[eventStream:{0}]", context.EventStream),
                                                errorMessage =>
            {
                _logger.Fatal(string.Format("Persist event has unknown exception, the code should not be run to here, errorMessage: {0}", errorMessage));
            },
                                                retryTimes, true);
        }
Пример #21
0
        public async Task Save <TAggregate>(TAggregate aggregate, CancellationToken cancellationToken)
            where TAggregate : IEventSourcedAggregate
        {
            if (aggregate == null)
            {
                throw new ArgumentNullException(nameof(aggregate));
            }

            var changeset = aggregate.GetChangeSet();

            foreach (var @event in changeset.Events)
            {
                await _eventStore.AppendAsync(aggregate.Id, @event, cancellationToken);
            }
        }
Пример #22
0
        public async Task CreateAggregate()
        {
            var id          = Guid.NewGuid();
            var color       = "Green";
            var createApple = new CreateApple(id, color,
                                              new CommandMeta(Guid.NewGuid(), Guid.NewGuid()));
            var aggregate = new AppleAggregate(createApple);

            var events = aggregate.GetUncommittedEvents();
            await _eventStore.AppendAsync(events);

            Assert.Equal(id, aggregate.Id);
            Assert.Equal(aggregate.Color, color);
            Assert.Single(events);
        }
Пример #23
0
        private async Task HandleEventAsync(IBackupReader reader, IEnumerable <IBackupHandler> handlers, string stream, Envelope <IEvent> @event)
        {
            if (@event.Payload is AppCreated appCreated)
            {
                if (!string.IsNullOrWhiteSpace(CurrentJob.NewAppName))
                {
                    appCreated.Name = CurrentJob.NewAppName;

                    CurrentJob.AppId = NamedId.Of(appCreated.AppId.Id, CurrentJob.NewAppName);
                }
                else
                {
                    CurrentJob.AppId = appCreated.AppId;
                }

                await CreateContextAsync(reader);
            }

            if (@event.Payload is SquidexEvent squidexEvent && squidexEvent.Actor != null)
            {
                if (restoreContext.UserMapping.TryMap(squidexEvent.Actor, out var newUser))
                {
                    squidexEvent.Actor = newUser;
                }
            }

            if (@event.Payload is AppEvent appEvent)
            {
                appEvent.AppId = CurrentJob.AppId;
            }

            foreach (var handler in handlers)
            {
                if (!await handler.RestoreEventAsync(@event, restoreContext))
                {
                    return;
                }
            }

            var eventData   = eventDataFormatter.ToEventData(@event, @event.Headers.CommitId());
            var eventCommit = new List <EventData> {
                eventData
            };

            await eventStore.AppendAsync(Guid.NewGuid(), stream, eventCommit);

            Log($"Read {reader.ReadEvents} events and {reader.ReadAttachments} attachments.", true);
        }
Пример #24
0
        public async Task HandleAsync(PlayerBought domainEvent)
        {
            var readModel = await _readModelRepository.LoadAllAsync <RaceReadModel>();

            var races = readModel.Value.ToList();
            var race  = races.SingleOrDefault(r =>
                                              r.AllowedPlayers.Any(a => a.PlayerTypeId == domainEvent.PlayerTypeId));
            var playerRule = race.AllowedPlayers.Single(a => a.PlayerTypeId == domainEvent.PlayerTypeId);
            var result     = Player.Create(
                domainEvent.PlayerId,
                domainEvent.TeamId,
                domainEvent.PlayerPositionNumber,
                playerRule);
            var storeResult = await _eventStore.AppendAsync(result.DomainEvents, 0);

            storeResult.Check();
        }
Пример #25
0
        private async Task ReadEventsAsync(BackupReader reader)
        {
            await reader.ReadEventsAsync(streamNameResolver, async (storedEvent) =>
            {
                var @event = eventDataFormatter.Parse(storedEvent.Data);

                if (@event.Payload is SquidexEvent squidexEvent)
                {
                    squidexEvent.Actor = actor;
                }

                if (@event.Payload is AppCreated appCreated)
                {
                    CurrentJob.AppId = appCreated.AppId.Id;

                    if (!string.IsNullOrWhiteSpace(CurrentJob.NewAppName))
                    {
                        appCreated.Name = CurrentJob.NewAppName;
                    }
                }

                if (@event.Payload is AppEvent appEvent && !string.IsNullOrWhiteSpace(CurrentJob.NewAppName))
                {
                    appEvent.AppId = new NamedId <Guid>(appEvent.AppId.Id, CurrentJob.NewAppName);
                }

                foreach (var handler in handlers)
                {
                    await handler.RestoreEventAsync(@event, CurrentJob.AppId, reader, actor);
                }

                var eventData   = eventDataFormatter.ToEventData(@event, @event.Headers.CommitId());
                var eventCommit = new List <EventData> {
                    eventData
                };

                await eventStore.AppendAsync(Guid.NewGuid(), storedEvent.StreamName, eventCommit);

                Log($"Read {reader.ReadEvents} events and {reader.ReadAttachments} attachments.", true);
            });

            Log("Reading events completed.");
        }
Пример #26
0
        public async Task HandleAsync(AggregateCommit aggregateCommit)
        {
            foreach (var migration in migrations)
            {
                if (migration.ShouldApply(aggregateCommit))
                    aggregateCommit = migration.Apply(aggregateCommit);
            }

            await eventStore.AppendAsync(aggregateCommit).ConfigureAwait(false);

            try
            {
                theLogic.OnAggregateCommit(aggregateCommit);
            }
            catch (Exception ex)
            {
                logger.ErrorException(ex, () => "We do not trust people that inject their custom logic into important LOOOOONG running processes like thsi one.");
            }
        }
        public async Task Add_Comand_Event_Handler_Async()
        {
            var command = new CreateCar(Guid.NewGuid(), "mercedes", 2,
                                        new CommandMeta()
            {
                CorrelationId = Guid.NewGuid(), UserId = "geno"
            });
            var carAgr = new CarAgr(command);


            await _eventStore.AppendAsync(carAgr.GetUncommittedEvents());


            var RestoreAgr = await _eventStore.RestoreAsync(carAgr.Id);



            Assert.Equal(carAgr.Id, RestoreAgr.Id);
        }
Пример #28
0
        private async Task SaveAggregateChangesAsync(ICorrelationContext context, AggregateRoot aggregate)
        {
            var uncommittedEvents = aggregate.UncommittedEvents
                                    .OrderBy(o => o.CreatedAt)
                                    .Cast <UncommittedEvent>()
                                    .Select(GenerateMetadata)
                                    .ToList();

            await _eventStore.AppendAsync(aggregate, uncommittedEvents);

            foreach (var @event in uncommittedEvents)
            {
                await _busClient.PublishAsync(@event.Data, context);
            }
            await _eventStore.Commit(aggregate);

            //ToDo remove events from store if failed
            aggregate.UpdateVersion(aggregate.Sequence);
            aggregate.ClearUncommittedEvents();
        }
Пример #29
0
        public async Task SaveAsync(TA aggregateRoot, CancellationToken cancellationToken = default)
        {
            var events = aggregateRoot.FlushUncommittedEvents();

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

            await _eventStore.AppendAsync(events, cancellationToken);

            try
            {
                await _eventPublisher.PublishAsync(events, cancellationToken);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
Пример #30
0
        private async Task <object> Upsert <TCommand>(TCommand command, Func <TCommand, object> handler) where TCommand : CommentsCommand
        {
            Guard.NotNull(command);
            Guard.NotNull(handler);

            if (command.ExpectedVersion > EtagVersion.Any && command.ExpectedVersion != Version)
            {
                throw new DomainObjectVersionException(Key, GetType(), Version, command.ExpectedVersion);
            }

            var prevVersion = version;

            try
            {
                var result = handler(command);

                if (uncommittedEvents.Count > 0)
                {
                    var commitId = Guid.NewGuid();

                    var eventData = uncommittedEvents.Select(x => eventDataFormatter.ToEventData(x, commitId)).ToList();

                    await eventStore.AppendAsync(commitId, streamName, prevVersion, eventData);
                }

                events.AddRange(uncommittedEvents);

                return(result);
            }
            catch
            {
                version = prevVersion;

                throw;
            }
            finally
            {
                uncommittedEvents.Clear();
            }
        }