public bool CommitIfNecessary(bool localTx)
        {
            if (DeliveryTags.Count == 0)
            {
                return(false);
            }

            var isLocallyTransacted = localTx || (Transactional && TransactionSynchronizationManager.GetResource(ConnectionFactory) == null);

            try
            {
                var ackRequired = !AcknowledgeMode.IsAutoAck() && !AcknowledgeMode.IsManual();
                if (ackRequired && (!Transactional || isLocallyTransacted))
                {
                    var deliveryTag = new List <ulong>(DeliveryTags)[DeliveryTags.Count - 1];
                    Channel.BasicAck(deliveryTag, true);
                }

                if (isLocallyTransacted)
                {
                    // For manual acks we still need to commit
                    RabbitUtils.CommitIfNecessary(Channel);
                }
            }
            finally
            {
                DeliveryTags.Clear();
            }

            return(true);
        }
        public Models.UrlRequest Post()
        {
            if (!Request.Form.ContainsKey("url"))
            {
                return(null);
            }
            var urls    = Request.Form["url"];
            var request = new Models.UrlRequest
            {
                Urls = urls,
            };
            var requestString = JsonConvert.SerializeObject(request);

            var factory = RabbitUtils.GetRabbitConnection();

            using (var connection = factory.CreateConnection())
                using (var channel = connection.CreateModel())
                {
                    channel.QueueDeclare(queue: "URL",
                                         durable: false,
                                         exclusive: false,
                                         autoDelete: false,
                                         arguments: null);
                    var body = Encoding.UTF8.GetBytes(requestString);
                    channel.BasicPublish(exchange: "",
                                         routingKey: "URL",
                                         basicProperties: null,
                                         body: body);
                    Console.WriteLine("[URL] Sent {0}", requestString);
                }
            return(request);
        }
Exemple #3
0
        private SimpleConsumer Consume(string queue, Connection.IConnection connection)
        {
            R.IModel       channel  = null;
            SimpleConsumer consumer = null;

            try
            {
                channel = connection.CreateChannel(IsChannelTransacted);
                channel.BasicQos(0, (ushort)PrefetchCount, false);  // TODO: Verify this
                consumer = new SimpleConsumer(this, connection, channel, queue);
                channel.QueueDeclarePassive(queue);
                consumer.ConsumerTag = channel.BasicConsume(
                    queue,
                    AcknowledgeMode.IsAutoAck(),
                    ConsumerTagStrategy != null ? ConsumerTagStrategy.CreateConsumerTag(queue) : string.Empty,
                    NoLocal,
                    Exclusive,
                    ConsumerArguments,
                    consumer);
            }

            // catch (AmqpApplicationContextClosedException e)
            // {
            //    throw new AmqpConnectException(e);
            // }
            catch (Exception e)
            {
                RabbitUtils.CloseChannel(channel, _logger);
                RabbitUtils.CloseConnection(connection, _logger);

                consumer = HandleConsumeException(queue, consumer, e);
            }

            return(consumer);
        }
Exemple #4
0
        private void CleanUpAfterInvoke(RabbitResourceHolder resourceHolder, R.IModel channelToUse, bool boundHere)
        {
            if (resourceHolder != null && boundHere)
            {
                // so the channel exposed (because exposeListenerChannel is false) will be closed
                resourceHolder.SynchronizedWithTransaction = false;
            }

            ConnectionFactoryUtils.ReleaseResources(resourceHolder); // NOSONAR - null check in method
            if (boundHere)
            {
                // unbind if we bound
                TransactionSynchronizationManager.UnbindResource(ConnectionFactory);
                if (!ExposeListenerChannel && IsChannelLocallyTransacted)
                {
                    /*
                     *  commit the temporary channel we exposed; the consumer's channel
                     *  will be committed later. Note that when exposing a different channel
                     *  when there's no transaction manager, the exposed channel is committed
                     *  on each message, and not based on txSize.
                     */
                    RabbitUtils.CommitIfNecessary(channelToUse, _logger);
                }
            }
        }
