Exemplo n.º 1
0
        private async Task Dispatch <TBusEvent>(TBusEvent busEvent, NimbusMessage nimbusMessage, Type handlerType) where TBusEvent : IBusEvent
        {
            var subscriptionFilter = _filterConditionProvider.GetFilterConditionFor(handlerType);

            if (!nimbusMessage.MatchesFilter(subscriptionFilter))
            {
                _logger.Debug("Message {MessageId} does not match the subscription filter for {HandlerType}. Dropping it immediately.", nimbusMessage.MessageId, handlerType);
                return;
            }

            using (var scope = _dependencyResolver.CreateChildScope())
            {
                var handler = CreateHandlerFromScope(scope, busEvent, handlerType, nimbusMessage);

                var interceptors = _inboundInterceptorFactory.CreateInterceptors(scope, handler, busEvent, nimbusMessage);

                Exception exception;
                try
                {
                    foreach (var interceptor in interceptors)
                    {
                        _logger.Debug("Executing OnEventHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);

                        await interceptor.OnEventHandlerExecuting(busEvent, nimbusMessage);

                        _logger.Debug("Executed OnEventHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                    }

                    await DispatchToHandleMethod(busEvent, handler);

                    foreach (var interceptor in interceptors.Reverse())
                    {
                        _logger.Debug("Executing OnEventHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);

                        await interceptor.OnEventHandlerSuccess(busEvent, nimbusMessage);

                        _logger.Debug("Executed OnEventHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                    }
                    return;
                }
                catch (Exception exc)
                {
                    exception = exc;
                }

                foreach (var interceptor in interceptors.Reverse())
                {
                    _logger.Debug("Executing OnEventHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                  interceptor.GetType().FullName,
                                  nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                  nimbusMessage.MessageId,
                                  nimbusMessage.CorrelationId);

                    await interceptor.OnEventHandlerError(busEvent, nimbusMessage, exception);

                    _logger.Debug("Executed OnEventHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                  interceptor.GetType().FullName,
                                  nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                  nimbusMessage.MessageId,
                                  nimbusMessage.CorrelationId);
                }

                _logger.Debug("Failed to dispatch EventMessage for message [MessageType:{0}, MessageId:{1}, CorrelationId:{2}]",
                              nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                              nimbusMessage.MessageId,
                              nimbusMessage.CorrelationId);
                throw new DispatchFailedException("Failed to dispatch EventMessage", exception);
            }
        }
        // ReSharper disable UnusedMember.Local
        private async Task Dispatch <TBusRequest, TBusResponse>(TBusRequest busRequest, NimbusMessage nimbusMessage, Type handlerType)
            where TBusRequest : IBusMulticastRequest <TBusRequest, TBusResponse>
            where TBusResponse : IBusMulticastResponse
        {
            var subscriptionFilter = _filterConditionProvider.GetFilterConditionFor(handlerType);

            if (!nimbusMessage.MatchesFilter(subscriptionFilter))
            {
                _logger.Debug("Message {MessageId} does not match the subscription filter for {HandlerType}. Dropping it immediately.", nimbusMessage.MessageId, handlerType);
                return;
            }

            var replyQueueName   = nimbusMessage.From;
            var replyQueueClient = _transport.GetQueueSender(replyQueueName);

            Exception exception = null;

            using (var scope = _dependencyResolver.CreateChildScope())
            {
                var handler = (IHandleMulticastRequest <TBusRequest, TBusResponse>)scope.Resolve(handlerType);
                _propertyInjector.Inject(handler, nimbusMessage);
                var inboundInterceptors = _inboundInterceptorFactory.CreateInterceptors(scope, handler, busRequest, nimbusMessage);

                foreach (var interceptor in inboundInterceptors)
                {
                    _logger.Debug("Executing OnRequestHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                  interceptor.GetType().FullName,
                                  nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                  nimbusMessage.MessageId,
                                  nimbusMessage.CorrelationId);
                    await interceptor.OnMulticastRequestHandlerExecuting(busRequest, nimbusMessage);

                    _logger.Debug("Executed OnRequestHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                  interceptor.GetType().FullName,
                                  nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                  nimbusMessage.MessageId,
                                  nimbusMessage.CorrelationId);
                }

                try
                {
                    var response = await handler.Handle(busRequest);

                    if (response != null)
                    {
                        var responseMessage = await _nimbusMessageFactory.CreateSuccessfulResponse(replyQueueName, response, nimbusMessage);

                        DispatchLoggingContext.NimbusMessage = responseMessage;

                        var outboundInterceptors = _outboundInterceptorFactory.CreateInterceptors(scope, nimbusMessage);
                        _logger.Debug("Sending successful response message {0} to {1} [MessageId:{2}, CorrelationId:{3}]",
                                      responseMessage.SafelyGetBodyTypeNameOrDefault(),
                                      replyQueueName,
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                        foreach (var interceptor in outboundInterceptors)
                        {
                            await interceptor.OnMulticastResponseSending(response, nimbusMessage);
                        }

                        await replyQueueClient.Send(responseMessage);

                        foreach (var interceptor in outboundInterceptors.Reverse())
                        {
                            await interceptor.OnMulticastResponseSent(response, nimbusMessage);
                        }

                        _logger.Debug("Sent successful response message {0} to {1} [MessageId:{2}, CorrelationId:{3}]",
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      replyQueueName,
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                    }
                    else
                    {
                        _logger.Debug("Handler declined to reply. [MessageId: {0}, CorrelationId: {1}]", nimbusMessage.MessageId, nimbusMessage.CorrelationId);
                    }
                }
                catch (Exception exc)
                {
                    // Capture any exception so we can send a failed response outside the catch block
                    exception = exc;
                }
                if (exception == null)
                {
                    foreach (var interceptor in inboundInterceptors.Reverse())
                    {
                        _logger.Debug("Executing OnRequestHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);

                        await interceptor.OnMulticastRequestHandlerSuccess(busRequest, nimbusMessage);

                        _logger.Debug("Executed OnRequestHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                    }
                }
                else
                {
                    foreach (var interceptor in inboundInterceptors.Reverse())
                    {
                        _logger.Debug("Executing OnRequestHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);

                        await interceptor.OnMulticastRequestHandlerError(busRequest, nimbusMessage, exception);

                        _logger.Debug("Executed OnRequestHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]",
                                      interceptor.GetType().FullName,
                                      nimbusMessage.SafelyGetBodyTypeNameOrDefault(),
                                      nimbusMessage.MessageId,
                                      nimbusMessage.CorrelationId);
                    }

                    var failedResponseMessage =
                        await _nimbusMessageFactory.CreateFailedResponse(replyQueueName, nimbusMessage, exception);

                    _logger.Warn("Sending failed response message to {0} [MessageId:{1}, CorrelationId:{2}]",
                                 replyQueueName,
                                 exception.Message,
                                 nimbusMessage.MessageId,
                                 nimbusMessage.CorrelationId);
                    await replyQueueClient.Send(failedResponseMessage);

                    _logger.Debug("Sent failed response message to {0} [MessageId:{1}, CorrelationId:{2}]",
                                  replyQueueName,
                                  nimbusMessage.MessageId,
                                  nimbusMessage.CorrelationId);
                }
            }
        }