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 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 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 async Task InsertEventsAndCorrelation <T>( List <Envelope> envelopes, Guid?correlationId, CancellationToken cancellationToken) where T : class, IEventSourced { var batch = new TableBatchOperation(); var firstEvent = (IDomainEvent)envelopes.First().Message; Guid sourceId = firstEvent.SourceId; foreach (Envelope envelope in envelopes) { batch.Insert(EventTableEntity.FromEnvelope <T>(envelope, _serializer)); } if (correlationId.HasValue) { batch.Insert(CorrelationTableEntity.Create(typeof(T), sourceId, correlationId.Value)); } try { await _eventTable.ExecuteBatchAsync(batch, cancellationToken).ConfigureAwait(false); } catch (StorageException exception) when(correlationId.HasValue) { string filter = CorrelationTableEntity.GetFilter(typeof(T), sourceId, correlationId.Value); var query = new TableQuery <CorrelationTableEntity>().Where(filter); if (await _eventTable.Any(query, cancellationToken)) { throw new DuplicateCorrelationException( typeof(T), sourceId, correlationId.Value, exception); } throw; } }
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(); }