async Task <IExecutionResult> IOperationHandler <AppendToStreamAsync, IExecutionResult> .Handle(AppendToStreamAsync operation, CancellationToken cancellationToken) { var id = CosmosStreamNameStrategy.GetStreamIdentifier(operation.StreamId); var streamType = CosmosStreamNameStrategy.GetStreamType(operation.StreamId); long eventPosition = EventPosition.Start; if (operation.ExpectedVersion == ExpectedVersion.NoStream || operation.ExpectedVersion == ExpectedVersion.Any) { await _operationDispatcher.Dispatch(new CreateNewStream(id, streamType, operation.Events)).ConfigureAwait(false); eventPosition++; } else { var streamDoc = await _operationDispatcher .Dispatch <GetStreamDocumentByIdAsync, Optional <StreamDocument> >(new GetStreamDocumentByIdAsync(id)).ConfigureAwait(false); streamDoc.ThrowsIf(stream => !stream.HasValue, new AggregateNotFoundException(operation.StreamId)); var existingStream = streamDoc.Value.ToCosmosStream(); existingStream.ThrowsIf(stream => operation.ExpectedVersion.Value != stream.Version.Value && operation.ExpectedVersion != ExpectedVersion.SafeStream, new WrongExpectedStreamVersionException(operation.ExpectedVersion.Value.ToString(), existingStream.Version.Value.ToString())); var streamEvents = await _operationDispatcher .Dispatch <GetEventDocumentsForward, IEnumerable <EventDocument> > ( new GetEventDocumentsForward(eDoc => eDoc.StreamId == id, Convert.ToInt32(StreamPosition.Start), _cosmosDBConfigurations.ReadBatchSize) ).ConfigureAwait(false); existingStream = existingStream.AppendEvents(streamEvents.Select(e => e.ToCosmosEvent())); operation.ExpectedVersion = operation.ExpectedVersion.WithVersion(operation.ExpectedVersion + operation.Events.Length); var newVersionedStream = existingStream.ChangeVersion(operation.ExpectedVersion); await _cosmosClient.UpdateItemAsync(id, _cosmosDBConfigurations.StreamContainerName, newVersionedStream.ToCosmosStreamDocument(), operation.ExpectedVersion.MetaData).ConfigureAwait(false); eventPosition = newVersionedStream.NextEventNumber; } foreach (var @event in operation.Events) { var newEvent = new EventDocument(@event.EventId, id, eventPosition, this._eventSerializer.Serialize(@event.Data), @event.EventMetadata, @event.EventType); await _cosmosClient.CreateItemAsync(newEvent, this._cosmosDBConfigurations.EventContainerName).ConfigureAwait(false); eventPosition++; } return(ExecutionResult.Success); }
public async Task <IExecutionResult> TakeSnapshotAsync(string stream) { Optional <TAggregateRoot> root = await _rootRepository.GetAsync(stream); root.ThrowsIf(r => !r.HasValue, new AggregateNotFoundException(stream)); _changeTracker.TryGet(stream, out Aggregate aggregate); var serializedState = _eventSerializer.Serialize(root.Value.TakeSnapshot()); var newSnapshot = new SnapshotDocument(aggregate.Identifier, serializedState, aggregate.ExpectedVersion.Value.ToString(), null, typeof(TSnapshot).TypeQualifiedName()); await _cosmosDbClient.CreateItemAsync(newSnapshot, _cosmosDBConfigurations.SnapshotContainerName).ConfigureAwait(false); return(ExecutionResult.Success); }
private void RegisterHandlers() { _operationDispatcher.RegisterHandler <CreateNewStream>(new CreateNewStreamHandler(async doc => await _cosmosClient.CreateItemAsync(doc, _cosmosDBConfigurations.StreamContainerName))); _operationDispatcher.RegisterHandler <GetStreamDocumentByIdAsync>(new GetStreamDocumentByIdAsyncHandler(_cosmosClient, _cosmosDBConfigurations)); _operationDispatcher.RegisterHandler <ReadStreamWithEventsByDirection>(new ReadStreamWithEventsByDirectionHandler(async opt => await _operationDispatcher.Dispatch <GetStreamDocumentByIdAsync, Optional <StreamDocument> >(opt).ConfigureAwait(false))); _operationDispatcher.RegisterHandler <GetEventDocumentsForward>(new GetEventDocumentsForwardHandler(_cosmosClient, _cosmosDBConfigurations)); _operationDispatcher.RegisterHandler <AppendToStreamAsync>(new AppendToStreamAsyncHandler(_eventSerializer, _cosmosClient, _cosmosDBConfigurations, _operationDispatcher)); _operationDispatcher.RegisterPipeline <AppendToStreamAsync>(new AppendToStreamAsyncPipeline()); }