Nullpointer
Nullpointer

Reputation: 1086

Sending message to reply-channel of http-inbound-gateway

I have a below setup with spring integration.

<int-http:inbound-gateway id="restListener"
                          request-channel="restChannel"
                          reply-channel="restResponseChannel"
                          path="/service"
                          supported-methods="POST"
                          reply-timeout="5000"
</int-http:inbound-gateway>



<int:channel id="restChannel"/>
<int:channel id="restResponseChannel"/>

<int:service-activator input-channel="restChannel"
                       ref="restRequestHandler"
                       method="handleRestRequest"/>

I receive 2 different types of POST requests on gateway and both of them are passed to service-activator for processing. In one type of POST request my service-activator can immediately process it and reply back with a standard response. However, other type of request will be routed through different channels and processed by different processors (depending on the content). I want the output for processing both type of requests to be sent as response of REST call.

For first type of request I can simply do this

public void handleRestRequest(Message<JsonNode> postMessage) {
     if (type1) {
        // Do processing
        restResponseChannel.send(MessageBuilder
                .withPayload("{\"result\":\"success!\"}")
                .copyHeaders(postMessage.getHeaders())
                .build());
     } else {
        // send to another channel for further processing
     }

}

But for second type of request if I try to send my output to restResponseChannel (without headers) then I get below exception

org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available

I do not have access to original headers for second type of request. How can I send the output to reply-channel? (I read somewhere that gateway creates an anonymous channel to connect to the reply-channel and not having those headers is causing the exception, however I don't understand the underlying mechanism completely to debug this myself)

Upvotes: 1

Views: 2148

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121560

You understand that absolutely correctly.

If you don't carry request headers, there is no TemporaryReplyChannel header to correlate reply with response. See GenericMessagingTemplate.doSendAndReceive() for implementation:

TemporaryReplyChannel tempReplyChannel = new TemporaryReplyChannel(this.throwExceptionOnLateReply);
    requestMessage = MessageBuilder.fromMessage(requestMessage).setReplyChannel(tempReplyChannel)
            .setHeader(this.sendTimeoutHeader, null)
            .setHeader(this.receiveTimeoutHeader, null)
            .setErrorChannel(tempReplyChannel).build();

    try {
        doSend(channel, requestMessage, sendTimeout);
    }
    catch (RuntimeException ex) {
        tempReplyChannel.setSendFailed(true);
        throw ex;
    }

    Message<?> replyMessage = this.doReceive(tempReplyChannel, receiveTimeout);

So, if there is no that header, no possibility to accept reply. The behavior is the same like in many other messaging replyAddress patterns.

That reply-channel="restResponseChannel" is just for convenience when you don't want to consult header for the next channel or when you would like to send a reply not only to the response but to somewhere else - publish-subscribe pattern.

You don't have choice unless carry headers anyway. One case is to use Message directly, another is with the @Headers Map<String, Object> service method.

Upvotes: 2

Related Questions