예제 #1
0
        public async Task CorrectlyRetriesMessageWithExplicitDelayAsync(
            string subscriberName,
            int retryNum,
            bool requeueRequested,
            bool shouldRetry,
            bool shouldAckManually           = true,
            string?expectedExchange          = null,
            string?expectedRoutingKey        = null,
            string?expectedQueueDeclaredName = null
            )
        {
            #region Arrage

            const ulong deliveryTag = 100500;

            const string publishedFromExchange = "to-exchange";
            const string publishedRoutingKey   = "to-routing-key";
            var          retryDelay            = TimeSpan.FromSeconds(10);

            var propertiesMock = new FakeOptions
            {
                Headers = new Dictionary <string, object>()
            };

            propertiesMock.IncrementRetryCount(retryNum);

            var channelMock = new Mock <IModel>();

            var messageContext = CreateTestMessageContext(
                deliveryTag,
                propertiesMock,
                publishedFromExchange,
                publishedRoutingKey
                );

            var subscriberSettings = _configurationManager.GetSubscriberSettings(subscriberName);

            #endregion Arrage

            #region Act

            await _acknowledgementBehaviour.HandleAsync <TestMessage>(
                Retry.In(retryDelay),
                channelMock.Object,
                messageContext,
                subscriberSettings
                );

            #endregion Act

            #region Assert

            if (requeueRequested && shouldRetry)
            {
                channelMock.Verify(
                    c => c.QueueDeclare(
                        expectedQueueDeclaredName,
                        true,
                        false,
                        false,
                        It.Is <Dictionary <string, object> >(d =>
                                                             string.IsNullOrEmpty(d[QueueArgument.DEAD_LETTER_EXCHANGE] as string) &&            // возвращается в осн. очередь через стандартный обменник
                                                             (string)d[QueueArgument.DEAD_LETTER_ROUTING_KEY] == subscriberSettings.QueueName && // по названию оригинальной очереди
                                                             d.ContainsKey(QueueArgument.EXPIRES) &&                                             // TTL самой очереди тоже (чтобы не мусорить)
                                                             d.ContainsKey(QueueArgument.MESSAGE_TTL)                                            // TTL должен быть указан
                                                             )
                        ),
                    "Очередь не отложенного ретрая не объявлена с ожидаемыми параметрами."
                    );
                channelMock.Verify(
                    c => c.BasicPublish(
                        expectedExchange,
                        expectedRoutingKey,
                        false,
                        It.Is <IBasicProperties>(p =>
                                                 (int)p.Headers[RetryExtensions.RETRY_NUMBER_KEY] == retryNum + 1 && // счетчик ретраев +1

                                                                                                                     // проверка на прокидывание оригинальных (с тем, которыми был опубликован) ключ роутинга и обменник
                                                 (string)p.Headers[RetryExtensions.ORIGINAL_EXCHANGE_HEADER] == publishedFromExchange &&
                                                 (string)p.Headers[RetryExtensions.ORIGINAL_ROUTING_KEY_HEADER] == publishedRoutingKey
                                                 ),
                        It.IsAny <ReadOnlyMemory <byte> >()
                        ), "Ретрай не произведен с ожидаемыми параметрами. Сообщение не отправлено в конец очереди через стандартный обменник."
                    );
                if (shouldAckManually)
                {
                    channelMock.Verify(c => c.BasicAck(deliveryTag, false), "Обработанное сообщение не подтверждено.");
                }
            }
            else
            {
                if (shouldAckManually)
                {
                    channelMock.Verify(c => c.BasicReject(deliveryTag, false));
                }
            }
            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }
예제 #2
0
        public async Task CorrectlyRetriesMessageToTheEndOfQueueAsync(
            string subscriberName,
            int retryNum,
            bool requeueRequested,
            bool shouldRetry,
            bool shouldAckManually    = true,
            string?expectedExchange   = null,
            string?expectedRoutingKey = null
            )
        {
            #region Arrage

            const ulong deliveryTag = 100500;

            var propertiesMock = new FakeOptions
            {
                Headers = new Dictionary <string, object>()
            };

            propertiesMock.IncrementRetryCount(retryNum);

            var channelMock = new Mock <IModel>();

            var messageContext = CreateTestMessageContext(deliveryTag, propertiesMock);

            var subscriberSettings = _configurationManager.GetSubscriberSettings(subscriberName);

            #endregion Arrage

            #region Act

            await _acknowledgementBehaviour.HandleAsync <TestMessage>(
                new Reject("Ошибка", requeue : requeueRequested),
                channelMock.Object,
                messageContext,
                subscriberSettings
                );

            #endregion Act

            #region Assert

            if (requeueRequested && shouldRetry)
            {
                channelMock.Verify(
                    c => c.BasicPublish(
                        expectedExchange,
                        expectedRoutingKey,
                        false,
                        It.Is <IBasicProperties>(p => (int)p.Headers["x-retry-number"] == retryNum + 1), // счетчик ретраев +1
                        It.IsAny <ReadOnlyMemory <byte> >()
                        ), "Ретрай не произведен. Сообщение не отправлено в конец очереди через стандартный обменник."
                    );
                if (shouldAckManually)
                {
                    channelMock.Verify(c => c.BasicAck(deliveryTag, false), "Обработанное сообщение не подтверждено.");
                }
            }
            else
            {
                if (shouldAckManually)
                {
                    channelMock.Verify(c => c.BasicReject(deliveryTag, false));
                }
            }
            channelMock.VerifyNoOtherCalls();

            #endregion Assert
        }