Пример #1
0
        public async Task when_message_handler_throws_any_exception_it_should_stop_ingress_message_routing()
        {
            var          state      = new TestDriverState();
            const string brokerName = "broker-1";
            const string queueName  = "sample.facts.service-2.v1";

            await using var container = RoutingTests.SetupContainer(_testOutputHelper).AddRouterWithThrowingHandler(state, brokerName);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            Func <Task> sut = () => messageRouter.RouteIngressMessage(
                brokerName,
                queueName,
                DateTimeOffset.UtcNow,
                new byte[0],
                new byte[0],
                new Dictionary <string, string>());

            sut.Should().ThrowExactly <PoezdOperationException>().Where(
                exception => exception.Message.Contains("message handling"),
                $"exception should be thrown by {nameof(MessageRouter.RouteIngressMessage)}");
            // TODO: It's a wrong behavior. What to do with erroneous message should decide some API-related strategy.
            sut.Should().ThrowExactly <PoezdOperationException>().Where(
                exception => exception.Message.Contains("stopped"),
                "it's not possible to route a message after another message handled with an error");
        }
Пример #2
0
        public async Task when_publish_with_all_parameters_it_should_pass_them_to_driver()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithConfiguredEgressApi(state);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            const string correlationId = "correlation ID";
            const string causationId   = "causation ID";
            const string messageId     = "message ID";
            var          timestamp     = DateTimeOffset.UtcNow;
            await messageRouter.RouteEgressMessage(
                new TestEgressMessage1(),
                correlationId,
                causationId,
                messageId,
                timestamp);

            state.PublishingContext.CorrelationId.Should().Be(correlationId);
            state.PublishingContext.CausationId.Should().Be(causationId);
            state.PublishingContext.MessageId.Should().Be(messageId);
            state.PublishingContext.Timestamp.Should().Be(timestamp);
        }
Пример #3
0
        public async Task when_message_received_it_should_create_pipeline_for_its_handling()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithComplexApis <SampleBrokerPipeFitter, EmptyPipeFitter, EmptyPipeFitter, EmptyPipeFitter>(state);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            await messageRouter.RouteIngressMessage(
                RoutingTests.SampleBrokerServer,
                "sample.facts.service-2.v1",
                DateTimeOffset.UtcNow,
                new byte[0],
                new byte[0],
                new Dictionary <string, string>());

            InMemorySink.Instance.LogEvents
            .Where(@event => @event.Level == LogEventLevel.Information)
            .Select(@event => @event.MessageTemplate.Text)
            .Should().BeEquivalentTo(
                new[]
            {
                nameof(LogMessageHandlingContextStep),
                nameof(Service2DeserializeMessageStep),
                nameof(GetMessageHandlersStep),
                nameof(DispatchMessageToHandlersStep),
                nameof(CommitMessageStep)
            },
                options => options.WithStrictOrdering(),
                "pipeline should be built with expected steps order");
        }
Пример #4
0
        public async Task when_message_published_it_should_create_pipeline_for_its_publishing()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithConfiguredEgressApi(state);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            await messageRouter.RouteEgressMessage(new TestEgressMessage1());

            InMemorySink.Instance.LogEvents
            .Where(@event => @event.Level == LogEventLevel.Information)
            .Select(@event => @event.MessageTemplate.Text)
            .Should().BeEquivalentTo(
                new[]
            {
                nameof(TestBrokerEgressEnterStep),
                nameof(TestBrokerEgressApiStep),
                nameof(TestBrokerEgressExitStep)
            },
                options => options.WithStrictOrdering(),
                "pipeline should be built with expected steps order");
        }
Пример #5
0
        public async Task when_starting_with_invalid_configuration_it_should_fail()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithInvalidConfiguration(state);
            var         messageRouter = container.GetMessageRouter();
            Func <Task> sut           = () => messageRouter.Start();

            sut.Should().ThrowExactly <PoezdConfigurationException>()
            .Where(exception => exception.Message.StartsWith("Unable to start the message router due configuration errors:"));
        }
Пример #6
0
        public async Task when_publishing_message_it_should_publish_using_driver()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithConfiguredEgressApi(state);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            await messageRouter.RouteEgressMessage(new TestEgressMessage1());

            state.PublishedMessageCount.Should().Be(expected: 1, "message should be published using driver");
        }
