コード例 #1
0
        public void Should_return_routing_key_with_delay_zero_seconds_for_negative_delay()
        {
            var result = DelayInfrastructure.CalculateRoutingKey(-123, "some-address", out var startingDelayLevel);

            Assert.That(result, Is.EqualTo("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.some-address"));
            Assert.That(startingDelayLevel, Is.EqualTo(0));
        }
コード例 #2
0
        public void Should_return_correct_routing_key_based_on_delay(int delayInSeconds, string address, string expectedRoutingKey, int expectedStartingDelayLevel)
        {
            var result = DelayInfrastructure.CalculateRoutingKey(delayInSeconds, address, out var startingDelayLevel);

            Assert.That(result, Is.EqualTo(expectedRoutingKey));
            Assert.That(startingDelayLevel, Is.EqualTo(expectedStartingDelayLevel));
        }
        public void Should_allow_startup_if_DisableTimeoutManager_setting_is_set()
        {
            settings.Set(SettingsKeys.DisableTimeoutManager, true);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }
コード例 #4
0
        public void Should_allow_startup_if_external_timeout_manager_address_is_configured()
        {
            settings.Set(coreExternalTimeoutManagerAddressKey, "endpoint");

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }
コード例 #5
0
        public void Should_allow_startup_if_timeout_manager_feature_is_disabled()
        {
            settings.Set(typeof(TimeoutManager).FullName, FeatureState.Disabled);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }
コード例 #6
0
        public void Should_prevent_startup_if_DisableTimeoutManager_setting_is_set()
        {
            settings.Set(SettingsKeys.DisableTimeoutManager, true);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.False(result.Succeeded);
            Assert.AreEqual("Cannot disable the timeout manager when the specified routing topology does not implement ISupportDelayedDelivery.", result.ErrorMessage);
        }
コード例 #7
0
        public static (string DestinationQueue, string NewRoutingKey, int NewDelayLevel) GetNewRoutingKey(int delayInSeconds, DateTimeOffset timeSent, string currentRoutingKey, DateTimeOffset utcNow)
        {
            var originalDeliveryDate = timeSent.AddSeconds(delayInSeconds);
            var newDelayInSeconds    = Convert.ToInt32(originalDeliveryDate.Subtract(utcNow).TotalSeconds);
            var destinationQueue     = currentRoutingKey.Substring(currentRoutingKey.LastIndexOf('.') + 1);
            var newRoutingKey        = DelayInfrastructure.CalculateRoutingKey(newDelayInSeconds, destinationQueue, out int newDelayLevel);

            return(destinationQueue, newRoutingKey, newDelayLevel);
        }
コード例 #8
0
        public void Should_allow_startup_if_timeout_manager_feature_is_deactivated_by_send_only()
        {
            settings.Set(typeof(TimeoutManager).FullName, FeatureState.Deactivated);
            settings.Set(coreSendOnlyEndpointKey, true);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }
        public void Should_prevent_startup_if_external_timeout_manager_address_is_configured()
        {
            settings.Set(coreExternalTimeoutManagerAddressKey, "endpoint");

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.False(result.Succeeded);
            Assert.AreEqual("An external timeout manager address cannot be configured because the timeout manager is not being used for delayed delivery.", result.ErrorMessage);
        }
コード例 #10
0
        public void Should_allow_startup_if_EnableTimeoutManager_setting_is_set_and_timeout_manager_feature_is_active()
        {
            settings.Set(SettingsKeys.EnableTimeoutManager, true);
            settings.Set(typeof(TimeoutManager).FullName, FeatureState.Active);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }
        public void Should_prevent_startup_if_timeout_manager_feature_is_disabled_and_DisableTimeoutManager_setting_is_not_set()
        {
            settings.Set(typeof(TimeoutManager).FullName, FeatureState.Disabled);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.False(result.Succeeded);
            Assert.AreEqual("The timeout manager is not active, but the transport has not been properly configured for this. " +
                            "Use 'EndpointConfiguration.UseTransport<RabbitMQTransport>().DelayedDelivery().DisableTimeoutManager()' to ensure delayed messages can be sent properly.", result.ErrorMessage);
        }
コード例 #12
0
        public void Should_prevent_startup_if_EnableTimeoutManager_setting_is_set_and_timeout_feature_is_deactivated()
        {
            settings.Set(SettingsKeys.EnableTimeoutManager, true);
            settings.Set(typeof(TimeoutManager).FullName, FeatureState.Deactivated);

            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.False(result.Succeeded);
            Assert.AreEqual("The transport has been configured to enable the timeout manager, but the timeout manager is not active." +
                            "Ensure that the timeout manager is active or remove the call to 'EndpointConfiguration.UseTransport<RabbitMQTransport>().DelayedDelivery().EnableTimeoutManager()'.", result.ErrorMessage);
        }
コード例 #13
0
        public Task Run(CancellationToken cancellationToken = default)
        {
            console.WriteLine($"Creating delay infrastructure v2..");

            using var connection = connectionFactory.CreateAdministrationConnection();
            using var channel    = connection.CreateModel();

            DelayInfrastructure.Build(channel);

            console.WriteLine("Delay infrastructure v2 created successfully");

            return(Task.CompletedTask);
        }
        public static void Reset(
            this ConventionalRoutingTopology routingTopology,
            ConnectionFactory connectionFactory,
            IEnumerable <string> receivingAddresses,
            IEnumerable <string> sendingAddresses)
        {
            using (var connection = connectionFactory.CreateAdministrationConnection())
                using (var channel = connection.CreateModel())
                {
                    foreach (var address in receivingAddresses.Concat(sendingAddresses))
                    {
                        channel.QueueDelete(address, false, false);
                        channel.ExchangeDelete(address, false);
                    }

                    DelayInfrastructure.TearDown(channel);
                    DelayInfrastructure.Build(channel);

                    routingTopology.Initialize(channel, receivingAddresses, sendingAddresses);
                }
        }
