Esempio n. 1
0
        public Task <IReadOnlyCollection <IDomainEvent> > UpdateAsync <TAggregate, TIdentity>(
            TIdentity id,
            ISourceId sourceId,
            Func <TAggregate, CancellationToken, Task> updateAggregate,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
        {
            return(_transientFaultHandler.TryAsync(
                       async c =>
            {
                var aggregate = await LoadAsync <TAggregate, TIdentity>(id, c).ConfigureAwait(false);
                if (aggregate.HasSourceId(sourceId))
                {
                    throw new DuplicateOperationException(
                        sourceId,
                        id,
                        $"Aggregate '{typeof(TAggregate).PrettyPrint()}' has already had operation '{sourceId}' performed");
                }

                await updateAggregate(aggregate, c).ConfigureAwait(false);

                return await StoreAsync <TAggregate, TIdentity>(aggregate, sourceId, c).ConfigureAwait(false);
            },
                       Label.Named("aggregate-update"),
                       cancellationToken));
        }
Esempio n. 2
0
            public async Task <TSaga> UpdateAsync <TSaga>(
                ISagaId sagaId,
                SagaDetails sagaDetails,
                ISourceId sourceId,
                Func <TSaga, CancellationToken, Task> updateSaga,
                CancellationToken cancellationToken)
                where TSaga : ISaga
            {
                using (await _asyncLock.WaitAsync(cancellationToken).ConfigureAwait(false))
                {
                    _hasUpdateBeenCalled = true;

                    if (!_sagas.TryGetValue(sagaId, out var obj))
                    {
                        obj            = Activator.CreateInstance(sagaDetails.SagaType, sagaId);
                        _sagas[sagaId] = obj;
                    }

                    var saga = (TSaga)obj;

                    await updateSaga(saga, cancellationToken).ConfigureAwait(false);

                    return(saga);
                }
            }
Esempio n. 3
0
 public CommandException(Type commandType, ISourceId sourceId, IExecutionResult executionResult, string message, Exception innerException)
     : base(message, innerException)
 {
     CommandType     = commandType;
     ExecutionResult = executionResult;
     SourceId        = sourceId;
 }
 public DuplicateOperationException(
     ISourceId sourceId, IIdentity aggregateId, string message)
     : base(message)
 {
     SourceId    = sourceId;
     AggregateId = aggregateId;
 }
Esempio n. 5
0
        public async Task <TSaga> UpdateAsync <TSaga>(
            ISagaId sagaId,
            SagaDetails sagaDetails,
            ISourceId sourceId,
            Func <TSaga, CancellationToken, Task> updateSaga,
            CancellationToken cancellationToken)
            where TSaga : ISaga
        {
            var saga = default(TSaga);

            var storeAggregateSagaAsync = await GetUpdateAsync(
                sagaDetails.SagaType,
                cancellationToken)
                                          .ConfigureAwait(false);

            var domainEvents = await storeAggregateSagaAsync(
                sagaId,
                sourceId,
                async (s, c) => {
                var specificSaga = (TSaga)s;
                await updateSaga(specificSaga, c).ConfigureAwait(false);
                saga = specificSaga;
            },
                cancellationToken)
                               .ConfigureAwait(false);

            return(domainEvents.Any()
                ? saga
                : default(TSaga));
        }
Esempio n. 6
0
 public CreateCustomerCommand(CustomerId aggregateId, ISourceId sourceId, Guid employeeId, string userName, string personalIdentificationNumber, string address) : base(aggregateId, sourceId)
 {
     EmployeeId = employeeId;
     UserName   = userName;
     PersonalIdentificationNumber = personalIdentificationNumber;
     Address = address;
 }
 public DuplicateOperationException(
     ISourceId sourceId, IIdentity aggregateId, string message)
     : base(message)
 {
     SourceId = sourceId;
     AggregateId = aggregateId;
 }
Esempio n. 8
0
            public override async Task <ISaga> UpdateAsync(
                ISagaId sagaId,
                Type sagaType,
                ISourceId sourceId,
                Func <ISaga, CancellationToken, Task> updateSaga,
                CancellationToken cancellationToken)
            {
                var commandBus = _serviceProvider.GetRequiredService <ICommandBus>();

                ISaga saga;

                using (await _asyncLock.WaitAsync(cancellationToken).ConfigureAwait(false))
                {
                    _hasUpdateBeenCalled = true;

                    if (!_sagas.TryGetValue(sagaId, out var obj))
                    {
                        obj            = Activator.CreateInstance(sagaType, sagaId);
                        _sagas[sagaId] = obj;
                    }

                    saga = (ISaga)obj;

                    await updateSaga(saga, cancellationToken).ConfigureAwait(false);
                }

                await saga.PublishAsync(commandBus, cancellationToken).ConfigureAwait(false);

                return(saga);
            }
Esempio n. 9
0
        public virtual async Task <IReadOnlyCollection <IDomainEvent <TAggregate, TIdentity> > > StoreAsync <TAggregate, TIdentity>(
            TIdentity id,
            IReadOnlyCollection <IUncommittedEvent> uncommittedDomainEvents,
            ISourceId sourceId,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }
            if (sourceId.IsNone())
            {
                throw new ArgumentNullException(nameof(sourceId));
            }

            if (uncommittedDomainEvents == null || !uncommittedDomainEvents.Any())
            {
                return(new IDomainEvent <TAggregate, TIdentity>[] {});
            }

            var aggregateType = typeof(TAggregate);

            _log.Verbose(
                "Storing {0} events for aggregate '{1}' with ID '{2}'",
                uncommittedDomainEvents.Count,
                aggregateType.Name,
                id);

            var batchId       = Guid.NewGuid().ToString();
            var storeMetadata = new[]
            {
                new KeyValuePair <string, string>(MetadataKeys.BatchId, batchId),
                new KeyValuePair <string, string>(MetadataKeys.SourceId, sourceId.Value)
            };

            var serializedEvents = uncommittedDomainEvents
                                   .Select(e =>
            {
                var md = _metadataProviders
                         .SelectMany(p => p.ProvideMetadata <TAggregate, TIdentity>(id, e.AggregateEvent, e.Metadata))
                         .Concat(e.Metadata)
                         .Concat(storeMetadata);
                return(_eventJsonSerializer.Serialize(e.AggregateEvent, md));
            })
                                   .ToList();

            var committedDomainEvents = await _eventPersistence.CommitEventsAsync(
                id,
                serializedEvents,
                cancellationToken)
                                        .ConfigureAwait(false);

            var domainEvents = committedDomainEvents
                               .Select(e => _eventJsonSerializer.Deserialize <TAggregate, TIdentity>(id, e))
                               .ToList();

            return(domainEvents);
        }
