public TAggregate GetById <TAggregate>(Guid id) where TAggregate : Aggregate
        {
            List <EventData> eventDataHistory;

            if (!_eventStorage.TryGetValue(id, out eventDataHistory))
            {
                return(_aggregateFactory.Create <TAggregate>(new object[0]));
            }

            var history = eventDataHistory.Select(x => x.FromEventData());

            return(_aggregateFactory.Create <TAggregate>(history));
        }
        public async Task <TAggregate> FindBy(Guid id)
        {
            var streamName = StreamNameFor(id);

            var fromEventNumber = 0;
            var toEventNumber   = int.MaxValue;

            var snapshot = _eventStore.GetLatestSnapshot <TAggregate>(streamName);

            if (snapshot != null)
            {
                fromEventNumber = snapshot.Version + 1; // load only events after snapshot
            }

            var stream = _eventStore.GetStream(streamName, fromEventNumber, toEventNumber);

            TAggregate aggregate = null;

            if (snapshot != null)
            {
                aggregate = snapshot;
                aggregate.SetEventPublisher(_eventPublisher);
            }
            else
            {
                aggregate = _aggregateFactory.Create <TAggregate>();
            }

            foreach (var @event in stream)
            {
                aggregate.Replay(@event);
            }

            return(aggregate);
        }
Exemple #3
0
        protected override Task <CommandResult <Guid> > ExecuteCommand(UpdateEntityCommand command, CancellationToken cancellationToken)
        {
            var agg = _aggregateFactory.Create(
                EventStream <EntityTestId> .From(EntityTestId.Empty(),
                                                 new AggregationName(),
                                                 VersionId.Empty(), new ImmutableArray <IDomainEvent>())
                );
            var isSucceed = agg.IsValid;
            var okId      = Guid.Empty;


            if (isSucceed)
            {
                agg.UpdateName(EntityTestId.From(command.AggregateId), Name.From(command.Name));

                isSucceed = agg.IsValid;

                agg.GetEvents().ToImmutableList()
                .ForEach(ev => Publisher.Publish(ev));

                okId = agg.GetChange().AggregationId.Value;
            }

            return(Task.FromResult(new CommandResult <Guid>(isSucceed, okId, agg.Failures)));
        }
        public T GetById <T>(Guid aggregateId) where T : IAggregate
        {
            var loadFromEvent = 0L;

            // Check for Snapshots
            var lastEventIndex = _eventRepository.GetVersionByAggregateId(aggregateId);
            var snapshotSize   = _aggregateFactory.GetSnapshotSize <T>();

            if (lastEventIndex.HasValue && lastEventIndex.Value >= snapshotSize)
            {
                loadFromEvent = lastEventIndex.Value - lastEventIndex.Value % (snapshotSize + 1);
            }

            // Load events
            var events = _eventRepository.GetEventsByAggregateId(loadFromEvent, aggregateId);

            if (events == null)
            {
                throw new IndexOutOfRangeException("Could not find Aggregate with ID: " + aggregateId);
            }

            // Event spool aggregate
            var aggregate = _aggregateFactory.Create <T>(
                aggregateId,
                events.Select(x => x.EventPayload).ToArray()
                );

            aggregate.Version = lastEventIndex ?? 0;

            return(aggregate);
        }
Exemple #5
0
        public async Task <T> GetById <T>(
            string id,
            int version = Int32.MaxValue,
            CancellationToken cancellationToken = default(CancellationToken)
            ) where T : IAggregate
        {
            var aggregate = _factory.Create <T>();

            aggregate.Init();
            var stream = OpenStream(id);

            await stream.Read(
                0,
                version,
                (l, payload) =>
            {
                aggregate.Append(payload);
                return(ScanCallbackResult.Continue);
            },
                cancellationToken
                )
            .ConfigureAwait(false);

            return(aggregate);
        }
Exemple #6
0
        public async Task <TAggregate> GetAsync(Guid id)
        {
            var streamName = RedisExtensions.GetAggregateStream <TAggregate>(id);
            var db         = _connectionMultiplexer.GetDatabase();
            var events     = new List <AggregateEvent>();
            var checkpoint = "0-0";
            var batchSize  = _configuration.BatchSize;
            var info       = db.StreamInfo(streamName);

            do
            {
                var currentSlice = await db.StreamReadAsync(streamName, checkpoint, batchSize);

                foreach (var streamEntry in currentSlice)
                {
                    foreach (var streamEntryValue in streamEntry.Values)
                    {
                        events.Add(JsonConvert.DeserializeObject <AggregateEvent>(streamEntryValue.Value.ToString(), _serializerSettings));
                        checkpoint = streamEntry.Id;
                    }
                }
            } while (info.LastEntry.Id != checkpoint);
            var aggregate = _factory.Create <TAggregate>(events);

            return(aggregate);
        }
