来自原始 jmsReplyTo 的 jms 动态目标

jms dynamic destination from original jmsReplyTo

只有一个请求队列,回复队列由客户端服务器实例创建并固定到每个实例,而不是使用临时队列。

用例需要获取入站 jms 消息,然后将该消息发送到异步进程。从服务接收到异步回复消息后,我需要获取这些结果并回复原始消息的 jmsReplyTo。在这种情况下 Jms 网关将不起作用 AFAIK>

我正在使用一个 jms 消息驱动的通道适配器来接收消息,并使用一系列通道和服务激活器来处理进程外调用和异步回复。我试图使用 DynamicDestinationResolver 无济于事。此外,我曾尝试以编程方式设置出站目标地址,但找不到执行此操作的好方法。

这似乎是一种常见的模式,但我找不到一个完全断开的异步请求响应的好例子。断开连接意味着通常的异步 jms 请求回复似乎不符合需要。

上下文配置:

<!-- 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" />

我刚刚更新了 jms sample app 使服务器端使用独立的适配器而不是入站网关并且它工作得很好...

<!--    <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']" />

打开 DEBUG 日志记录 - 我们提供了很多有用的东西。

编辑

我刚刚让它异步了...

<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

根据您在客户端使用的内容,许多客户端需要将入站消息 ID 用作关联 ID。 (默认情况下出站网关也是如此,命名回复 queue,除非您提供 correlation-key)。

因此,要设置 correlationId,您可以使用 header enricher;我刚刚测试了这个...

<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>

如果客户端自己设置相关 ID header,则这不是问题。