Spring Integration - 使用JMS和网关的请求/回复消息传递

时间:2013-12-19 16:04:01

标签: spring jboss jms spring-integration spring-jms

我使用SpringIntegration 2.2.1时遇到问题:我想使用JMS(WMQ作为代理)在两个不同系统之间交换消息,在JBoss AS 7中实现请求/回复模式(作为同步消息传递)。


我的xml配置文件包含:

1)出站配置:

<bean id="BOHAdjustmentConverter" class="com.test.interoperabilitytracking.internal.BOHAdjustmentConverter" />

<si:publish-subscribe-channel id="outboundBOHAdjustmentChannel" task-executor="integrationTaskExecutor" />
<si:publish-subscribe-channel id="outboundBOHAdjustmentErrorChannel" task-executor="integrationTaskExecutor" />

<si:gateway id="outboundAspectGateway" service-interface="com.test.interoperabilityframework.service.RequestGateway"
    default-request-channel="outboundBOHAdjustmentChannel" 
    default-reply-channel="outboundBOHAdjustmentReplyChannelEnriched" 
    error-channel="interoperabilityError"
    default-reply-timeout="20000" />

<!-- INTEROPERABILITY FRAMEWORK GATEWAY -->
<bean id="outboundBOHAdjustmentAspectBean" class="com.test.interoperabilityframework.service.impl.OutboundAspect">
    <property name="requestGateway" ref="outboundAspectGateway" />
    <property name="outboundEnrichedErrorChannel" ref="interoperabilityError" />
    <property name="defaultChannelTimeout" value="1000" />
</bean>

<aop:config>
    <aop:aspect id="outboundBOHAdjustmentAspect" ref="outboundBOHAdjustmentAspectBean">
        <aop:pointcut id="theExecutionOfCreateUpdateBOHAdjustmentMethod"
            expression="execution(* com.test.interoperabilitytracking.internal.*AdjustmentBOHOutboundImpl.notifyCreateBOHAdjustment(..))" />
        <aop:around pointcut-ref="theExecutionOfCreateUpdateBOHAdjustmentMethod" method="sendReceiveAndReturnWithGateway" />
        <aop:after-throwing pointcut-ref="theExecutionOfCreateUpdateBOHAdjustmentMethod" throwing="error" method="handleError" />
    </aop:aspect>
</aop:config>

<si:header-enricher input-channel="outboundBOHAdjustmentChannel" output-channel="outboundBOHAdjustmentChannelEnriched">
    <si:header name="direction" value="outbound" />
    <si:header name="directionType" value="request" />
    <si:header name="entityName" value="BOHAdjustment" />
    <si:header name="entityFQN" value="createupdatebohadjustment.api.interoperabilitysample.tsf.BOHAdjustment" />
    <si:header name="domainName" value="Inventory" />
    <si:header name="apiID" value="BOHAdjustment.C.O.R" />
    <si:header name="apiVersion" value="1.0" />
    <si:header name="operationName" value="createBOHAdjustment" />
    <si:header name="sourceApplication" value="VPS" />
    <si:header name="targetApplication" value="HOST" />
    <si:error-channel ref="interoperabilityError" />
</si:header-enricher>

<si:header-enricher input-channel="outboundBOHAdjustmentErrorChannel" output-channel="interoperabilityError">
    <si:header name="direction" value="outbound" />
    <si:header name="directionType" value="request" overwrite="true" />
    <si:header name="entityName" value="BOHAdjustment" />
    <si:header name="domainName" value="Inventory" />
    <si:header name="apiID" value="BOHAdjustment.C.O.R" />
    <si:header name="apiVersion" value="1.0" />
    <si:header name="operationName" value="createBOHAdjustment" />
    <si:header name="sourceApplication" value="VPS" />
    <si:header name="targetApplication" value="HOST" />
    <si:error-channel ref="interoperabilityError" />
</si:header-enricher>