Exemple #7
0
        public void Process <TAggregateRoot>(Command <TAggregateRoot> command) where TAggregateRoot : AggregateRoot, new()
        {
            var aggregateId = command.AggregateId;
            var aggregate   = _aggregateFactory.Get <TAggregateRoot>(aggregateId);

            if (aggregate == null)
            {
                aggregate = _aggregateFactory.Create <TAggregateRoot>(aggregateId);

                var eventHistory = new List <DomainEvent>();
                if (_eventStore.Exists(aggregateId))
                {
                    // Get all events for aggregate here from eventstore
                    eventHistory = _eventStore.Load(aggregateId);
                }

                // Load all events
                aggregate.LoadsFromHistory(eventHistory);
            }

            // Execute command
            command.Execute(aggregate);

            // Get uncommitted events
            var uncommittedEvents = aggregate.GetUncommittedChanges();

            // Save uncommitted events to eventstore
            _eventStore.Save(aggregateId, uncommittedEvents);

            // Clear uncommitted changes
            aggregate.MarkChangesAsCommitted();
        }
Exemple #8
0
        public async Task <T> GetByIdAsync <T>(Guid id) where T : class, IAggregate
        {
            var events = (await ObjectFactory.RetrieveAsync <EventData>(sql: RetrieveByIdSql, parameters: new[] { new Param {
                                                                                                                      Name = "id", Value = id
                                                                                                                  } }, connection: DbFactory.CreateConnection(_connectionString))).Select(ConvertEvent);

            return(_factory.Create <T>(events));
        }
Exemple #9
0
        public async Task <T> GetById <T>(
            string id,
            CancellationToken cancellationToken
            ) where T : IAggregate
        {
            if (_trackingAggregates.TryGetValue(id, out IAggregate aggregate))
            {
                return((T)aggregate);
            }

            aggregate = _factory.Create <T>();
            var persister = (IEventSourcedAggregate)aggregate;

            SnapshotInfo snapshot = null;

            if (_snapshots != null && aggregate is ISnaphottable snaphottable)
            {
                snapshot = await _snapshots.GetLastAsync(id, cancellationToken).ConfigureAwait(false);

                if (snapshot != null)
                {
                    //@@REVIEW: invalidate snapshot on false?
                    snaphottable.TryRestore(snapshot);
                }
            }

            if (!aggregate.IsInitialized)
            {
                aggregate.Init(id);
            }

            _trackingAggregates.Add(id, aggregate);
            var stream = OpenStream(id);

            int readCount = 0;
            var consumer  = ConfigureConsumer(new LambdaSubscription(data =>
            {
                readCount++;
                persister.ApplyChanges((Changeset)data.Payload);
                return(Task.FromResult(true));
            }), cancellationToken);

            // we use aggregate.Version because snapshot could be rejected
            // Starting point is inclusive, so almost one changeset should be loaded
            // aggregate will ignore because ApplyChanges is idempotent
            await stream.ReadAsync(consumer, aggregate.Version, long.MaxValue, cancellationToken)
            .ConfigureAwait(false);

            persister.Loaded();

            // no data from stream, we cannot validate the aggregate
            if (snapshot != null && readCount == 0)
            {
                throw new StaleSnapshotException(snapshot.SourceId, snapshot.SourceVersion);
            }

            return((T)aggregate);
        }
        public IActionResult Post([FromBody] Models.MeterCreate meter)
        {
            _meterRepository.Add(_meterFactory.Create(new MeterFactoryInput()
            {
                AddressId = meter.AddressId, MeterId = meter.MeterId, SerialNumber = meter.SerialNumber, State = meter.State
            }));

            return(CreatedAtRoute("GetMeter", new { meterId = meter.MeterId }, meter));
        }
