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)); }
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); } }
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; }
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)); }
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 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); }
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); }
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); }
public static TestExecutionResult FailedWith(ISourceId sourceId) { return(new TestExecutionResult { Result = ExecutionResult.Failed(), SourceId = sourceId }); }
public static TestExecutionResult SucceededWith(ISourceId sourceId) { return(new TestExecutionResult { Result = ExecutionResult.Success(), SourceId = sourceId }); }
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); }
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)); }
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); }
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)); }
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); }
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; }
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 })); }
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>[] { }); } }
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)); }
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); }
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); }
// 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)); }
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); }
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)); }
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)); }
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); }
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; }