Esempio n. 1
0
        private IModel CreateConsumerChannel()
        {
            if (!_persistentConnection.IsConnected)
            {
                _persistentConnection.TryConnect();
            }

            _logger.LogTrace("Creating RabbitMQ consumer channel");

            var channel = _persistentConnection.CreateModel();

            channel.ExchangeDeclare(exchange: BROKER_NAME,
                                    type: "direct");

            channel.QueueDeclare(queue: _queueName,
                                 durable: true,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);

            channel.CallbackException += (sender, ea) =>
            {
                _logger.LogWarning(ea.Exception, "Recreating RabbitMQ consumer channel");

                _consumerChannel.Dispose();
                _consumerChannel = CreateConsumerChannel();
                StartBasicConsume();
            };

            return(channel);
        }
Esempio n. 2
0
        private void DeclareBindings(RC.IModel channel, params IBinding[] bindings)
        {
            foreach (var binding in bindings)
            {
                _logger?.LogDebug("Binding destination [{destination} ({type})] to exchange [{exchange}] with routing key [{routingKey}]", binding.Destination, binding.Type, binding.Exchange, binding.RoutingKey);

                try
                {
                    if (binding.IsDestinationQueue)
                    {
                        if (!IsDeclaringImplicitQueueBinding(binding))
                        {
                            channel.QueueBind(binding.Destination, binding.Exchange, binding.RoutingKey, binding.Arguments);
                        }
                    }
                    else
                    {
                        channel.ExchangeBind(binding.Destination, binding.Exchange, binding.RoutingKey, binding.Arguments);
                    }
                }
                catch (Exception e)
                {
                    LogOrRethrowDeclarationException(binding, "binding", e);
                }
            }
        }
Esempio n. 3
0
        private static void PullMQ()
        {
            Console.WriteLine("Begin pull all msg...");

            var MQQueueName = ConfigurationManager.AppSettings["MQQueueName"];
            var factory     = MQUtils.MQFactory;

            using (var conn = factory.CreateConnection())
            {
                using (RabbitMQ.Client.IModel channel = conn.CreateModel())
                {
                    IDictionary <string, object> queueArgs = new Dictionary <string, object>
                    {
                        { "x-ha-policy", "all" }
                    };
                    channel.QueueDeclare(queue: MQQueueName,
                                         durable: true,
                                         exclusive: false,
                                         autoDelete: false,
                                         arguments: queueArgs);
                    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
                    while (!MQUtils.QueueEmpty())
                    {
                        if (!MQUtils.Pull(channel, ExcuteMessage))
                        {
                            Console.WriteLine("{0} - Queue is empty!", Thread.CurrentThread.ManagedThreadId);
                            Thread.Sleep(1000);
                        }
                    }
                    Console.WriteLine("pull all msg done!");
                }
            }
        }
Esempio n. 4
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);
        }
 public InternalConsumer(BlockingQueueConsumer consumer, RC.IModel channel, string queue, ILogger <InternalConsumer> logger = null)
     : base(channel)
 {
     Consumer  = consumer;
     QueueName = queue;
     Logger    = logger;
 }
Esempio n. 6
0
 public RabbitAckInfo(IConnection connection, RC.IModel channel, bool transacted, RC.BasicGetResult getResponse)
 {
     Connection = connection;
     Channel    = channel;
     Transacted = transacted;
     Response   = getResponse;
 }
Esempio n. 7
0
            public SimpleConsumer(DirectMessageListenerContainer container, Connection.IConnection connection, R.IModel channel, string queue, ILogger logger = null)
                : base(channel)
            {
                _container  = container;
                _connection = connection;
                Queue       = queue;
                AckRequired = !_container.AcknowledgeMode.IsAutoAck() && !_container.AcknowledgeMode.IsManual();
                if (channel is IChannelProxy)
                {
                    _targetChannel = ((IChannelProxy)channel).TargetChannel;
                }
                else
                {
                    _targetChannel = null;
                }

                _logger              = logger;
                TransactionManager   = _container.TransactionManager;
                TransactionAttribute = _container.TransactionAttribute;
                IsRabbitTxManager    = TransactionManager is RabbitTransactionManager;
                ConnectionFactory    = _container.ConnectionFactory;
                MessagesPerAck       = _container.MessagesPerAck;
                LastAck              = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                AckTimeout           = _container.AckTimeout;
            }
