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(); }
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(); }
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(); }
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); }
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()); }
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(); }
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(); }
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(); }
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(); } }
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(); } }
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(); }
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); }
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(); } }
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(); }
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); }
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); } }
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); }
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); }
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(); }
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."); }
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); }
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(); }
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; } }
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(); } }