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); } }
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); }