Search code examples
spring-integrationvoidgatewayspring-integration-http

Spring Integration Gateway with void method return type: why doesn't it set a NullChannel replyChannel automatically?


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.


Solution

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