public async Task PublishPendingEvents_does_not_fails_even_if_all_events_persisted() { // Arrange var userId = Guid.NewGuid(); var userCreated = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var domainEvents = new DomainEvent[] { userCreated, usernameChanged }; RaiseEvents(userId, domainEvents); var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e))); var batchOperation = new TableBatchOperation(); envelopes .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); batchOperation.Clear(); envelopes .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); // Act Func <Task> action = () => sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None); // Assert action.ShouldNotThrow(); }
public void FromEnvelope_sets_MessageId_correctly() { var domainEvent = fixture.Create <FakeUserCreated>(); var envelope = new Envelope(domainEvent); PendingEventTableEntity actual = FromEnvelope <FakeUser>(envelope, serializer); actual.MessageId.Should().Be(envelope.MessageId); }
public void FromEnvelope_sets_RowKey_correctly() { var domainEvent = fixture.Create <FakeUserCreated>(); var envelope = new Envelope(domainEvent); PendingEventTableEntity actual = FromEnvelope <FakeUser>(envelope, serializer); actual.RowKey.Should().Be(GetRowKey(domainEvent.Version)); }
public void FromEnvelope_sets_PartitionKey_correctly() { var domainEvent = fixture.Create <FakeUserCreated>(); var envelope = new Envelope(domainEvent); PendingEventTableEntity actual = FromEnvelope <FakeUser>(envelope, serializer); actual.PartitionKey.Should().Be( GetPartitionKey(typeof(FakeUser), domainEvent.SourceId)); }
public void FromEnvelope_sets_CorrelationId_correctly() { var domainEvent = fixture.Create <FakeUserCreated>(); var correlationId = GuidGenerator.Create(); var envelope = new Envelope(correlationId, domainEvent); PendingEventTableEntity actual = FromEnvelope <FakeUser>(envelope, serializer); actual.CorrelationId.Should().Be(correlationId); }
public async Task PublishAllEvents_sends_pending_events() { // Arrange var domainEvents = new List <DomainEvent>(); List <Guid> users = fixture.CreateMany <Guid>().ToList(); foreach (Guid userId in users) { var userCreated = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var events = new DomainEvent[] { userCreated, usernameChanged }; RaiseEvents(userId, events); var envelopes = new List <Envelope>(events.Select(e => new Envelope(e))); var batchOperation = new TableBatchOperation(); envelopes .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); batchOperation.Clear(); envelopes .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); domainEvents.AddRange(events); } var messages = new List <IDomainEvent>(); Mock.Get(messageBus) .Setup( x => x.SendBatch( It.IsAny <IEnumerable <Envelope> >(), It.IsAny <CancellationToken>())) .Callback <IEnumerable <Envelope>, CancellationToken>( (batch, cancellationToken) => messages.AddRange(batch .Select(b => b.Message) .OfType <IDomainEvent>() .Where(m => users.Contains(m.SourceId)))) .Returns(Task.FromResult(true)); // Act await sut.PublishAllEvents(CancellationToken.None); // Assert messages.Should().OnlyContain(e => e is IDomainEvent); messages.ShouldAllBeEquivalentTo(domainEvents); }
public void FromEnvelope_sets_EventJson_correctly() { var domainEvent = fixture.Create <FakeUserCreated>(); var envelope = new Envelope(domainEvent); PendingEventTableEntity actual = FromEnvelope <FakeUser>(envelope, serializer); object message = serializer.Deserialize(actual.EventJson); message.Should().BeOfType <FakeUserCreated>(); message.ShouldBeEquivalentTo(domainEvent); }
public async Task PublishPendingEvents_does_not_delete_pending_events_if_fails_to_send() { // Arrange var userId = Guid.NewGuid(); var userCreated = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var domainEvents = new DomainEvent[] { userCreated, usernameChanged }; RaiseEvents(userId, domainEvents); var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e))); var batchOperation = new TableBatchOperation(); var pendingEvents = new List <PendingEventTableEntity>( envelopes.Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer))); pendingEvents.ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); batchOperation.Clear(); envelopes .Take(1) .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); Mock.Get(messageBus) .Setup( x => x.SendBatch( It.IsAny <IEnumerable <Envelope> >(), It.IsAny <CancellationToken>())) .Throws(new InvalidOperationException()); // Act try { await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None); } catch (InvalidOperationException) { } // Assert string partitionKey = PendingEventTableEntity.GetPartitionKey(typeof(FakeUser), userId); var query = new TableQuery <PendingEventTableEntity>().Where($"PartitionKey eq '{partitionKey}'"); IEnumerable <object> actual = s_eventTable.ExecuteQuery(query).Select(e => e.RowKey); actual.ShouldAllBeEquivalentTo(pendingEvents.Select(e => e.RowKey)); }
public async Task PublishPendingEventss_sends_only_persisted_pending_events() { // Arrange var userId = Guid.NewGuid(); var userCreated = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var domainEvents = new DomainEvent[] { userCreated, usernameChanged }; RaiseEvents(userId, domainEvents); var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e))); var batchOperation = new TableBatchOperation(); envelopes .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); batchOperation.Clear(); envelopes .Take(1) .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); List <Envelope> batch = null; Mock.Get(messageBus) .Setup( x => x.SendBatch( It.IsAny <IEnumerable <Envelope> >(), It.IsAny <CancellationToken>())) .Callback <IEnumerable <Envelope>, CancellationToken>((b, t) => batch = b.ToList()) .Returns(Task.FromResult(true)); // Act await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None); // Assert Mock.Get(messageBus).Verify( x => x.SendBatch( It.IsAny <IEnumerable <Envelope> >(), CancellationToken.None), Times.Once()); batch.ShouldAllBeEquivalentTo(envelopes.Take(1), opts => opts.RespectingRuntimeTypes()); }
private Task InsertPendingEvents <T>( List <Envelope> envelopes, CancellationToken cancellationToken) where T : class, IEventSourced { var batch = new TableBatchOperation(); foreach (Envelope envelope in envelopes) { batch.Insert(PendingEventTableEntity.FromEnvelope <T>(envelope, _serializer)); } return(_eventTable.ExecuteBatchAsync(batch, cancellationToken)); }
public Task PublishPendingEvents <T>( Guid sourceId, CancellationToken cancellationToken) where T : class, IEventSourced { if (sourceId == Guid.Empty) { throw new ArgumentException( $"{sourceId} cannot be empty.", nameof(sourceId)); } string pendingPartition = PendingEventTableEntity.GetPartitionKey(typeof(T), sourceId); return(Publish(pendingPartition, cancellationToken)); }
private async Task SendPendingEvents( List <PendingEventTableEntity> pendingEvents, CancellationToken cancellationToken) { PendingEventTableEntity firstEvent = pendingEvents.First(); string persistentPartition = firstEvent.PersistentPartition; List <EventTableEntity> persistentEvents = await GetPersistentEvents(persistentPartition, firstEvent.Version, cancellationToken).ConfigureAwait(false); var persistentVersions = new HashSet <int>(persistentEvents.Select(e => e.Version)); var envelopes = from e in pendingEvents where persistentVersions.Contains(e.Version) select new Envelope(e.MessageId, e.CorrelationId, _serializer.Deserialize(e.EventJson)); await _messageBus.SendBatch(envelopes, cancellationToken).ConfigureAwait(false); }
public async Task SaveEvents_inserts_pending_event_entities_correctly() { // Arrange var created = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var events = new DomainEvent[] { created, usernameChanged }; var correlationId = Guid.NewGuid(); RaiseEvents(userId, events); // Act await sut.SaveEvents <FakeUser>(events, correlationId); // Assert string partitionKey = PendingEventTableEntity.GetPartitionKey(typeof(FakeUser), userId); var query = new TableQuery <PendingEventTableEntity>().Where($"PartitionKey eq '{partitionKey}'"); IEnumerable <PendingEventTableEntity> pendingEvents = s_eventTable.ExecuteQuery(query); foreach (var t in pendingEvents.Zip(events, (pending, source) => new { Pending = pending, Source = source })) { var actual = new { t.Pending.RowKey, t.Pending.PersistentPartition, t.Pending.Version, t.Pending.CorrelationId, Message = serializer.Deserialize(t.Pending.EventJson) }; actual.ShouldBeEquivalentTo(new { RowKey = PendingEventTableEntity.GetRowKey(t.Source.Version), PersistentPartition = EventTableEntity.GetPartitionKey(typeof(FakeUser), userId), t.Source.Version, CorrelationId = correlationId, Message = t.Source }, opts => opts.RespectingRuntimeTypes()); } }
public async Task PublishPendingEvents_deletes_all_pending_events() { // Arrange var userId = Guid.NewGuid(); var userCreated = fixture.Create <FakeUserCreated>(); var usernameChanged = fixture.Create <FakeUsernameChanged>(); var domainEvents = new DomainEvent[] { userCreated, usernameChanged }; RaiseEvents(userId, domainEvents); var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e))); var batchOperation = new TableBatchOperation(); envelopes .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); batchOperation.Clear(); envelopes .Take(1) .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer)) .ForEach(batchOperation.Insert); await s_eventTable.ExecuteBatchAsync(batchOperation); // Act await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None); // Assert string partitionKey = PendingEventTableEntity.GetPartitionKey(typeof(FakeUser), userId); var query = new TableQuery <PendingEventTableEntity>().Where($"PartitionKey eq '{partitionKey}'"); List <PendingEventTableEntity> actual = s_eventTable.ExecuteQuery(query).ToList(); actual.Should().BeEmpty(); }