private void DeclareBinding(string rootName, RabbitConfig.IBinding bindingArg)
        {
            var binding = bindingArg;

            foreach (var customizer in Customizers)
            {
                binding = (RabbitConfig.IBinding)customizer.Apply(binding);
            }

            try
            {
                Admin.DeclareBinding(binding);
            }
            catch (RabbitConnectException e)
            {
                _logger.LogDebug("Declaration of binding: " + rootName + ".binding deferred - connection not available; " + e.Message);
            }
            catch (Exception e)
            {
                if (_notOurAdminException)
                {
                    _notOurAdminException = false;
                    throw;
                }

                _logger.LogDebug("Declaration of binding: " + rootName + ".binding deferred", e);
            }

            AddToAutoDeclareContext(rootName + ".binding", binding);
        }
            public RabbitConsumerDestination(string queueName, RabbitConfig.IBinding binding)
            {
                if (queueName == null)
                {
                    throw new ArgumentNullException(nameof(queueName));
                }

                Name    = queueName;
                Binding = binding;
            }
            public RabbitProducerDestination(IExchange exchange, RabbitConfig.IBinding binding)
            {
                if (exchange == null)
                {
                    throw new ArgumentNullException(nameof(exchange));
                }

                Exchange = exchange;
                Binding  = binding;
            }
        public IProducerDestination ProvisionProducerDestination(string name, IProducerOptions options)
        {
            var producerProperties = Options.GetRabbitProducerOptions(options.BindingName);

            var exchangeName = ApplyPrefix(producerProperties.Prefix, name);
            var exchange     = BuildExchange(producerProperties, exchangeName);

            if (producerProperties.DeclareExchange.Value)
            {
                DeclareExchange(exchangeName, exchange);
            }

            RabbitConfig.IBinding binding = null;
            foreach (var requiredGroupName in options.RequiredGroups)
            {
                var baseQueueName = producerProperties.QueueNameGroupOnly.Value ? requiredGroupName : exchangeName + "." + requiredGroupName;
                if (!options.IsPartitioned)
                {
                    AutoBindDLQ(baseQueueName, baseQueueName, producerProperties);
                    if (producerProperties.BindQueue.Value)
                    {
                        var queue = new Queue(baseQueueName, true, false, false, GetQueueArgs(baseQueueName, producerProperties, false));
                        DeclareQueue(baseQueueName, queue);
                        var routingKeys = BindingRoutingKeys(producerProperties);
                        if (routingKeys == null || routingKeys.Count == 0)
                        {
                            binding = NotPartitionedBinding(exchange, queue, null, producerProperties);
                        }
                        else
                        {
                            foreach (var routingKey in routingKeys)
                            {
                                binding = NotPartitionedBinding(exchange, queue, routingKey, producerProperties);
                            }
                        }
                    }
                }
                else
                {
                    // if the stream is partitioned, create one queue for each target partition for the default group
                    for (var i = 0; i < options.PartitionCount; i++)
                    {
                        var partitionSuffix    = "-" + i;
                        var partitionQueueName = baseQueueName + partitionSuffix;
                        AutoBindDLQ(baseQueueName, baseQueueName + partitionSuffix, producerProperties);
                        if (producerProperties.BindQueue.Value)
                        {
                            var queue = new Queue(partitionQueueName, true, false, false, GetQueueArgs(partitionQueueName, producerProperties, false));
                            DeclareQueue(queue.QueueName, queue);
                            var prefix      = producerProperties.Prefix;
                            var destination = string.IsNullOrEmpty(prefix) ? exchangeName : exchangeName.Substring(prefix.Length);
                            var routingKeys = BindingRoutingKeys(producerProperties);
                            if (routingKeys == null || routingKeys.Count == 0)
                            {
                                binding = PartitionedBinding(destination, exchange, queue, null, producerProperties, i);
                            }
                            else
                            {
                                foreach (var routingKey in routingKeys)
                                {
                                    binding = PartitionedBinding(destination, exchange, queue, routingKey, producerProperties, i);
                                }
                            }
                        }
                    }
                }
            }

            return(new RabbitProducerDestination(exchange, binding));
        }
        private IConsumerDestination DoProvisionConsumerDestination(string name, string group, IConsumerOptions options)
        {
            var consumerProperties = Options.GetRabbitConsumerOptions(options.BindingName);
            var anonymous          = string.IsNullOrEmpty(group);
            Base64UrlNamingStrategy anonQueueNameGenerator = null;

            if (anonymous)
            {
                anonQueueNameGenerator = new Base64UrlNamingStrategy(consumerProperties.AnonymousGroupPrefix ?? string.Empty);
            }

            string baseQueueName;

            if (consumerProperties.QueueNameGroupOnly.GetValueOrDefault())
            {
                baseQueueName = anonymous ? anonQueueNameGenerator.GenerateName() : group;
            }
            else
            {
                baseQueueName = GetGroupedName(name, anonymous ? anonQueueNameGenerator.GenerateName() : group);
            }

            // logger.info("declaring queue for inbound: " + baseQueueName + ", bound to: " + name);
            var prefix       = consumerProperties.Prefix;
            var exchangeName = ApplyPrefix(prefix, name);
            var exchange     = BuildExchange(consumerProperties, exchangeName);

            if (consumerProperties.DeclareExchange.GetValueOrDefault())
            {
                DeclareExchange(exchangeName, exchange);
            }

            var   queueName   = ApplyPrefix(prefix, baseQueueName);
            var   partitioned = !anonymous && options.IsPartitioned;
            var   durable     = !anonymous && consumerProperties.DurableSubscription.Value;
            Queue queue;

            if (anonymous)
            {
                var anonQueueName = queueName;
                queue = new AnonymousQueue(new GivenNamingStrategy(() => anonQueueName), GetQueueArgs(queueName, consumerProperties, false));
            }
            else
            {
                if (partitioned)
                {
                    var partitionSuffix = "-" + options.InstanceIndex;
                    queueName += partitionSuffix;
                }

                if (durable)
                {
                    queue = new Queue(queueName, true, false, false, GetQueueArgs(queueName, consumerProperties, false));
                }
                else
                {
                    queue = new Queue(queueName, false, false, true, GetQueueArgs(queueName, consumerProperties, false));
                }
            }

            RabbitConfig.IBinding binding = null;
            if (consumerProperties.BindQueue.GetValueOrDefault())
            {
                DeclareQueue(queueName, queue);
                var routingKeys = BindingRoutingKeys(consumerProperties);
                if (routingKeys == null || routingKeys.Count == 0)
                {
                    binding = DeclareConsumerBindings(name, null, options, exchange, partitioned, queue);
                }
                else
                {
                    foreach (var routingKey in routingKeys)
                    {
                        binding = DeclareConsumerBindings(name, routingKey, options, exchange, partitioned, queue);
                    }
                }
            }

            if (durable)
            {
                AutoBindDLQ(ApplyPrefix(consumerProperties.Prefix, baseQueueName), queueName, consumerProperties);
            }

            return(new RabbitConsumerDestination(queue.QueueName, binding));
        }