コード例 #15
0
        void MigrateQueue(IModel channel, int delayLevel, CancellationToken cancellationToken)
        {
            var currentDelayQueue         = $"nsb.delay-level-{delayLevel:00}";
            var messageCount              = channel.MessageCount(currentDelayQueue);
            var declaredDestinationQueues = new HashSet <string>();

            if (messageCount > 0)
            {
                if (!quietMode)
                {
                    console.Write($"Processing {messageCount} messages at delay level {delayLevel:00}. ");
                }

                int skippedMessages   = 0;
                int processedMessages = 0;

                for (int i = 0; i < messageCount && !cancellationToken.IsCancellationRequested; i++)
                {
                    var message = channel.BasicGet(currentDelayQueue, false);

                    if (message == null)
                    {
                        // Queue is empty
                        break;
                    }

                    if (MessageIsInvalid(message))
                    {
                        skippedMessages++;

                        if (!poisonQueueCreated)
                        {
                            channel.QueueDeclare(poisonMessageQueue, true, false, false);
                            poisonQueueCreated = true;
                        }

                        channel.BasicPublish(string.Empty, poisonMessageQueue, message.BasicProperties, message.Body);
                        channel.WaitForConfirmsOrDie();
                        channel.BasicAck(message.DeliveryTag, false);

                        continue;
                    }

                    var messageHeaders = message.BasicProperties.Headers;
                    var delayInSeconds = (int)messageHeaders[DelayInfrastructure.DelayHeader];
                    var timeSent       = GetTimeSent(message);

                    var(destinationQueue, newRoutingKey, newDelayLevel) = GetNewRoutingKey(delayInSeconds, timeSent, message.RoutingKey, DateTimeOffset.UtcNow);

                    // Make sure the destination queue is bound to the delivery exchange to ensure delivery
                    if (!declaredDestinationQueues.Contains(destinationQueue))
                    {
                        routingTopology.BindToDelayInfrastructure(channel, destinationQueue, DelayInfrastructure.DeliveryExchange, DelayInfrastructure.BindingKey(destinationQueue));
                        declaredDestinationQueues.Add(destinationQueue);
                    }

                    var publishExchange = DelayInfrastructure.LevelName(newDelayLevel);

                    if (messageHeaders != null)
                    {
                        //These headers need to be removed so that they won't be copied to an outgoing message if this message gets forwarded
                        messageHeaders.Remove(DelayInfrastructure.XDeathHeader);
                        messageHeaders.Remove(DelayInfrastructure.XFirstDeathExchangeHeader);
                        messageHeaders.Remove(DelayInfrastructure.XFirstDeathQueueHeader);
                        messageHeaders.Remove(DelayInfrastructure.XFirstDeathReasonHeader);
                    }

                    channel.BasicPublish(publishExchange, newRoutingKey, message.BasicProperties, message.Body);
                    channel.WaitForConfirmsOrDie();
                    channel.BasicAck(message.DeliveryTag, false);
                    processedMessages++;
                }

                if (!quietMode)
                {
                    console.WriteLine($"{processedMessages} successful, {skippedMessages} skipped.");
                }
            }
            else
            {
                if (!quietMode)
                {
                    console.WriteLine($"No messages to process at delay level {delayLevel:00}.");
                }
            }
        }
コード例 #16
0
        public Task Run(string endpointName, string?errorQueue, string?auditQueue, IEnumerable <string> instanceDiscriminators, CancellationToken cancellationToken = default)
        {
            console.WriteLine("Connecting to broker");

            using var connection = connectionFactory.CreateAdministrationConnection();
            using var channel    = connection.CreateModel();

            console.WriteLine("Checking for delay infrastructure v2");

            try
            {
                channel.ExchangeDeclarePassive(DelayInfrastructure.DeliveryExchange);
            }
            catch (OperationInterruptedException)
            {
                console.Error.Write("Fail: Delay infrastructure v2 not found.\n");
                throw;
            }

            console.WriteLine($"Creating queues");

            var receivingAddresses = new List <string>()
            {
                endpointName
            };

            if (instanceDiscriminators.Any())
            {
                receivingAddresses.AddRange(instanceDiscriminators.Select(discriminator => $"{endpointName}-{discriminator}"));
            }

            var sendingAddresses = new List <string>();

            if (!string.IsNullOrWhiteSpace(errorQueue))
            {
                sendingAddresses.Add(errorQueue);
            }

            if (!string.IsNullOrWhiteSpace(auditQueue))
            {
                sendingAddresses.Add(auditQueue);
            }

            routingTopology.Initialize(channel, receivingAddresses, sendingAddresses);

            foreach (var receivingAddress in receivingAddresses)
            {
                routingTopology.BindToDelayInfrastructure(channel, receivingAddress, DelayInfrastructure.DeliveryExchange, DelayInfrastructure.BindingKey(receivingAddress));
            }

            console.WriteLine($"Completed successfully");

            return(Task.CompletedTask);
        }
コード例 #17
0
        public void Should_allow_startup_if_EnableTimeoutManager_setting_is_not_set()
        {
            var result = DelayInfrastructure.CheckForInvalidSettings(settings);

            Assert.True(result.Succeeded);
        }