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); }
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); } } }
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!"); } } }
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; }
public RabbitAckInfo(IConnection connection, RC.IModel channel, bool transacted, RC.BasicGetResult getResponse) { Connection = connection; Channel = channel; Transacted = transacted; Response = getResponse; }
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; }
} // 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 _); } } }
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"); } } }
public void AddDeliveryTag(R.IModel channel, ulong deliveryTag) { if (_deliveryTags.TryGetValue(channel, out var tags)) { tags.Add(deliveryTag); } }
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); } }
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); } }
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; } }
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); }
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); } }
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); } }
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); } }
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)); }
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; }
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"); } }