Exemple #5
0
            private void Rollback(ulong deliveryTag, Exception e)
            {
                if (_container.IsChannelTransacted)
                {
                    RabbitUtils.RollbackIfNecessary(Model);
                }

                if (AckRequired || ContainerUtils.IsRejectManual(e))
                {
                    try
                    {
                        if (MessagesPerAck > 1)
                        {
                            lock (_lock)
                            {
                                if (PendingAcks > 0)
                                {
                                    SendAck(DateTimeOffset.Now.ToUnixTimeMilliseconds());
                                }
                            }
                        }

                        Model.BasicNack(deliveryTag, true, ContainerUtils.ShouldRequeue(_container.DefaultRequeueRejected, e, _logger));
                    }
                    catch (IOException e1)
                    {
                        _logger?.LogError("Failed to nack message", e1);
                    }
                }

                if (_container.IsChannelTransacted)
                {
                    RabbitUtils.CommitIfNecessary(Model);
                }
            }
Exemple #6
0
        private void CancelConsumer(SimpleConsumer consumer)
        {
            try
            {
                _logger?.LogDebug("Canceling " + consumer);
                lock (consumer)
                {
                    consumer.Canceled = true;
                    if (MessagesPerAck > 1)
                    {
                        try
                        {
                            consumer.AckIfNecessary(0L);
                        }
                        catch (IOException e)
                        {
                            _logger?.LogError("Exception while sending delayed ack", e);
                        }
                    }
                }

                RabbitUtils.Cancel(consumer.Model, consumer.ConsumerTag, _logger);
            }
            finally
            {
                _consumers.Remove(consumer);
                ConsumerRemoved(consumer);
            }
        }
        public void Stop()
        {
            if (AbortStarted == 0)
            {
                AbortStarted = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            }

            if (!Cancelled)
            {
                try
                {
                    RabbitUtils.CloseMessageConsumer(Channel, GetConsumerTags(), Transactional);
                }
                catch (Exception e)
                {
                    Logger?.LogDebug(e, "Error closing consumer: {consumer}", ToString());
                }
            }

            Logger?.LogDebug("Closing Rabbit Channel : {channel}", Channel);
            RabbitUtils.SetPhysicalCloseRequired(Channel, true);
            ConnectionFactoryUtils.ReleaseResources(ResourceHolder);
            DeliveryTags.Clear();
            _ = Consumers.TakeWhile((kvp) => Consumers.Count > 0);
            _ = Queue.TakeWhile((d) => Queue.Count > 0);
        }
        public string Get(string id)
        {
            if (String.IsNullOrWhiteSpace(id))
            {
                return("No ticket number provided");
            }
            var factory = RabbitUtils.GetRabbitConnection();

            using (var connection = factory.CreateConnection())
                using (var channel = connection.CreateModel())
                {
                    channel.QueueDeclare(queue: "JIRA",
                                         durable: false,
                                         exclusive: false,
                                         autoDelete: false,
                                         arguments: null);
                    var body = Encoding.UTF8.GetBytes(id);
                    channel.BasicPublish(exchange: "",
                                         routingKey: "JIRA",
                                         basicProperties: null,
                                         body: body);
                    Console.WriteLine("[JIRA] Sent {0}", id);
                }
            return("Ticket accepted");
        }
Exemple #9
0
 private void FinalizeConsumer()
 {
     RabbitUtils.SetPhysicalCloseRequired(Model, true);
     RabbitUtils.CloseChannel(Model);
     RabbitUtils.CloseConnection(_connection);
     _container._cancellationLock.Release(this);
     _container.ConsumerRemoved(this);
 }
        /// <summary>
        /// Disposes this instance.
        /// </summary>
        public void Dispose()
        {
            if (this.target != null)
            {
                this.outer.ConnectionListener.OnClose(this.target);
                RabbitUtils.CloseConnection(this.target);
            }

            this.target = null;
        }
            public void Destroy()
            {
                if (Target != null)
                {
                    _factory.ConnectionListener.OnClose(Target);
                    RabbitUtils.CloseConnection(Target);
                }

                Target = null;
            }
