1
votes

Previously i was able to develop a little framework using the Spring Integration Where developers can specify the URLs, HTTP methods and Request Body and invoke any external REST API.

This is the configuration for my Spring Integration

<int:channel id='reply.channel'>
    <int:queue capacity='10' />
</int:channel>
<int:channel id='request.channel'/>

<int:channel id='outbound.Channel'/>

<int:gateway id="outboundGateway"
    service-interface="com.bst.pm.PostGateway"
    default-request-channel="outbound.Channel">
</int:gateway>

<int:object-to-json-transformer input-channel="outbound.Channel" output-channel="request.channel"/>



<int-http:outbound-gateway id="outbound.gateway"
    request-channel="request.channel" url-expression="headers.bstUrl"
    http-method-expression="headers.bstHttpMethod" expected-response-type-expression="headers.bstExpectedResponseType"
    charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel"
    mapped-request-headers="bst*, HTTP_REQUEST_HEADERS">

</int-http:outbound-gateway>

Then Developers can invoke external rest API calls using the above infrastruture as below

@Autowired @Qualifier("reply.channel") PollableChannel receivedChannel;
@Autowired @Qualifier("request.channel") MessageChannel getRequestChannel;
@Autowired @Qualifier("outbound.Channel") MessageChannel httpOutboundGateway;

    Post post = new Post();
    post.setTitle("Spring INtegration Test");
    post.setBody("This is a sample request body to test Spring Integration HTTP Outbound gateway");
    post.setUserId(Long.valueOf(1));

    Message<?> message = MessageBuilder.withPayload(post)
                        .setHeader("bstUrl", "https://jsonplaceholder.typicode.com/posts")
                        .setHeader("bstHttpMethod", "POST")
                        .setHeader("bstExpectedResponseType", "com.bst.pages.crm.web.Post")
                         .build();

    httpOutboundGateway.send(message);
    Message<?> receivedMsg = receivedChannel.receive();

    Post post = (Post) receivedMsg.getPayload();
    System.out.println("############## ServerMsg ##############");
    System.out.println(o);
    System.out.println("############## Done! ##############");

In here i want to make all the REST calls via this integration infrastructure to be Synchronous. However i have used a QUEUE channel as the reply-channel for the http:outbound-gateway. Therefore as per my understanding the reply can be received by a wrong sender as any one can pool the channel for the messages.

How can we make sure the the correct sender will always receive the correct response?

Thanks, Keth

1

1 Answers

2
votes

Your is correct. Really having a global reply channel and several concurrent processes you may end up with work stealing situation.

To fix your problem you need to get rid of the reply-channel on your HTTP Gateway and just rely on your the replyChannel header populated by the Messaging Gateway. However your Gateway method should really be as a request-reply signature: it has to return Object.

See more info about replyChannel header in the Reference Manual: https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#gateway