public void SimpleAggregateSnapshottingViaSnapshotCreator() { IStoreEvents memoryStore = Wireup.Init().UsingInMemoryPersistence().Build(); IConstructAggregates aggregateFactory = A.Fake <IConstructAggregates>(); IEventStoreRepository repository = new InMemoryDomainRepository(memoryStore, aggregateFactory, new CommonDomain.Core.ConflictDetector()); Guid aggregateID = Guid.NewGuid(); SimpleAggregate aggregate = new SimpleAggregate(aggregateID, DateTime.Now); repository.Save(aggregate, Guid.NewGuid()); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, null)).ReturnsLazily(() => new SimpleAggregate()); SnapshotCreator <SimpleAggregate> snapshotCreator = new SnapshotCreator <SimpleAggregate>(repository, 1); Snapshot snapshot = snapshotCreator.SaveSnapShot(aggregate.Id); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.IsNull())).MustHaveHappened(Repeated.Exactly.Once); ISnapshot retrievedSnapshot = repository.EventStore.Advanced.GetSnapshot(aggregate.Id, int.MaxValue); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.IsNull())).MustHaveHappened(Repeated.Exactly.Once); retrievedSnapshot.Should().NotBeNull(); retrievedSnapshot.StreamRevision.Should().Be(1); retrievedSnapshot.ShouldBeEquivalentTo(snapshot); SimpleAggregate retrievedAggregate = repository.GetById <SimpleAggregate>(aggregate.Id); retrievedAggregate.Should().NotBeNull(); aggregate.Version.Should().Be(1); retrievedAggregate.ShouldBeEquivalentTo(aggregate); A.CallTo(aggregateFactory).Where(o => o.Method.Name != "Build").MustNotHaveHappened(); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.IsNull())).MustHaveHappened(Repeated.Exactly.Once); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.Not.IsNull())).MustHaveHappened(); }
protected DomainEventSourcedActor(IConstructAggregates aggregateConstructor, IConstructSnapshots snapshotsConstructor, ISnapshotsPersistencePolicy policy) { _snapshotsConstructor = snapshotsConstructor; _snapshotsPolicy = policy; _snapshotsSaveTracker = (policy as ISnapshotsSavePolicy).Tracking; _snapshotsDeleteTracker = (policy as ISnapshotsDeletePolicy).Tracking; PersistenceId = Self.Path.Name; Id = EntityActorName.Parse <T>(Self.Path.Name).Id; State = (T)aggregateConstructor.Build(typeof(T), Id, null); Monitor = new ActorMonitor(Context, typeof(T).Name); Behavior = new BehaviorQueue(Become); DefaultBehavior(); Recover <DomainEvent>(e => State.Apply(e)); Recover <SnapshotOffer>(offer => { _snapshotsPolicy.MarkSnapshotApplied(offer.Metadata.SequenceNr); State = (T)aggregateConstructor.Build(typeof(T), Id, (IMemento)offer.Snapshot); Log.Debug("Built state from snapshot #{snapshotNum}", offer.Metadata.SequenceNr); }); Recover <RecoveryCompleted>(message => { Log.Debug("Recovery completed"); NotifyPersistenceWatchers(message); }); }
public TAggregate GetById <TAggregate>(string bucketId, Guid id, int version) where TAggregate : class, IAggregate { var aggregate = aggregateFactory.Build(typeof(TAggregate), id, null); givenEvents.ForEach(aggregate.ApplyEvent); return((TAggregate)aggregate); }
public TAggregate GetById <TAggregate>(string bucketId, Guid id, int version) where TAggregate : class, IAggregate { var aggregate = _aggregateFactory.Build(typeof(TAggregate), id, null); Hydrate(aggregate); return((TAggregate)aggregate); }
public void SimpleAggregateRetrieval() { IStoreEvents memoryStore = Wireup.Init().UsingInMemoryPersistence().Build(); IConstructAggregates aggregateFactory = A.Fake <IConstructAggregates>(); IEventStoreRepository repository = new InMemoryDomainRepository(memoryStore, aggregateFactory, new CommonDomain.Core.ConflictDetector()); Guid aggregateID = Guid.NewGuid(); SimpleAggregate aggregate = new SimpleAggregate(aggregateID, DateTime.Now); repository.Save(aggregate, Guid.NewGuid()); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, null)).Returns(new SimpleAggregate(aggregateID, DateTime.Now)); repository.GetById <SimpleAggregate>(aggregate.Id); A.CallTo(aggregateFactory).MustHaveHappened(); A.CallTo(aggregateFactory).Where(o => o.Method.Name != "Build").MustNotHaveHappened(); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.Not.IsNull())).MustNotHaveHappened(); }
public EventSourcedActor(IConstructAggregates aggregateConstructor, ISnapshotsPersistencePolicy policy, IPublisher publisher) { PersistenceId = Self.Path.Name; SnapshotsPolicy = policy; _aggregateConstructor = aggregateConstructor; Publisher = publisher; Id = AggregateActorName.Parse <T>(Self.Path.Name).Id; State = (AggregateBase)aggregateConstructor.Build(typeof(T), Id, null); Monitor = new ActorMonitor(Context, typeof(T).Name); Command <GracefullShutdownRequest>(req => { Monitor.IncrementMessagesReceived(); DeleteSnapshots(SnapshotsPolicy.GetSnapshotsToDelete()); Become(Terminating); }); Command <CheckHealth>(s => Sender.Tell(new HealthStatus(s.Payload))); Command <SaveSnapshotSuccess>(s => { NotifyWatchers(s); SnapshotsPolicy.MarkSnapshotSaved(s.Metadata); }); Command <NotifyOnPersistenceEvents>(c => { var waiter = c.Waiter ?? Sender; if (IsRecoveryFinished) { waiter.Tell(RecoveryCompleted.Instance); } _persistenceWaiters.Add(waiter); }); Recover <DomainEvent>(e => { State.ApplyEvent(e); SnapshotsPolicy.MarkActivity(e.CreatedTime); }); Recover <SnapshotOffer>(offer => { SnapshotsPolicy.MarkSnapshotApplied(offer.Metadata); State = _aggregateConstructor.Build(typeof(T), Id, (IMemento)offer.Snapshot); }); Recover <RecoveryCompleted>(message => { _log.Debug("Recovery for actor {Id} is completed", PersistenceId); NotifyWatchers(message); }); }
public PlacementDto CreatePlacement(User user, PlacementDto placementDto) { var id = Guid.NewGuid(); var placementAggregate = (PlacementAggregate)_factory.Build(typeof(PlacementAggregate), id, null); placementAggregate.OnFirstCreated(); placementAggregate.Create(placementDto.UserId, placementDto.Title, placementDto.Start, placementDto.End, placementDto.Reference, user.Id); _repository.Save(placementAggregate, commitId: Guid.NewGuid(), updateHeaders: null); placementDto.Id = id; placementDto.FullyQualifiedTitle = PlacementAggregate.GetFullyQualifiedTitle(placementDto.Title, placementDto.Start, placementDto.End); return(placementDto); }
public AggregateVersion <T>[] Load <T>(Guid id) where T : IAggregate { var serializer = new WireJsonSerializer(); using (var repo = new RawSnapshotsRepository(_writeString)) return(repo.Load(AggregateActorName.New <T>(id).Name) .Select(s => { var memento = (IMemento)serializer.FromBinary(s.Snapshot, typeof(IMemento)); var aggregate = (T)_aggregatesConstructor.Build(typeof(T), id, memento); aggregate.ClearUncommittedEvents(); //in case json will call public constructor return new AggregateVersion <T>(aggregate, s.Timestamp); }).ToArray()); }
private SelfAssessingAggregate GetUserSkillSetAggregate(int userId, int skillSetId) { _logger.LogDebug($"\n{DateTime.UtcNow.ToUnixTimeMilliseconds()} - {Thread.CurrentThread.ManagedThreadId}: GetUserSkillSetAggregate({userId}, {skillSetId}) called.\n"); // We use a deterministic id for this aggregate as we need to access it using the userId & skillsSetId. var id = AggregateIdentityGenerator.CreateDeterministicGuid($"{userId}{skillSetId}"); // Get the aggregate. var aggregate = _repository.GetById <SelfAssessingAggregate>(id); _logger.LogDebug($"\n{DateTime.UtcNow.ToUnixTimeMilliseconds()} - {Thread.CurrentThread.ManagedThreadId}: GetUserSkillSetAggregate({userId}, {skillSetId}) - Aggregate.Version: {aggregate.Version}.\n"); // Check we have the aggregate, otherwise create it. if (aggregate.Version == 0) { aggregate = (SelfAssessingAggregate)_factory.Build(typeof(SelfAssessingAggregate), id, null); aggregate.OnFirstCreated(); aggregate.Create(userId, skillSetId); _repository.Save(aggregate, commitId: Guid.NewGuid(), updateHeaders: null); } return(aggregate); }
public EntryDto CreateEntry(User user, EntryDto entryDto) { var id = Guid.NewGuid(); var entryAggregate = (EntryAggregate)_factory.Build(typeof(EntryAggregate), id, null); entryAggregate.OnFirstCreated(); entryAggregate.Create(entryDto.SkillSetId, entryDto.Title, entryDto.DescriptionString(), user.Id, entryDto.Where, entryDto.When, entryDto.EntryType?.Id); entryAggregate.AddAssessmentBundle( entryDto.AssessmentBundle.ToDictionary( s => s.Key, s => new SelfAssessment { EntryId = id, Score = s.Value.Score, SelfAssessmentLevelId = s.Value.LevelId, SkillId = s.Key, UserId = user.Id })); _repository.Save(entryAggregate, commitId: Guid.NewGuid(), updateHeaders: null); entryDto.Id = id; return(entryDto); }
public IAggregate Build(Type type, Guid id, IMemento snapshot, IDictionary <string, object> headers) { Type concreteType; object concreteTypeName; if (headers.TryGetValue(EventStoreRepository.AggregateTypeHeader, out concreteTypeName)) { string typeName = (string)concreteTypeName; if (!types.TryGetValue(typeName, out concreteType)) { concreteType = domainAssemblies.Select(a => a.GetType(typeName)).First(t => t != null); if (concreteType == null) { throw new TypeLoadException(string.Format("Type {0} is not found", typeName)); } types[typeName] = concreteType; } } else { concreteType = type; } return(factory.Build(concreteType, id, snapshot, headers)); }
public void SimpleAggregateDirectSnapshotting() { IStoreEvents memoryStore = Wireup.Init().UsingInMemoryPersistence().Build(); IConstructAggregates aggregateFactory = A.Fake <IConstructAggregates>(); IEventStoreRepository repository = new InMemoryDomainRepository(memoryStore, aggregateFactory, new CommonDomain.Core.ConflictDetector()); Guid aggregateID = Guid.NewGuid(); SimpleAggregate aggregate = new SimpleAggregate(aggregateID, DateTime.Now); repository.Save(aggregate, Guid.NewGuid()); IMemento memento = aggregate.CreateMemento(); ISnapshot snapshot = new Snapshot(aggregate.Id.ToString(), aggregate.Version, memento); repository.EventStore.Advanced.AddSnapshot(snapshot); ISnapshot retrievedSnapshot = repository.EventStore.Advanced.GetSnapshot(aggregate.Id, int.MaxValue); retrievedSnapshot.Should().NotBeNull(); retrievedSnapshot.StreamRevision.Should().Be(1); retrievedSnapshot.ShouldBeEquivalentTo(snapshot); repository.GetById <SimpleAggregate>(aggregate.Id); A.CallTo(() => aggregateFactory.Build(typeof(SimpleAggregate), aggregate.Id, A <IMemento> .That.Not.IsNull())).MustHaveHappened(); }
public static T BuildEmpty <T>(this IConstructAggregates factory, string id = null) where T : IAggregate { return((T)factory.Build(typeof(T), id ?? Guid.NewGuid().ToString(), null)); }
private TAggregate ConstructAggregate <TAggregate>(Guid id) { return((TAggregate)m_ConstructAggregates.Build(typeof(TAggregate), id, null)); //return (TAggregate)Activator.CreateInstance(typeof(TAggregate), true); }
public async Task<Version<T>[]> Load<T>(string id) where T : class, IAggregate { var snapshotType = _snapshotsConstructor.GetSnapshot(_aggregatesConstructor.BuildEmpty<T>()) .GetType(); var serializer = new DomainSerializer(); using (var snapshotItemsRepo = new RawSnapshotsRepository(option)) { return (await snapshotItemsRepo.Load(EntityActorName.New<T>(id). Name)).Select(s => { var memento = (IMemento) serializer.FromBinary(s.Snapshot, snapshotType); var aggregate = (T) _aggregatesConstructor.Build(typeof(T), id, memento); return new Version<T>(aggregate, s.Timestamp); }). ToArray(); } }
private IAggregate GetAggregate <TAggregate>(ISnapshot snapshot, IEventStream stream) { IMemento memento = snapshot == null ? null : snapshot.Payload as IMemento; return(_factory.Build(typeof(TAggregate), stream.StreamId.ToGuid().Get(), memento)); }
public static T Build <T>(this IConstructAggregates constructor, string id, IMemento snapshot = null) where T : IAggregate { return((T)constructor.Build(typeof(T), id, snapshot)); }
private IAggregate GetAggregate <TAggregate>(ISnapshot snapshot, IEventStream stream) { IMemento memento = snapshot == null ? null : snapshot.Payload as IMemento; return(_factory.Build(typeof(TAggregate), new Guid(stream.StreamId), memento, stream.CommittedHeaders)); }