Пример #7
0
        public async Task when_publishing_and_some_pipeline_step_throws_exception_it_should_fail()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithThrowingHandler(state, "broker-1");
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            Func <Task> sut = () => messageRouter.RouteEgressMessage(new TestEgressMessage1());

            sut.Should().ThrowExactly <PoezdOperationException>()
            .Where(exception => exception.Message.Contains("message publishing"), "exception in a step should break publishing");
        }
Пример #8
0
        public async Task when_starting_it_should_subscribe_to_all_queues_specified_in_configuration()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithComplexApis <SampleBrokerPipeFitter, EmptyPipeFitter, EmptyPipeFitter, EmptyPipeFitter>(state);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            var patters = state.SubscribedQueueNamePatters;

            patters.Should().BeEquivalentTo(
                new[]
            {
                @"^sample\.(commands|facts)\.service1\.v1",
                "sample.facts.service-2.v1",
                @"^sample\.cdc\..*"
            },
                "it is full list of subscribed queues");
        }
Пример #9
0
        public async Task when_constructed_without_required_arguments_it_should_fail()
        {
            var state = new TestDriverState();

            await using var container = RoutingTests
                                        .SetupContainer(_testOutputHelper)
                                        .AddRouterWithComplexApis <SampleBrokerPipeFitter, EmptyPipeFitter, EmptyPipeFitter, EmptyPipeFitter>(state);

            var containerAdapter = new SimpleInjectorAdapter(container);
            var configuration    = new MessageRouterConfiguration();
            // ReSharper disable AccessToModifiedClosure - it's a way to test.
            // ReSharper disable once ObjectCreationAsStatement
            Action sut = () => new MessageRouter(configuration, containerAdapter);

            containerAdapter = null;
            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("diContainerAdapter"));

            containerAdapter = new SimpleInjectorAdapter(container);
            configuration    = null;
            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("configuration"));
        }
Пример #10
0
        public async Task when_disposed_it_should_not_be_possible_to_start_router()
        {
            var            state = new TestDriverState();
            IMessageRouter messageRouter;

            await using (var container = RoutingTests.SetupContainer(_testOutputHelper)
                                         .AddRouterWithThreeBrokers(
                             RoutingTests.RandomString(),
                             RoutingTests.RandomString(),
                             RoutingTests.RandomString(),
                             state))
            {
                messageRouter = container.GetMessageRouter();
            }

            Func <Task> sut = () => messageRouter.Start();

            sut.Should().ThrowExactly <PoezdOperationException>().Where(
                exception => exception.Message.Contains("disposed", StringComparison.InvariantCultureIgnoreCase),
                "it's not possible to start disposed message router");
        }
Пример #11
0
        public async Task when_used_it_should_live_expected_life()
        {
            var state = new TestDriverState();

            await using (var container = RoutingTests.SetupContainer(_testOutputHelper)
                                         .AddRouterWithThreeBrokers(
                             RoutingTests.RandomString(),
                             RoutingTests.RandomString(),
                             RoutingTests.RandomString(),
                             state))
            {
                var messageRouter = container.GetMessageRouter();
                state.InitializedCount.Should().Be(expected: 0, "all 6 drivers should not be initialized");
                state.MessageConsumingStartedCount.Should().Be(expected: 0, "among 6 drivers none should start message consuming at this moment");
                await messageRouter.Start();

                state.MessageConsumingStartedCount.Should().Be(expected: 3, "among 6 drivers 3 ingress drivers should be started");
                state.DisposedCount.Should().Be(expected: 0, "among 6 drivers none should be disposed at this moment");
            }

            state.DisposedCount.Should().Be(expected: 6, "all 6 drivers should be disposed at this moment");
        }
Пример #12
0
        public async Task when_some_message_handling_step_request_to_break_pipeline_execution_it_should_be_allowed_to_handle_next_message()
        {
            const string brokerName = "broker-1";

            await using var container = RoutingTests.SetupContainer(_testOutputHelper).AddRouterWithBreakHandlingStep(brokerName);
            var messageRouter = container.GetMessageRouter();
            await messageRouter.Start();

            await messageRouter.RouteIngressMessage(
                brokerName,
                "sample.facts.service-2.v1",
                DateTimeOffset.UtcNow,
                new byte[0],
                new byte[0],
                new Dictionary <string, string>());

            InMemorySink.Instance.LogEvents
            .Where(@event => @event.Level == LogEventLevel.Information)
            .Select(@event => @event.MessageTemplate.Text)
            .Should().BeEquivalentTo(
                new[] { nameof(BreakingIngressStep) },
                "after message skipped in a step following steps shouldn't be executed");
        }