Exemple #11
0
        public async Task Consume(ConsumeContext <MeterReadProcessBagan> context)
        {
            var meterRead =
                _meterReadFactory.Create(new MeterReadFactoryInput(context.Message.MeterReadId,
                                                                   context.Message.AddressId, context.Message.MeterIds, context.Message.ReadProcessStartDate));

            _meterReadRepository.Add(meterRead);
            await _asyncUnitOfWork.CommitAsync();
        }
Exemple #12
0
        public void AutoCreateRitWhenNeeded(Guid id, int stand, DateTime datum, Guid adresId)
        {
            // get previous
            var prevStandView = _kmStandViewRepository.GetPrevious();

            // zoek laatste kmstand
            var lastStandView = _kmStandViewRepository.GetLastOne();

            if (prevStandView != null)
            {
                var ritViewPrevFirst = _ritViewRepository.FindByFirstKmStandId(prevStandView?.Id ?? Guid.Empty);

                // is deze gekoppeld als eerste stand aan een rit?
                var ritViewFirst = _ritViewRepository.FindByFirstKmStandId(id);

                // is deze al gekoppeld aan een rit als eind stand?
                var ritViewLast = _ritViewRepository.FindByLastKmStandId(id);

                if (ritViewPrevFirst == null && ritViewFirst == null && ritViewLast == null)
                {
                    // niet gekoppeld dan rit aanmaken en koppelen als eerste stand
                    Rit rit = _aggregateFactory.Create <Rit>();
                    rit.Create("Generated", lastStandView.Stand, lastStandView.Id, 0, Guid.Empty, Guid.NewGuid());
                    _ritRepository.Add(rit);
                }
                else
                {
                    var ritv = _ritViewRepository.FindByFirstKmStandId(prevStandView.Id);
                    // rit updaten en kmstand als laatste stand
                    Rit rit = _ritRepository.FindBy(ritv.Id).Result;
                    rit.Update(rit.Name, rit.BeginStand, rit.BeginStandId, stand, id, rit.Id);
                    _ritRepository.Update(rit);
                }
            }
            else
            { // eerste stand
                // zo nee, dan rit aanmaken en de kmstandid koppelen als begin stand
                Rit rit = _aggregateFactory.Create <Rit>();
                rit.Create("First Generated", lastStandView.Stand, lastStandView.Id, 0, Guid.Empty, Guid.NewGuid());
                _ritRepository.Add(rit);
            }
        }
Exemple #13
0
        public async Task When(AddNewKmStand command)
        {
            _logger.LogInformation($"received command: {command.GetType().Name}");
            var repository = _repositoryFactory();

            KmStand kmStand = aggregateFactory.Create <KmStand>();

            kmStand.Create(command.Stand, command.Datum, command.AdresId);

            await Task.Run(() => repository.Add(kmStand));
        }
 public T Get <T>(Guid id) where T : AggregateBase <T>
 {
     using (var conn = new SqlConnection(config.ConnectionString))
     {
         const string sql             = "SELECT * FROM Events WHERE AggregateId=@id";
         var          listOfEventData = conn.Query <EventData>(sql, new { id });
         var          events          = listOfEventData.Select(x => x.DeserializeEvent());
         var          aggregate       = factory.Create <T>(events);
         return((T)aggregate);
     }
 }
        public async Task Consume(ConsumeContext <IAddressAdded> context)
        {
            var address =
                _factory.Create(new AddressFactoryInput()
            {
                AddressId    = context.Message.Id,
                SquareMeters = context.Message.SquareMeters
            });

            _repository.Add(address);

            await _asyncUnitOfWork.CommitAsync();
        }
Exemple #16
0
        protected AbstractAggregateTest()
        {
            this.Aggregate = _defaultFactory.Create <TAggregate>();
            this.State     = new TState();
            var snapshot = new SnapshotInfo("test", 1, this.State, "1");

            ((ISnaphottable)this.Aggregate).TryRestore(snapshot);

            if (!this.Aggregate.IsInitialized)
            {
                throw new Exception("something went wrong");
            }
        }
Exemple #17
0
        public IActionResult CreateAddress([FromBody] CreateAddress address)
        {
            var aggregate =
                _addressFactory.Create(new AddressFactoryInput
            {
                AddressId       = address.AddressId,
                FullAddressName = address.FullAddress
            });

            _addressRepository.Add(aggregate);

            return(CreatedAtRoute("GetAddress", new { address.AddressId }, aggregate));
        }
