private async Task ProcessEvent(string eventName, string message)
        {
            _logger.LogTrace("Processing RabbitMQ event: {eventName}", eventName);

            var messageType = _messageHandlerManager.MessageHandlerWrappers
                              .FirstOrDefault(p => p.MessageName == eventName)
                              ?.MessageType;

            if (messageType != null)
            {
                var integrationEvent = (IMessage)JsonConvert.DeserializeObject(message, messageType);

                _logger.LogTrace("Enable diagnostic listeners before consume,name is {name}", DiagnosticListenerConstants.BeforeConsume);
                EventBusDiagnosticListener.TracingConsumeBefore(integrationEvent);

                var messageHandlers = _messageHandlerProvider.GetHandlers(messageType);
                foreach (var messageHandler in messageHandlers)
                {
                    var concreteType = typeof(IMessageHandler <>).MakeGenericType(messageType);
                    var method       = concreteType.GetMethod("HandAsync");
                    if (method == null)
                    {
                        continue;
                    }
                    try
                    {
                        await(Task) method.Invoke(messageHandler, new object[] { integrationEvent });
                    }
                    catch (Exception e)
                    {
                        var handlerType = messageHandler.GetType();
                        _logger.LogError("Message processing failure,message type is {messageType},handler type is {handlerType},error message is {errorMessage}",
                                         messageType, handlerType, e.Message);

                        _logger.LogTrace("Enable diagnostic listeners incorrect consume,name is {name}", DiagnosticListenerConstants.ErrorConsume);
                        EventBusDiagnosticListener.TracingConsumeError(integrationEvent, handlerType, e.Message);
                    }
                }

                _logger.LogTrace("Enable diagnostic listeners after consume,name is {name}", DiagnosticListenerConstants.AfterConsume);
                EventBusDiagnosticListener.TracingConsumeAfter(integrationEvent);
            }
            else
            {
                _logger.LogWarning("No subscription for RabbitMQ event: {eventName}", eventName);

                _logger.LogTrace("Not subscribed to enable diagnostic listener,name is {name}", DiagnosticListenerConstants.NotSubscribed);
                EventBusDiagnosticListener.TracingNotSubscribed(message);
            }
        }
Example #2
0
        public override async Task SendAsync <T>(T message)
        {
            var messageHandlers = _messageHandlerProvider
                                  .GetHandlers <T>()
                                  .ToList();

            if (messageHandlers.Any())
            {
                _logger.LogTrace("Enable diagnostic listeners before consume,name is {name}", DiagnosticListenerConstants.BeforeConsume);
                EventBusDiagnosticListener.TracingConsumeBefore(message);

                foreach (var messageHandler in messageHandlers)
                {
                    var concreteType = typeof(IMessageHandler <>).MakeGenericType(typeof(T));
                    var method       = concreteType.GetMethod("HandAsync");
                    if (method == null)
                    {
                        continue;
                    }
                    try
                    {
                        await(Task) method.Invoke(messageHandler, new object[] { message });
                    }
                    catch (Exception e)
                    {
                        var handlerType = messageHandler.GetType();
                        var messageType = message.GetType();
                        _logger.LogError("Message processing failure,message type is {messageType},handler type is {handlerType},error message is {errorMessage}",
                                         messageType, handlerType, e.Message);

                        _logger.LogTrace("Enable diagnostic listeners incorrect consume,name is {name}", DiagnosticListenerConstants.ErrorConsume);
                        EventBusDiagnosticListener.TracingConsumeError(message, handlerType, e.Message);
                    }
                }

                _logger.LogTrace("Enable diagnostic listeners after consume,name is {name}", DiagnosticListenerConstants.AfterConsume);
                EventBusDiagnosticListener.TracingConsumeAfter(message);
            }
            else
            {
                var messageName = MessageNameAttribute.GetNameOrDefault(message.GetType());
                _logger.LogWarning("No subscription for local memory message: {eventName}", messageName);

                _logger.LogTrace("Not subscribed to enable diagnostic listener,name is {name}", DiagnosticListenerConstants.NotSubscribed);
                EventBusDiagnosticListener.TracingNotSubscribed(message);
            }
            await Task.CompletedTask;
        }
        public override async Task SendAsync <T>(T message)
        {
            _logger.LogTrace("Enable diagnostic listeners before publishing,name is {name}", DiagnosticListenerConstants.BeforePublish);
            EventBusDiagnosticListener.TracingPublishBefore(message);

            var policy = Policy.Handle <BrokerUnreachableException>()
                         .Or <SocketException>()
                         .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(retryAttempt), (ex, time) =>
            {
                _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", message.Id, $"{time.TotalSeconds:n1}", ex.Message);
            });

            var eventName = MessageNameAttribute.GetNameOrDefault(message.GetType());
            var data      = message.ToJson();
            var body      = Encoding.UTF8.GetBytes(data).AsMemory();

            var exchangeName = _options.Value.ExchangeName;

            policy.Execute(() =>
            {
                if (!_persistentConnection.IsConnected)
                {
                    _persistentConnection.TryConnect();
                }

                using (var channel = _persistentConnection.CreateModel())
                {
                    var model = channel;
                    _logger.LogTrace("Declaring RabbitMQ exchange {ExchangeName} to publish event: {EventId}", exchangeName, message.Id);
                    model.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true, autoDelete: false,
                                          arguments: new ConcurrentDictionary <string, object>());

                    var properties          = model.CreateBasicProperties();
                    properties.DeliveryMode = 2; // persistent
                    _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", message.Id);
                    model.BasicPublish(
                        exchange: exchangeName,
                        routingKey: eventName,
                        mandatory: true,
                        basicProperties: properties,
                        body: body);
                }
            });

            _logger.LogTrace("Enable diagnostic listeners after publishing,name is {name}", DiagnosticListenerConstants.AfterPublish);
            EventBusDiagnosticListener.TracingPublishAfter(message);
            await Task.CompletedTask;
        }