Exemple #12
0
        public void TestUninterruptibleListenerDMLC()
        {
            var cf    = new CachingConnectionFactory("localhost");
            var admin = new RabbitAdmin(cf);

            admin.DeclareQueue(new Config.Queue("test.shutdown"));

            var container = new DirectMessageListenerContainer(null, cf)
            {
                ShutdownTimeout = 500
            };

            container.SetQueueNames("test.shutdown");
            var latch     = new CountdownEvent(1);
            var testEnded = new CountdownEvent(1);
            var listener  = new TestListener(latch, testEnded);

            container.MessageListener = listener;
            var connection = cf.CreateConnection() as ChannelCachingConnectionProxy;

            // var channels = TestUtils.getPropertyValue(connection, "target.delegate._channelManager._channelMap");
            var field = typeof(RC.Framing.Impl.Connection)
                        .GetField("m_sessionManager", BindingFlags.Instance | BindingFlags.NonPublic);

            Assert.NotNull(field);
            var channels = (SessionManager)field.GetValue(connection.Target.Connection);

            Assert.NotNull(channels);

            container.Start();
            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            try
            {
                var template = new RabbitTemplate(cf);
                template.Execute(c =>
                {
                    var properties = c.CreateBasicProperties();
                    var bytes      = EncodingUtils.GetDefaultEncoding().GetBytes("foo");
                    c.BasicPublish(string.Empty, "test.shutdown", false, properties, bytes);
                    RabbitUtils.SetPhysicalCloseRequired(c, false);
                });
                Assert.True(latch.Wait(TimeSpan.FromSeconds(30)));
                Assert.Equal(2, channels.Count);
            }
            finally
            {
                container.Stop();
                Assert.Equal(1, channels.Count);

                cf.Destroy();
                testEnded.Signal();
                admin.DeleteQueue("test.shutdown");
            }
        }
        protected override object DoReceive()
        {
            var connection = ConnectionFactory.CreateConnection();
            var channel    = connection.CreateChannel(Transacted);

            try
            {
                var resp = channel.BasicGet(QueueName, false);
                if (resp == null)
                {
                    RabbitUtils.CloseChannel(channel);
                    RabbitUtils.CloseConnection(connection);
                    return(null);
                }

                var callback          = AckCallbackFactory.CreateCallback(new RabbitAckInfo(connection, channel, Transacted, resp));
                var envelope          = new Envelope(resp.DeliveryTag, resp.Redelivered, resp.Exchange, resp.RoutingKey);
                var messageProperties = MessageHeaderConverter.ToMessageHeaders(resp.BasicProperties, envelope, EncodingUtils.Utf8);
                var accessor          = RabbitHeaderAccessor.GetMutableAccessor(messageProperties);
                accessor.ConsumerQueue = this.QueueName;

                // Map<String, Object> headers = this.headerMapper.toHeadersFromRequest(messageProperties);
                var message = Message.Create <byte[]>(resp.Body, accessor.MessageHeaders);

                object payload;
                if (BatchingStrategy.CanDebatch(message.Headers))
                {
                    var payloads = new List <object>();
                    BatchingStrategy.DeBatch(message, fragment => payloads.Add(MessageConverter.FromMessage(fragment, null)));
                    payload = payloads;
                }
                else
                {
                    payload = MessageConverter.FromMessage(message, null);
                }

                var builder = MessageBuilderFactory.WithPayload(payload)
                              .CopyHeaders(accessor.MessageHeaders)
                              .SetHeader(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK, callback);
                if (RawMessageHeader)
                {
                    builder.SetHeader(RabbitMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE, message);
                    builder.SetHeader(IntegrationMessageHeaderAccessor.SOURCE_DATA, message);
                }

                return(builder);
            }
            catch (Exception e)
            {
                RabbitUtils.CloseChannel(channel);
                RabbitUtils.CloseConnection(connection);
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(e);
            }
        }
        /// <summary>Perform a rollback, handling rollback exceptions properly.</summary>
        /// <param name="ex">The thrown application exception.</param>
        public virtual void RollbackOnExceptionIfNecessary(Exception ex)
        {
            var ackRequired = !this.acknowledgeMode.IsAutoAck() && !this.acknowledgeMode.IsManual();

            try
            {
                if (this.transactional)
                {
                    Logger.Debug(m => m("Initiating transaction rollback on application exception"), ex);
                    RabbitUtils.RollbackIfNecessary(this.channel);
                }

                if (ackRequired)
                {
                    Logger.Debug(m => m("Rejecting message"));

                    var shouldRequeue = this.defaultRequeueRejected;
                    var t             = ex;
                    while (shouldRequeue && t != null)
                    {
                        if (t is AmqpRejectAndDontRequeueException)
                        {
                            shouldRequeue = false;
                        }

                        t = t.InnerException;
                    }

                    foreach (var deliveryTag in this.deliveryTags)
                    {
                        // With newer RabbitMQ brokers could use basicNack here...
                        this.channel.BasicReject((ulong)deliveryTag, shouldRequeue);
                    }

                    if (this.transactional)
                    {
                        // Need to commit the reject (=nack)
                        RabbitUtils.CommitIfNecessary(this.channel);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(m => m("Application exception overriden by rollback exception"), ex);
                throw;
            }
            finally
            {
                this.deliveryTags.Clear();
            }
        }
        protected void BasicCancel(bool expected)
        {
            NormalCancel = expected;
            GetConsumerTags().ForEach(consumerTag =>
            {
                if (Channel.IsOpen)
                {
                    RabbitUtils.Cancel(Channel, consumerTag);
                }
            });

            Cancel.Value = true;
            AbortStarted = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        }
        /// <summary>Perform a commit or message acknowledgement, as appropriate</summary>
        /// <param name="locallyTransacted">if set to <c>true</c> [locally transacted].</param>
        /// <returns>True if committed, else false.</returns>
        public bool CommitIfNecessary(bool locallyTransacted)
        {
            if (this.deliveryTags == null || this.deliveryTags.Count < 1)
            {
                return(false);
            }

            try
            {
                var ackRequired = !this.acknowledgeMode.IsAutoAck() && !this.acknowledgeMode.IsManual();

                if (ackRequired)
                {
                    if (this.transactional && !locallyTransacted)
                    {
                        // Not locally transacted but it is transacted so it
                        // could be synchronized with an external transaction
                        foreach (var deliveryTag in this.deliveryTags)
                        {
                            ConnectionFactoryUtils.RegisterDeliveryTag(this.connectionFactory, this.channel, deliveryTag);
                        }
                    }
                    else
                    {
                        if (this.deliveryTags != null && this.deliveryTags.Count > 0)
                        {
                            var copiedTags = new List <long>(this.deliveryTags);
                            if (copiedTags.Count > 0)
                            {
                                var deliveryTag = copiedTags[copiedTags.Count - 1];
                                this.channel.BasicAck((ulong)deliveryTag, true);
                            }
                        }
                    }
                }

                if (locallyTransacted)
                {
                    // For manual acks we still need to commit
                    RabbitUtils.CommitIfNecessary(this.channel);
                }
            }
            finally
            {
                this.deliveryTags.Clear();
            }

            return(true);
        }
        /// <summary>Sends the given response message to the given destination.</summary>
        /// <param name="channel">The channel to operate on.</param>
        /// <param name="replyTo">The replyto property to determine where to send a response.</param>
        /// <param name="message">The outgoing message about to be sent.</param>
        protected virtual void SendResponse(IModel channel, Address replyTo, Message message)
        {
            this.PostProcessChannel(channel, message);

            try
            {
                Logger.Debug(m => m("Publishing response to exchange = [{0}], routingKey = [{1}]", replyTo.ExchangeName, replyTo.RoutingKey));
                channel.BasicPublish(
                    replyTo.ExchangeName, replyTo.RoutingKey, this.mandatoryPublish, this.immediatePublish, this.messagePropertiesConverter.FromMessageProperties(channel, message.MessageProperties, this.encoding), message.Body);
            }
            catch (Exception ex)
            {
                throw RabbitUtils.ConvertRabbitAccessException(ex);
            }
        }
Exemple #18
0
        private List <string> ProcessStackTrace(Exception cause, string exceptionMessage)
        {
            var stackTraceAsString = cause.StackTrace;

            if (MaxStackTraceLength < 0)
            {
                var maxStackTraceLen = RabbitUtils.GetMaxFrame(ErrorTemplate.ConnectionFactory);
                if (maxStackTraceLen > 0)
                {
                    maxStackTraceLen   -= FrameMaxHeadroom;
                    MaxStackTraceLength = maxStackTraceLen;
                }
            }

            return(TruncateIfNecessary(cause, exceptionMessage, stackTraceAsString));
        }
Exemple #19
0
        private void CheckConsumers(long now)
        {
            List <SimpleConsumer> consumersToCancel;

            lock (_consumersMonitor)
            {
                consumersToCancel = _consumers
                                    .Where(consumer =>
                {
                    var open = consumer.Model.IsOpen && !consumer.AckFailed && !consumer.TargetChanged;
                    if (open && MessagesPerAck > 1)
                    {
                        try
                        {
                            consumer.AckIfNecessary(now);
                        }
                        catch (IOException e)
                        {
                            _logger?.LogError("Exception while sending delayed ack", e);
                        }
                    }

                    return(!open);
                })
                                    .ToList();
            }

            consumersToCancel
            .ForEach(consumer =>
            {
                try
                {
                    RabbitUtils.CloseMessageConsumer(consumer.Model, new List <string>()
                    {
                        consumer.ConsumerTag
                    }, IsChannelTransacted, _logger);
                }
                catch (Exception e)
                {
                    _logger?.LogDebug("Error closing consumer " + consumer, e);
                }

                _logger?.LogError("Consumer canceled - channel closed " + consumer);
                consumer.CancelConsumer("Consumer " + consumer + " channel closed");
            });
        }
Exemple #20
0
        static void Main(string[] args)
        {
            // Setup cancel key (Ctrl-C)
            Console.CancelKeyPress += (sender, eArgs) =>
            {
                _quitEvent.Set();
                eArgs.Cancel = true;
            };

            // Initialize the JIRA listener
            Console.WriteLine("[RABBIT][JIRA] Listener starting");
            var factory = RabbitUtils.GetRabbitConnection();

            using (var connection = factory.CreateConnection())
                using (var channel = connection.CreateModel())
                {
                    channel.QueueDeclare(queue: "JIRA",
                                         durable: false,
                                         exclusive: false,
                                         autoDelete: false,
                                         arguments: null);

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        var body    = ea.Body;
                        var message = Encoding.UTF8.GetString(body);
                        Console.WriteLine(String.Format("[RABBIT][JIRA] Received: {0}", message));
                        if (string.IsNullOrWhiteSpace(message))
                        {
                            return;
                        }
                        // Send this ticket to the Orchestrator
                        JiraAsync(message).GetAwaiter().GetResult();
                    };
                    channel.BasicConsume(queue: "JIRA",
                                         autoAck: true,
                                         consumer: consumer);

                    Console.WriteLine("[RABBIT][JIRA] Listener started");

                    // Wait for the Ctrl-C to come through
                    _quitEvent.WaitOne();
                    Console.WriteLine("[RABBIT][JIRA] Listener stopping...");
                }
        }
            public void Acknowledge(Status status)
            {
                // logger.trace("acknowledge(" + status + ") for " + this);
                try
                {
                    var deliveryTag = AckInfo.Response.DeliveryTag;
                    switch (status)
                    {
                    case Status.ACCEPT:
                        AckInfo.Channel.BasicAck(deliveryTag, false);
                        break;

                    case Status.REJECT:
                        AckInfo.Channel.BasicReject(deliveryTag, false);
                        break;

                    case Status.REQUEUE:
                        AckInfo.Channel.BasicReject(deliveryTag, true);
                        break;

                    default:
                        break;
                    }

                    if (AckInfo.Transacted)
                    {
                        AckInfo.Channel.TxCommit();
                    }
                }
                catch (Exception e)
                {
                    throw RabbitExceptionTranslator.ConvertRabbitAccessException(e);
                }
                finally
                {
                    RabbitUtils.CloseChannel(AckInfo.Channel);
                    RabbitUtils.CloseConnection(AckInfo.Connection);
                    IsAcknowledged = true;
                }
            }
Exemple #22
0
 protected virtual void CheckMismatchedQueues()
 {
     if (MismatchedQueuesFatal && AmqpAdmin != null)
     {
         try
         {
             AmqpAdmin.Initialize();
         }
         catch (AmqpConnectException e)
         {
             _logger?.LogInformation("Broker not available; cannot check queue declarations", e);
         }
         catch (AmqpIOException e)
         {
             if (RabbitUtils.IsMismatchedQueueArgs(e))
             {
                 throw new FatalListenerStartupException("Mismatched queues", e);
             }
             else
             {
                 _logger?.LogInformation("Failed to get connection during start(): ", e);
             }
         }
     }
     else
     {
         try
         {
             var connection = ConnectionFactory.CreateConnection();
             if (connection != null)
             {
                 connection.Close();
             }
         }
         catch (Exception e)
         {
             _logger?.LogInformation("Broker not available; cannot force queue declarations during start: " + e.Message);
         }
     }
 }
Exemple #23
0
            private void HandleAck(ulong deliveryTag, bool channelLocallyTransacted)
            {
                /*
                 * If we have a TX Manager, but no TX, act like we are locally transacted.
                 */
                var isLocallyTransacted = channelLocallyTransacted ||
                                          (_container.IsChannelTransacted && TransactionSynchronizationManager.GetResource(ConnectionFactory) == null);

                try
                {
                    if (AckRequired)
                    {
                        if (MessagesPerAck > 1)
                        {
                            lock (_lock)
                            {
                                LatestDeferredDeliveryTag = deliveryTag;
                                PendingAcks++;
                                AckIfNecessary(LastAck);
                            }
                        }
                        else if (!_container.IsChannelTransacted || isLocallyTransacted)
                        {
                            Model.BasicAck(deliveryTag, false);
                        }
                    }

                    if (isLocallyTransacted)
                    {
                        RabbitUtils.CommitIfNecessary(Model);
                    }
                }
                catch (Exception e)
                {
                    AckFailed = true;
                    _logger?.LogError("Error acking", e);
                }
            }
        /// <summary>
        /// Stop the channel.
        /// </summary>
        public void Stop()
        {
            this.cancelled.LazySet(true);
            if (this.consumer != null && this.consumer.Model != null && this.consumer.ConsumerTag != null && !this.cancelReceived.Value)
            {
                try
                {
                    RabbitUtils.CloseMessageConsumer(this.consumer.Model, this.consumer.ConsumerTag, this.transactional);
                }
                catch (Exception ex)
                {
                    Logger.Debug(m => m("Error closing consumer"), ex);
                }
            }

            Logger.Debug("Closing Rabbit Channel: " + this.channel);
            RabbitUtils.SetPhysicalCloseRequired(true);

            // This one never throws exceptions...
            RabbitUtils.CloseChannel(this.channel);
            this.deliveryTags.Clear();
            this.consumer = null;
        }
Exemple #25
0
        protected virtual void RedeclareElementsIfNecessary()
        {
            lock (_lock)
            {
                var admin = AmqpAdmin;
                if (!IsLazyLoad && admin != null && AutoDeclare)
                {
                    try
                    {
                        AttemptDeclarations(admin);
                    }
                    catch (Exception e)
                    {
                        if (RabbitUtils.IsMismatchedQueueArgs(e))
                        {
                            throw new FatalListenerStartupException("Mismatched queues", e);
                        }

                        _logger?.LogError("Failed to check/redeclare auto-delete queue(s).", e);
                    }
                }
            }
        }
        public void RollbackOnExceptionIfNecessary(Exception ex)
        {
            bool ackRequired = !AcknowledgeMode.IsAutoAck() && (!AcknowledgeMode.IsManual() || ContainerUtils.IsRejectManual(ex));

            try
            {
                if (Transactional)
                {
                    Logger?.LogDebug(ex, "Initiating transaction rollback on application exception");
                    RabbitUtils.RollbackIfNecessary(Channel);
                }

                if (ackRequired)
                {
                    if (DeliveryTags.Count > 0)
                    {
                        ulong deliveryTag = DeliveryTags.Max();
                        Channel.BasicNack(deliveryTag, true, ContainerUtils.ShouldRequeue(DefaultRequeueRejected, ex, Logger));
                    }

                    if (Transactional)
                    {
                        // Need to commit the reject (=nack)
                        RabbitUtils.CommitIfNecessary(Channel);
                    }
                }
            }
            catch (Exception e)
            {
                Logger?.LogError(ex, "Application exception overridden by rollback exception");
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(e); // NOSONAR stack trace loss
            }
            finally
            {
                DeliveryTags.Clear();
            }
        }
            public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, RC.IBasicProperties properties, byte[] body)
            {
                Logger?.LogDebug("Storing delivery for consumer tag: {tag} with deliveryTag: {deliveryTag} for consumer: {consumer}", ConsumerTag, deliveryTag, ToString());
                try
                {
                    var delivery = new Delivery(consumerTag, new Envelope(deliveryTag, redelivered, exchange, routingKey), properties, body, QueueName);
                    if (Consumer.AbortStarted > 0)
                    {
                        if (!Consumer.Queue.TryAdd(delivery, Consumer.ShutdownTimeout))
                        {
                            RabbitUtils.SetPhysicalCloseRequired(Model, true);
                            _ = Consumer.Queue.TakeWhile((d) => Consumer.Queue.Count > 0);
                            if (!Canceled)
                            {
                                RabbitUtils.Cancel(Model, consumerTag);
                            }

                            try
                            {
                                Model.Close();
                            }
                            catch (Exception)
                            {
                                // Noop
                            }
                        }
                    }
                    else
                    {
                        Consumer.Queue.TryAdd(delivery);
                    }
                }
                catch (Exception e)
                {
                    Logger?.LogWarning(e, "Unexpected exception during delivery");
                }
            }
        /// <summary>The start.</summary>
        public void Start()
        {
            Logger.Debug(m => m("Starting consumer {0}", this));

            this.channel  = ConnectionFactoryUtils.GetTransactionalResourceHolder(this.connectionFactory, this.transactional).Channel;
            this.consumer = new InternalConsumer(this.channel, this);
            this.deliveryTags.Clear();
            this.activeObjectCounter.Add(this);
            var passiveDeclareTries = 3; // mirrored queue might be being moved

            while (passiveDeclareTries > 0)
            {
                passiveDeclareTries--;
                try
                {
                    if (!this.acknowledgeMode.IsAutoAck())
                    {
                        // Set basicQos before calling basicConsume (otherwise if we are not acking the broker
                        // will send blocks of 100 messages)
                        // The Java client includes a convenience method BasicQos(ushort prefetchCount), which sets 0 as the prefetchSize and false as global
                        this.channel.BasicQos(0, (ushort)this.prefetchCount, false);
                    }

                    foreach (var t in this.queues)
                    {
                        this.channel.QueueDeclarePassive(t);
                    }

                    passiveDeclareTries = 0;
                }
                catch (Exception e)
                {
                    if (passiveDeclareTries > 0 && this.channel.IsOpen)
                    {
                        Logger.Warn(m => m("Reconnect failed; retries left=" + (passiveDeclareTries - 1)), e);
                        try
                        {
                            Thread.Sleep(5000);
                        }
                        catch (ThreadInterruptedException e1)
                        {
                            Thread.CurrentThread.Interrupt();
                        }
                    }
                    else
                    {
                        this.activeObjectCounter.Release(this);
                        throw new FatalListenerStartupException("Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.", e);
                    }
                }
            }

            try
            {
                foreach (var t in this.queues)
                {
                    this.channel.BasicConsume(t, this.acknowledgeMode.IsAutoAck(), this.consumer);
                    Logger.Debug(m => m("Started on queue '{0}': {1}", t, this));
                }
            }
            catch (Exception e)
            {
                throw RabbitUtils.ConvertRabbitAccessException(e);
            }
        }
