2
votes

There is one request queue and the reply queues are created by the client server instances and pinned to each instance rather than using temporary queues.

The use case needs to get an inbound jms message and then send that message to an asynchronous process. Once the async reply messsage is received from the service I need to take those results and reply back to the original message's jmsReplyTo. The Jms gateway would not work in this instance AFAIK>

I am using a jms message driven channel adapter for the message in with a series of channels and service activators to handle the out of process calls and async replies. I am trying to use the DynamicDestinationResolver to no avail. Additionally I have tried to set the outbound destination address programatically but could not figure out a good way to do this.

This seems like a common pattern but I could not find a good example for a completely disconnected async request response. Disconnected meaning that the usual async jms request reply did not seem to fit the need.

Context Config:

<!-- Input from Amq -->

<amq:queue id="requestQueue" physicalName="${request.queue}" />

<int-jms:message-driven-channel-adapter id="jmsIn"
                                    connection-factory="jmsConnectionFactory"
                                    destination="requestQueue"
                                    channel="queueRequestChannel" concurrent-consumers="5" />

<int:channel id="queueRequestChannel" />

<int:service-activator input-channel="queueRequestChannel" ref="switchMessageHandler" method="processSwitchMessage"
        output-channel="cardNetworkOutChannel"/>

<!-- Output to Card Network-->
<int:channel id="cardNetworkOutChannel" />

<!--<int:service-activator input-channel="cardNetworkOutChannel" ref="cardNetworkHandler" method="send8583Message" />-->

<!-- Simply used to mock the card network by transforming a SwithMessage to a SwitchMessageResponse * Not needed for target solution -->
<int:transformer id="requestResponseTransformer" ref="nettyCardNetworkClientMock" input-channel="cardNetworkOutChannel"
                 method="process" output-channel="cardNetworkInChannel"/>

<!-- Input from Card Network -->
<int:channel id="cardNetworkInChannel" />

<int:service-activator input-channel="cardNetworkInChannel" ref="switchMessageHandler" method="sendSwitchMessage"
                       output-channel="queueReplyChannel"/>


<int:channel id="queueReplyChannel"/>

<int-jms:outbound-channel-adapter
        destination-resolver="simpleDestinationResolver" connection-factory="jmsConnectionFactory"
        channel="queueReplyChannel" destination-expression="headers.jms_replyTo" />
1
Sorry but your question is not clear at all. Please always try to be very specific... e.g. "..the gateway would not work...". Client side? or Server side? You should be able to use outbound and message-driven adapters on both sides and use destination-expression on the outbound adapters.Gary Russell
Sorry Gary - This is a server side component from an ActiveMQ standpoint. The app consumes messages from a fixed queue. It then communicates via TCP via a specific protocol and receives replies over TCP. These replies will then need to be sent back to ActiveMQ referencing the original inbound ActiveMQ message's jmsReplyTo address. At design time this server component does not know what the reply to queues will be. The clients (ActiveMQ) to this app each create a reply queue unique to the client.Cory E Adams
OK, but you need to explain exactly what your issue is.Gary Russell
The ActiveMQ clients are not receiving the response as I am guessing that the server side jms outbound channel adapter is not setting the destination.Cory E Adams

1 Answers

-1
votes

I just updated the jms sample app to make the server side use independent adapters instead of the inbound gateway and it works just fine...

<!--    <jms:inbound-gateway id="jmsin" -->
<!--                         request-destination="requestQueue" -->
<!--                         request-channel="demoChannel"/> -->

<channel id="demoChannel"/>

<jms:message-driven-channel-adapter destination="requestQueue" channel="demoChannel" />

<service-activator input-channel="demoChannel" ref="demoBean" output-channel="reply" />

<channel id="reply" />

<jms:outbound-channel-adapter channel="reply" destination-expression="headers['jms_replyTo']" />

Turn on DEBUG logging - we put out lots of useful stuff.

EDIT

I just made it async by...

<channel id="reply">
    <queue/>
</channel>

<jms:outbound-channel-adapter channel="reply" destination-expression="headers['jms_replyTo']">
    <poller fixed-delay="3000"/>
</jms:outbound-channel-adapter>

EDIT2

Depending on what you are using on the client side, many clients require the inbound message id to be used as the correlation id. (This is true for the outbound gateway by default, with named reply queue, unless you provide a correlation-key).

So, to set up the correlationId, you can use a header enricher; I just tested this...

<chain input-channel="reply">
    <header-enricher>
        <header name="jms_correlationId" expression="headers['jms_messageId']" />
    </header-enricher>
    <jms:outbound-channel-adapter destination-expression="headers['jms_replyTo']"/>
    <poller fixed-delay="1000" />
</chain>

This is not the issue if the client side is setting the correlation id header itself.