public async Task IndexAsync(AggregateCommit aggregateCommit, ProjectionVersion version) { IEnumerable <(IEvent, EventOrigin)> eventDataList = GetEventData(aggregateCommit); foreach (var eventData in eventDataList) { List <Task> projectionSaveTasks = new List <Task>(); Type messagePayloadType = eventData.Item1.GetType(); foreach (var projectionType in projectionsContainer.Items) { if (projectionType.GetContractId().Equals(version.ProjectionName, StringComparison.OrdinalIgnoreCase) == false) { continue; } bool isInterested = projectionType.GetInterfaces() .Where(@interface => @interface.IsGenericType && @interface.GetGenericArguments().Length == 1 && (baseMessageType.IsAssignableFrom(@interface.GetGenericArguments()[0]))) .Where(@interface => @interface.GetGenericArguments()[0].IsAssignableFrom(messagePayloadType)) .Any(); if (isInterested) { projectionSaveTasks.Add(projection.SaveAsync(projectionType, eventData.Item1, eventData.Item2, version)); } } await Task.WhenAll(projectionSaveTasks).ConfigureAwait(false); } }
private byte[] SerializeEvent(AggregateCommit commit) { using (var stream = new MemoryStream()) { serializer.Serialize(stream, commit); return(stream.ToArray()); } }
public void Append(AggregateCommit aggregateCommit) { byte[] data = SerializeEvent(aggregateCommit); string aggregateId = Convert.ToBase64String(aggregateCommit.AggregateRootId); var document = new CosmosDbDocument(aggregateId, data); ResourceResponse <Document> response = client.CreateDocumentAsync(queryUri, document).Result; }
private IEnumerable <(IEvent, EventOrigin)> GetEventData(AggregateCommit commit) { string aggregateId = Convert.ToBase64String(commit.AggregateRootId); for (int pos = 0; pos < commit.Events.Count; pos++) { IEvent currentEvent = commit.Events[pos].Unwrap(); yield return(currentEvent, new EventOrigin(aggregateId, commit.Revision, pos, commit.Timestamp)); } }
public void Index(AggregateCommit aggregateCommit) { List <IndexRecord> indexRecordsBatch = new List <IndexRecord>(); foreach (var @event in aggregateCommit.Events) { string eventTypeId = @event.Unwrap().GetType().GetContractId(); var record = new IndexRecord(eventTypeId, aggregateCommit.AggregateRootId); indexRecordsBatch.Add(record); } indexStore.Apend(indexRecordsBatch); }
/// <summary> /// Flushes the specified aggregate commit. /// </summary> /// <param name="aggregateCommit">The aggregate commit.</param> internal protected void Flush(AggregateCommit aggregateCommit) { var idHash = Convert.ToBase64String(aggregateCommit.AggregateRootId); if (!eventsStreams.ContainsKey(idHash)) { eventsStreams.TryAdd(idHash, new ConcurrentQueue<AggregateCommit>()); } var evnts = eventsStreams[idHash]; evnts.Enqueue(aggregateCommit); eventsForReplay.Enqueue(aggregateCommit); }
Dictionary <string, string> BuildHeaders(AggregateCommit commit) { Dictionary <string, string> messageHeaders = new Dictionary <string, string> { { MessageHeader.AggregateRootId, Convert.ToBase64String(commit.AggregateRootId) } }; foreach (var trace in context.Trace) { messageHeaders.Add(trace.Key, trace.Value.ToString()); } return(messageHeaders); }
/// <summary> /// Flushes the specified aggregate commit. /// </summary> /// <param name="aggregateCommit">The aggregate commit.</param> internal protected void Flush(AggregateCommit aggregateCommit) { var idHash = Convert.ToBase64String(aggregateCommit.AggregateRootId); if (!eventsStreams.ContainsKey(idHash)) { eventsStreams.TryAdd(idHash, new ConcurrentQueue <AggregateCommit>()); } var evnts = eventsStreams[idHash]; evnts.Enqueue(aggregateCommit); eventsForReplay.Enqueue(aggregateCommit); }
private PreparedStatement GetPreparedStatementToPersistAnAggregateCommit(AggregateCommit aggregateCommit) { PreparedStatement persistAggregatePreparedStatement; if (persistAggregateEventsPreparedStatements.TryGetValue(aggregateCommit.BoundedContext, out persistAggregatePreparedStatement) == false) { string tableName = tableNameStrategy.GetEventsTableName(boundedContext); persistAggregatePreparedStatement = session.Prepare(String.Format(InsertEventsQueryTemplate, tableName)); persistAggregateEventsPreparedStatements.TryAdd(aggregateCommit.BoundedContext, persistAggregatePreparedStatement); } persistAggregatePreparedStatement.SetConsistencyLevel(writeConsistencyLevel); return(persistAggregatePreparedStatement); }
public void Append(AggregateCommit aggregateCommit) { byte[] data = SerializeEvent(aggregateCommit); try { session .Execute(GetPreparedStatementToPersistAnAggregateCommit(aggregateCommit) .Bind(Convert.ToBase64String(aggregateCommit.AggregateRootId), aggregateCommit.Timestamp, aggregateCommit.Revision, data)); } catch (WriteTimeoutException ex) { log.WarnException("Write timeout while persisting an aggregate commit", ex); } }
public async Task <IPublicEvent> FindPublicEventAsync(IAggregateRootId id, int commitRevision, int eventPosition) { EventStream stream = await eventStore.LoadAsync(id).ConfigureAwait(false); AggregateCommit commit = stream.Commits.Where(commit => commit.Revision == commitRevision).SingleOrDefault(); if (commit is null == false) { if (commit.Events.Count > eventPosition) { return(commit.PublicEvents[eventPosition]); } } return(null); }
public string Resolve(AggregateCommit aggregateCommit) { if (ReferenceEquals(null, aggregateCommit) == true) { throw new ArgumentNullException(nameof(aggregateCommit)); } var tenant = string.Empty; if (TryResolve(aggregateCommit.AggregateRootId, out tenant)) { return(tenant); } throw new NotSupportedException($"Unable to resolve tenant for id {aggregateCommit.AggregateRootId}"); }
public async Task IndexAsync(AggregateCommit aggregateCommit) { List <IndexRecord> indexRecordsBatch = new List <IndexRecord>(); foreach (var @event in aggregateCommit.Events) { string eventTypeId = @event.Unwrap().GetType().GetContractId(); var record = new IndexRecord(eventTypeId, aggregateCommit.AggregateRootId); indexRecordsBatch.Add(record); } foreach (var publicEvent in aggregateCommit.PublicEvents) { string eventTypeId = publicEvent.GetType().GetContractId(); var record = new IndexRecord(eventTypeId, aggregateCommit.AggregateRootId); indexRecordsBatch.Add(record); } await indexStore.ApendAsync(indexRecordsBatch).ConfigureAwait(false); }
public override async Task RunAsync(IEnumerable <IMigration <AggregateCommit> > migrations) { LoadAggregateCommitsResult result = await source.LoadAggregateCommitsAsync(string.Empty, 5000).ConfigureAwait(false); int counter = 0; try { while (result.Commits.Any()) { for (int i = 0; i < result.Commits.Count; i++) { counter++; AggregateCommit sourceCommit = result.Commits[i]; foreach (var migration in migrations) { if (migration.ShouldApply(sourceCommit)) { sourceCommit = migration.Apply(sourceCommit); } } if (ForSomeReasonTheAggregateCommitHasBeenDeleted(sourceCommit)) { logger.Debug(() => $"An aggregate commit has been wiped from the face of the Earth. R.I.P.{Environment.NewLine}{result.Commits[i].ToString()}"); // Bonus: How Пикасо is spelled in English => Piccasso, Picasso, Piccaso ?? I bet spmeone will git-blame me continue; } await target.AppendAsync(sourceCommit).ConfigureAwait(false); } result = await source.LoadAggregateCommitsAsync(result.PaginationToken, 5000).ConfigureAwait(false); // think of paging logger.Info(() => $"Migrated commits - Counter: `{counter}` - Pagination Token: `{result.PaginationToken}`"); } } catch (System.Exception ex) { logger.ErrorException(ex, () => $"Something boom bam while runnning migration. Here is paginator: {result.PaginationToken}"); } }
public async Task SaveAsync <AR>(AR aggregateRoot) where AR : IAggregateRoot { AggregateCommit commit = await aggregateRepository.SaveInternalAsync(aggregateRoot).ConfigureAwait(false); if (commit is default(AggregateCommit)) { logger.Debug(() => "Aggregate commit has not been persisted and no events have been published because the `source` persistence action did not finish successfully. This usually happens when the AR did not generate any new events such as ignoring a command. (It is fine but check your business logic.)"); return; } try { bool publishResult = commiter.Publish(commit, BuildHeaders(commit)); if (publishResult == false) { logger.Error(() => "Unable to publish aggregate commit."); } } catch (Exception ex) { logger.ErrorException(ex, () => "Unable to publish aggregate commit."); } }
public void OnAggregateCommit(AggregateCommit migratedAggregateCommit) { }
private static bool ForSomeReasonTheAggregateCommitHasBeenDeleted(AggregateCommit aggregateCommit) { return(aggregateCommit is null || aggregateCommit.Events.Any() == false); }
/// <summary> /// Persists the specified aggregate commit. /// </summary> /// <param name="aggregateCommit">The aggregate commit.</param> public void Append(AggregateCommit aggregateCommit) { eventStoreStorage.Flush(aggregateCommit); }
public Task AppendAsync(AggregateCommit aggregateCommit) { Storage.Add(aggregateCommit); return(Task.CompletedTask); }
public AggregateCommit Transform(AggregateCommit origin) => origin;
public string GetEventsTableName(AggregateCommit aggregateCommit) { var boundedContext = aggregateCommit.BoundedContext; return(GetEventsTableName(boundedContext)); }
public void Append(AggregateCommit aggregateCommit) { storage.Add(aggregateCommit); }
/// <summary> /// Persists the specified aggregate commit. /// </summary> /// <param name="aggregateCommit">The aggregate commit.</param> public Task AppendAsync(AggregateCommit aggregateCommit) { eventStoreStorage.Flush(aggregateCommit); return(Task.CompletedTask); }