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);
            });
        }
Example #3
0
        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);
        }
Example #4
0
        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();
        }
Example #6
0
        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);
            });
        }
Example #7
0
        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);
        }
Example #10
0
        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));
        }