Exemple #29
0
 /// <summary>Converts a rabbit access exception.</summary>
 /// <param name="ex">The ex.</param>
 /// <returns>The system exception.</returns>
 protected Exception ConvertRabbitAccessException(Exception ex)
 {
     return(RabbitUtils.ConvertRabbitAccessException(ex));
 }
        public async Task TestDeclareDelayedExchange()
        {
            provider = services.BuildServiceProvider();
            var rabbitAdmin = provider.GetRabbitAdmin();
            var exchange    = new DirectExchange("test.delayed.exchange")
            {
                IsDelayed = true
            };
            var queue        = new Queue(Guid.NewGuid().ToString(), true, false, false);
            var exchangeName = exchange.ExchangeName;
            var binding      = new Binding("baz", queue.QueueName, DestinationType.QUEUE, exchangeName, queue.QueueName, null);

            try
            {
                rabbitAdmin.DeclareExchange(exchange);
            }
            catch (RabbitIOException e)
            {
                if (RabbitUtils.IsExchangeDeclarationFailure(e))
                {
                    var inner = e.InnerException;
                    if (inner.Message.Contains("exchange type 'x-delayed-message'"))
                    {
                        return; // Broker doesn't support?
                    }
                }

                throw;
            }

            rabbitAdmin.DeclareQueue(queue);
            rabbitAdmin.DeclareBinding(binding);
            var cf       = provider.GetRabbitConnectionFactory();
            var context  = provider.GetApplicationContext();
            var pp       = new TestPostProcessor();
            var template = new RabbitTemplate(cf)
            {
                ReceiveTimeout = 10000
            };

            template.ConvertAndSend(exchangeName, queue.QueueName, "foo", pp);
            var headers = RabbitHeaderAccessor.GetMutableAccessor(new MessageHeaders());

            headers.Delay = 500;
            var send = MessageBuilder.WithPayload(Encoding.UTF8.GetBytes("foo")).SetHeaders(headers).Build();

            template.Send(exchangeName, queue.QueueName, send);
            var t1       = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            var received = template.Receive(queue.QueueName);

            Assert.NotNull(received);
            var delay = received.Headers.ReceivedDelay();

            Assert.NotNull(delay);
            Assert.Equal(500, delay.Value);
            received = template.Receive(queue.QueueName);
            Assert.NotNull(received);
            delay = received.Headers.ReceivedDelay();
            Assert.NotNull(delay);
            Assert.Equal(1000, delay.Value);
            var t2  = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            var dif = t2 - t1;

            Assert.InRange(dif, 950, 1250);
            var config = await GetExchange(exchangeName);

            Assert.Equal("direct", config.GetValue <string>("x-delayed-type"));
            Assert.Equal("x-delayed-message", config.GetValue <string>("type"));
        }