Exemple #18
0
        public async Task <TAggregateRoot> GetByStream <TAggregateRoot, TAggregate>(string stream,
                                                                                    int maxVersion = Int32.MaxValue)
            where TAggregateRoot : class, IAggregateRoot <TAggregate>
        {
            if (maxVersion < 0)
            {
                throw new InvalidOperationException("Cannot get max version less than 0.");
            }

            var aggregate = _factory.Create <IAggregateRoot <TAggregate>, TAggregateRoot>();

            var sliceStart = 0;
            StreamEventsSlice currentSlice;

            do
            {
                var sliceCount = sliceStart + _settings.ReadPageSize <= maxVersion
                    ? _settings.ReadPageSize
                    : maxVersion - sliceStart + 1;

                currentSlice =
                    await _connection.ReadStreamEventsForwardAsync(stream, sliceStart, sliceCount, true);

                if (currentSlice.Status == SliceReadStatus.StreamNotFound)
                {
                    throw new AggregateNotFoundException(stream, typeof(TAggregateRoot));
                }

                if (currentSlice.Status == SliceReadStatus.StreamDeleted)
                {
                    throw new AggregateDeletedException(stream, typeof(TAggregateRoot));
                }

                sliceStart = (int)currentSlice.NextEventNumber;

                foreach (var resolvedEvent in currentSlice.Events)
                {
                    aggregate.AddEvent(new EventData(resolvedEvent.Event.EventId,
                                                     resolvedEvent.Event.EventType, resolvedEvent.Event.IsJson,
                                                     resolvedEvent.Event.Data, resolvedEvent.Event.Metadata));
                }
            } while (maxVersion >= currentSlice.NextEventNumber && !currentSlice.IsEndOfStream);

            if (aggregate.OriginalVersion != maxVersion && maxVersion < Int32.MaxValue)
            {
                throw new AggregateVersionException(stream, typeof(TAggregateRoot), aggregate.OriginalVersion,
                                                    maxVersion);
            }

            return(aggregate as TAggregateRoot);
        }
        public ActionResult CreateRent([FromBody] CreateRent rent)
        {
            var entity =
                _rentAggregateFactory.Create(new RentFactoryInput()
            {
                RentItems = rent.RentItems.Select(ToEntity).ToArray(),
                RentId    = rent.RentId,
                ValidTo   = rent.ValidTo,
            });

            _rentRepository.Add(entity);

            return(CreatedAtRoute("GetRent", new { RentId = entity.Id }, entity));
        }
        public async Task Consume(ConsumeContext <IRegistratorAdded> context)
        {
            var registrator =
                _factory.Create(new FactoryInput()
            {
                AddressId     = context.Message.AddressId,
                Description   = context.Message.Description,
                RegistratorId = context.Message.RegistratorId
            });

            _repository.Add(registrator);

            await _asyncUnitOfWork.CommitAsync();
        }
Exemple #21
0
        protected async Task <TAggregate> TryFindAsync(Guid streamId)
        {
            var eventData = await _dbContext.Events
                            .Where(e => e.StreamId.Equals(streamId))
                            .OrderBy(e => e.Created)
                            .ThenBy(e => e.CommitSequence)
                            .ToListAsync();

            var events = eventData
                         .Select(d => _serializer.DeserializeObject <IAggregateEvent>(d.Json))
                         .ToList();

            return(events.Any() ? _aggregateFactory.Create <TAggregate>(events) : null);
        }
Exemple #22
0
        public IActionResult CreateRegistrator([FromBody] Models.CreateRegistrator model)
        {
            var entity =
                _factory.Create(new FactoryInput()
            {
                AddressId     = model.AddressId,
                Description   = model.Description,
                RegistratorId = model.RegistratorId,
                TariffId      = model.TariffId
            });

            _repository.Add(entity);

            return(CreatedAtRoute("GetRegistrator", new { model.RegistratorId }, entity));
        }
Exemple #23
0
        public async Task <Maybe <TAggregate> > GetAsync(TId id)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            var stream     = GetStream(id);
            var readResult = await stream.ReadEventsForward();

            return(readResult.Events.Count > 0
                ? _aggregateFactory.Create(id, readResult.NextExpectedVersion,
                                           readResult.Events.Select(x => x.Data).ToArray())
                : new Maybe <TAggregate>());
        }
