示例#1
0
        public async Task CorrectlyHandlesIncorrectJsonAsync()
        {
            var args = new BasicDeliverEventArgs
            {
                DeliveryTag     = 123,
                RoutingKey      = "some-key",
                Exchange        = "some-exchange",
                BasicProperties = new FakeOptions
                {
                    Headers         = new Dictionary <string, object>(),
                    ContentType     = "application/json",
                    ContentEncoding = "UTF8"
                },
                Body = Encoding.UTF8.GetBytes("NotJson")
            };

            var subscriberSettingsDto = new SubscriberSettingsDto("MySubscriberName");

            var(acknowledgement, ctx) = await _subscriber.HandleMessageAsync <MyIntegrationEvent>(
                args,
                x => Task.FromResult <Acknowledgement>(Ack.Ok),
                subscriberSettingsDto.Create(null !)
                );

            Assert.Multiple(() =>
            {
                Assert.IsInstanceOf <FormatReject>(acknowledgement, "Тип Acknowledgement некорректен.");
                Assert.AreEqual(args.DeliveryTag, ctx.MessageData.DeliverEventArgs?.DeliveryTag, "DeliveryTag не совпадает.");
            });
        }
示例#2
0
        public void DeclareSimpleQueueWithFanoutBindings()
        {
            #region Arrange

            const string queueName    = "my-queue";
            const string exchangeName = "my-exchange";

            var subscriberSettingsDto = new SubscriberSettingsDto("TestMessageSubscriber")
            {
                QueueName = queueName,
                Bindings  = new List <ExchangeBindingDto>
                {
                    new ExchangeBindingDto
                    {
                        ExchangeType = ExchangeType.Fanout,
                        FromExchange = exchangeName
                    }
                }
            };

            var channelMock = new Mock <IModel>();

            #endregion Arrange

            #region Act

            _topologyProvider.DeclareQueue(channelMock.Object, subscriberSettingsDto.Create(null !), typeof(TestMessage));

            #endregion Act

            #region Assert

            channelMock.Verify(
                c => c.QueueDeclare(
                    queueName,
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.ExchangeDeclare(
                    exchangeName,
                    ExchangeType.Fanout,
                    true,
                    false,
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.QueueBind(
                    queueName,
                    exchangeName,
                    "",
                    It.IsAny <Dictionary <string, object> >()));

            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
        public string CorrectlyCreateConsumerTagName()
        {
            var subscriberSettingsDto = new SubscriberSettingsDto("myConsumerName");

            var actualConsumerTag = _namingConvention.ConsumerTagNamingConvention(
                subscriberSettingsDto.Create(null !),
                1,
                2
                );

            return(actualConsumerTag);
        }
示例#4
0
        public void DeclareDeadLetterQueue()
        {
            #region Arrange

            const string queueName = "my-queue";
            const string expectedDeadLetterExchangeName = "dead-letter";
            const string expectedDeadLetterQueue        = "my-queue-dead-letter";

            var subscriberSettingsDto = new SubscriberSettingsDto("TestMessageSubscriber")
            {
                QueueName = queueName
            };

            var channelMock = new Mock <IModel>();

            #endregion Arrange

            #region Act

            _topologyProvider.UseDeadLetteredQueue(channelMock.Object, subscriberSettingsDto.Create(null !), typeof(TestMessage));

            #endregion Act

            #region Assert

            channelMock.Verify(
                c => c.QueueDeclare(
                    expectedDeadLetterQueue,
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.ExchangeDeclare(
                    expectedDeadLetterExchangeName,
                    ExchangeType.Direct,
                    true,
                    false,
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.QueueBind(
                    expectedDeadLetterQueue,
                    expectedDeadLetterExchangeName,
                    queueName,
                    It.IsAny <Dictionary <string, object> >()));

            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
示例#5
0
        public void DeclareDelayedRetryQueue()
        {
            #region Arrange

            var subscriberSettingsDto = new SubscriberSettingsDto("TestMessageSubscriber")
            {
                QueueName = "my-queue",
            };

            var channelMock = new Mock <IModel>();

            #endregion Arrange

            #region Act

            var delayedRetryQueueName = _topologyProvider.DeclareDelayedQueue(
                channelMock.Object,
                subscriberSettingsDto.Create(null !),
                typeof(TestMessage),
                TimeSpan.FromSeconds(15)
                );

            #endregion Act

            #region Assert

            const string expectedDelayedQueueName = "my-queue-15s-delayed-queue";

            Assert.AreEqual(expectedDelayedQueueName, delayedRetryQueueName, "Наименование delayed-очередей не равны.");

            channelMock.Verify(
                c => c.QueueDeclare(
                    expectedDelayedQueueName,
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.Is <Dictionary <string, object> >(
                        d =>
                        string.IsNullOrEmpty(d[QueueArgument.DEAD_LETTER_EXCHANGE] as string) &&
                        (string)d[QueueArgument.DEAD_LETTER_ROUTING_KEY] == subscriberSettingsDto.QueueName &&
                        d.ContainsKey(QueueArgument.EXPIRES) &&
                        d.ContainsKey(QueueArgument.MESSAGE_TTL)
                        ))
                );

            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
        public string CorrectlyCreateQueueName(Type messageType, string queueName, bool useModelTypeAsSuffix)
        {
            var subscriberSettingsDto = new SubscriberSettingsDto("Test")
            {
                QueueName            = queueName,
                UseModelTypeAsSuffix = useModelTypeAsSuffix
            };

            var actualQueueName = _namingConvention.QueueNamingConvention(
                messageType,
                subscriberSettingsDto.Create(null !)
                );

            return(actualQueueName);
        }
        public string CorrectlyCreateDelayedQueueName(Type messageType, string queueName, bool useModelTypeAsSuffix = false)
        {
            var subscriberSettingsDto = new SubscriberSettingsDto("Test")
            {
                QueueName            = queueName,
                UseModelTypeAsSuffix = useModelTypeAsSuffix
            };

            var actualQueueName = _namingConvention.DelayedQueueNamingConvention(
                messageType,
                subscriberSettingsDto.Create(null !),
                TimeSpan.FromSeconds(15)
                );

            return(actualQueueName);
        }
示例#8
0
        public async Task CorrectlyHandlesOriginalExchangeAsync()
        {
            const string originalExchange   = "original-exchange";
            const string originalRoutingKey = "original-routing-key";

            var msg       = new MyIntegrationEvent();
            var mqMessage = new MqMessage(JsonConvert.SerializeObject(msg), "Type", "1.0", "1.0", "myApp");

            var args = new BasicDeliverEventArgs
            {
                RoutingKey      = "some-key",
                Exchange        = "some-exchange",
                BasicProperties = new FakeOptions
                {
                    Headers = new Dictionary <string, object>
                    {
                        [RetryExtensions.ORIGINAL_EXCHANGE_HEADER]    = Encoding.UTF8.GetBytes(originalExchange),
                        [RetryExtensions.ORIGINAL_ROUTING_KEY_HEADER] = Encoding.UTF8.GetBytes(originalRoutingKey)
                    },
                    ContentType     = "application/json",
                    ContentEncoding = "UTF8"
                },
                Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(mqMessage))
            };

            var subscriberSettingsDto = new SubscriberSettingsDto("MySubscriberName")
            {
                TracingSettings = new TracingSettingsDto
                {
                    LogWhenMessageIncome = true
                }
            };

            var(_, ctx) = await _subscriber.HandleMessageAsync <MyIntegrationEvent>(
                args,
                x => Task.FromResult <Acknowledgement>(Ack.Ok),
                subscriberSettingsDto.Create(null !)
                );

            Assert.Multiple(() =>
            {
                Assert.AreEqual(originalExchange, ctx.MessageData.Exchange, "Оригинальный обменник не установлен.");
                Assert.AreEqual(originalRoutingKey, ctx.MessageData.RoutingKey, "Оригинальный ключ роутинга не установлен.");
            });
        }
示例#9
0
        public async Task CorrectlyHandlesPoisonedMessageAsync(int alreadyRetriedCount, bool shouldRetryOneMoreTime)
        {
            var mqMessage = new MqMessage(
                JsonConvert.SerializeObject(new MyIntegrationEvent()),
                "Type",
                "1.0",
                "1.0",
                "myApp"
                );

            var args = new BasicDeliverEventArgs
            {
                DeliveryTag     = 123,
                RoutingKey      = "some-key",
                Exchange        = "some-exchange",
                BasicProperties = new FakeOptions
                {
                    Headers = new Dictionary <string, object>
                    {
                        [PoisonedMessageExtensions.RETRY_CNT_KEY] = alreadyRetriedCount
                    },
                    ContentType     = "application/json",
                    ContentEncoding = "UTF8"
                },
                Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(mqMessage))
            };

            var subscriberSettingsDto = new SubscriberSettingsDto("MySubscriberName");

            var(acknowledgement, ctx) = await _subscriber.HandleMessageAsync <MyIntegrationEvent>(
                args,
                _ => throw new Exception("Unhandled exception!"),
                subscriberSettingsDto.Create(null !)
                );

            Assert.Multiple(() =>
            {
                Assert.IsInstanceOf <Reject>(acknowledgement, "Тип Acknowledgement некорректен.");
                Assert.AreEqual(args.DeliveryTag, ctx.MessageData.DeliverEventArgs?.DeliveryTag, "DeliveryTag не совпадает.");
                Assert.AreEqual(shouldRetryOneMoreTime, (acknowledgement as Reject)?.Requeue, "ShouldRetryOneMoreTime не совпадает.");
            });
        }
示例#10
0
        public void DeclareQueueWithDeadLetteredWithDirectBindings(bool useDeadLetter, bool useSingleActiveConsumer)
        {
            #region Arrange

            const string queueName    = "my-queue";
            const string exchangeName = "my-exchange";

            var subscriberSettingsDto = new SubscriberSettingsDto("TestMessageSubscriber")
            {
                QueueName     = queueName,
                UseDeadLetter = useDeadLetter,
                Bindings      = new List <ExchangeBindingDto>
                {
                    new ExchangeBindingDto
                    {
                        ExchangeType = ExchangeType.Direct,
                        FromExchange = exchangeName,
                        RoutingKeys  = new List <string>
                        {
                            "rk1"
                        }
                    },
                    new ExchangeBindingDto
                    {
                        ExchangeType = ExchangeType.Direct,
                        FromExchange = exchangeName,
                        RoutingKeys  = new List <string>
                        {
                            "rk2"
                        }
                    }
                },
                ScalingSettings = new ScalingSettingsDto
                {
                    UseSingleActiveConsumer = useSingleActiveConsumer
                }
            };

            var channelMock = new Mock <IModel>();

            #endregion Arrange

            #region Act

            _topologyProvider.DeclareQueue(channelMock.Object, subscriberSettingsDto.Create(null !), typeof(TestMessage));

            #endregion Act

            #region Assert

            channelMock.Verify(
                c => c.QueueDeclare(
                    queueName,
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.Is <Dictionary <string, object> >(
                        d =>
                        (
                            (useDeadLetter &&
                             (string)d[QueueArgument.DEAD_LETTER_EXCHANGE] == "dead-letter" &&
                             (string)d[QueueArgument.DEAD_LETTER_ROUTING_KEY] == subscriberSettingsDto.QueueName) ||
                            useDeadLetter == false
                        ) &&
                        (
                            (useSingleActiveConsumer && (bool)d[QueueArgument.SINGLE_ACTIVE_CONSUMER]) ||
                            useSingleActiveConsumer == false
                        ))));
            channelMock.Verify(
                c => c.ExchangeDeclare(
                    exchangeName,
                    ExchangeType.Direct,
                    true,
                    false,
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.QueueBind(
                    queueName,
                    exchangeName,
                    "rk1",
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.QueueBind(
                    queueName,
                    exchangeName,
                    "rk2",
                    It.IsAny <Dictionary <string, object> >()));

            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
示例#11
0
        public void DeclareSimpleQueueWithHeadersBindings()
        {
            #region Arrange

            const string queueName    = "my-queue";
            const string exchangeName = "my-topic-exchange";
            var          arguments    = new Dictionary <string, object>
            {
                ["x-match"] = "any",
                ["type"]    = "button"
            };

            var subscriberSettingsDto = new SubscriberSettingsDto("TestMessageSubscriber")
            {
                QueueName = queueName,
                Bindings  = new List <ExchangeBindingDto>
                {
                    new ExchangeBindingDto
                    {
                        ExchangeType = ExchangeType.Headers,
                        FromExchange = exchangeName,
                        Arguments    = arguments
                    }
                }
            };

            var channelMock = new Mock <IModel>();

            #endregion Arrange

            #region Act

            _topologyProvider.DeclareQueue(channelMock.Object, subscriberSettingsDto.Create(null !), typeof(TestMessage));

            #endregion Act

            #region Assert

            channelMock.Verify(
                c => c.QueueDeclare(
                    queueName,
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <bool>(),
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.ExchangeDeclare(
                    exchangeName,
                    ExchangeType.Headers,
                    true,
                    false,
                    It.IsAny <Dictionary <string, object> >()));
            channelMock.Verify(
                c => c.QueueBind(
                    queueName,
                    exchangeName,
                    string.Empty,
                    arguments));

            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
示例#12
0
        public async Task CorrectlyCreatesTraceContextAsync(
            bool setToCorrelationId,
            bool setTraceIdToHeader,
            bool setToEvent,
            bool tracesShouldMatch = true
            )
        {
            #region Arrange

            var expectedTraceId = Guid.Parse("35bb4d03-0af2-4e95-b865-572c2e5daee5");

            var integrationEvent = new MyIntegrationEvent();
            if (setToEvent)
            {
                integrationEvent.TraceId = expectedTraceId;
            }

            var headers = new Dictionary <string, object>();
            if (setTraceIdToHeader)
            {
                headers[TracingExtensions.TRACE_ID_KEY] = Encoding.UTF8.GetBytes(expectedTraceId.ToString());
            }

            var args = new BasicDeliverEventArgs
            {
                RoutingKey      = "some-key",
                Exchange        = "some-exchange",
                BasicProperties = new FakeOptions
                {
                    CorrelationId   = setToCorrelationId ? expectedTraceId.ToString() : null,
                    Headers         = headers,
                    ContentType     = "application/json",
                    ContentEncoding = "UTF8"
                },
                Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(
                                                  new MqMessage(JsonConvert.SerializeObject(integrationEvent), "Type", "1.0", "1.0", "myApp"))
                                              )
            };

            Assert.IsNull(TraceContext.Current.TraceId, "TraceId is not null");
            Guid?actualTraceIdFromContext = default;

            var subscriberSettingsDto = new SubscriberSettingsDto("MySubscriberName");

            #endregion Arrange

            #region Act

            var(_, ctx) = await _subscriber.HandleMessageAsync <MyIntegrationEvent>(
                args,
                x =>
            {
                actualTraceIdFromContext = TraceContext.Current.TraceId;

                return(Task.FromResult <Acknowledgement>(Ack.Ok));
            },
                subscriberSettingsDto.Create(null !)
                );

            #endregion Act

            #region Assert

            Assert.Multiple(() =>
            {
                if (tracesShouldMatch)
                {
                    Assert.AreEqual(expectedTraceId, ctx.MessageData.TraceId, "TraceId в MessageContext не установлен.");
                    Assert.AreEqual(expectedTraceId, actualTraceIdFromContext, "TraceContext не установлен.");
                }
                else
                {
                    Assert.AreEqual(actualTraceIdFromContext, ctx.MessageData.TraceId, "TraceId в мете и контексте не совпадают.");
                }
            });

            #endregion Assert
        }