<si:channel id="outboundBOHAdjustmentChannelMapMessage">
    <si:interceptors>
        <si:wire-tap channel="interoperabilityResult" /> <!-- TODO this is a temporary solution because if the adapter fails to sent the message we don't trace it -->
    </si:interceptors>
</si:channel>

<si:chain input-channel="outboundBOHAdjustmentChannelEnriched" output-channel="outboundBOHAdjustmentChannelMapMessage">
    <si:transformer ref="dozerMapper" method="convert" />
    <si:service-activator ref="mapMessageBuilderCreateupdatebohadjustmentOutbound" />
</si:chain>

<!-- ***** reply channel used by outbound gateway ***** -->
<si:channel id="outboundBOHAdjustmentReplyChannelEnriched">
    <si:interceptors>
        <si:wire-tap channel="interoperabilityResult" />
    </si:interceptors>
</si:channel>

<si:channel id="requestResponseReplyChannel" />

<si-jms:outbound-gateway id="requestReplyOutboundGateway" 
    request-channel="outboundBOHAdjustmentChannelMapMessage"
    connection-factory="leoEcoSystemConnectionFactory" 
    reply-channel="requestResponseReplyChannel" 
    request-destination-name="outboundBOHAdjustmentRequestDestination"
    reply-destination-name="outboundBOHAdjustmentReplyDestination"
    extract-reply-payload="true"
    extract-request-payload="true"
    correlation-key="JMSCorrelationID" receive-timeout="10000">
</si-jms:outbound-gateway>

<!-- outbound reply header enricher -->
<si:header-enricher input-channel="requestResponseReplyChannel" output-channel="outboundBOHAdjustmentReplyChannelEnriched">
    <si:header name="direction" value="outbound" />
    <si:header name="directionType" value="reply" overwrite="true" />
    <si:header name="entityName" value="BOHAdjustment" />
    <si:header name="domainName" value="Inventory" />
    <si:header name="apiID" value="BOHAdjustment.C.O.R" />
    <si:header name="apiVersion" value="1.0" />
    <si:header name="operationName" value="createBOHAdjustment" />
    <si:header name="sourceApplication" value="VPS" />
    <si:header name="targetApplication" value="HOST" />
    <si:error-channel ref="interoperabilityError" />
</si:header-enricher>


<bean id="channelBridgeHandlerBOHAdjustment.C.O.R" class="com.test.interoperabilityframework.service.impl.ChannelBridgeHandler">
    <property name="channel" ref="outboundBOHAdjustmentChannel" />
</bean>

2)我的入站配置文件包含:

<bean id="inboundBOHAdjustmentContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="leoEcoSystemConnectionFactory" />
    <property name="destination" ref="outboundBOHAdjustmentDestination" />
    <property name="concurrency" value="3-7" />
    <property name="errorHandler" ref="interoperabilityErrorHandler" />
</bean>

<si:header-enricher input-channel="inboundBOHAdjustmentChannel" output-channel="inboundBOHAdjustmentChannelEnriched">
    <si:header name="boundPayload" expression="payload" overwrite="true" />
    <si:header name="direction" value="inbound" overwrite="true" />
    <si:header name="directionType" value="request" overwrite="true" />
    <si:header name="entityName" value="BOHAdjustment" overwrite="true" />
    <si:header name="entityFQN" value="com.test.interoperabilitytracking.internal.BOHAdjustementVO" overwrite="true" />
    <si:header name="domainName" value="Automat" overwrite="true" />
    <si:header name="entity" overwrite="true" expression="payload.get('BOHAdjustment')" />
    <si:header name="serviceContext" overwrite="true" expression="payload.get('ServiceContext')" />
    <si:header name="operationName" value="createUpdateBOHAdjustment" overwrite="true" />
    <si:header name="sourceApplication" value="LEO" overwrite="true" />
    <si:header name="targetApplication" value="AA" overwrite="true" />
    <si:header name="apiID" value="BOHAdjustment.C.I.R" overwrite="true" />
    <si:header name="apiVersion" value="2.0" overwrite="false" />
    <si:error-channel ref="interoperabilityError" />