Exemple #24
0
        public async Task <T> GetByIdAsync <T>(Guid id) where T : class, IAggregate
        {
            var list       = new List <object>();
            var start      = 0L;
            var streamName = GetStreamName <T>(id);
            StreamEventsSlice streamEventsSlice;

            do
            {
                streamEventsSlice = await _connection.ReadStreamEventsForwardAsync(streamName, start, 200, false);

                start = streamEventsSlice.NextEventNumber;
                list.AddRange(streamEventsSlice.Events.Select(ConvertEvent));
            }while (!streamEventsSlice.IsEndOfStream);
            return(_factory.Create <T>(list));
        }
Exemple #25
0
        public async Task <IActionResult> Post([FromBody] Models.Address data)
        {
            if (await _addressDataProvider.AddressExists(data.City, data.Street, data.StreetNumber, data.HomeNumber))
            {
                return(StatusCode((int)HttpStatusCode.Conflict));
            }

            var address = _addressFactory.Create(new AddressFactoryInput()
            {
                Street = data.Street, City = data.City, StreetNumber = data.StreetNumber, HomeNumber = data.HomeNumber, Id = Guid.NewGuid(), SquareMeters = data.SquareMeters
            });

            _addressRepository.Add(address);

            return(CreatedAtRoute("GetAddress", new { id = address.Id }, address));
        }
Exemple #26
0
        public IActionResult CreateTariff([FromBody] CreateTariff command)
        {
            var tariff =
                _tariffFactory.Create(new TariffFactoryInput()
            {
                Created     = DateTime.Now,
                Description = command.Description,
                TariffId    = command.TariffId,
                TariffValue = command.TariffPrice,
                ValidTo     = command.ValidTo
            });

            _tariffRepository.Add(tariff);

            return(CreatedAtRoute("GetTariff", new { TariffId = tariff.Id }, tariff));
        }
Exemple #27
0
        public AbstractProcessManagerTest()
        {
            Process = _defaultFactory.Create <TProcess>();
            State   = new TState();

            //restore @ version 1
            var snapshot = new SnapshotInfo("test", 1, State, "1");

            ((ISnaphottable)this.Process).TryRestore(snapshot);

            if (!this.Process.IsInitialized)
#pragma warning disable S112 // General exceptions should never be thrown
            {
                throw new Exception("something went wrong");
            }
#pragma warning restore S112 // General exceptions should never be thrown
        }
Exemple #28
0
        public async Task <MediatR.Unit> Handle(CreateStyleCommand request, CancellationToken cancellationToken)
        {
            var style = _factory.Create <IAggregateRoot <StyleAggregate>, StyleAggregateRoot>();

            var domainEvent = new CreateStyle
            {
                StyleId     = request.StyleId,
                ProductData = request.ProductData
            };

            style.AddEvent(domainEvent);
            using (_metrics.Measure.Timer.Time(_commandTimer))
            {
                await _repository.SaveAsync(style, $"{typeof(StyleAggregateRoot).Name}-{request.StyleId}");
            }

            return(MediatR.Unit.Value);
        }
        public T Get <T>(int id) where T : IAggregate
        {
            var events = new List <object>();
            StreamEventsSlice currentSlice;
            var nextSliceStart = StreamPosition.Start;
            var streamName     = GetStreamName <T>(id);

            do
            {
                currentSlice = connection
                               .ReadStreamEventsForwardAsync(streamName, nextSliceStart, 200, false)
                               .Result;
                nextSliceStart = currentSlice.NextEventNumber;
                events.AddRange(currentSlice.Events.Select(x => x.DeserializeEvent()));
            } while (!currentSlice.IsEndOfStream);
            var aggregate = factory.Create <T>(events);

            return((T)aggregate);
        }
Exemple #30
0
        protected override Task <CommandResult <Guid> > ExecuteCommand(AddEntityCommand command, CancellationToken cancellationToken)
        {
            var agg = _aggregateFactory.Create(command);

            var isSucceed = false;
            var okId      = Guid.Empty;

            //validation is not working nice yet
            if (agg.IsValid)
            {
                isSucceed = true;

                agg.GetEvents().ToImmutableList()
                .ForEach(ev => Publisher.Publish(ev));

                okId = agg.GetChange().AggregationId.Value;
            }

            return(Task.FromResult(new CommandResult <Guid>(isSucceed, okId, agg.Failures.ToImmutableList())));
        }