I have an integration flow like this, using Spring Integration 4.3.x:
<int:gateway> => <int:transformer> => <int-http:outbound-gateway> => <int:transformer> => return to the gateway
The gateway is defined by an interface with multiple methods, some of which have a return type, some others don't. Indeed, I'm calling a REST API through the HTTP outbound gateway and some methods are returning something meaningful, others nothing (i.e.: an empty response + a status code that I just use to detect errors).
As soon as I call any gateway method with a return type, all works fine. When I call one with void return type, I get this error:
org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
I searched a lot, read SI documentation and debugged and I ended up to this: org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(MethodInvocation, boolean)
, which substantially does this: if a reply is expected, do a "sendAndReceive", otherwise do a simple "send". The former sets a replyChannel
header, the second does not.
This makes sense, but... why not simply automatically setting a NullChannel
replyChannel
header in the latter case? What I don't fully understand is whether this behaviour (i.e.: getting an exception whenever the flow produces a response that can't be translated into a gateway response) is the desired one, because I can't find any mention of it in the documentation. The docs seem to suggest that any reply is simply ignored, but it is not the case and I now need to put a transformer in the chain that sets a NullChannel
replyChannel
header whenever I detect that no actual response is going to be returned... indeed, something that I would have expected the gateway to do for me. Indeed, it seems like void methods in gateways can work "out-of-the-box" only when you have an adapter as the final flow endpoint.
Perhaps I'm missing something, so this is the reason of this question.
That's an interesting suggestion (NullChannel
in replyChannel
) header.
We'd have to think about it as to whether there might be some unintended consequences.
In the meantime, you should be able to use
@Gateway(headers = @GatewayHeader(name = MessageHeaders.REPLY_CHANNEL,
expression = "@nullChannel"))
void foo(String bar);