public async Task HandleError_InboundMessage_MessagePreserved() { var policy = ErrorPolicy.Move(TestProducerEndpoint.GetDefault()).Build(_serviceProvider); var message = new TestEventOne { Content = "hey oh!" }; var headers = new MessageHeaderCollection { { "key1", "value1" }, { "key2", "value2" } }; var rawContent = await TestConsumerEndpoint.GetDefault().Serializer .SerializeAsync(message, headers, MessageSerializationContext.Empty); var envelope = new InboundEnvelope( message, rawContent, headers, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider), new InvalidOperationException("test")); var producer = (TestProducer)_broker.GetProducer(TestProducerEndpoint.GetDefault()); var producedMessage = producer.ProducedMessages.Last(); var(deserializedMessage, _) = await producedMessage.Endpoint.Serializer.DeserializeAsync( producedMessage.Message, producedMessage.Headers, MessageSerializationContext.Empty); deserializedMessage.Should().BeEquivalentTo(envelope.Message); }
public async Task GetLatestValue_SomeStoredOffsetsWithLegacySerialization_LatestOffsetReturned() { _dbContext.StoredOffsets.Add( new StoredOffset { Key = "topic1|group1|topic1", #pragma warning disable 618 Offset = $"{{\"$type\":\"{typeof(TestOffset).AssemblyQualifiedName}\"," + "\"Key\":\"topic1|group1\",\"Value\":\"42\"}" #pragma warning restore 618 }); await _dbContext.SaveChangesAsync(); var endpoint = new TestConsumerEndpoint("topic1") { GroupId = "group1" }; var latestOffset = await _offsetStore.GetLatestValueAsync("topic1", endpoint); latestOffset.Should().NotBeNull(); latestOffset !.Value.Should().Be("42"); }
public async Task Exists_SameIdInDifferentTopic_FalseIsReturned() { var messageId = Guid.NewGuid(); var endpoint1 = new TestConsumerEndpoint("topic1") { GroupId = "same" }; var endpoint2 = new TestConsumerEndpoint("topic2") { GroupId = "same" }; var envelope1 = GetEnvelope(messageId, endpoint1); var envelope2 = GetEnvelope(messageId, endpoint2); await _log.AddAsync(envelope1); await _log.CommitAsync(); var result = await _log.ExistsAsync(envelope2); result.Should().BeFalse(); }
public void HandleAsync_ExceptionThrown_ExceptionRethrown() { var logger = new SilverbackIntegrationLogger <FatalExceptionLoggerConsumerBehavior>( new LoggerSubstitute <FatalExceptionLoggerConsumerBehavior>(), new LogTemplates()); var rawEnvelope = new RawInboundEnvelope( new byte[5], null, TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name, new TestOffset()); Func <Task> act = () => new FatalExceptionLoggerConsumerBehavior(logger).HandleAsync( new ConsumerPipelineContext( rawEnvelope, Substitute.For <IConsumer>(), Substitute.For <ISequenceStore>(), Substitute.For <IServiceProvider>()), _ => throw new InvalidCastException()); act.Should().ThrowExactly <InvalidCastException>(); }
public void CanHandle_WithApplyToAndExclude_ExpectedResultReturned( Exception exception, bool mustApply) { var policy = new TestErrorPolicy() .ApplyTo <ArgumentException>() .Exclude <ArgumentOutOfRangeException>() .ApplyTo <FormatException>() .Build(Substitute.For <IServiceProvider>()); var canHandle = policy.CanHandle( ConsumerPipelineContextHelper.CreateSubstitute( new InboundEnvelope( new MemoryStream(), new[] { new MessageHeader(DefaultMessageHeaders.FailedAttempts, "99") }, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name)), exception); canHandle.Should().Be(mustApply); }
public async Task HandleErrorAsync_WithPublishReturningNull_NoMessagePublished() { var publisher = Substitute.For<IPublisher>(); var serviceProvider = new ServiceCollection().AddScoped(_ => publisher) .BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true }); var policy = new TestErrorPolicy() .Publish(_ => null) .Build(serviceProvider); var envelope = new InboundEnvelope( new MemoryStream(), new[] { new MessageHeader(DefaultMessageHeaders.FailedAttempts, "3") }, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, serviceProvider), new ArgumentNullException()); await publisher.DidNotReceive().PublishAsync(Arg.Any<object>()); }
public async Task HandleErrorAsync_Whatever_ConsumerRolledBackAndTransactionAborted() { var policy = ErrorPolicy.Retry().MaxFailedAttempts(3).Build(_serviceProvider); var envelope = new InboundEnvelope( "hey oh!", new MemoryStream(), null, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); var transactionManager = Substitute.For <IConsumerTransactionManager>(); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider, transactionManager), new InvalidOperationException("test")); await transactionManager.Received(1).RollbackAsync( Arg.Any <InvalidOperationException>(), false, true, false); }
public async Task HandleErrorAsync_MultiplePoliciesWithMaxFailedAttempts_CorrectPolicyApplied( int failedAttempts, int expectedAppliedPolicy) { var rawMessage = new MemoryStream(); var headers = new[] { new MessageHeader( DefaultMessageHeaders.FailedAttempts, failedAttempts.ToString(CultureInfo.InvariantCulture)) }; var policies = new[] { new TestErrorPolicy().MaxFailedAttempts(2), new TestErrorPolicy().MaxFailedAttempts(2), new TestErrorPolicy().MaxFailedAttempts(2) }; var chain = new ErrorPolicyChain(policies) .Build(_serviceProvider); await chain.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute( new InboundEnvelope( rawMessage, headers, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name)), new InvalidOperationException("test")); for (var i = 0; i < policies.Length; i++) { policies[i].As <TestErrorPolicy>().Applied.Should().Be(i == expectedAppliedPolicy); } }
public async Task Transform_SingleMessage_HeadersProperlyModified() { var policy = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()) .Transform((outboundEnvelope, ex) => { outboundEnvelope.Headers.Add("error", ex.GetType().Name); }) .Build(_serviceProvider); var envelope = new InboundEnvelope( new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")), null, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); envelope.Headers.Add("key", "value"); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider), new InvalidOperationException("test")); var producer = (TestProducer)_broker.GetProducer(TestProducerEndpoint.GetDefault()); var newHeaders = producer.ProducedMessages[0].Headers; newHeaders.Should().HaveCount(4); // key, error, traceparent, message-id }
public async Task HandleErrorAsync_InboundMessage_HeadersPreserved() { var policy = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider); var headers = new MessageHeaderCollection { { "key1", "value1" }, { "key2", "value2" } }; var envelope = new InboundEnvelope( "hey oh!", new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")), headers, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider), new InvalidOperationException("test")); var producer = (TestProducer)_broker.GetProducer(TestProducerEndpoint.GetDefault()); producer.ProducedMessages.Last().Headers.Should().Contain(envelope.Headers); }
public async Task HandleErrorAsync_WithPublishForwardingException_MessagePublished() { var publisher = Substitute.For<IPublisher>(); var serviceProvider = new ServiceCollection().AddScoped(_ => publisher) .BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true }); var policy = new TestErrorPolicy() .Publish((_, exception) => new TestEventTwo { Content = exception.Message }) .Build(serviceProvider); var envelope = new InboundEnvelope( new MemoryStream(), new[] { new MessageHeader(DefaultMessageHeaders.FailedAttempts, "3") }, new TestOffset(), TestConsumerEndpoint.GetDefault(), TestConsumerEndpoint.GetDefault().Name); await policy.HandleErrorAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, serviceProvider), new TimeoutException("Exception message.")); await publisher.Received().PublishAsync( Arg.Is<TestEventTwo>(message => message.Content == "Exception message.")); }
public void Configure(IEndpointsConfigurationBuilder builder) { builder.AddInbound(TestConsumerEndpoint.GetDefault()); }
public void GetDisplayName_NotSet_NameReturned() { var endpoint = new TestConsumerEndpoint("name"); endpoint.DisplayName.Should().Be("name"); }