Exemple #1
0
        protected override void ApplySnapshot(IAggregateSnapshot <Guid> snapshot)
        {
            GiftCardSnapshot giftCardSnapshot = snapshot as GiftCardSnapshot
                                                ?? throw new InvalidOperationException();

            Balance = giftCardSnapshot.Balance;
        }
        public async Task <IAggregateSnapshot <TKey> > FindLastSnapshotAsync(TKey aggregateId, int maxVersion,
                                                                             CancellationToken cancellationToken = default)
        {
            var filter = new QueryFilter("aggregateId", QueryOperator.Equal, aggregateId as dynamic);

            filter.AddCondition("aggregateVersion", QueryOperator.LessThanOrEqual, maxVersion);
            Search search = _table.Query(new QueryOperationConfig
            {
                Filter         = filter,
                Limit          = 1,
                BackwardSearch = true,
            });

            List <Document> documents = await search.GetNextSetAsync(cancellationToken).ConfigureAwait(false);

            if (documents.Count == 0)
            {
                return(null);
            }

            string json = documents.First().ToJson();
            IAggregateSnapshot <TKey> snapshot = JsonConvert.DeserializeObject <IAggregateSnapshot <TKey> >(json, Defaults.JsonSerializerSettings);

            return(snapshot);
        }
Exemple #3
0
        public Task <IAggregateSnapshot <TKey> > FindLastSnapshotAsync(TKey aggregateId, int maxVersion,
                                                                       CancellationToken cancellationToken = default)
        {
            if (!Directory.Exists(_options.Folder))
            {
                return(Task.FromResult(null as IAggregateSnapshot <TKey>));
            }

            int latestVersion = Directory
                                .GetFiles(_options.Folder, "*.snapshot")
                                .Select(x => Path.GetFileNameWithoutExtension(x))
                                .Select(x => x.Split('.').LastOrDefault())
                                .Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out int version) ? version : -1)
                                .Where(x => x <= maxVersion)
                                .OrderByDescending(x => x)
                                .FirstOrDefault();

            if (latestVersion < 1)
            {
                return(Task.FromResult(null as IAggregateSnapshot <TKey>));
            }

            string filePath   = GetFilePath(aggregateId, latestVersion);
            string serialized = File.ReadAllText(filePath);
            IAggregateSnapshot <TKey> snapshot = JsonConvert.DeserializeObject <IAggregateSnapshot <TKey> >(
                serialized, Defaults.JsonSerializerSettings);

            return(Task.FromResult(snapshot));
        }
Exemple #4
0
        protected virtual void HydrateSnapshot(IAggregateSnapshot <TAggregate, TIdentity> aggregateSnapshot, Int64 version)
        {
            var snapshotHydrater = GetSnapshotHydrateMethods(aggregateSnapshot);

            snapshotHydrater(aggregateSnapshot);
            Version = version;
        }
Exemple #5
0
        protected virtual async Task <TAggregate> FindAggregateAsync(TKey id,
                                                                     bool ignoreSnapshot = false,
                                                                     int version         = -1,
                                                                     CancellationToken cancellationToken = default)
        {
            int maxVersion = version <= 0 ? int.MaxValue : version;

            IAggregateSnapshot <TKey> snapshot = null;

            if (!ignoreSnapshot)
            {
                snapshot = await _snapshotStore
                           .FindLastSnapshotAsync(id, maxVersion, cancellationToken)
                           .ConfigureAwait(false);
            }

            int minVersion = snapshot == null ? 1 : snapshot.AggregateVersion + 1;

            IAggregateEvent <TKey>[] events = await _eventStore
                                              .GetEventsAsync(id, minVersion, maxVersion, cancellationToken)
                                              .ConfigureAwait(false);

            if (snapshot == null)
            {
                return(events.Length == 0
                    ? null
                    : Activator.CreateInstance(typeof(TAggregate), id, events as IEnumerable <IAggregateEvent <TKey> >) as TAggregate);
            }
            else
            {
                return(Activator.CreateInstance(typeof(TAggregate), id, snapshot, events as IEnumerable <IAggregateEvent <TKey> >) as TAggregate);
            }
        }
