I'm attempting to send a message from an AMQ Virtual Topic consumer to an
http endpoint using http4 with transactions. When the http service is down
http4 returns a org.apache.http.conn.HttpHostConnectException. When this
exception is thrown I would like the transaction to be rolled back and the
failed message to be placed back in the queue. AMQ then has a redelivery
policy for these messages. All other exceptions are marked has handled and
placed in a DLQ.
The route looks like this,
<route id="service.requests.consumer" streamCache="true">
<from
uri="activemq:Consumer.service-requests.VirtualTopic.service.requests"/>
<convertBodyTo type="String" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<transacted ref="PROPAGATION_REQUIRES_NEW"/>
<to uri="http4:{{service.requests.httpproduceruri}}"/>
<onException>
<exception>org.apache.http.conn.HttpHostConnectException</exception>
<rollback markRollbackOnly="true"/>
</onException>
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<transform>
<simple>{Exception:${exception}, Request:${body}}</simple>
</transform>
<to uri="activemq:queue:service-requests.dlq"/>
</onException>
</route>
The DQL piece of the route works perfectly. But I'm not seeing what I would
expect from the rollback. My expectation was that by using <rollback
markRollbackOnly="true"/> I should see no exception when I do the rollback.
However this is not the case, when I look at the log I see a
RollbackExchangeException and I don't know why.
org.apache.camel.RuntimeCamelException:
org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]
at
org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
at
org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
at
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
Source)[:1.7.0_07]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
Source)[:1.7.0_07]
at java.lang.Thread.run(Unknown Source)[:1.7.0_07]
Is there something I'm missing between the AMQ transaction and the camel
route? Any help would be greatly appreciated, thank you.
http endpoint using http4 with transactions. When the http service is down
http4 returns a org.apache.http.conn.HttpHostConnectException. When this
exception is thrown I would like the transaction to be rolled back and the
failed message to be placed back in the queue. AMQ then has a redelivery
policy for these messages. All other exceptions are marked has handled and
placed in a DLQ.
The route looks like this,
<route id="service.requests.consumer" streamCache="true">
<from
uri="activemq:Consumer.service-requests.VirtualTopic.service.requests"/>
<convertBodyTo type="String" />
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<transacted ref="PROPAGATION_REQUIRES_NEW"/>
<to uri="http4:{{service.requests.httpproduceruri}}"/>
<onException>
<exception>org.apache.http.conn.HttpHostConnectException</exception>
<rollback markRollbackOnly="true"/>
</onException>
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<transform>
<simple>{Exception:${exception}, Request:${body}}</simple>
</transform>
<to uri="activemq:queue:service-requests.dlq"/>
</onException>
</route>
The DQL piece of the route works perfectly. But I'm not seeing what I would
expect from the rollback. My expectation was that by using <rollback
markRollbackOnly="true"/> I should see no exception when I do the rollback.
However this is not the case, when I look at the log I see a
RollbackExchangeException and I don't know why.
org.apache.camel.RuntimeCamelException:
org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]
at
org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
at
org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
at
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
Source)[:1.7.0_07]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
Source)[:1.7.0_07]
at java.lang.Thread.run(Unknown Source)[:1.7.0_07]
Is there something I'm missing between the AMQ transaction and the camel
route? Any help would be greatly appreciated, thank you.