William Hill
William Hill

Reputation: 186

How is Request/Reply best implemented using JMS and Spring Integration (2.2)

I have a simple request reply test implemented using the following configuration:

<int:gateway id="myGateway"
    service-interface="TestGateway" 
    default-request-channel="sendingChannel"
    default-reply-channel="replyChannel"
    default-reply-timeout="2000"
    />

<int:channel id="sendingChannel" />
<int:channel id="replyChannel" />

<int-jms:outbound-gateway id="myJmsGateway"
    connection-factory="jmsConnectionFactory"
    request-channel="sendingChannel"
    request-destination-name="outQueue"
    reply-channel="replyChannel"
    reply-destination-name="outQueueReply"
    receive-timeout="60000"
    />

and the Interface:

public interface TestGateway {
    @Gateway
    public String requestReply(@Header("myHeaderKey") String headerValue, String data);
}

While the above configuration does "work" I have the following reservations.

  1. The configuration feels redundant. Extra gateway and two extra channels required. Both gateways implement a reply timeout (although the int:gateway timeout doesn't fire when connected to a int-jms:outbound-gateway).

  2. The semantics of the gateway method change depending on what is implementing the request/reply. On Timeout the int-jms:outbound-gateway will throw an exception, which will propagate to the user of TestGateway. If the config is changed to replace int-jms:outbound-gateway the int:gateway will return null.

Given this the client code has to both handle null and the exception in the same way.

Are there any better ways to wire up the gateways? One option would be to change the int:channel's to PollableChannel's which solves problem 2 at the expense of an extra thread pool.

Upvotes: 1

Views: 3423

Answers (1)

Gary Russell
Gary Russell

Reputation: 174494

  1. You don't need to configure reply channels; by default the jms gateway (with no reply channel) will return the message to the inbound gateway automatically.
  2. When using direct channels, the messaging gateway's timeout only starts when the thread tries to receive any reply that was returned from the flow.

You can avoid the different semantics (null Vs exception) by adding an error-channel to the inbound gateway.

It's important to understand that myGateway isolates your client from the messaging system, you code to the interface only. Of course you could inject the JMS gateway directly but then you've added dependencies to your code. With a messaging gateway, you can change technologies without making any changes to your client code. You can also unit test your code by providing a test implementation of TestGateway. This is a powerful feature of Spring Integration.

Upvotes: 2

Related Questions