0

We are using Spring Integration to consume messages from a queue and the requirement is to send the message to Error queue if there is any issue in the processing of the message consumed. Flow works fine but one issue we see is when there is any exception thrown in processing of message, the message is redirected to the Error queue which we have configured but it is appended by the entire stack trace of the exception. We are looking only for the original message to be delivered to the queue. Below is the configuration we have done,

<bean id="errorQ" class="com.ibm.mq.jms.MQQueue">
    <constructor-arg value="${error.queue}" />
</bean>
<bean id="inQ" class="com.ibm.mq.jms.MQQueue">
    <constructor-arg value="${inbound.queue}" />
</bean>

<int:channel id="error" />
<int:channel id="inbound" />

<int-jms:message-driven-channel-adapter
    id="jmsIn" channel="inbound" container="messageListenerContainer"
    acknowledge="transacted"></int-jms:message-driven-channel-adapter>

<int-jms:outbound-channel-adapter id="jmsError"
channel="error" connection-factory="mqConnectionFactory"
destination="errorQ" delivery-persistent="true"></int-jms:outbound-channel-adapter>


<int:service-activator id="service"
input-channel="inbound" ref="messageListener" method="someMethodInListerner">
    <int:request-handler-advice-chain>
        <ref bean="retryWithBackoffAdviceSession" />
    </int:request-handler-advice-chain>

<bean id="retryWithBackoffAdviceSession"
    class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
    <property name="retryTemplate">
        <bean class="org.springframework.retry.support.RetryTemplate">
            <property name="backOffPolicy">
                <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                    <property name="initialInterval" value="${initialInterval}" />
                    <property name="multiplier" value="${multiplier}" />
                    <property name="maxInterval" value="${maxInterval}" />
                </bean>
            </property>
            <property name="retryPolicy">
                <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                    <property name="maxAttempts" value="${redelivery}" />
                </bean>
            </property>
        </bean>
    </property>
    <property name="recoveryCallback">
        <bean
            class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
            <constructor-arg ref="error" />
        </bean>
    </property>
</bean>
Ashish
  • 85
  • 1
  • 1
  • 11

1 Answers1

1

The message sent to the error is an ErrorMessage with payload MessagingException.

The MessagingException has two properties cause and failedMessage.

So, if you want to send the original failed message to errorQ, you will need to add a transformer to the error flow...

<int:transformer ... expression="payload.failedMessage" />

EDIT

<int:chain input-channel="error">
    <int:transformer expression="payload.failedMessage" />
    <int-jms:outbound-channel-adapter ... />
</int:chain>

EDIT2

Generally, when using these techniques, it's useful to convey the reason for the failure. You can add the exception's message as a header...

<int:chain input-channel="error">
    <int:header-enricher>
        <int:header name="failureReason" expression="payload.cause.message" />
    </int:header-enricher>
    <int:transformer expression="payload.failedMessage" />
    <int-jms:outbound-channel-adapter ... />
</int:chain>
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Hi Gary, added the input channel code as well now above, so it is being handled on a flow. I do understand your comment of adding a transformer to send only original payload to Error queue but where do I need to put that in the flow ? – Ashish Aug 09 '15 at 07:54
  • I think adding a transformer passing the payload should work ? – Ashish Aug 09 '15 at 08:01
  • A transformer with `expression="payload"` does nothing at all - see my edit. – Gary Russell Aug 09 '15 at 13:32
  • Sorry - I missed that you were using a retry recover, but the transformer's the same because the recoverer also creates an `ErrorMessage`. – Gary Russell Aug 09 '15 at 13:46
  • It might be useful to capture the reason for the failure and convey it as a header in errorQ. – Gary Russell Aug 09 '15 at 14:10