Esempio n. 8
0
        } // AmqpClient

        #region ConnectionHandlerProgram

        private Exception MakeNewConnection(ref RmqCl.IConnection connection, ref RmqCl.IModel channel, bool reconnecting)
        {
            // This method attempts to make a new connection. Returns true if success, otherwise false.

            var connRequest = ConnectionRequestObj;

            var factory = new RmqCl.ConnectionFactory()
            {
                HostName = connRequest.Host,
                UserName = connRequest.Username,
                Password = connRequest.Password
            };

            // Secure connection?
            if (connRequest.Secure)
            {
                factory.Ssl.Enabled    = true;
                factory.Ssl.ServerName = connRequest.Host;
                factory.Ssl.Version    = System.Security.Authentication.SslProtocols.Tls12;
            }

            try
            {
                // Create connection and channel
                connection = factory.CreateConnection();
                channel    = connection.CreateModel();

                // Declare the exchange
                channel.ExchangeDeclare(exchange: connRequest.Exchange, type: "topic", autoDelete: false, durable: true, arguments: null);

                // Create a queue to receive messages
                var queueName = channel.QueueDeclare(queue: "",        // Use a generated queue name
                                                     durable: false,   // The queue does not survive a broker restart
                                                     exclusive: true,  // The queue is only for this application, and it will be deleted on app exit
                                                     autoDelete: true, // The queue is deleted when no one is bound to it
                                                     arguments: null
                                                     ).QueueName;

                // Bind the queue to the topic pattern
                channel.QueueBind(queue: queueName, exchange: connRequest.Exchange, routingKey: connRequest.TopicPattern, arguments: null);

                // Set up a consumer for messages
                m_messageConsumer           = new RmqCl.Events.EventingBasicConsumer(channel);
                m_messageConsumer.Received += MessageReceived;
                channel.BasicConsume(queue: queueName, noAck: true, consumerTag: "", noLocal: false, exclusive: false, arguments: new Dictionary <string, object> {
                }, consumer: m_messageConsumer);

                // Sign up for the shutdown event
                channel.ModelShutdown += ModelShutdown; // This event will fire if the connection is lost

                return(null);
            }
            catch (Exception e)
            {
                // Clean the connection
                DestroyConnection(ref connection, ref channel);

                return(e);
            }
        } // MakeNewConnection
 public void OnMessageBatch(List <IMessage> messages, RC.IModel channel)
 {
     if (_listener is IChannelAwareMessageListener chanAwareListener)
     {
         try
         {
             chanAwareListener.OnMessageBatch(messages, channel);
         }
         finally
         {
             _container._inUseConsumerChannels.Remove(channel, out _);
         }
     }
     else
     {
         try
         {
             _listener.OnMessageBatch(messages);
         }
         finally
         {
             _container._inUseConsumerChannels.Remove(channel, out _);
         }
     }
 }
Esempio n. 10
0
 public static void CloseChannel(RC.IModel channel, ILogger logger = null)
 {
     if (channel != null)
     {
         try
         {
             channel.Close();
         }
         catch (AlreadyClosedException)
         {
             // empty
         }
         catch (ShutdownSignalException sig)
         {
             if (!IsNormalShutdown(sig))
             {
                 logger?.LogDebug(sig, "Unexpected exception on closing RabbitMQ Channel");
             }
         }
         catch (Exception ex)
         {
             logger?.LogDebug(ex, "Unexpected exception on closing RabbitMQ Channel");
         }
     }
 }
Esempio n. 11
0
 public void AddDeliveryTag(R.IModel channel, ulong deliveryTag)
 {
     if (_deliveryTags.TryGetValue(channel, out var tags))
     {
         tags.Add(deliveryTag);
     }
 }
