Ejemplo n.º 1
0
        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());
     }
 }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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));
            }
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 8
0
        /// <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);
            }
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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}");
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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.");
            }
        }
Ejemplo n.º 16
0
 public void OnAggregateCommit(AggregateCommit migratedAggregateCommit)
 {
 }
Ejemplo n.º 17
0
 private static bool ForSomeReasonTheAggregateCommitHasBeenDeleted(AggregateCommit aggregateCommit)
 {
     return(aggregateCommit is null || aggregateCommit.Events.Any() == false);
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Persists the specified aggregate commit.
 /// </summary>
 /// <param name="aggregateCommit">The aggregate commit.</param>
 public void Append(AggregateCommit aggregateCommit)
 {
     eventStoreStorage.Flush(aggregateCommit);
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Persists the specified aggregate commit.
 /// </summary>
 /// <param name="aggregateCommit">The aggregate commit.</param>
 public void Append(AggregateCommit aggregateCommit)
 {
     eventStoreStorage.Flush(aggregateCommit);
 }
Ejemplo n.º 20
0
        public Task AppendAsync(AggregateCommit aggregateCommit)
        {
            Storage.Add(aggregateCommit);

            return(Task.CompletedTask);
        }
Ejemplo n.º 21
0
 public AggregateCommit Transform(AggregateCommit origin) => origin;
        public string GetEventsTableName(AggregateCommit aggregateCommit)
        {
            var boundedContext = aggregateCommit.BoundedContext;

            return(GetEventsTableName(boundedContext));
        }
Ejemplo n.º 23
0
 public void Append(AggregateCommit aggregateCommit)
 {
     storage.Add(aggregateCommit);
 }
Ejemplo n.º 24
0
        /// <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);
        }