1
votes

Please let me know if we can configure int-jms:outbound-channel-adapter to return a value to the caller (can be a dummy value). I have header enricher, which internally calls the jms outbound adapter to send a message to active mq. I am able to send the message to MQ but since there is no return from jms adapter, the steps after header enricher is not getting executed. Below is my configuration

    <int:header-enricher input-channel="inputMessageChannel"  output-channel="messagePublishChannel">
        <int:header name="message_success" expression="@gateway.exchange(#root).payload" />
 </int:header-enricher>



  <int:header-value-router  input-channel="messagePublishChannel" header-name="mqstatus">
        <int:mapping value="success" channel="responseCreatorChannel" />
        <int:mapping value="failure" channel="errorChannel" />
  </int:header-value-router>

<int:gateway id="gateway" default-request-channel="getQdetails" />
<int:chain input-channel="getQdetails">
    <int:service-activator  ref="rdrBusinessRulesValidationService" method="transform" />
    <int-xml:marshalling-transformer marshaller="marshaller" result-transformer="messageResultTransformer">
    </int-xml:marshalling-transformer>
     <int:header-value-router header-name="region">
        <int:mapping value="USA" channel="region1Channel" />
        <int:mapping value="PRI" channel="region2Channel" />
     </int:header-value-router>
</int:chain>

<int-jms:outbound-channel-adapter channel="region1Channel" connection-factory="activeMqconnectionFactory"  destination="region1Destination">
    <int-jms:request-handler-advice-chain>
        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="@service.setSuccess(#root)" />
            <property name="onFailureExpression" value="@service.setFailure(#root)" />
        </bean>

    </int-jms:request-handler-advice-chain> 

</int-jms:outbound-channel-adapter>
1

1 Answers

0
votes

You don't need to return anything from any Outbound Channel Adapter. They fully aren't intended for such a behavior.

You just need to configure PublishSubscribeChannel as an output-channel for your Header Enricher and make two subscribers for that. The first one is still your JMS Outbound Channel Adapter. Another one that which you would like to perform after sending JMS message.

Note: the same message will be send to both subscribers.

UPDATE

OK. Thank you for sharing the config. Now I see your point.

Your use-case is to enrich a message with the header as a result of the <gateway> invocation. But since the <int-jms:outbound-channel-adapter> is one-way component you don't receive from there any reply.

I'm not sure what you are going to represent as a message_success header, but I see that you can make getQdetails as a <publish-subscribe-channel> and add the second subscriber (alongside with that <chain>) as:

<bridge input-channel="getQdetails" order="2"/>

And the same message as an input for the top-level header-enricher will be sent you back to the message_success header.

UPDATE2

According to your requirements with the true/false value for the top-level header I can suggest something like this instead of publish-subscriber-channel:

<int-jms:outbound-channel-adapter channel="region1Channel" connection-factory="activeMqconnectionFactory"  destination="region1Destination">
    <int-jms:request-handler-advice-chain>
        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="T(Boolean).TRUE" />
            <property name="onFailureExpression" value="T(Boolean).FALSE" />
            <property name="successChannel" ref="toReplySuccess" />
            <property name="failureChannel" ref="toReplyFailure" />
            <property name="trapException" ref="true" />
        </bean>
    </int-jms:request-handler-advice-chain> 
</int-jms:outbound-channel-adapter>

<chain input-channel="toReplySuccess">
    <transformer 
       expression="T(org.springframework.messaging.support.MessageBuilder).createMessage(payload, inputMessage.headers)" />
    <bridge />
</chain>


<chain input-channel="toReplyFailure">
    <transformer 
       expression="T(org.springframework.messaging.support.MessageBuilder).createMessage(payload.evaluationResult, payload.failedMessage.headers)" />
    <bridge />
</chain>

So, what I do here:

  1. Instead of your service to enrich header in the ExpressionEvaluatingRequestHandlerAdvice I simply return boolean according the success/failure state.

  2. In success case the ExpressionEvaluatingRequestHandlerAdvice sends an AdviceMessage without the copy of requestMessage headers.

  3. So, that smart <chain input-channel="toReplySuccess"> tries to restore requestMessage headers to get access to the standard replyChannel mechanism.

  4. We build here a new message with the Boolean.TRUE payload and headers from that inputMessage property of the incoming AdviceMessage.

  5. We use here further a <bridge> to really send reply to your top-level header-enricher

  6. For the toReplyFailure we have similar "smart" <chain> but with a bit different transformer, just because on failure the ExpressionEvaluatingRequestHandlerAdvice sends an ErrorMessage with the MessageHandlingExpressionEvaluatingAdviceException as a payload, where we can find our requestMessage with desired replyChannel header in the failedMessage property of the exception.

Hope that is clear.

UPDATE3

<int:header-enricher input-channel="inputMessageChannel"  output-channel="messagePublishChannel">
        <int:header name="message_success" expression="@gateway.exchange(#root).payload" />
    </int:header-enricher>



    <int:header-value-router  input-channel="messagePublishChannel" header-name="mqstatus">
        <int:mapping value="success" channel="responseCreatorChannel" />
        <int:mapping value="failure" channel="errorChannel" />
    </int:header-value-router>

    <int:gateway id="gateway" default-request-channel="getQdetails" />
    <int:chain input-channel="getQdetails">
        <int:service-activator  ref="rdrBusinessRulesValidationService" method="transform" />
        <int-xml:marshalling-transformer marshaller="marshaller" result-transformer="messageResultTransformer">
        </int-xml:marshalling-transformer>
        <int:header-value-router header-name="region">
            <int:mapping value="USA" channel="region1Channel" />
            <int:mapping value="PRI" channel="region2Channel" />
        </int:header-value-router>
    </int:chain>

    <int-jms:outbound-channel-adapter channel="region1Channel" connection-factory="activeMqconnectionFactory"  destination="region1Destination">
        <int-jms:request-handler-advice-chain>
            <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                <property name="onSuccessExpression" value="T(Boolean).TRUE" />
                <property name="onFailureExpression" value="T(Boolean).FALSE" />
                <property name="successChannel" ref="toReplySuccess" />
                <property name="failureChannel" ref="toReplyFailure" />
                <property name="trapException" ref="true" />
            </bean>
        </int-jms:request-handler-advice-chain>
    </int-jms:outbound-channel-adapter>

        <int:transformer input-channel="toReplySuccess" output-channel="toReplyChannel"
                expression="T(org.springframework.messaging.support.MessageBuilder)
                .createMessage(payload, inputMessage.headers)" />



    <int:transformer input-channel="toReplyFailure"
                expression="T(org.springframework.messaging.support.MessageBuilder)
                .createMessage(payload.evaluationResult, payload.failedMessage.headers)" />

    <int:bridge input-channel="toReplyChannel"/>