public async Task When_receiving_valid_message_it_should_flow_through_pipeline_normally()
        {
            TestMessage receivedMessage = null;
            Dictionary <string, string>     receivedHeaders = null;
            IValidationFailed <TestMessage> failedMessage   = null;
            var sync = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>((bus, context, message) =>
            {
                // This should happen.
                receivedMessage = message;
                receivedHeaders = context.Message.Headers;
                sync.Set();
                return(Task.CompletedTask);
            })
            .Handle <IValidationFailed <TestMessage> >(failed =>
            {
                // This should not happen, but signal completion.
                failedMessage = failed;
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator, o => o.ValidateIncomingMessages(_validatorFactoryMock.Object)))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = true
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                failedMessage.Should().BeNull();

                receivedMessage.Should().NotBeNull();
                receivedMessage.IsValidated.Should().BeTrue();
                receivedHeaders.Should()
                .ContainKey(ValidateIncomingStep.ValidatorTypeKey)
                .WhichValue.Should()
                .Be(typeof(TestMessageValidator).GetSimpleAssemblyQualifiedName());
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
        }
        public async Task Given_passThrough_is_configured_when_receiving_invalid_message_it_should_be_normally_handled()
        {
            string      messageId       = null;
            TestMessage receivedMessage = null;
            var         sync            = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>((bus, context, message) =>
            {
                // This should happen.
                receivedMessage = message;
                messageId       = context.Message.GetMessageId();
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator,
                                        o =>
            {
                o.ValidateIncomingMessages(_validatorFactoryMock.Object,
                                           v => v.PassThrough <TestMessage>()
                                           );
            }))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = false
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                receivedMessage.Should().NotBeNull();
                receivedMessage.IsValidated.Should().BeTrue();
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
            _loggerFactory.LogEvents
            .Select(le => le.ToString())
            .Should()
            .ContainMatch($"Debug: Message \"{messageId}\" failed to validate.*The specified condition was not met for 'Should Pass Validation'.*");
            _loggerFactory.LogEvents
            .Select(le => le.Message)
            .Should()
            .ContainMatch("*is configured to pass through.");
        }
Exemple #3
0
            public async Task OnlyDeliversMessagesOfTheCorrectType()
            {
                Mock <IMessageDeserializer <TestMessage> > mockTestMessageDeserializer = new Mock <IMessageDeserializer <TestMessage> >();

                mockTestMessageDeserializer.Setup(md => md.GetTypeName())
                .Returns(typeof(TestMessage).Name);

                TestMessage testMessage = new TestMessage();

                mockTestMessageDeserializer.Setup(md => md.Deserialize(It.IsAny <Stream>()))
                .Returns(testMessage);

                BrokeredMessage brokeredMessageThatShouldBeIgnored = new BrokeredMessage()
                {
                    Properties =
                    {
                        { MessagePropertyNames.TypeName, "SomeMessageTypeThatIDontWant" }
                    }
                };

                BrokeredMessage brokeredMessageThatShouldBeReceived = new BrokeredMessage()
                {
                    Properties =
                    {
                        { MessagePropertyNames.TypeName, typeof(TestMessage).Name }
                    }
                };

                IObservable <BrokeredMessage> brokeredMessages = Observable.Create <BrokeredMessage>(o =>
                {
                    o.OnNext(brokeredMessageThatShouldBeIgnored);

                    o.OnNext(brokeredMessageThatShouldBeReceived);

                    o.OnCompleted();

                    return(Disposable.Empty);
                });

                MessageSource <TestMessage> messageSource = new MessageSource <TestMessage>(brokeredMessages, new[] { mockTestMessageDeserializer.Object }, Mock.Of <IMessageBrokeredMessageTable>());

                TestMessage message = await messageSource.Messages.SingleOrDefaultAsync();

                message.Should().NotBeNull();

                // NOTE: Would be great to be able to verify that testBrokeredMessage.CompleteAsync() wasn't called here, but I would have to build abstraction around BrokeredMessage for that because it can't be mocked (since it's sealed)

                mockTestMessageDeserializer.Verify(md => md.Deserialize(It.IsAny <Stream>()), Times.Once());
            }
        public async Task Given_deadLetter_is_configured_when_receiving_invalid_message_it_should_be_moved_to_error_queue()
        {
            string      messageId       = null;
            TestMessage receivedMessage = null;
            var         sync            = new ManualResetEvent(false);

            var inMemNetwork = new InMemNetwork();
            var activator    = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>(message =>
            {
                // This should not happen, but signal completion.
                receivedMessage = message;
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator,
                                        o =>
            {
                o.ValidateIncomingMessages(_validatorFactoryMock.Object,
                                           v => v.DeadLetter <TestMessage>()
                                           );
                o.OnPipelineCompletion <TestMessage>(failed =>
                {
                    messageId = MessageContext.Current.Message.GetMessageId();
                    sync.Set();
                });
            },
                                        inMemNetwork))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = false
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                receivedMessage.Should().BeNull();

                var errorQueueMessages        = inMemNetwork.GetMessages(ErrorQueueName).ToList();
                InMemTransportMessage message = errorQueueMessages.Should()
                                                .HaveCount(1)
                                                .And.Subject.Single();
                message.Headers.Should()
                .ContainKey(Headers.ErrorDetails)
                .WhichValue.Should()
                .Match($"*{nameof(TestMessage.ShouldPassValidation)}: The specified condition was not met*");
                message.Headers.Should()
                .ContainKey(Headers.Type)
                .WhichValue.Should()
                .StartWith(typeof(TestMessage).FullName);
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
            _loggerFactory.LogEvents
            .Select(le => le.ToString())
            .Should()
            .ContainMatch($"Debug: Message \"{messageId}\" failed to validate.*The specified condition was not met for 'Should Pass Validation'.*");
            _loggerFactory.LogEvents
            .Select(le => le.Message)
            .Should()
            .ContainMatch("*is configured to be moved to error queue.")
            .And
            .ContainMatch("Moving message with ID *");
        }
        public async Task When_receiving_invalid_message_it_should_be_wrapped_as_invalid_message()
        {
            string      messageId       = null;
            TestMessage receivedMessage = null;
            IValidationFailed <TestMessage> failedMessage = null;
            var sync = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>(message =>
            {
                // This should not happen, but signal completion.
                receivedMessage = message;
                sync.Set();
                return(Task.CompletedTask);
            })
            .Handle <IValidationFailed <TestMessage> >((bus, context, failed) =>
            {
                // This should happen.
                failedMessage = failed;
                messageId     = context.Message.GetMessageId();
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator, o => o.ValidateIncomingMessages(_validatorFactoryMock.Object)))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = false
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                receivedMessage.Should().BeNull();

                failedMessage.Should().NotBeNull();
                failedMessage.ValidationResult.Should().NotBeNull();
                failedMessage.Headers.Should()
                .NotBeNull()
                .And.NotBeEmpty()
                .And.ContainKey(ValidateIncomingStep.ValidatorTypeKey)
                .WhichValue.Should()
                .Be(typeof(TestMessageValidator).GetSimpleAssemblyQualifiedName());
                failedMessage.Message.IsValidated.Should().BeTrue();
                failedMessage.ValidatorType.Should().Be <TestMessageValidator>();
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
            _loggerFactory.LogEvents
            .Select(le => le.ToString())
            .Should()
            .ContainMatch($"Debug: Message \"{messageId}\" failed to validate.*The specified condition was not met for 'Should Pass Validation'.*");
            _loggerFactory.LogEvents
            .Select(le => le.Message)
            .Should()
            .ContainMatch("*is configured to be wrapped as *");
        }