Exemple #6
0
 protected AggregateRoot(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history)
 {
     Version = snapshot.Version;
     Id      = snapshot.Id;
     ApplySnapshot(snapshot);
     ApplyHistory(history);
 }
 private T CreateAggregateFromSnapshotAndHistory <T>(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history)
 {
     return((T)typeof(T)
            .GetConstructor(
                BindingFlags.Instance | BindingFlags.NonPublic,
                null, new Type[] { typeof(IAggregateSnapshot), typeof(IEnumerable <IDomainEvent>) }, new ParameterModifier[0])
            .Invoke(new object[] { snapshot, history }));
 }
        public void SaveSnapshot(IAggregateSnapshot snapshot)
        {
            var snapshotItem = SnapshotItem.FromDomainSnapshot(snapshot);

            collection.ReplaceOne(f => f.AggregateId == snapshot.Id.ToString(), snapshotItem, new ReplaceOptions()
            {
                IsUpsert = true
            });
        }
Exemple #9
0
        private void IntegrateSnapshot(IAggregateSnapshot <TKey> snapshot)
        {
            if (!snapshot.AggregateId.Equals(Id))
            {
                throw new InvalidOperationException($"Cannot integrate snapshot of aggregate #{snapshot.AggregateId} on aggregate #{Id}");
            }

            ApplySnapshot(snapshot);

            Version = snapshot.AggregateVersion;
        }
        public async Task AddSnapshotAsync(IAggregateSnapshot <TKey> snapshot,
                                           CancellationToken cancellationToken = default)
        {
            if (snapshot is null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }

            string json = JsonConvert.SerializeObject(snapshot, Defaults.JsonSerializerSettings);
            var    item = Document.FromJson(json);
            await _table.PutItemAsync(item, cancellationToken).ConfigureAwait(false);
        }
Exemple #11
0
 public static SnapshotItem FromDomainSnapshot(IAggregateSnapshot snapshot)
 {
     return(new SnapshotItem()
     {
         Id = snapshot.Id.ToString(),
         AggregateId = snapshot.Id.ToString(),
         Version = snapshot.Version,
         SnapshotType = $"{snapshot.GetType().FullName}, {snapshot.GetType().Assembly.GetName().Name}",
         Data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(snapshot)),
         DateTime = DateTime.Now
     });
 }
Exemple #12
0
 public Task SaveSnapshotAsync <T, TId>(IAggregateSnapshot snapshot, StreamId stream)
     where T : IAggregate <TId>
 {
     try
     {
         return(_store.SaveSnapshotAsync <T, TId>(snapshot, stream));
     }
     catch (Exception e)
     {
         _logger.LogError(e, "Snapshot saving error.");
         throw;
     }
 }
        protected virtual void HydrateSnapshot(IAggregateSnapshot <TAggregateSaga, TIdentity>?aggregateSnapshot, long version)
        {
            if (aggregateSnapshot == null)
            {
                return;
            }

            var snapshotHydrater = GetSnapshotHydrateMethods(aggregateSnapshot);

            snapshotHydrater(aggregateSnapshot);

            Version = version;
        }
Exemple #14
0
        public Task AddSnapshotAsync(IAggregateSnapshot <TKey> snapshot,
                                     CancellationToken cancellationToken = default)
        {
            if (snapshot is null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }

            string serialized = JsonConvert.SerializeObject(snapshot, Defaults.JsonSerializerSettings);
            string filePath   = GetFilePath(snapshot.AggregateId, snapshot.AggregateVersion);

            File.WriteAllText(filePath, serialized);
            return(Task.CompletedTask);
        }
Exemple #15
0
            public Changeset(
                Aggregate <TKey> aggregate,
                IEnumerable <IAggregateEvent <TKey> > events,
                IAggregateSnapshot <TKey> snapshot = null)
            {
                if (events is null)
                {
                    throw new ArgumentNullException(nameof(events));
                }

                _aggregate = aggregate ?? throw new ArgumentNullException(nameof(aggregate));
                Events     = events.ToList().AsReadOnly();
                Snapshot   = snapshot;
            }
