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); }
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)); }
protected virtual void HydrateSnapshot(IAggregateSnapshot <TAggregate, TIdentity> aggregateSnapshot, Int64 version) { var snapshotHydrater = GetSnapshotHydrateMethods(aggregateSnapshot); snapshotHydrater(aggregateSnapshot); Version = version; }
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); } }
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 }); }
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); }
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 }); }
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; }
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); }
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; }
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); }
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; }
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); }
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); }
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); }
/// <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); } }
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())); }
protected virtual void ApplySnapshot(IAggregateSnapshot <TKey> snapshot) => throw new NotImplementedException();
private Extrato(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history) : base(snapshot, history) { }
public IFixtureExecutor <TAggregate, TIdentity> Given(IAggregateSnapshot <TAggregate, TIdentity> aggregateSnapshot, long snapshotSequenceNumber) { InitializeSnapshotStore(AggregateId, aggregateSnapshot, snapshotSequenceNumber); return(this); }
public GiftCard(Guid id, IAggregateSnapshot <Guid> snapshot, IEnumerable <IAggregateEvent <Guid> > savedEvents) : base(id, snapshot, savedEvents) { }
private Participante(IAggregateSnapshot snapshot, IEnumerable <IDomainEvent> history) : base(snapshot, history) { }