Esempio n. 12
0
        public static void CloseMessageConsumer(RC.IModel channel, List <string> consumerTags, bool transactional, ILogger logger = null)
        {
            if (!channel.IsOpen)
            {
                return;
            }

            try
            {
                foreach (var consumerTag in consumerTags)
                {
                    Cancel(channel, consumerTag);
                }

                if (transactional)
                {
                    // Re-queue in-flight messages if any (after the consumer is cancelled to prevent the broker from simply
                    // sending them back to us). Does not require a tx.commit.
                    channel.BasicRecover(true);
                }

                // If not transactional then we are auto-acking (at least as of 1.0.0.M2) so there is nothing to recover.
                // Messages are going to be lost in general.
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "Exception during CloseMessageConsumer");

                throw RabbitExceptionTranslator.ConvertRabbitAccessException(ex);
            }
        }
Esempio n. 13
0
        private void DoExecuteListener(R.IModel channel, object data)
        {
            if (data is Message asMessage)
            {
                if (AfterReceivePostProcessors != null)
                {
                    foreach (var processor in AfterReceivePostProcessors)
                    {
                        asMessage = processor.PostProcessMessage(asMessage);
                        if (asMessage == null)
                        {
                            throw new ImmediateAcknowledgeAmqpException("Message Post Processor returned 'null', discarding message");
                        }
                    }
                }

                if (IsDeBatchingEnabled && BatchingStrategy.CanDebatch(asMessage.MessageProperties))
                {
                    BatchingStrategy.DeBatch(asMessage, (fragment) => ActualInvokeListener(channel, fragment));
                }
                else
                {
                    ActualInvokeListener(channel, asMessage);
                }
            }
            else
            {
                ActualInvokeListener(channel, data);
            }
        }
Esempio n. 14
0
        protected virtual void ExecuteListener(R.IModel channel, object data)
        {
            if (!IsRunning)
            {
                _logger?.LogWarning("Rejecting received message(s) because the listener container has been stopped: " + data);
                throw new MessageRejectedWhileStoppingException();
            }

            try
            {
                DoExecuteListener(channel, data);
            }
            catch (Exception ex)
            {
                var message = data as Message;
                if (message == null && data is IList <Message> asList && asList.Count > 0)
                {
                    message = asList[0];
                }

                CheckStatefulRetry(ex, message);
                HandleListenerException(ex);
                throw;
            }
        }
Esempio n. 15
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);
                }
            }
        }
        private void AsyncSuccess(InvocationResult resultArg, IMessage request, RC.IModel channel, object source, object deferredResult)
        {
            if (deferredResult == null)
            {
                _logger?.LogDebug("Async result is null, ignoring");
            }
            else
            {
                var returnType = resultArg.ReturnType;
                if (returnType != null)
                {
                    var actualTypeArguments = returnType.ContainsGenericParameters ? returnType.GetGenericArguments() : new Type[0];
                    if (actualTypeArguments.Length > 0)
                    {
                        returnType = actualTypeArguments[0];

                        // if (returnType instanceof WildcardType)
                        //  {
                        //  // Set the return type to null so the converter will use the actual returned
                        //  // object's class for type info
                        //  returnType = null;
                        // }
                    }
                }

                DoHandleResult(new InvocationResult(deferredResult, resultArg.SendTo, returnType, resultArg.Instance, resultArg.Method), request, channel, source);
            }
        }
 public void PublishEvent <T>(T @event) where T : IEvent
 {
     using (IConnection conn = connectionFactory.CreateConnection())
     {
         using (RabbitMQ.Client.IModel channel = conn.CreateModel())
         {
             var queue = @event is CustomerCreatedEvent ?
                         Constants.QUEUE_CUSTOMER_CREATED : @event is CustomerUpdatedEvent ?
                         Constants.QUEUE_CUSTOMER_UPDATED : Constants.QUEUE_CUSTOMER_DELETED;
             channel.QueueDeclare(
                 queue: queue,
                 durable: false,
                 exclusive: false,
                 autoDelete: false,
                 arguments: null
                 );
             var body = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(@event));
             channel.BasicPublish(
                 exchange: "",
                 routingKey: queue,
                 basicProperties: null,
                 body: body
                 );
         }
     }
 }
        protected virtual void DoPublish(RC.IModel channel, Address replyTo, IMessage <byte[]> message)
        {
            var props = channel.CreateBasicProperties();

            MessagePropertiesConverter.FromMessageHeaders(message.Headers, props, EncodingUtils.GetEncoding(Encoding));
            channel.BasicPublish(replyTo.ExchangeName, replyTo.RoutingKey, MandatoryPublish, props, message.Payload);
        }