Exemple #16
0
        public bool Hydrate(
            TSaga aggregate,
            IAggregateSnapshot <TSaga, TIdentity> aggregateSnapshot)
        {
            var aggregateSnapshotType = aggregateSnapshot.GetType();
            Action <TMessageApplier, IAggregateSnapshot> hydrater;

            if (!HydrateMethods.TryGetValue(aggregateSnapshotType, out hydrater))
            {
                return(false);
            }

            hydrater((TMessageApplier)(object)this, aggregateSnapshot);
            return(true);
        }
Exemple #17
0
        public void TakeSnapshot()
        {
            IAggregateSnapshot <TKey> snapshot = CreateSnapshot();

            if (!Id.Equals(snapshot.AggregateId))
            {
                throw new InvalidOperationException($"Snapshot AggregateId must be {Id}");
            }

            if (!Version.Equals(snapshot.AggregateVersion))
            {
                throw new InvalidOperationException($"Snapshot AggregateVersion must be {Version}");
            }

            _unsavedSnapshot = snapshot;
        }
Exemple #18
0
        public async Task AddSnapshotAsync(IAggregateSnapshot <TKey> snapshot,
                                           CancellationToken cancellationToken = default)
        {
            if (snapshot is null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }

            await _container
            .CreateItemAsync(new
            {
                id   = Guid.NewGuid(),
                data = snapshot
            }, cancellationToken : cancellationToken)
            .ConfigureAwait(false);
        }
Exemple #19
0
        protected override void ApplySnapshot(IAggregateSnapshot snapshot)
        {
            base.ApplySnapshot(snapshot);
            var extratoSnapshot = (ExtratoSnapshot)snapshot;

            ParticipanteId = extratoSnapshot.ParticipanteId;

            if (extratoSnapshot.Movimentacoes != null)
            {
                Movimentacoes = extratoSnapshot.Movimentacoes.Select(o =>
                                                                     new Movimentacao(
                                                                         (DateTime)o.Data,
                                                                         (Movimentacao.TipoMovimentacao)Enum.Parse(typeof(Movimentacao.TipoMovimentacao), (string)o.Tipo),
                                                                         (int)o.Pontos)).ToList();
            }

            Saldo = extratoSnapshot.Saldo;
        }
        public async Task AddSnapshotAsync(IAggregateSnapshot <TKey> snapshot, CancellationToken cancellationToken = default)
        {
            if (snapshot is null)
            {
                throw new System.ArgumentNullException(nameof(snapshot));
            }

            string json = JsonConvert.SerializeObject(snapshot, Defaults.JsonSerializerSettings);

            S3SnapshotStoreOptions options = _monitor.AggregateOptions;
            var request = new PutObjectRequest
            {
                BucketName  = options.BucketName,
                Key         = $"{options.Prefix}/{snapshot.AggregateId}/{snapshot.AggregateVersion}.json",
                ContentBody = json
            };
            await _client.PutObjectAsync(request, cancellationToken).ConfigureAwait(false);
        }
