public async Task <object> InvokeDispatcherAsync(MessageDispatchInfo dispatcher, IMessage message, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(dispatcher, nameof(dispatcher)); Check.NotNull(message, nameof(message)); if (!message.GetType().CanAssignTo(dispatcher.MessageType)) { throw new ContainerException( $"The message event type: {message.GetType()} being dispatched does not match or " + $"derived from the dispatch information type of: {dispatcher.MessageType}."); } // Invoke the message consumers in a new lifetime scope. This is for the case where a message // is received outside of the normal lifetime scope such as the one associated with the current // web request. using (var scope = AppContainer.Instance.Services.BeginLifetimeScope()) { try { // Resolve the component and call the message handler. var consumer = (IMessageConsumer)scope.Resolve(dispatcher.ConsumerType); return(await dispatcher.Dispatch(message, consumer, cancellationToken)); } catch (Exception ex) { Context.Logger.LogError(MessagingLogEvents.MESSAGING_EXCEPTION, "Message Dispatch Error Details.", ex); throw; } } }
private void RpcConsumerReplyReceived(BasicDeliverEventArgs deliveryEvent) { ValidateRpcReply(deliveryEvent); // Determine the command type based on the type name stored in basic properties. NOTE: a command type name is // just a value used to identify the type used to determine the C# class type on the receiving end corresponding // to the type on the caller's end. They may or may not be the same physical C# type. string typeName = deliveryEvent.BasicProperties.Type; Type commandType = _brokerState.RpcTypes[typeName]; // Dispatch the message the handler to obtain the result. MessageDispatchInfo dispatcher = _messagingModule.GetInProcessCommandDispatcher(commandType); IMessage message = _serializationMgr.Deserialize(commandType, deliveryEvent); object result = null; try { result = _messagingModule.InvokeDispatcherAsync(dispatcher, message).Result; // Publish the reply back to the publisher that made the request on the // queue specified by them in the message header on a new channel. PublishConsumerReply(result, deliveryEvent.BasicProperties); } catch (AggregateException ex) { PublishConsumerExceptionReply(ex.InnerException, deliveryEvent.BasicProperties); } catch (Exception ex) { PublishConsumerExceptionReply(ex, deliveryEvent.BasicProperties); } }
public MessageQueueSubscriber(string hostId, MessageDispatchInfo dispatchInfo) { if (string.IsNullOrWhiteSpace(hostId)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(hostId)); } if (dispatchInfo == null) { throw new ArgumentNullException(nameof(dispatchInfo)); } _hostId = hostId; // Obtain the subscriber attribute so the definition metadata // can be retrieved. var queueAttribute = dispatchInfo.MessageHandlerMethod .GetCustomAttribute <SubscriberQueueAttribute>(); DispatchInfo = dispatchInfo; QueueMeta = queueAttribute.QueueFactory.CreateQueueMeta(queueAttribute); QueueMeta.QueueFactory = queueAttribute.QueueFactory; ApplyScopedQueueName(QueueMeta); }
// Any dispatch corresponding to a method decorated with a // ChannelSubscriptionAttribute attribute will be bound to a channel. public static bool IsSubscriber(MessageDispatchInfo dispatchInfo) { if (dispatchInfo == null) { throw new ArgumentNullException(nameof(dispatchInfo)); } return(dispatchInfo.MessageHandlerMethod.HasAttribute <ChannelSubscriptionAttribute>()); }
// Any dispatch corresponding to a method decorated with a derived // HostItem attribute will be bound as a receiver. public static bool IsSubscriber(MessageDispatchInfo dispatchInfo) { if (dispatchInfo == null) { throw new ArgumentNullException(nameof(dispatchInfo)); } return (dispatchInfo.MessageHandlerMethod.HasAttribute <HostItemAttribute>() && dispatchInfo.ConsumerType.HasAttribute <HostAttribute>()); }
private void LogMessageReceiveEx(Exception ex, IMessage message, MessageDispatchInfo dispatchInfo) { var logger = LoggerFactory.CreateLogger <SubscriberLinkerBase>(); logger.LogError(ex, "Error handling received message of type: {MessageType} when calling " + "the consumer: {Consumer} with handler: {Handler}.", message.GetType(), dispatchInfo.ConsumerType, dispatchInfo.MessageHandlerMethod.Name); }
/// <summary> /// Dispatch Exception. /// </summary> /// <param name="message">Dispatch error message.</param> /// <param name="dispatchInfo">Describes how the message is to be dispatched when published.</param> /// <param name="innerException">The source exception. If the exception is derived from /// NetFusionException, the detail will be added to this exception's details.</param> public MessageDispatchException(string message, MessageDispatchInfo dispatchInfo, Exception innerException) : base(message, innerException) { Check.NotNull(dispatchInfo, nameof(dispatchInfo)); Details["DispatchInfo"] = new { MessageType = dispatchInfo.MessageType.FullName, ConsumerType = dispatchInfo.ConsumerType.FullName, HandlerMethod = dispatchInfo.MessageHandlerMethod.Name }; }
/// <summary> /// Dispatch Exception. /// </summary> /// <param name="message">Dispatch error message.</param> /// <param name="dispatchInfo">Describes how the message is to be dispatched when published.</param> /// <param name="innerException">The source exception. If the exception is derived from /// NetFusionException, the detail will be added to this exception's details.</param> public MessageDispatchException(string message, MessageDispatchInfo dispatchInfo, Exception innerException) : base(message, innerException) { if (dispatchInfo == null) { throw new ArgumentNullException(nameof(dispatchInfo)); } Details["DispatchInfo"] = new { MessageType = dispatchInfo.MessageType.FullName, ConsumerType = dispatchInfo.ConsumerType.FullName, HandlerMethod = dispatchInfo.MessageHandlerMethod.Name }; }
public MessageChannelSubscriber(MessageDispatchInfo dispatchInfo) { if (dispatchInfo == null) { throw new ArgumentNullException(nameof(dispatchInfo)); } // Obtain the subscriber attribute so the metadata // can be retrieved. var channelAttrib = dispatchInfo.MessageHandlerMethod .GetCustomAttribute <ChannelSubscriptionAttribute>(); DispatchInfo = dispatchInfo; DatabaseName = channelAttrib.DatabaseName; Channel = channelAttrib.Channel; }
private void LogReceivedExchangeMessage(IMessage message, MessageConsumer messageConsumer) { MessageDispatchInfo dispatchInfo = messageConsumer.DispatchInfo; _logger.LogTraceDetails(RabbitMqLogEvents.MESSAGE_CONSUMER, "Exchange Message Received", new { messageConsumer.BrokerName, messageConsumer.ExchangeName, messageConsumer.RouteKeys, dispatchInfo.ConsumerType, dispatchInfo.MessageType, MethodName = dispatchInfo.MessageHandlerMethod.Name, Message = message }); }
public MessageConsumer( BrokerAttribute brokerAttrib, QueueConsumerAttribute queueAttrib, MessageDispatchInfo dispatchInfo) { Check.NotNull(brokerAttrib, nameof(brokerAttrib)); Check.NotNull(queueAttrib, nameof(queueAttrib)); Check.NotNull(dispatchInfo, nameof(dispatchInfo)); _brokerAttrib = brokerAttrib; _queueAttrib = queueAttrib; _queueName = _queueAttrib.QueueName; _routeKeys = _queueAttrib.RouteKeys ?? new string[] { }; MessageHandlers = new List <MessageHandler>(); DispatchInfo = dispatchInfo; }
public async Task <object> InvokeDispatcherInNewLifetimeScopeAsync(MessageDispatchInfo dispatcher, IMessage message, CancellationToken cancellationToken = default) { if (dispatcher == null) { throw new ArgumentNullException(nameof(dispatcher)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (cancellationToken == null) { throw new ArgumentNullException(nameof(cancellationToken)); } if (!message.GetType().CanAssignTo(dispatcher.MessageType)) { throw new ContainerException( $"The message event type: {message.GetType()} being dispatched does not match or " + $"derive from the dispatch information type of: {dispatcher.MessageType}."); } // Invoke the message consumers in a new lifetime scope. This is for the case where a message // is received outside of the normal lifetime scope such as the one associated with the current // web request. using (var scope = CompositeApp.Instance.CreateServiceScope()) { try { // Resolve the component and call the message handler. var consumer = (IMessageConsumer)scope.ServiceProvider.GetRequiredService(dispatcher.ConsumerType); return(await dispatcher.Dispatch(message, consumer, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) { Context.Logger.LogError(MessagingLogEvents.MessagingException, ex, "Message Dispatch Error Details."); throw; } } }
// When a RPC style command message is received, it is dispatched to the in-process handler having the // matching queue name and action-namespace. This is unlike the other message patterns where a queue // is associated directly with only a single handler. This allows for several RPC style commands to // use the same queue. This allows for more efficient use of queues. public async Task OnMessageReceivedAsync(ConsumeContext context) { MessageDispatchInfo rpcCommandHandler = GetDispatchInfoForRpcCommand(context); var message = context.DeserializeIntoMessage(rpcCommandHandler.MessageType); context.LogReceivedMessage(message); try { object response = await context.MessagingModule.InvokeDispatcherInNewLifetimeScopeAsync( rpcCommandHandler, message).ConfigureAwait(false); await ReplyWithResponse(context, response); } catch (AggregateException ex) { await ReplyWithException(context, ex.InnerException); } catch (Exception ex) { await ReplyWithException(context, ex); } }
// The criteria that determines if a given consumer message handler method // is bound to a queue. private bool IsQueueConsumer(MessageDispatchInfo dispatchInfo) { return(dispatchInfo.ConsumerType.HasAttribute <BrokerAttribute>() && dispatchInfo.MessageHandlerMethod.HasAttribute <QueueConsumerAttribute>()); }
// Lookup the dispatch rules specified on the message consumer handler and // store a reference to the associated rule object. private void SetDispatchRule(MessageDispatchInfo dispatchInfo) { dispatchInfo.DispatchRules = DispatchRules .Where(r => dispatchInfo.DispatchRuleTypes.Contains(r.GetType())) .ToArray(); }
public HostItemSubscriber(MessageDispatchInfo dispatchInfo) { DispatchInfo = dispatchInfo ?? throw new ArgumentNullException(nameof(dispatchInfo)); HostAttribute = dispatchInfo.ConsumerType.GetAttribute <HostAttribute>(); HostItemAttribute = dispatchInfo.MessageHandlerMethod.GetAttribute <HostItemAttribute>(); }