Esempio n. 19
0
 public static void SetPhysicalCloseRequired(RC.IModel channel, bool b)
 {
     if (channel is IChannelProxy asProxy)
     {
         _physicalCloseRequired.Value = b;
     }
 }
 public void Dispose()
 {
     _channel?.Dispose();
     _channel = null;
     _connection?.Dispose();
     _connection = null;
 }
        private void ReturnOrThrow(IMessage amqpMessage, RC.IModel channel, IMessage message, Exception exceptionToRetrun, Exception exceptionToThrow)
        {
            if (!ReturnExceptions)
            {
                throw exceptionToThrow;
            }

            try
            {
                HandleResult(
                    new InvocationResult(
                        exceptionToRetrun,
                        null,
                        HandlerAdapter.GetReturnTypeFor(message.Payload),
                        HandlerAdapter.Instance,
                        HandlerAdapter.GetMethodFor(message.Payload)),
                    amqpMessage,
                    channel,
                    message);
            }
            catch (ReplyFailureException)
            {
                if (typeof(void).Equals(HandlerAdapter.GetReturnTypeFor(message.Payload)))
                {
                    throw exceptionToThrow;
                }
                else
                {
                    throw;
                }
            }
        }
        protected void SendResponse(RC.IModel channel, Address replyTo, IMessage <byte[]> messageIn)
        {
            var message = messageIn;

            if (BeforeSendReplyPostProcessors != null)
            {
                var      processors    = BeforeSendReplyPostProcessors;
                IMessage postProcessed = message;
                foreach (var postProcessor in processors)
                {
                    postProcessed = postProcessor.PostProcessMessage(postProcessed);
                }

                message = postProcessed as IMessage <byte[]>;
                if (message == null)
                {
                    throw new InvalidOperationException("A BeforeSendReplyPostProcessors failed to return IMessage<byte[]>");
                }
            }

            PostProcessChannel(channel, message);

            try
            {
                _logger?.LogDebug("Publishing response to exchange = [{exchange}], routingKey = [{routingKey}]", replyTo.ExchangeName, replyTo.RoutingKey);
                if (RetryTemplate == null)
                {
                    DoPublish(channel, replyTo, message);
                }
                else
                {
                    var messageToSend = message;
                    RetryTemplate.Execute <object>(
                        ctx =>
                    {
                        DoPublish(channel, replyTo, messageToSend);
                        return(null);
                    },
                        ctx =>
                    {
                        if (RecoveryCallback != null)
                        {
                            ctx.SetAttribute(SendRetryContextAccessor.MESSAGE, messageToSend);
                            ctx.SetAttribute(SendRetryContextAccessor.ADDRESS, replyTo);
                            RecoveryCallback.Recover(ctx);
                            return(null);
                        }
                        else
                        {
                            throw RabbitExceptionTranslator.ConvertRabbitAccessException(ctx.LastException);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(ex);
            }
        }
Esempio n. 23
0
        private void ConnectionHandlerProgram()
        {
            // This method is run in the connection handler thread.
            // Multiple variables are declared here, because this limits their access for this thread only.

            RmqCl.IConnection connection = null;
            RmqCl.IModel      channel    = null;

            // This indicates if the connection is being restored
            bool connectionRestoreSequenceOn = false;

            // Run the thread until "break"
            while (true)
            {
                // Wait for something to happen.
                // This wait has a maximum length, as this same wait call occurs between reconnect attempts.
                m_connectionWait.WaitOne(TimeSpan.FromSeconds(RetryIntervalSeconds));

                // Choosing what to do based on the flags
                if (m_disposed.Value || m_userHasRequestedTerminate.Value)
                {
                    // Quitting
                    break;
                }
                else if (m_triggerConnectionRestore.Value || connectionRestoreSequenceOn)
                {
                    // Connection lost! Attempting to restore.

                    // Reset the triggering flag
                    m_triggerConnectionRestore.Value = false;

                    // Keep on attempting restore until successful
                    connectionRestoreSequenceOn = !AttemptConnectionRestore(ref connection, ref channel);
                }
                else if (ConnectionRequestObj != null && connection == null)
                {
                    // Attempting to connect

                    SendConnectionEvent(true, ConnectionEventType.Connecting);
                    var exception = MakeNewConnection(ref connection, ref channel, false);

                    if (exception == null)
                    {
                        SendConnectionEvent(true, ConnectionEventType.Connected);
                    }
                    else
                    {
                        SendConnectionEvent(false, ConnectionEventType.ConnectingFailed, exception);
                    }
                }
                // Otherwise, nothing to do
            }

            // Quitting the thread
            TerminateImpl(ref connection, ref channel);
            m_connectionWait.Dispose();
        } // ConnectionHandlerProgram
        public void OnCreate(RC.IModel channel, bool transactional)
        {
            _logger?.LogDebug("OnCreate");
            var listeners = _channelListeners;

            foreach (var listener in listeners)
            {
                listener.OnCreate(channel, transactional);
            }
        }
Esempio n. 25
0
        public override void OnMessageBatch(List <IMessage> messages, RC.IModel channel)
        {
            IMessage converted = null;

            if (IsMessageByteArrayList)
            {
                var list = new List <IMessage <byte[]> >();
                foreach (var m in messages)
                {
                    list.Add((IMessage <byte[]>)m);
                }

                converted = Message.Create(list);
            }
            else
            {
                if (IsMessageList)
                {
                    var messagingMessages = CreateMessageList(InferredArgumentType);
                    foreach (var message in messages)
                    {
                        messagingMessages.Add(ToMessagingMessage(message));
                    }

                    converted = Message.Create(messagingMessages);
                }
                else
                {
                    var payloads = CreateList(InferredArgumentType);

                    foreach (var message in messages)
                    {
                        PreprocesMessage(message);
                        var convertedObject = MessageConverter.FromMessage(message, InferredArgumentType);
                        if (convertedObject == null)
                        {
                            throw new MessageConversionException("Message converter returned null");
                        }

                        payloads.Add(convertedObject);
                    }

                    converted = Message.Create(payloads);
                }
            }

            try
            {
                InvokeHandlerAndProcessResult(null, channel, converted);
            }
            catch (Exception e)
            {
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(e);
            }
        }
Esempio n. 26
0
        public static bool IsChannelTransactional(R.IModel channel, IConnectionFactory connectionFactory)
        {
            if (channel == null || connectionFactory == null)
            {
                return(false);
            }

            var resourceHolder = (RabbitResourceHolder)TransactionSynchronizationManager.GetResource(connectionFactory);

            return(resourceHolder != null && resourceHolder.ContainsChannel(channel));
        }
Esempio n. 27
0
        private void InitializeInputExchange(IModel channel)
        {
            channel.ExchangeDeclare(
                exchange: $"{_serviceName}.Input.E.Direct.{Env}",
                type: "direct");

            channel.ExchangeBind(
                destination: $"{_serviceName}.Input.E.Direct.{Env}",
                source: $"RabbitMqPocMessageHub.E.Fanout.{Env}",
                routingKey: "");
        }
 public EventBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, ILogger <EventBusRabbitMQ> logger,
                         ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, int retryCount = 5)
 {
     _persistentConnection = persistentConnection ?? throw new ArgumentNullException(nameof(persistentConnection));
     _logger                      = logger ?? throw new ArgumentNullException(nameof(logger));
     _subsManager                 = subsManager ?? new InMemoryEventBusSubscriptionsManager();
     _consumerChannel             = CreateConsumerChannel();
     _autofac                     = autofac;
     _retryCount                  = retryCount;
     _subsManager.OnEventRemoved += SubsManager_OnEventRemoved;
 }
Esempio n. 29
0
 public void OnMessage(IMessage message, RC.IModel channel)
 {
     try
     {
         MessageListener.OnMessage(message, channel);
     }
     finally
     {
         Latch.Signal();
     }
 }
 private void AsyncFailure(IMessage request, RC.IModel channel, Exception exception)
 {
     _logger?.LogError(exception, "Async method was completed with an exception for {request} ", request);
     try
     {
         channel.BasicNack(request.Headers.DeliveryTag().Value, false, ContainerUtils.ShouldRequeue(DefaultRequeueRejected, exception, _logger));
     }
     catch (Exception e)
     {
         _logger?.LogError(e, "Failed to nack message");
     }
 }