public void InstantiatingCommittedEvent_ValidData_ConformsToContracts() { var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{aggregateSequenceNumber}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); committedEvent.GetIdentity().Should().Be(aggregateId); committedEvent.GetAggregateEvent().Should().Be(aggregateEvent); }
public void CommittedEvent_MappedToDomainEvent_IsValid() { var domainEventReadAdapter = new DomainEventReadAdapter(); var aggregateSequenceNumber = 5; var aggregateId = TestAggregateId.New; var aggregateEvent = new TestCreatedEvent(aggregateId); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic(GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{3}"); var eventMetadata = new EventMetadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregateId, TestCreatedEvent>( aggregateId, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); var eventSequence = domainEventReadAdapter.FromJournal(committedEvent, String.Empty); var upcastedEvent = eventSequence.Events.Single(); if (upcastedEvent is IDomainEvent <TestAggregateId, TestCreatedEvent> e) { e.AggregateEvent.GetType().Should().Be <TestCreatedEvent>(); } else { false.Should().BeTrue(); } }
public void InstantiatingDomainEvent_WithNegativeSequenceNumber_ThrowsException() { var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{aggregateSequenceNumber}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; this.Invoking(test => new DomainEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, eventMetadata, now, -4)) .Should().Throw <ArgumentOutOfRangeException>().And.Message.Contains("aggregateSequenceNumber"); }
protected virtual void Emit <TEvent>(TEvent aggregateEvent, IMetadata metadata = null) where TEvent : IAggregateEvent <TAggregate, TIdentity> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } var aggregateSequenceNumber = Version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.Now; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var uncommittedEvent = new UncommittedEvent(aggregateEvent, eventMetadata); ApplyEvent(aggregateEvent); _uncommittedEvents.Add(uncommittedEvent); }
public void CommittedEvent_AfterSerialization_IsValidAfterDeserialization() { var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{3}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = 3, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, eventMetadata); committedEvent.SerializeDeserialize().Should().BeEquivalentTo(committedEvent); }
public void CommittedEvent_WithUpgradableEvent_GetsUpgrades() { var aggregateEventUpcaster = new TestAggregateEventUpcaster(); var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var aggregateEvent = new TestCreatedEvent(aggregateId); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{3}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregate, TestAggregateId, TestCreatedEvent>( aggregateId, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); var eventSequence = aggregateEventUpcaster.FromJournal(committedEvent, string.Empty); var upcastedEvent = eventSequence.Events.Single(); upcastedEvent .As <ICommittedEvent <TestAggregate, TestAggregateId, TestCreatedEventV2> >() .AggregateEvent.Name .Should().Be("default upcasted string"); }
public virtual CommittedEvent <TIdentity, TAggregateEvent> From <TAggregateEvent>(TAggregateEvent aggregateEvent, Int64 version, IEventMetadata metadata = null) where TAggregateEvent : class, IAggregateEvent <TIdentity> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } var eventDefinition = _eventDefinitionService.GetDefinition(aggregateEvent.GetType()); var aggregateSequenceNumber = version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new EventMetadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId, EventName = eventDefinition.Name, EventVersion = eventDefinition.Version }; eventMetadata.AddOrUpdateValue(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var committedEvent = new CommittedEvent <TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); return(committedEvent); }
/// <summary> /// Emits the specified aggregate event. /// </summary> /// <typeparam name="TEvent">The type of the event.</typeparam> /// <param name="aggregateEvent">The aggregate event.</param> /// <param name="metadata">The metadata.</param> /// <exception cref="ArgumentNullException">aggregateEvent</exception> protected override void Emit <TEvent>(TEvent aggregateEvent, IMetadata metadata = null) { if (EqualityComparer <TEvent> .Default.Equals(aggregateEvent, default(TEvent))) { throw new ArgumentNullException(nameof(aggregateEvent)); } //Version = (int)sequenceStore.GetNextSequence(EventSequenceTableName); var aggregateSequenceNumber = Version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.Now; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = (int)aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var uncommittedEvent = new UncommittedEvent(aggregateEvent, eventMetadata); ApplyEvent(aggregateEvent); uncommittedEvents.Add(uncommittedEvent); }
public void InstantiatingCommittedEvent_WithNullAggregateEvent_ThrowsException() { var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{aggregateSequenceNumber}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; this.Invoking(test => new DomainEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, null, eventMetadata, now, aggregateSequenceNumber)) .Should().Throw <ArgumentNullException>().And.Message.Contains("aggregateEvent").Should().BeTrue(); }
private void Signal <TAggregateEvent>(TAggregateEvent aggregateEvent, IMetadata metadata = null) where TAggregateEvent : class, IAggregateEvent <TestAggregate, TestAggregateId> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } var aggregateSequenceNumber = Version; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var domainEvent = new DomainEvent <TestAggregate, TestAggregateId, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version); Publish(domainEvent); }
protected virtual object FromObject(object aggregateEvent, long version, IMetadata metadata = null) { if (aggregateEvent is IAggregateEvent) { _eventDefinitionService.Load(aggregateEvent.GetType()); var eventDefinition = _eventDefinitionService.GetDefinition(aggregateEvent.GetType()); var aggregateSequenceNumber = version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId, EventName = eventDefinition.Name, EventVersion = eventDefinition.Version }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var genericType = typeof(CommittedEvent <, ,>) .MakeGenericType(typeof(TAggregateSaga), typeof(TIdentity), aggregateEvent.GetType()); var committedEvent = Activator.CreateInstance( genericType, Id, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); return(committedEvent); } throw new InvalidOperationException("could not perform the required mapping for committed event."); }
public void InstantiatingCommittedEvent_WithNullMetadata_ThrowsException() { var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{aggregateSequenceNumber}"); this.Invoking(test => new CommittedEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, null, now, aggregateSequenceNumber)) .Should().Throw <ArgumentNullException>().And.Message.Contains("metadata"); }
protected virtual void Emit <TAggregateEvent>(TAggregateEvent aggregateEvent, IMetadata metadata = null) where TAggregateEvent : IAggregateEvent <TAggregateSaga, TIdentity> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } var aggregateSequenceNumber = Version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var aggregateApplyMethod = GetEventApplyMethods(aggregateEvent); Persist(aggregateEvent, aggregateApplyMethod); Logger.Info($"[{Name}] With Id={Id} Commited [{typeof(TAggregateEvent).PrettyPrint()}]"); Version++; var domainEvent = new DomainEvent <TAggregateSaga, TIdentity, TAggregateEvent>(aggregateEvent, eventMetadata, now, Id, Version); Publish(domainEvent); }
public void CommittedEvent_WhenTagged_ContainsAggregateEventAsTaggedElement() { var aggregateEventTagger = new AggregateEventTagger(); var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{3}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregate, TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); var taggedEvent = aggregateEventTagger.ToJournal(committedEvent); if (taggedEvent is Tagged a) { a.Tags.Should().Contain("TestAdded"); } else { false.Should().BeTrue(); } }
private void Signal <TAggregateEvent>(TAggregateEvent aggregateEvent, IMetadata metadata = null) where TAggregateEvent : IAggregateEvent <TestAggregate, TestAggregateId> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } EventDefinitionService.Load(aggregateEvent.GetType()); var eventDefinition = EventDefinitionService.GetDefinition(aggregateEvent.GetType()); var aggregateSequenceNumber = Version; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId, EventName = eventDefinition.Name, EventVersion = eventDefinition.Version }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } Logger.Info($"[{Name}] With Id={Id} Commited [{typeof(TAggregateEvent).PrettyPrint()}]"); var domainEvent = new DomainEvent <TestAggregate, TestAggregateId, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version); Publish(domainEvent); }
public void CommittedEvent_Tagged_ContainsTaggedElements() { var aggregateEventTagger = new TestAggregateEventUpcaster(); var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var aggregateEvent = new TestCreatedEvent(aggregateId); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{3}"); var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; var committedEvent = new CommittedEvent <TestAggregate, TestAggregateId, TestCreatedEvent>( aggregateId, aggregateEvent, eventMetadata, now, aggregateSequenceNumber); var eventSequence = aggregateEventTagger.FromJournal(committedEvent, string.Empty); var upcastedEvent = eventSequence.Events.Single(); if (upcastedEvent is ICommittedEvent <TestAggregate, TestAggregateId, TestCreatedEventV2> e) { e.AggregateEvent.GetType().Should().Be <TestCreatedEventV2>(); } else { false.Should().BeTrue(); } }
public void InstantiatingCommittedEvent_WithDefaultTimeOffset_ThrowsException() { var aggregateSequenceNumber = 3; var aggregateId = TestAggregateId.New; var entityId = TestId.New; var entity = new Test(entityId); var aggregateEvent = new TestAddedEvent(entity); var now = DateTimeOffset.UtcNow; var eventId = EventId.NewDeterministic(GuidFactories.Deterministic.Namespaces.Events, $"{aggregateId.Value}-v{aggregateSequenceNumber}"); var eventMetadata = new EventMetadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = typeof(TestAggregate).GetAggregateName().Value, AggregateId = aggregateId.Value, EventId = eventId }; this.Invoking(test => new CommittedEvent <TestAggregateId, TestAddedEvent>( aggregateId, aggregateEvent, eventMetadata,
protected virtual void Emit <TAggregateEvent>(TAggregateEvent aggregateEvent, IMetadata metadata = null) where TAggregateEvent : IAggregateEvent <TAggregateSaga, TIdentity> { if (aggregateEvent == null) { throw new ArgumentNullException(nameof(aggregateEvent)); } _eventDefinitionService.Load(typeof(TAggregateEvent)); var eventDefinition = _eventDefinitionService.GetDefinition(typeof(TAggregateEvent)); var aggregateSequenceNumber = Version + 1; var eventId = EventId.NewDeterministic( GuidFactories.Deterministic.Namespaces.Events, $"{Id.Value}-v{aggregateSequenceNumber}"); var now = DateTimeOffset.UtcNow; var eventMetadata = new Metadata { Timestamp = now, AggregateSequenceNumber = aggregateSequenceNumber, AggregateName = Name.Value, AggregateId = Id.Value, EventId = eventId, EventName = eventDefinition.Name, EventVersion = eventDefinition.Version, }; eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString()); if (metadata != null) { eventMetadata.AddRange(metadata); } var committedEvent = new CommittedEvent <TAggregateSaga, TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version); Persist(committedEvent, ApplyCommittedEvents); Logger.Info($"[{Name}] With Id={Id} Commited [{typeof(TAggregateEvent).PrettyPrint()}]"); Version++; var aggregateApplyMethod = GetEventApplyMethods(aggregateEvent); Persist(aggregateEvent, aggregateApplyMethod); Logger.Info($"[{Name}] With Id={Id} Commited [{typeof(TAggregateEvent).PrettyPrint()}]"); Version++; var domainEvent = new DomainEvent <TAggregateSaga, TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version); Publish(domainEvent); if (SnapshotStrategy.ShouldCreateSnapshot(this)) { var aggregateSnapshot = CreateSnapshot(); if (aggregateSnapshot != null) { var t = aggregateSnapshot.GetType(); _snapshotDefinitionService.Load(aggregateSnapshot.GetType()); var snapshotDefinition = _snapshotDefinitionService.GetDefinition(aggregateSnapshot.GetType()); var snapshotMetadata = new Aggregates.Snapshot.SnapshotMetadata { AggregateId = Id.Value, AggregateName = Name.Value, AggregateSequenceNumber = Version, SnapshotName = snapshotDefinition.Name, SnapshotVersion = snapshotDefinition.Version }; var commitedSnapshot = new ComittedSnapshot <TAggregateSaga, TIdentity, IAggregateSnapshot <TAggregateSaga, TIdentity> >( Id, aggregateSnapshot, snapshotMetadata, now, Version); SaveSnapshot(commitedSnapshot); } } }