public async Task HandleAsync_ValidMessage_NoLogAndNoException(MessageValidationMode validationMode)
        {
            var message = new TestValidationMessage
            {
                Id = "1", String10 = "123", IntRange = 5, NumbersOnly = "123"
            };
            var endpoint = TestProducerEndpoint.GetDefault();

            endpoint.MessageValidationMode = validationMode;
            var envelope = new OutboundEnvelope(message, null, endpoint);

            IOutboundEnvelope?result = null;
            Func <Task>       act    = () => new ValidatorProducerBehavior(_outboundLogger).HandleAsync(
                new ProducerPipelineContext(
                    envelope,
                    Substitute.For <IProducer>(),
                    Substitute.For <IServiceProvider>()),
                context =>
            {
                result = context.Envelope;
                return(Task.CompletedTask);
            });

            await act.Should().NotThrowAsync <ValidationException>();

            result.Should().NotBeNull();
            result !.Message.Should().NotBeNull();
            _loggerSubstitute.DidNotReceive(LogLevel.Warning, null).Should().BeTrue();
        }
        public async Task HandleAsync_LogWarning_WarningIsLogged(
            IIntegrationMessage message,
            string expectedValidationMessage)
        {
            var endpoint = TestProducerEndpoint.GetDefault();

            endpoint.MessageValidationMode = MessageValidationMode.LogWarning;
            var envelope = new OutboundEnvelope(message, null, endpoint);

            IOutboundEnvelope?result = null;

            await new ValidatorProducerBehavior(_outboundLogger).HandleAsync(
                new ProducerPipelineContext(
                    envelope,
                    Substitute.For <IProducer>(),
                    Substitute.For <IServiceProvider>()),
                context =>
            {
                result = context.Envelope;
                return(Task.CompletedTask);
            });

            result.Should().NotBeNull();
            result !.Message.Should().NotBeNull();
            _loggerSubstitute.Received(LogLevel.Warning, null, expectedValidationMessage, 1079);
        }
        public async Task Transform_SingleMessage_HeadersProperlyModified()
        {
            var policy = ErrorPolicy
                         .Move(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(6); // message-id, message-type, key, traceid, error, source-endpoint
        }
Exemple #4
0
        public void Enrich_SpecificBaseMessageType_HeaderAddedToMessagesOfMatchingType()
        {
            var envelopeEventOne = EnvelopeFactory.Create(
                new TestEventOne(),
                null,
                TestProducerEndpoint.GetDefault());
            var envelopeEventTwo = EnvelopeFactory.Create(
                new TestEventTwo(),
                null,
                TestProducerEndpoint.GetDefault());
            var envelopeBinaryMessage = EnvelopeFactory.Create(
                new BinaryMessage(),
                null,
                TestProducerEndpoint.GetDefault());

            var enricher = new GenericOutboundHeadersEnricher <IIntegrationEvent>("x-test", "value");

            enricher.Enrich(envelopeEventOne);
            enricher.Enrich(envelopeEventTwo);
            enricher.Enrich(envelopeBinaryMessage);

            envelopeEventOne.Headers.Should().HaveCount(1);
            envelopeEventTwo.Headers.Should().HaveCount(1);
            envelopeBinaryMessage.Headers.Should().BeEmpty();
        }
        public async Task HandleAsync_NonBinaryFileMessage_EnvelopeUntouched()
        {
            var message = new BinaryFileMessage
            {
                Content = new MemoryStream(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 })
            };
            var endpoint = TestProducerEndpoint.GetDefault();

            endpoint.Serializer = new BinaryFileMessageSerializer();
            var envelope = new OutboundEnvelope(message, null, endpoint);

            IOutboundEnvelope?result = null;

            await new BinaryFileHandlerProducerBehavior().HandleAsync(
                new ProducerPipelineContext(
                    envelope,
                    Substitute.For <IProducer>(),
                    Substitute.For <IServiceProvider>()),
                context =>
            {
                result = context.Envelope;
                return(Task.CompletedTask);
            });

            result.Should().NotBeNull();
            result !.Should().BeSameAs(envelope);
        }
        public async Task HandleErrorAsync_WithTransform_MessageTranslated()
        {
            var policy = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault())
                         .Transform((originalEnvelope, _) => { originalEnvelope.Message = new TestEventTwo(); })
                         .Build(_serviceProvider);

            var rawMessage = new MemoryStream(Encoding.UTF8.GetBytes("hey oh!"));

            var headers = new[]
            {
                new MessageHeader(DefaultMessageHeaders.MessageType, typeof(string).AssemblyQualifiedName)
            };

            var envelope = new InboundEnvelope(
                rawMessage,
                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, _) = await producer.Endpoint.Serializer.DeserializeAsync(
                new MemoryStream(producer.ProducedMessages[0].Message !),
                producer.ProducedMessages[0].Headers,
                MessageSerializationContext.Empty);

            producedMessage.Should().BeOfType <TestEventTwo>();
        }
        public void CanHandle_Sequence_FalseReturned()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(),
                null,
                new TestOffset(),
                new TestConsumerEndpoint("test")
            {
                Batch = new BatchSettings
                {
                    Size = 10
                }
            },
                TestConsumerEndpoint.GetDefault().Name);

            var context = ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider);

            context.SetSequence(new BatchSequence("batch", context), false);

            var result = policy.CanHandle(
                context,
                new InvalidOperationException("test"));

            result.Should().BeFalse();
        }
        public async Task HandleAsync_ThrowException_ExceptionIsThrown()
        {
            var message = new TestValidationMessage
            {
                Id = "1", String10 = "123456789abc", IntRange = 5, NumbersOnly = "123"
            };
            var expectedMessage = $"The message is not valid:{Environment.NewLine}- The field String10 must be a string with a maximum length of 10.";
            var endpoint        = TestProducerEndpoint.GetDefault();

            endpoint.MessageValidationMode = MessageValidationMode.ThrowException;
            var envelope = new OutboundEnvelope(message, null, endpoint);

            IOutboundEnvelope?result = null;
            Func <Task>       act    = () => new ValidatorProducerBehavior(_outboundLogger).HandleAsync(
                new ProducerPipelineContext(
                    envelope,
                    Substitute.For <IProducer>(),
                    Substitute.For <IServiceProvider>()),
                context =>
            {
                result = context.Envelope;
                return(Task.CompletedTask);
            });

            result.Should().BeNull();
            await act.Should().ThrowAsync <MessageValidationException>().WithMessage(expectedMessage);
        }
        public async Task HandleAsync_FromProduceAsyncWithStartedActivity_TraceIdHeaderIsSet()
        {
            var services = new ServiceCollection();

            services
            .AddNullLogger()
            .AddSilverback().WithConnectionToMessageBroker(
                options => options
                .AddBroker <TestBroker>());
            var serviceProvider = services.BuildServiceProvider();
            var broker          = serviceProvider.GetRequiredService <TestBroker>();

            var activity = new Activity("test");

            activity.SetParentId("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
            activity.Start();

            await broker.GetProducer(TestProducerEndpoint.GetDefault()).ProduceAsync("123");

            broker.ProducedMessages.Single().Headers.Should().Contain(
                header =>
                header.Name == DefaultMessageHeaders.TraceId &&
                header.Value != null &&
                header.Value.StartsWith("00-0af7651916cd43dd8448eb211c80319c", StringComparison.Ordinal));
        }
Exemple #10
0
        public void LogCreatingNewProducer_Logged()
        {
            var expectedMessage = "Creating new producer for endpoint 'test'.";

            _silverbackLogger.LogCreatingNewProducer(TestProducerEndpoint.GetDefault());

            _loggerSubstitute.Received(LogLevel.Information, null, expectedMessage, 1016);
        }
        public void Move_Endpoint_MovePolicyCreated()
        {
            var builder  = new ErrorPolicyBuilder();
            var endpoint = TestProducerEndpoint.GetDefault();

            builder.Move(endpoint);
            var policy = builder.Build();

            policy.Should().BeOfType <MoveMessageErrorPolicy>();
            policy.As <MoveMessageErrorPolicy>().Endpoint.Should().BeSameAs(endpoint);
        }
        public void HandleAsync_NoStartedActivity_ActivityStartedAndTraceIdHeaderIsSet()
        {
            var envelope = new OutboundEnvelope(null, null, TestProducerEndpoint.GetDefault());

            new ActivityProducerBehavior().HandleAsync(
                new ProducerPipelineContext(envelope, Substitute.For <IProducer>(), Substitute.For <IServiceProvider>()),
                _ => Task.CompletedTask);

            envelope.Headers.Should().Contain(
                header => header.Name == DefaultMessageHeaders.TraceId && !string.IsNullOrEmpty(header.Value));
        }
        public void Move_EndpointWithConfiguration_SkipPolicyCreatedAndConfigurationApplied()
        {
            var builder  = new ErrorPolicyBuilder();
            var endpoint = TestProducerEndpoint.GetDefault();

            builder.Move(endpoint, movePolicy => movePolicy.MaxFailedAttempts(42));
            var policy = builder.Build();

            policy.Should().BeOfType <MoveMessageErrorPolicy>();
            policy.As <MoveMessageErrorPolicy>().Endpoint.Should().BeSameAs(endpoint);
            policy.As <MoveMessageErrorPolicy>().MaxFailedAttemptsCount.Should().Be(42);
        }
Exemple #14
0
        public void LogProducerDisconnected_Logged()
        {
            var producer = _serviceProvider.GetRequiredService <TestBroker>()
                           .GetProducer(TestProducerEndpoint.GetDefault());

            var expectedMessage =
                "Disconnected producer from endpoint. " +
                $"| producerId: {producer.Id}, endpointName: test";

            _silverbackLogger.LogProducerDisconnected(producer);

            _loggerSubstitute.Received(LogLevel.Debug, null, expectedMessage, 1028);
        }
Exemple #15
0
        public void Enrich_StaticValues_HeaderAdded()
        {
            var envelope = EnvelopeFactory.Create(
                new TestEventOne(),
                null,
                TestProducerEndpoint.GetDefault());

            var enricher = new GenericOutboundHeadersEnricher("x-test", "value");

            enricher.Enrich(envelope);

            envelope.Headers.Should().HaveCount(1);
            envelope.Headers.Should().BeEquivalentTo(new[] { new MessageHeader("x-test", "value") });
        }
Exemple #16
0
        public void LogInvalidEndpointConfiguration_Logged()
        {
            var expectedMessage = "Invalid configuration for endpoint 'test'.";

            _silverbackLogger.LogInvalidEndpointConfiguration(
                TestProducerEndpoint.GetDefault(),
                new EndpointConfigurationException());

            _loggerSubstitute.Received(
                LogLevel.Critical,
                typeof(EndpointConfigurationException),
                expectedMessage,
                1101);
        }
Exemple #17
0
        public void GetProducer_SomeEndpoint_ProducerIsReturned()
        {
            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddSilverback()
                .WithConnectionToMessageBroker(
                    options => options
                    .AddBroker <TestBroker>()));

            var broker   = serviceProvider.GetRequiredService <IBroker>();
            var producer = broker.GetProducer(TestProducerEndpoint.GetDefault());

            producer.Should().NotBeNull();
        }
