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);
            }
        }
        protected void InvokeHandlerAndProcessResult(IMessage amqpMessage, RC.IModel channel, IMessage message)
        {
            _logger?.LogDebug("Processing [{message}]", message);
            InvocationResult result = null;

            try
            {
                if (Method == null)
                {
                    var accessor = RabbitHeaderAccessor.GetMutableAccessor(message);
                    accessor.TargetMethod = HandlerAdapter.GetMethodFor(message.Payload);
                }

                result = InvokeHandler(amqpMessage, channel, message);
                if (result.ReturnValue != null)
                {
                    HandleResult(result, amqpMessage, channel, message);
                }
                else
                {
                    _logger?.LogTrace("No result object given - no result to handle");
                }
            }
            catch (ListenerExecutionFailedException e)
            {
                if (ErrorHandler != null)
                {
                    try
                    {
                        var messageWithChannel = RabbitMessageBuilder.FromMessage(message).SetHeader(RabbitMessageHeaders.CHANNEL, channel).Build();
                        var errorResult        = ErrorHandler.HandleError(amqpMessage, messageWithChannel, e);
                        if (errorResult != null)
                        {
                            HandleResult(HandlerAdapter.GetInvocationResultFor(errorResult, message.Payload), amqpMessage, channel, message);
                        }
                        else
                        {
                            _logger?.LogTrace("Error handler returned no result");
                        }
                    }
                    catch (Exception ex)
                    {
                        ReturnOrThrow(amqpMessage, channel, message, ex, ex);
                    }
                }
                else
                {
                    ReturnOrThrow(amqpMessage, channel, message, e.InnerException, e);
                }
            }
        }
 protected virtual void DoHandleResult(InvocationResult resultArg, IMessage request, RC.IModel channel, object source)
 {
     _logger?.LogDebug("Listener method returned result [{result}] - generating response message for it", resultArg);
     try
     {
         var response = BuildMessage(channel, resultArg.ReturnValue, resultArg.ReturnType);
         var accessor = RabbitHeaderAccessor.GetMutableAccessor(response);
         accessor.Target       = resultArg.Instance;
         accessor.TargetMethod = resultArg.Method;
         PostProcessResponse(request, response);
         var replyTo = GetReplyToAddress(request, source, resultArg);
         SendResponse(channel, replyTo, response);
     }
     catch (Exception ex)
     {
         throw new ReplyFailureException("Failed to send reply with payload '" + resultArg + "'", ex);
     }
 }
Пример #4
0
        protected virtual Address GetReplyToAddress(IMessage request, object source, InvocationResult result)
        {
            var replyTo = request.Headers.ReplyToAddress();

            if (replyTo == null)
            {
                if (ResponseAddress == null && ResponseExchange != null)
                {
                    ResponseAddress = new Address(ResponseExchange, ResponseRoutingKey);
                }

                if (result.SendTo != null)
                {
                    replyTo = EvaluateReplyTo(request, source, result.ReturnValue, result.SendTo);
                }
                else if (request.Headers.ReplyTo() != null)
                {
                    return(new Address(request.Headers.ReplyTo()));
                }

                // TODO: When expressions work
                // else if (ResponseExpression != null)
                // {
                //    replyTo = EvaluateReplyTo(request, source, result.ReturnValue, ResponseExpression);
                // }
                else if (ResponseAddress == null)
                {
                    throw new RabbitException(
                              "Cannot determine ReplyTo message property value: " +
                              "Request message does not contain reply-to property, " +
                              "and no default response Exchange was set.");
                }
                else
                {
                    replyTo = ResponseAddress;
                }
            }

            return(replyTo);
        }
        protected virtual void HandleResult(InvocationResult resultArg, IMessage request, RC.IModel channel, object source)
        {
            if (channel != null)
            {
                if (resultArg.ReturnValue is Task)
                {
                    if (!IsManualAck)
                    {
                        _logger?.LogWarning("Container AcknowledgeMode must be MANUAL for a Future<?> return type; "
                                            + "otherwise the container will ack the message immediately");
                    }

                    var asTask = resultArg.ReturnValue as Task;
                    asTask.ContinueWith(
                        (t) =>
                    {
                        if (t.IsCompletedSuccessfully)
                        {
                            AsyncSuccess(resultArg, request, channel, source, GetReturnValue(t));
                            BasicAck(request, channel);
                        }
                        else
                        {
                            AsyncFailure(request, channel, t.Exception);
                        }
                    });
                }
                else
                {
                    DoHandleResult(resultArg, request, channel, source);
                }
            }
            else
            {
                _logger?.LogWarning("Listener method returned result [" + resultArg
                                    + "]: not generating response message for it because no Rabbit Channel given");
            }
        }
 protected virtual void HandleResult(InvocationResult resultArg, IMessage request, RC.IModel channel)
 {
     HandleResult(resultArg, request, channel, null);
 }