Esempio n. 10
0
        public async Task <IReadOnlyCollection <IDomainEvent> > StoreAsync <TAggregate, TIdentity>(
            TAggregate aggregate,
            ISourceId sourceId,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
        {
            var domainEvents = await aggregate.CommitAsync(
                _eventStore,
                _snapshotStore,
                sourceId,
                cancellationToken)
                               .ConfigureAwait(false);

            if (domainEvents.Any())
            {
                var domainEventPublisher = _serviceProvider.GetRequiredService <IDomainEventPublisher>();
                await domainEventPublisher.PublishAsync(
                    domainEvents,
                    cancellationToken)
                .ConfigureAwait(false);
            }

            return(domainEvents);
        }
Esempio n. 11
0
 public static TestExecutionResult FailedWith(ISourceId sourceId)
 {
     return(new TestExecutionResult
     {
         Result = ExecutionResult.Failed(),
         SourceId = sourceId
     });
 }
Esempio n. 12
0
 public static TestExecutionResult SucceededWith(ISourceId sourceId)
 {
     return(new TestExecutionResult
     {
         Result = ExecutionResult.Success(),
         SourceId = sourceId
     });
 }
Esempio n. 13
0
 private async Task ShipOrderAsync(OrderId orderId, ISourceId sourceId)
 {
     await _aggregateStore.UpdateAsync <Order, OrderId>(orderId, sourceId,
                                                        (order, c) => {
         order.SetShippedStatus();
         return(Task.FromResult(0));
     }, CancellationToken.None
                                                        ).ConfigureAwait(false);
 }
Esempio n. 14
0
 public static IReadOnlyCollection <IDomainEvent> Store <TAggregate, TIdentity>(
     this IAggregateStore aggregateStore,
     TAggregate aggregate,
     ISourceId sourceId)
     where TAggregate : IAggregateRoot <TIdentity>
     where TIdentity : IIdentity
 {
     return(aggregateStore.Store <TAggregate, TIdentity>(aggregate, sourceId, CancellationToken.None));
 }
Esempio n. 15
0
        public async Task <IAggregateUpdateResult <TExecutionResult> > UpdateAsync <TAggregate, TIdentity, TExecutionResult>(
            TIdentity id,
            ISourceId sourceId,
            Func <TAggregate, CancellationToken, Task <TExecutionResult> > updateAggregate,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
            where TExecutionResult : IExecutionResult
        {
            var aggregateUpdateResult = await _transientFaultHandler.TryAsync(
                async c =>
            {
                var aggregate = await LoadAsync <TAggregate, TIdentity>(id, c).ConfigureAwait(false);
                if (aggregate.HasSourceId(sourceId))
                {
                    throw new DuplicateOperationException(
                        sourceId,
                        id,
                        $"Aggregate '{typeof(TAggregate).PrettyPrint()}' has already had operation '{sourceId}' performed");
                }

                var result = await updateAggregate(aggregate, c).ConfigureAwait(false);
                if (!result.IsSuccess)
                {
                    _log.Debug(() => $"Execution failed on aggregate '{typeof(TAggregate).PrettyPrint()}', disregarding any events emitted");
                    return(new AggregateUpdateResult <TExecutionResult>(
                               result,
                               EmptyDomainEventCollection));
                }

                var domainEvents = await aggregate.CommitAsync(
                    _eventStore,
                    _snapshotStore,
                    sourceId,
                    cancellationToken)
                                   .ConfigureAwait(false);

                return(new AggregateUpdateResult <TExecutionResult>(
                           result,
                           domainEvents));
            },
                Label.Named("aggregate-update"),
                cancellationToken)
                                        .ConfigureAwait(false);

            if (aggregateUpdateResult.Result.IsSuccess &&
                aggregateUpdateResult.DomainEvents.Any())
            {
                var domainEventPublisher = _resolver.Resolve <IDomainEventPublisher>();
                await domainEventPublisher.PublishAsync(
                    aggregateUpdateResult.DomainEvents,
                    cancellationToken)
                .ConfigureAwait(false);
            }

            return(aggregateUpdateResult);
        }
Esempio n. 16
0
 public Task <IReadOnlyCollection <IDomainEvent> > StoreAsync <TAggregate, TIdentity>(
     TAggregate aggregate,
     ISourceId sourceId,
     CancellationToken cancellationToken)
     where TAggregate : IAggregateRoot <TIdentity>
     where TIdentity : IIdentity
 {
     return(aggregate.CommitAsync(_eventStore, _snapshotStore, sourceId, cancellationToken));
 }
Esempio n. 17
0
 public async Task StoreAsync <TAggregate, TIdentity>(TAggregate aggregate, ISourceId sourceId, CancellationToken cancellationToken)
     where TAggregate : class, IAggregateRoot <TIdentity>
     where TIdentity : IIdentity
 {
     await aggregate.CommitAsync(
         _eventJsonSerializer,
         sourceId,
         cancellationToken)
     .ConfigureAwait(false);
 }
Esempio n. 18
0
 public InvoiceCreateCommand(InvoiceId aggregateId, ISourceId sourceId, Guid employeeId, Guid customerId, DateTime startDate, DateTime endDate, string invoiceDescription, string name, decimal vat, InvoiceItem[] invoiceItems) : base(aggregateId, sourceId)
 {
     EmployeeId         = employeeId;
     CustomerId         = customerId;
     StartDate          = startDate;
     EndDate            = endDate;
     InvoiceDescription = invoiceDescription;
     Name         = name;
     Vat          = vat;
     InvoiceItems = invoiceItems;
 }
Esempio n. 19
0
        public async Task <IActionResult> PublishCommandAsync([FromBody] dynamic commandJson, string name)
        {
            const int version = 1;
            // if (!IsAuthorizedToPublish(name)) LoginManager.ReportSessionError("Invalid or expired login.");

            //  var json = JsonConvert.SerializeObject(commandJson);
            ISourceId sourceId =
                await
                _serializedCommandPublisher.PublishSerilizedCommandAsync(name, version, commandJson,
                                                                         CancellationToken.None).ConfigureAwait(false);

            return(Ok(new { SourceId = sourceId.Value }));
        }
Esempio n. 20
0
        protected Command(TIdentity aggregateId, ISourceId sourceId)
        {
            if (aggregateId == null)
            {
                throw new ArgumentNullException(nameof(aggregateId));
            }
            if (sourceId == null)
            {
                throw new ArgumentNullException(nameof(aggregateId));
            }

            AggregateId = aggregateId;
            SourceId    = sourceId;
        }
        public async Task <IReadOnlyCollection <IDomainEvent> > CommitAsync(
            IEventJsonSerializer _eventJsonSerializer,
            ISourceId sourceId,
            CancellationToken cancellationToken)
        {
            if (!_exists)
            {
                await Persistence.Save(this, CancellationToken.None);
            }
            else
            {
                await Persistence.Update(this, CancellationToken.None);
            }

            await Persistence.Dispose(cancellationToken);

            if (_occuredEvents.HasItems())
            {
                var domainEvents = _occuredEvents
                                   .Select(e =>
                {
                    return(_eventJsonSerializer.Serialize(e.AggregateEvent, e.Metadata));
                })
                                   .Select((e, i) =>
                {
                    var committedDomainEvent = new CommittedDomainEvent
                    {
                        AggregateId             = Id.Value,
                        AggregateName           = e.Metadata[MetadataKeys.AggregateName],
                        AggregateSequenceNumber = e.AggregateSequenceNumber,
                        Data                 = e.SerializedData,
                        Metadata             = e.SerializedMetadata,
                        GlobalSequenceNumber = i + 1,
                    };
                    return(committedDomainEvent);
                })
                                   .Select(e => _eventJsonSerializer.Deserialize <TAggregate, TIdentity>(Id, e))
                                   .ToList();

                _occuredEvents.Clear();

                return(domainEvents);
            }
            else
            {
                _occuredEvents.Clear();
                return(new IDomainEvent <TAggregate, TIdentity>[] { });
            }
        }
Esempio n. 22
0
 public async Task <TSaga> UpdateAsync <TSaga>(
     ISagaId sagaId,
     ISourceId sourceId,
     Func <TSaga, CancellationToken, Task> updateSaga,
     CancellationToken cancellationToken)
     where TSaga : ISaga
 {
     return((TSaga) await UpdateAsync(
                sagaId,
                typeof(TSaga),
                sourceId,
                (s, c) => updateSaga((TSaga)s, c),
                cancellationToken)
            .ConfigureAwait(false));
 }
Esempio n. 23
0
        public async Task <IReadOnlyCollection <IDomainEvent> > CommitAsync(
            IEventStore eventStore,
            ISourceId sourceId,
            CancellationToken cancellationToken)
        {
            var domainEvents = await eventStore.StoreAsync <TAggregate, TIdentity>(
                Id,
                _uncommittedEvents,
                sourceId,
                cancellationToken)
                               .ConfigureAwait(false);

            _uncommittedEvents.Clear();
            return(domainEvents);
        }
Esempio n. 24
0
 public async Task UpdateAsync <TAggregate, TIdentity>(TIdentity id, ISourceId sourceId, Func <TAggregate, CancellationToken, Task> updateAggregate, CancellationToken cancellationToken)
     where TAggregate : class, IAggregateRoot <TIdentity>
     where TIdentity : IIdentity
 {
     var aggregateUpdateResult = await UpdateAsync <TAggregate, TIdentity, IExecutionResult>(
         id,
         sourceId,
         async (a, c) =>
     {
         await updateAggregate(a, c).ConfigureAwait(false);
         return(ExecutionResult.Success());
     },
         cancellationToken)
                                 .ConfigureAwait(false);
 }
Esempio n. 25
0
 // ReSharper disable once MemberCanBePrivate.Global
 public async Task <IReadOnlyCollection <IDomainEvent> > UpdateAggregateAsync <TAggregate, TIdentity>(
     TIdentity id,
     ISourceId sourceId,
     Func <TAggregate, CancellationToken, Task> updateAggregate,
     CancellationToken cancellationToken)
     where TAggregate : IAggregateRoot <TIdentity>, ISaga
     where TIdentity : IIdentity
 {
     return(await _aggregateStore.UpdateAsync(
                id,
                sourceId,
                updateAggregate,
                cancellationToken)
            .ConfigureAwait(false));
 }
Esempio n. 26
0
        public ISourceId Publish <TAggregate, TIdentity, TSourceIdentity>(
            ICommand <TAggregate, TIdentity, TSourceIdentity> command,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
            where TSourceIdentity : ISourceId
        {
            ISourceId sourceId = null;

            using (var a = AsyncHelper.Wait)
            {
                a.Run(PublishAsync(command, cancellationToken), id => sourceId = id);
            }

            return(sourceId);
        }
Esempio n. 27
0
        public static IReadOnlyCollection <IDomainEvent> Store <TAggregate, TIdentity>(
            this IAggregateStore aggregateStore,
            TAggregate aggregate,
            ISourceId sourceId,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
        {
            IReadOnlyCollection <IDomainEvent> domainEvents = null;

            using (var a = AsyncHelper.Wait)
            {
                a.Run(aggregateStore.StoreAsync <TAggregate, TIdentity>(aggregate, sourceId, cancellationToken), r => domainEvents = r);
            }

            return(domainEvents);
        }
 public static IReadOnlyCollection <IDomainEvent> Update <TAggregate, TIdentity>(
     this IAggregateStore aggregateStore,
     TIdentity id,
     ISourceId sourceId,
     Action <TAggregate> updateAggregate)
     where TAggregate : IAggregateRoot <TIdentity>
     where TIdentity : IIdentity
 {
     return(aggregateStore.Update <TAggregate, TIdentity>(
                id,
                sourceId,
                (a, c) => {
         updateAggregate(a);
         return Task.FromResult(0);
     },
                CancellationToken.None));
 }
Esempio n. 29
0
        public static async Task <IAggregateUpdateResultEx <TResult> > Update <TAggregate, TIdentity, TResult>(
            this IAggregateStore aggregateStore,
            TIdentity id, ISourceId sourceId,
            Func <TAggregate, CancellationToken, Task <TResult> > updateAggregate,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
            where TResult : IResult
        {
            var updateResult = await aggregateStore.UpdateAsync <TAggregate, TIdentity, ExecutionResultWrapper <TResult> >(
                id, sourceId,
                async (aggregate, token) => new ExecutionResultWrapper <TResult>(await updateAggregate(aggregate, token)),
                cancellationToken
                );

            return(new AggregateUpdateResult <TResult>(updateResult.Result.Impl, updateResult.DomainEvents));
        }
Esempio n. 30
0
        public async Task <IReadOnlyCollection <IDomainEvent> > UpdateAsync <TAggregate, TIdentity>(
            TIdentity id,
            ISourceId sourceId,
            Func <TAggregate, CancellationToken, Task> updateAggregate,
            CancellationToken cancellationToken)
            where TAggregate : IAggregateRoot <TIdentity>
            where TIdentity : IIdentity
        {
            var domainEvents = await _transientFaultHandler.TryAsync(
                async c =>
            {
                var aggregate = await LoadAsync <TAggregate, TIdentity>(id, c).ConfigureAwait(false);
                if (aggregate.HasSourceId(sourceId))
                {
                    throw new DuplicateOperationException(
                        sourceId,
                        id,
                        $"Aggregate '{typeof(TAggregate).PrettyPrint()}' has already had operation '{sourceId}' performed");
                }

                await updateAggregate(aggregate, c).ConfigureAwait(false);

                return(await aggregate.CommitAsync(
                           _eventStore,
                           _snapshotStore,
                           sourceId,
                           cancellationToken)
                       .ConfigureAwait(false));
            },
                Label.Named("aggregate-update"),
                cancellationToken)
                               .ConfigureAwait(false);

            if (domainEvents.Any())
            {
                var domainEventPublisher = _resolver.Resolve <IDomainEventPublisher>();
                await domainEventPublisher.PublishAsync <TAggregate, TIdentity>(
                    id,
                    domainEvents,
                    cancellationToken)
                .ConfigureAwait(false);
            }

            return(domainEvents);
        }
Esempio n. 31
0
 public CreateOrderCommand(OrderId id, ISourceId sourceId, List <BasketItem> basketItems, string userId, string userName, string city, string street, string state, string country, string zipcode,
                           string cardNumber, string cardHolderName, DateTime cardExpiration,
                           string cardSecurityNumber, int cardTypeId) : this(id, sourceId)
 {
     _orderItems        = basketItems.ToOrderItemsDTO().ToList();
     UserId             = userId;
     UserName           = userName;
     City               = city;
     Street             = street;
     State              = state;
     Country            = country;
     ZipCode            = zipcode;
     CardNumber         = cardNumber;
     CardHolderName     = cardHolderName;
     CardExpiration     = cardExpiration;
     CardSecurityNumber = cardSecurityNumber;
     CardTypeId         = cardTypeId;
     CardExpiration     = cardExpiration;
 }