Exemple #18
0
        public void GetProducer_DifferentEndpoint_DifferentInstanceIsReturned()
        {
            var serviceProvider = ServiceProviderHelper.GetServiceProvider(
                services => services
                .AddSilverback()
                .WithConnectionToMessageBroker(
                    options => options
                    .AddBroker <TestBroker>()));

            var broker    = serviceProvider.GetRequiredService <IBroker>();
            var producer  = broker.GetProducer(TestProducerEndpoint.GetDefault());
            var producer2 = broker.GetProducer(new TestProducerEndpoint("test2"));

            producer2.Should().NotBeSameAs(producer);
        }
        public void Create_OutboundEnvelope_Created()
        {
            var envelope = EnvelopeFactory.Create(
                new TestEventOne(),
                new MessageHeaderCollection
            {
                { "one", "1" }, { "two", "2" }
            },
                TestProducerEndpoint.GetDefault());

            envelope.Should().NotBeNull();
            envelope.Should().BeOfType <OutboundEnvelope <TestEventOne> >();
            envelope.Message.Should().BeOfType <TestEventOne>();
            envelope.Headers.Should().HaveCount(2);
            envelope.Endpoint.Should().BeOfType <TestProducerEndpoint>();
        }
        public void CanHandle_SingleMessage_TrueReturned()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(),
                null,
                new TestOffset(),
                TestConsumerEndpoint.GetDefault(),
                TestConsumerEndpoint.GetDefault().Name);

            var result = policy.CanHandle(
                ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider),
                new InvalidOperationException("test"));

            result.Should().BeTrue();
        }
        public async Task HandleErrorAsync_SingleMessage_TrueReturned()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")),
                null,
                new TestOffset(),
                new TestConsumerEndpoint("source-endpoint"),
                "source-endpoint");

            var result = await policy.HandleErrorAsync(
                ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider),
                new InvalidOperationException("test"));

            result.Should().BeTrue();
        }