</si:header-enricher>

<si:channel id="inboundBOHAdjustmentChannel" />

<si:channel id="inboundBOHAdjustmentReplyChannel" />

<si:channel id="inboundBOHAdjustmentReplyChannelEnriched">
    <si:interceptors>
        <si:wire-tap channel="interoperabilityResult" />
    </si:interceptors>
</si:channel>

<si-jms:inbound-gateway id="inboundBOHAdjustementGateway" acknowledge="auto" 
    container="inboundBOHAdjustmentContainer"
    request-channel="inboundBOHAdjustmentChannel" 
    reply-channel="inboundBOHAdjustmentReplyChannel"
    request-destination-name="inboundBOHAdjustementRequestDestination"
    extract-reply-payload="true"
    extract-request-payload="true"
    correlation-key="JMSCorrelationID" />

<!-- inbound reply header enricher -->
<si:header-enricher input-channel="inboundBOHAdjustmentReplyChannel" output-channel="inboundBOHAdjustmentReplyChannelEnriched">
    <si:header name="direction" value="inbound" />
    <si:header name="directionType" value="reply" overwrite="true" />
    <si:header name="entityName" value="BOHAdjustment" />
    <si:header name="domainName" value="Inventory" />
    <si:header name="apiID" value="BOHAdjustment.C.O.R" />
    <si:header name="apiVersion" value="1.0" />
    <si:header name="operationName" value="createBOHAdjustment" />
    <si:header name="sourceApplication" value="VPS" />
    <si:header name="targetApplication" value="HOST" />
    <si:error-channel ref="interoperabilityError" />
</si:header-enricher>

<si:channel id="inboundBOHAdjustmentChannelEnsureTracking">
    <si:interceptors>
        <si:wire-tap channel="interoperabilityResult" />
    </si:interceptors>
</si:channel>

<si:chain input-channel="inboundBOHAdjustmentChannelEnriched" output-channel="inboundBOHAdjustmentChannelEnsureTracking">
    <si:service-activator ref="payloadHandler" method="getEntity" />
    <si:transformer ref="jaxbProviderInbound" method="unmarshal" />
    <si:transformer ref="dozerMapper" method="convert" />
    <si:service-activator ref="integrationLoginUtil" />
</si:chain>

<si:service-activator input-channel="inboundBOHAdjustmentChannelEnsureTracking" output-channel="interoperabilityResult" ref="service"
    method="createUpdateBOHAdjustment" />

3)我省略了一些其他的bean,比如converter和jaxb provider。 connectionFactory是配置到JBoss AS 7 standalone.xml的队列上的JNDI名称,这是由WMQ实现的JMS ConnectionFactory的实例。

4)我有其他配置文件和其他类来执行跟踪。

我想知道:

  • 调用服务时,启动方面,网关发送消息并等待响应;
  • 在频道上有一个henricher和一些其他服务激活器。此时,我会在数据库上保留一条记录来跟踪direction =“出站”和directionType =“请求”;
  • 消息到达队列;
  • 另一个系统上的入站网关,对消息进行解除队列并将消息应用于其逻辑。在这个频道上有标题增强。在这里,我将跟踪direction =“入站”和directionType =“请求”;
  • 将回复消息(也是相同的消息)发送到另一个带有标题扩展器的通道。此时我想坚持direction =“入站”和directionType =“回复”;
  • 回复邮件到达出站网关。在这个频道上我有另一个标题增加,我会坚持direction =“出站”和directionType =“回复”;

问题 问题是答复在入站时不起作用也不在ountbound中。 Spring Integration文档解释说,要执行此方案,出站和入站都必须是请求/回复,并建议将outbount-gatewayinbound-gateway与回复通道一起使用,因为它们是双向的。不幸的是,我不明白为什么它不能正常工作,servlet在回复时被阻止,当我尝试转换Spring消息时,我从未收到directionType的“回复”值。

0 个答案:

没有答案