private static void RegisterEventListeners(IEventStream stream) { var observationMutator = new ObservationMutator(); var observationStore = new AggregateStore <Observation>(Observations); var arrived = new AnimalArrivedEventProcessor(observationMutator, observationStore); stream.RegisterListener(arrived); var animalMutator = new AnimalMutator(); var animalStore = new AggregateStore <Animal>(Animals); var created = new AnimalCreatedEventProcessor(animalMutator, animalStore); stream.RegisterListener(created); var mobMutator = new MobMutator(); var mobStore = new AggregateStore <Mob>(Mobs); var mobCreated = new MobCreatedEventProcessor(mobMutator, mobStore); stream.RegisterListener(mobCreated); var animalHistory = new AnimalIntoMobExtrapolator(stream, MobHistories); var intoMob = new AnimalIntoMobEventProcessor(animalHistory); stream.RegisterListener(intoMob); var animalUpdated = new AnimalUpdatedEventProcessor(animalMutator, animalStore); stream.RegisterListener(animalUpdated); }
private async Task RecoverStateAsync(IContext ctx) { ActorId = ctx.Self.Id; var state = await AggregateStore.Load <TState>(ctx.Self.Id); State = state.Root as TState; }
public async Task ShouldSuccesfullyPersistAndHydrateEventsFromAggregate() { // ARRANGE var testAggregate = new TestAggregate(Guid.NewGuid()); //var eventRepository = new SqlServerEventRepository("Server=tcp:shuffle.database.windows.net,1433;Initial Catalog=Shuffle;Persist Security Info=False;User ID=kvinther;Password=k1617v_KV;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Application Name=Shuffle;"); var eventRepository = new SqlServerEventRepository("Server=.\\sqlexpress;Initial Catalog=VerdunEvents;Persist Security Info=False;Trusted_Connection=True;MultipleActiveResultSets=False;Connection Timeout=30;Application Name=Shuffle;"); var aggregateFactory = new DefaultAggregateFactory(); var repository = new AggregateRepository(eventRepository, aggregateFactory); var listener = new BasicEventListener(); IAggregateCache cache = null; //cache = new RedisAggregateCache("shuffle.redis.cache.windows.net:6380,password=z0cYd5K7aNjtE9tl8x6nxYa2lK5TwrJcB1aHsZGCx5Q=,ssl=True,abortConnect=False"); cache = new RedisAggregateCache("localhost"); var store = new AggregateStore(repository, listener, aggregateCache: cache); // ACT var now = DateTime.Now; for (var i = 1; i <= 50; i++) { testAggregate.PublishTestEvent($"{i}"); await store.Save(testAggregate); var hydratedTestAggregate = store.GetById <TestAggregate>(testAggregate.Id); // ASSERT Assert.AreEqual(testAggregate.Id, hydratedTestAggregate.Id); Assert.AreEqual(testAggregate.Version, hydratedTestAggregate.Version); Assert.AreEqual(testAggregate.State, hydratedTestAggregate.State); } Debug.WriteLine($"Total time: {(DateTime.Now - now):g}"); }
private void Execute(ChangeUser command) { var user = AggregateStore.GetAggregate <User>(command.Id); user.Change(command.Name, command.EMail, command.Password); AggregateStore.Save(user); }
private void Execute(DeleteUser command) { var user = AggregateStore.GetAggregate <User>(command.Id); user.Delete(); AggregateStore.Save(user); }
private async Task ValidateScheduleHappens(Func <IJob, IJobScheduler, Task <IJobId> > schedule) { // Arrange var testId = ThingyId.New; var pingId = PingId.New; var executeCommandJob = PublishCommandJob.Create(new ThingyPingCommand(testId, pingId), Resolver); // Act var jobId = await schedule(executeCommandJob, _jobScheduler).ConfigureAwait(false); // Assert var start = DateTimeOffset.Now; while (DateTimeOffset.Now < start + TimeSpan.FromSeconds(20)) { var testAggregate = await AggregateStore.LoadAsync <ThingyAggregate, ThingyId>(testId, CancellationToken.None).ConfigureAwait(false); if (!testAggregate.IsNew) { await AssertJobIsSuccessfullAsync(jobId).ConfigureAwait(false); Assert.Pass(); } await Task.Delay(TimeSpan.FromSeconds(0.2)).ConfigureAwait(false); } Assert.Fail("Aggregate did not receive the command as expected"); }
public void CanCallDisposeMoreThanOnce() { using (var aggregateStore = new AggregateStore(new Mock <IApplyEvents>().Object, new Mock <IStoreSnapshots>().Object, new Mock <IStoreEvents>().Object)) { aggregateStore.Dispose(); aggregateStore.Dispose(); } }
public void CreateNewAggregateIfNoExistingEventStream() { var id = GuidStrategy.NewGuid(); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); var aggregate = aggregateStore.Get(typeof(FakeAggregate), id); Assert.Equal(0, aggregate.Version); }
public void CanCallDisposeMoreThanOnce() { using (var aggregateStore = new AggregateStore(new Mock<IApplyEvents>().Object, new Mock<IStoreSnapshots>().Object, new Mock<IStoreEvents>().Object)) { aggregateStore.Dispose(); aggregateStore.Dispose(); } }
private Task <ThingySaga> LoadSagaAsync(ThingyId thingyId) { // This is specified in the ThingySagaLocator var expectedThingySagaId = new ThingySagaId($"saga-{thingyId.Value}"); return(AggregateStore.LoadAsync <ThingySaga, ThingySagaId>( expectedThingySagaId, CancellationToken.None)); }
public void CaptureAggregateTypeIfFirstCommit() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 0); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); eventStore.Verify(mock => mock.Save(It.Is <Commit>(c => c.Headers[Header.Aggregate] == typeof(FakeAggregate).GetFullNameWithAssembly())), Times.Once()); }
public void SaveSnapshotIfRequired() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 9); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); snapshotStore.Verify(mock => mock.Save(It.Is <Snapshot>(s => s.StreamId == aggregate.Id && s.Version == 10)), Times.Once()); }
public void IncrementAggregateVersionIfSuccessful() { var version = 11; var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), version); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); Assert.Equal(version + 1, aggregate.Version); }
public void RebuildAggregateIfExistingEventStream() { var id = GuidStrategy.NewGuid(); var events = new Event[] { new FakeEvent(), new FakeEvent() }; var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); eventStore.Setup(mock => mock.GetStream(id, 1)).Returns(new[] { new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 1, HeaderCollection.Empty, new EventCollection(events)) }); var aggregate = aggregateStore.Get(typeof(FakeAggregate), id); Assert.Equal(1, aggregate.Version); }
public void ThrowInvalidOperationExceptionIfAggregateStreamCorrupt() { var id = GuidStrategy.NewGuid(); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); snapshotStore.Setup(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue)).Returns(new Snapshot(id, 10, new FakeAggregate(id, 10))); eventStore.Setup(mock => mock.GetStream(id, 11)).Returns(new[] { new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 12, HeaderCollection.Empty, EventCollection.Empty) }); var ex = Assert.Throws <InvalidOperationException>(() => aggregateStore.Get(typeof(FakeAggregate), id)); Assert.Equal(Exceptions.MissingAggregateCommits.FormatWith(11, 12), ex.Message); }
public void IgnoreDuplicateCommits() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 8); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); eventStore.Setup(mock => mock.Save(It.IsAny <Commit>())).Throws <DuplicateCommitException>(); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); eventStore.Verify(mock => mock.Save(It.IsAny <Commit>()), Times.Once); }
public async Task AfterSelectedJourneysShouldHaveJourneys() { //Arrange var flight = new FlightBuilder().Build(); //Act await UpdateAsync(FlightAvailabilityId, (FlightAvailability x) => x.AddFlight(flight)); //Assert var flightAvailability = await AggregateStore.LoadAsync <FlightAvailability, FlightAvailabilityId>(FlightAvailabilityId, CancellationToken.None); flightAvailability.Flights.Count.Should().Be(1); }
public void Aggregate_ShouldBeRebuildedFromSnapshot_WhenSnapshotDataAvailable() { var aggStore = new AggregateStore(new EventStore(new DefaultEventSerializer(), new EventDataStorage()), new DefaultAggregateSerializer(), new SnapshotDataStorage()); var car = new Car(); car.ChangeTyre(new Tyre() { Price = 10 }, TyrePlacement.LeftBack); car.ChangeTyre(new Tyre() { Price = 11 }, TyrePlacement.RightBack); car.ChangeTyre(new Tyre() { Price = 12 }, TyrePlacement.RightBack); car.ChangeTyre(new Tyre() { Price = 13 }, TyrePlacement.RightBack); car.ChangeTyre(new Tyre() { Price = 14 }, TyrePlacement.RightBack); car.ChangeTyre(new Tyre() { Price = 15 }, TyrePlacement.RightFront); aggStore.Save(car); var carFromSnapshot = aggStore.Get <Car>(car.Id); carFromSnapshot.ChangeTyre(new Tyre() { Price = 17 }, TyrePlacement.RightBack); carFromSnapshot.ChangeTyre(new Tyre() { Price = 16 }, TyrePlacement.RightFront); aggStore.Save(carFromSnapshot); var carFromSnapshot2 = aggStore.Get <Car>(car.Id); Assert.Equal(8, carFromSnapshot2.Version); Assert.Equal(16, carFromSnapshot2.RightFrontTyre.Price); }
public void RetrieveCommandHandlerBasedOnCommandType() { var command = new FakeCommand(); var aggregate = new FakeAggregate(); var envelope = new CommandEnvelope(GuidStrategy.NewGuid(), command); var message = Message.Create(GuidStrategy.NewGuid(), HeaderCollection.Empty, envelope); HandlerRegistry.Setup(mock => mock.GetHandlerFor(command)).Returns(new CommandHandler(typeof(FakeAggregate), typeof(FakeCommand), AggregateStore.Object, (a, c) => { })); AggregateStore.Setup(mock => mock.Get(typeof(FakeAggregate), envelope.AggregateId)).Returns(aggregate); Processor.Process(message); HandlerRegistry.Verify(mock => mock.GetHandlerFor(command), Times.Once()); }
public async Task AfterSelectedJourneysShouldHaveJourneys() { //Arrange _journeys = new JourneysBuilder().BuildJourneys(); void SelectJourney(Booking.Booking b) => b.SelectJourneys(_journeys); //Act await UpdateAsync(BookingId, (Action <Booking.Booking>) SelectJourney); //Assert var booking = await AggregateStore.LoadAsync <Booking.Booking, BookingId>(BookingId, CancellationToken.None); booking.Journeys.Should().NotBeEmpty(); }
public async Task WhenSendSelectJourneysCommandShouldAddJourneys() { //Arrange var journeys = new JourneysBuilder().BuildJourneys(); var selectJourneysCommand = new SelectJourneysCommand(_bookingId, journeys); //Act await CommandBus.PublishAsync(selectJourneysCommand, CancellationToken.None); //Assert var booking = await AggregateStore.LoadAsync <Booking, BookingId>(_bookingId, CancellationToken.None); booking.Journeys.Should().NotBeEmpty(); }
public async Task WhenSendAddFlightCommandShouldAddFlight() { //Arrange var scenario = new AddFlightScenario(CommandBus); //Act await scenario.Execute(); //Assert var id = scenario.Id; var flightAvailability = await AggregateStore.LoadAsync <Domain.FlightAvailability, FlightAvailabilityId>(id, CancellationToken.None); flightAvailability.Flights.Count.Should().Be(1); }
public Tests() { _store = new AggregateStore <int>(new InMemoryEventStore()); _primary = User.Create(1, "Andy"); _primary.PushEvent(new MobilePhoneChangedEvent("0798 1234 123")); _primary.PushEvent(new HomePhoneChangedEvent("01412 123 123")); _primary.PushEvent(new DateOfBirthChangedEvent(new DateTime(1980, 7, 12))); _secondary = User.Create(2, "Andrew"); _secondary.PushEvent(new MobilePhoneChangedEvent("0798 9876 987")); _store.Save("Users", _primary); _store.Save("Users", _secondary); }
public void Initialize() { // Configuration Parameters var eventDatabaseConnectionString = "Data Source=localhost;Initial Catalog=eventway-sample-db;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; var projectionMetadataDatabaseConnectionString = eventDatabaseConnectionString; var cosmosDbEndpoint = "https://localhost:8081"; // This is the default endpoint for local emulator-instances of the Cosmos DB var cosmosDbAuthKey = "<REPLACE WITH YOUR COSMOS DB AUTH KEY>"; var cosmosDbDatabaseId = "eventway-sample-db"; var cosmosDbCollectionId = "projections"; var offerThroughput = 10000; var noOfPartitions = 1000; // Event Repository var eventRepository = new SqlServerEventRepository(eventDatabaseConnectionString); // Projection Metadata Repository var projectionMetadataRepository = new SqlServerProjectionMetadataRepository(projectionMetadataDatabaseConnectionString); // Query Model Repository var queryModelRepository = new DocumentDbQueryModelRepository(cosmosDbDatabaseId, cosmosDbCollectionId, offerThroughput, noOfPartitions, cosmosDbEndpoint, cosmosDbAuthKey); queryModelRepository.Initialize(); // Event Listener var eventListener = new BasicEventListener(); // Aggregate services var aggregateFactory = new DefaultAggregateFactory(); var aggregateRepository = new AggregateRepository(eventRepository, aggregateFactory); var aggregateStore = new AggregateStore(aggregateRepository, eventListener); // PROJECTIONS UserProjection = new UserProjection( eventRepository, eventListener, queryModelRepository, projectionMetadataRepository); // APPLICATION SERVICES UserApplicationService = new UserApplicationService( aggregateStore, queryModelRepository); // Start listening for events UserProjection.Listen(); }
public void Initialize() { // Configuration Parameters var eventDatabaseConnectionString = "Data Source=localhost;Initial Catalog=eventway;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; var projectionMetadataDatabaseConnectionString = eventDatabaseConnectionString; var cosmosDbEndpoint = "https://localhost:8081"; // This is the default endpoint for local emulator-instances of the Cosmos DB var cosmosDbAuthKey = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; var cosmosDbDatabaseId = "eventway"; var cosmosDbCollectionId = "projections"; var offerThroughput = 10000; var noOfPartitions = 1000; // Event Repository var eventRepository = new SqlServerEventRepository(eventDatabaseConnectionString); // Projection Metadata Repository var projectionMetadataRepository = new SqlServerProjectionMetadataRepository(projectionMetadataDatabaseConnectionString); // Query Model Repository var queryModelRepository = new CosmosDbQueryModelRepository(cosmosDbDatabaseId, cosmosDbCollectionId, offerThroughput, noOfPartitions, cosmosDbEndpoint, cosmosDbAuthKey); queryModelRepository.Initialize(); // Event Listener var eventListener = new BasicEventListener(); // Aggregate services var aggregateFactory = new DefaultAggregateFactory(); var aggregateRepository = new AggregateRepository(eventRepository, aggregateFactory); var aggregateStore = new AggregateStore(aggregateRepository, eventListener); // PROJECTIONS UserProjection = new UserProjection( eventRepository, eventListener, queryModelRepository, projectionMetadataRepository); // APPLICATION SERVICES UserApplicationService = new UserApplicationService( aggregateStore, queryModelRepository); // Start listening for events UserProjection.Listen(); }
public void UseSnapshotIfAvailable() { var id = GuidStrategy.NewGuid(); var snapshot = new FakeAggregate(id, 10); var events = new Event[] { new FakeEvent(), new FakeEvent() }; var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); snapshotStore.Setup(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue)).Returns(new Snapshot(id, 10, snapshot)); eventStore.Setup(mock => mock.GetStream(id, 11)).Returns(new[] { new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 11, HeaderCollection.Empty, new EventCollection(events)) }); var aggregate = aggregateStore.Get(typeof(FakeAggregate), id); snapshotStore.Verify(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue), Times.Once()); Assert.Equal(11, aggregate.Version); }
public void SaveAggregate <TAggregate>(Guid id) where TAggregate : IAggregateRoot { var aggregate = AggregateStore.Where(x => x.Id == id).FirstOrDefault(); if (aggregate == null) { aggregate = new AggregateStoreModel { Id = id, Type = typeof(TAggregate).AssemblyQualifiedName }; AggregateStore.Add(aggregate); } else { AggregateStore.Remove(aggregate); } }
public void WillTimeoutEventuallyIfCannotSave() { var command = new FakeCommand(); var aggregate = new FakeAggregate(); var envelope = new CommandEnvelope(GuidStrategy.NewGuid(), command); var message = Message.Create(GuidStrategy.NewGuid(), HeaderCollection.Empty, envelope); var processor = new CommandProcessor(HandlerRegistry.Object, TransientErrorRegistry.Object, new CommandProcessorSettings { RetryTimeout = TimeSpan.FromMilliseconds(20) }); SystemTime.ClearOverride(); AggregateStore.Setup(mock => mock.Get(typeof(FakeAggregate), envelope.AggregateId)).Returns(aggregate); AggregateStore.Setup(mock => mock.Save(aggregate, It.IsAny <CommandContext>())).Callback(() => { throw new ConcurrencyException(); }); HandlerRegistry.Setup(mock => mock.GetHandlerFor(command)).Returns(new CommandHandler(typeof(FakeAggregate), typeof(FakeCommand), AggregateStore.Object, (a, c) => ((FakeAggregate)a).Handle((FakeCommand)c))); Assert.Throws <TimeoutException>(() => processor.Process(message)); }
public Boot( Projectionist projectionist, AggregateStore<Guid> store, UserService users, RoleService roles, PermissionService permissions, CollectionsReadModel collectionsReadModel, HistoryReadModel history, AuthorizationReadModel authorizationRead) { _projectionist = projectionist; _store = store; projectionist .Add(users) .Add(roles) .Add(permissions) .Add(collectionsReadModel.Project) .Add(history.Project) .Add(authorizationRead.Project); }
public void SaveSnapshotIfLoadedCommitsGreaterThanSnapshotInterval() { var id = GuidStrategy.NewGuid(); var commits = new List <Commit>(); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); for (var i = 0; i < 10; i++) { commits.Add(new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 11 + i, HeaderCollection.Empty, EventCollection.Empty)); } snapshotStore.Setup(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue)).Returns(new Snapshot(id, 10, new FakeAggregate(id, 10))); eventStore.Setup(mock => mock.GetStream(id, 11)).Returns(commits); var aggregate = aggregateStore.Get(typeof(FakeAggregate), id); snapshotStore.Verify(mock => mock.Save(It.Is <Snapshot>(s => s.Version == 20)), Times.Once()); Assert.Equal(20, aggregate.Version); }
public async Task ExecutionResultShouldControlEventStore(bool isSuccess, int expectedAggregateVersion) { // Arrange var pingId = PingId.New; var thingyId = ThingyId.New; // Act var executionResult = await CommandBus.PublishAsync( new ThingyMaybePingCommand(thingyId, pingId, isSuccess), CancellationToken.None) .ConfigureAwait(false); executionResult.IsSuccess.Should().Be(isSuccess); // Assert var thingyAggregate = await AggregateStore.LoadAsync <ThingyAggregate, ThingyId>( thingyId, CancellationToken.None) .ConfigureAwait(false); thingyAggregate.Version.Should().Be(expectedAggregateVersion); }
public void ReloadAggregateOnConcurrencyException() { var save = 0; var command = new FakeCommand(); var aggregate = new FakeAggregate(); var envelope = new CommandEnvelope(GuidStrategy.NewGuid(), command); var message = Message.Create(GuidStrategy.NewGuid(), HeaderCollection.Empty, envelope); var ex = new ConcurrencyException(); HandlerRegistry.Setup(mock => mock.GetHandlerFor(command)).Returns(new CommandHandler(typeof(FakeAggregate), typeof(FakeCommand), AggregateStore.Object, (a, c) => ((FakeAggregate)a).Handle((FakeCommand)c))); AggregateStore.Setup(mock => mock.Get(typeof(FakeAggregate), envelope.AggregateId)).Returns(aggregate); AggregateStore.Setup(mock => mock.Save(aggregate, It.IsAny <CommandContext>())).Callback(() => { if (++save == 1) { throw ex; } }); Processor.Process(message); AggregateStore.Verify(mock => mock.Get(typeof(FakeAggregate), envelope.AggregateId), Times.Exactly(2)); }
public void CaptureAggregateTypeIfFirstCommit() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 0); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); eventStore.Verify(mock => mock.Save(It.Is<Commit>(c => c.Headers[Header.Aggregate] == typeof(FakeAggregate).GetFullNameWithAssembly())), Times.Once()); }
public void SaveSnapshotIfRequired() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 9); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); snapshotStore.Verify(mock => mock.Save(It.Is<Snapshot>(s => s.StreamId == aggregate.Id && s.Version == 10)), Times.Once()); }
public void ThrowInvalidOperationExceptionIfAggregateStreamCorrupt() { var id = GuidStrategy.NewGuid(); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); snapshotStore.Setup(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue)).Returns(new Snapshot(id, 10, new FakeAggregate(id, 10))); eventStore.Setup(mock => mock.GetStream(id, 11)).Returns(new[] { new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 12, HeaderCollection.Empty, EventCollection.Empty) }); var ex = Assert.Throws<InvalidOperationException>(() => aggregateStore.Get(typeof(FakeAggregate), id)); Assert.Equal(Exceptions.MissingAggregateCommits.FormatWith(11, 12), ex.Message); }
private Permission Clone(Permission permission) { var store = new AggregateStore<Guid>(new InMemoryEventStore()); store.Save("test", permission); return store.Load("test", permission.ID, () => Permission.Blank()); }
public void IgnoreDuplicateCommits() { var aggregate = new FakeAggregate(GuidStrategy.NewGuid(), 8); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); eventStore.Setup(mock => mock.Save(It.IsAny<Commit>())).Throws<DuplicateCommitException>(); using (var context = new CommandContext(GuidStrategy.NewGuid(), HeaderCollection.Empty, CommandEnvelope.Empty)) aggregateStore.Save(aggregate, context); eventStore.Verify(mock => mock.Save(It.IsAny<Commit>()), Times.Once); }
public void SaveSnapshotIfLoadedCommitsGreaterThanSnapshotInterval() { var id = GuidStrategy.NewGuid(); var commits = new List<Commit>(); var aggregateStore = new AggregateStore(aggregateUpdater.Object, snapshotStore.Object, eventStore.Object, new AggregateStoreSettings()); for (var i = 0; i < 10; i++) commits.Add(new Commit(1L, DateTime.UtcNow, Guid.NewGuid(), id, 11 + i, HeaderCollection.Empty, EventCollection.Empty)); snapshotStore.Setup(mock => mock.GetSnapshot(typeof(FakeAggregate), id, Int32.MaxValue)).Returns(new Snapshot(id, 10, new FakeAggregate(id, 10))); eventStore.Setup(mock => mock.GetStream(id, 11)).Returns(commits); var aggregate = aggregateStore.Get(typeof(FakeAggregate), id); snapshotStore.Verify(mock => mock.Save(It.Is<Snapshot>(s => s.Version == 20)), Times.Once()); Assert.Equal(20, aggregate.Version); }