Exemple #22
0
        public void Enrich_ValueProvider_HeaderAdded()
        {
            var envelope = EnvelopeFactory.Create(
                new TestEventOne {
                Content = "content"
            },
                null,
                TestProducerEndpoint.GetDefault());

            var enricher = new GenericOutboundHeadersEnricher <TestEventOne>(
                "x-test",
                envelopeToEnrich => envelopeToEnrich.Message?.Content);

            enricher.Enrich(envelope);

            envelope.Headers.Should().HaveCount(1);
            envelope.Headers.Should().BeEquivalentTo(new[] { new MessageHeader("x-test", "content") });
        }
        public void HandleAsync_StartedActivity_TraceIdHeaderIsSet()
        {
            var activity = new Activity("test");

            activity.SetParentId("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
            activity.Start();
            var envelope = new OutboundEnvelope(null, null, TestProducerEndpoint.GetDefault());

            new ActivityProducerBehavior().HandleAsync(
                new ProducerPipelineContext(envelope, Substitute.For <IProducer>(), Substitute.For <IServiceProvider>()),
                _ => Task.CompletedTask);

            envelope.Headers.Should().Contain(
                header =>
                header.Name == DefaultMessageHeaders.TraceId &&
                header.Value != null &&
                header.Value.StartsWith("00-0af7651916cd43dd8448eb211c80319c", StringComparison.Ordinal));
        }
        public async Task HandleErrorAsync_Whatever_ConsumerCommittedButTransactionAborted()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")),
                null,
                new TestOffset(),
                new TestConsumerEndpoint("source-endpoint"),
                "source-endpoint");

            var transactionManager = Substitute.For <IConsumerTransactionManager>();

            await policy.HandleErrorAsync(
                ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider, transactionManager),
                new InvalidOperationException("test"));

            await transactionManager.Received(1).RollbackAsync(Arg.Any <InvalidOperationException>(), true);
        }
        public async Task HandleErrorAsync_NotDeserializedInboundMessage_MessagePreserved()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")),
                null,
                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();

            producedMessage.Message.Should().BeEquivalentTo(producedMessage.Message);
        }
        public async Task HandleErrorAsync_InboundMessage_MessageMoved()
        {
            var policy   = new MoveMessageErrorPolicy(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(),
                null,
                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.Should().HaveCount(1);
        }
        public async Task HandleErrorAsync_InboundMessage_MessagePreserved()
        {
            var policy = new MoveMessageErrorPolicy(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(
                    new MemoryStream(producedMessage.Message !),
                    producedMessage.Headers,
                    MessageSerializationContext.Empty);

            deserializedMessage.Should().BeEquivalentTo(envelope.Message);
        }
Exemple #28
0
        public void CreateOutboundEnvelope_NullMessage_UntypedEnvelopeReturned()
        {
            var endpoint = TestProducerEndpoint.GetDefault();
            var headers  = new[] { new MessageHeader("one", "1"), new MessageHeader("two", "2") };

            var factory = new OutboundEnvelopeFactory(
                new OutboundRoutingConfiguration
            {
                PublishOutboundMessagesToInternalBus = true
            });

            var envelope = factory.CreateOutboundEnvelope(
                null,
                headers,
                TestProducerEndpoint.GetDefault());

            envelope.Should().BeOfType <OutboundEnvelope>();
            envelope.Message.Should().BeNull();
            envelope.Headers.Should().ContainSingle(header => header.Name == "one" && header.Value == "1");
            envelope.Headers.Should().ContainSingle(header => header.Name == "two" && header.Value == "2");
            envelope.Endpoint.Should().Be(endpoint);
        }
        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 HandleError_SingleMessage_SourceEndpointHeaderIsSet()
        {
            var policy   = ErrorPolicy.Move(TestProducerEndpoint.GetDefault()).Build(_serviceProvider);
            var envelope = new InboundEnvelope(
                "hey oh!",
                new MemoryStream(Encoding.UTF8.GetBytes("hey oh!")),
                null,
                new TestOffset(),
                new TestConsumerEndpoint("source-endpoint"),
                "source-endpoint");

            await policy.HandleErrorAsync(
                ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider),
                new InvalidOperationException("test"));

            var producer = (TestProducer)_broker.GetProducer(TestProducerEndpoint.GetDefault());

            producer.ProducedMessages.Last()
            .Headers
            .Should().ContainEquivalentOf(
                new MessageHeader(
                    DefaultMessageHeaders.SourceEndpoint,
                    "source-endpoint"));
        }