Exemple #21
0
        protected virtual void HydrateSnapshot(IAggregateSnapshot <TAggregate, TIdentity> aggregateSnapshot, long version)
        {
            var snapshotType = aggregateSnapshot.GetType();

            if (_snapshotHandlers.ContainsKey(snapshotType))
            {
                _snapshotHandlers[snapshotType](aggregateSnapshot);
            }
            else if (_snapshotHydraters.Any(ea => ea.Hydrate((TAggregate)this, aggregateSnapshot)))
            {
                // Already done
            }

            var snapshotHydrater = GetSnapshotHydrateMethods(aggregateSnapshot);

            snapshotHydrater(aggregateSnapshot);

            Version = version;
        }
        public async Task AddSnapshotAsync(IAggregateSnapshot <TKey> snapshot,
                                           CancellationToken cancellationToken = default)
        {
            if (snapshot is null)
            {
                throw new System.ArgumentNullException(nameof(snapshot));
            }

            string serialized = JsonConvert.SerializeObject(snapshot, Defaults.JsonSerializerSettings);
            var    entity     = new SnapshotEntity <TKey>
            {
                AggregateId      = snapshot.AggregateId,
                AggregateVersion = snapshot.AggregateVersion,
                Serialized       = serialized
            };
            await _context.GetSnapshotDbSet().AddAsync(entity, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        }
        public async Task <IAggregateSnapshot <TKey> > FindLastSnapshotAsync(TKey aggregateId, int maxVersion, CancellationToken cancellationToken = default)
        {
            S3SnapshotStoreOptions options = _monitor.AggregateOptions;
            string prefix = $"{options.Prefix}/{aggregateId}/";
            ListObjectsV2Response response = await _client.ListObjectsV2Async(new ListObjectsV2Request
            {
                BucketName = options.BucketName,
                Prefix     = prefix
            });

            var objects = response.S3Objects
                          .Select(x => x.Key)
                          .Select(x => new { Key = x, FileName = x.Substring(prefix.Length).Split('.').First() })
                          .Where(x => int.TryParse(x.FileName, out int _))
                          .Select(x => new { x.Key, Version = int.Parse(x.FileName) })
                          .Where(x => x.Version <= maxVersion)
                          .OrderByDescending(x => x.Version)
                          .ToList();

            if (objects.Count == 0)
            {
                return(null);
            }

            string json;
            var    request2 = new GetObjectRequest
            {
                BucketName = options.BucketName,
                Key        = objects.First().Key
            };

            using (GetObjectResponse response2 = await _client.GetObjectAsync(request2))
                using (Stream responseStream = response2.ResponseStream)
                    using (var reader = new StreamReader(responseStream))
                    {
                        json = reader.ReadToEnd(); // Now you process the response body.
                    }
            IAggregateSnapshot <TKey> snapshot = JsonConvert.DeserializeObject <IAggregateSnapshot <TKey> >(json, Defaults.JsonSerializerSettings);

            return(snapshot);
        }
Exemple #24
0
        /// <summary>
        /// Rehydrate an aggregate from a snapshot + historical events
        /// </summary>
        /// <param name="id">Aggregate ID</param>
        /// <param name="snapshot">Aggregate snapshot</param>
        /// <param name="savedEvents">Historical events after the snapshot</param>
        protected Aggregate(TKey id,
                            IAggregateSnapshot <TKey> snapshot,
                            IEnumerable <IAggregateEvent <TKey> > savedEvents)
        {
            if (snapshot is null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }

            if (savedEvents is null)
            {
                throw new ArgumentNullException(nameof(savedEvents));
            }

            Id = id;
            IntegrateSnapshot(snapshot);
            Snapshot = snapshot;

            foreach (IAggregateEvent <TKey> @event in savedEvents.OrderBy(x => x.AggregateVersion))
            {
                IntegrateEvent(@event);
                _savedEvents.Enqueue(@event);
            }
        }
Exemple #25
0
        private async Task <Maybe <TAggregate> > GetBySnapsotAsync(TId id, IStream stream, IAggregateSnapshot snapshot)
        {
            var readResult = await stream.ReadEventsForward(snapshot.Version + 1);

            var version = readResult.Events.Any()
                ? readResult.NextExpectedVersion
                : snapshot.Version;

            return(_aggregateFactory.Create(id, version, snapshot, readResult.Events.Select(x => x.Data).ToArray()));
        }
Exemple #26
0
 protected virtual void ApplySnapshot(IAggregateSnapshot <TKey> snapshot) => throw new NotImplementedException();
Exemple #27
0
 private Extrato(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history) : base(snapshot, history)
 {
 }
Exemple #28
0
        public IFixtureExecutor <TAggregate, TIdentity> Given(IAggregateSnapshot <TAggregate, TIdentity> aggregateSnapshot, long snapshotSequenceNumber)
        {
            InitializeSnapshotStore(AggregateId, aggregateSnapshot, snapshotSequenceNumber);

            return(this);
        }
Exemple #29
0
 public GiftCard(Guid id, IAggregateSnapshot <Guid> snapshot, IEnumerable <IAggregateEvent <Guid> > savedEvents)
     : base(id, snapshot, savedEvents)
 {
 }
Exemple #30
0
 private Participante(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history) : base(snapshot, history)
 {
 }