JMS Transaction rollback with dead letter channel using Apache Camel

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

JMS Transaction rollback with dead letter channel using Apache Camel

sujinsr
I am facing a issue while trying to implement JMS transaction using Camel.

Here is the scenario

1. Primary route which read the message from the queue(JMS_IN), pass the
same exchange to the two sub route(direct route)
2. First sub route process the message successfully and send to the another
queue(JMS_ONE)
3. Second sub route process the message and send to the another
queue(JMS_TWO).
4. If any error occurred during the sub route processing all the message
should rollback and original message sent to another queue(ERROR) that is
dead letter queue.
5. In the example Context I have created throw RuntimeException during
second sub route processing.
6. So expected behavior is to move the original message to ERROR queue,
same time no message should send to JMS_ONE & JMS_TWO
7. But actual behavior is original message was sent to the ERROR queue, but
message sent the JMS_ONE.

I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
manager.

Kindly help me on this, I am struck at this for couple of days

Camel Context Below

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
                <prop
key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
                <prop
key="java.naming.provider.url">http-remoting://localhost:9089</prop>
                <!--<prop
key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
                <prop key="java.naming.security.principal">TESTUSR</prop>
                <prop key="java.naming.security.credentials">TESTUSR</prop>
            </props>
        </property>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsConnectionFactory"/>
    </bean>

    <bean id="jmsConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate"/>
        <property name="jndiName" value="jms/RemoteConnectionFactory"/>
    </bean>

    <bean id="jmsTransactionManager"
class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory" ref="jmsConnectionFactory"/>
    </bean>

    <bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="jmsConnectionFactory"/>
        <property name="transactionManager" ref="jmsTransactionManager"/>
        <property name="transacted" value="true"/>
    </bean>

    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
        <property name="configuration" ref="jmsConfig"/>
    </bean>

    <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
    <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
    <bean id="deadChannelProcessor"
class="com.test.DeadChannelTestProcessor"/>


    <bean id="myDeadLetterErrorHandler"
class="org.apache.camel.builder.DeadLetterChannelBuilder">
        <property name="deadLetterUri" value="direct:dead_letter_channel"/>
        <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
    </bean>

    <bean id="myRedeliveryPolicyConfig"
class="org.apache.camel.processor.RedeliveryPolicy">
        <property name="maximumRedeliveries" value="0"/>
    </bean>

    <camelContext xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="myDeadLetterErrorHandler">

        <route id="route-one" >
            <from uri="jms:queue:t24IFInboundQueue"/>
            <transacted/>
            <to uri="direct:success-route"/>
            <to uri="direct:error-route"/>
        </route>

        <route id="direct-success-route">
            <from uri="direct:success-route"/>
            <transacted/>
            <process ref="successProcessor"/>
            <to uri="jms:queue:JMS_ONE"/>
        </route>

        <route id="direct-error-route">
            <from uri="direct:error-route"/>
            <transacted/>
            <process ref="errorProcessor"/>
            <to uri="jms:queue:JMS_TWO"/>
        </route>

        <route id="direct_dead_letter_channel">
            <from uri="direct:dead_letter_channel"/>
            <process ref="deadChannelProcessor"/>
            <to uri="jms:queue:ERROR"/>
        </route>

    </camelContext>

Thanks!!!
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

Zheng Feng
It looks like you need the JTA transaction manager to handle a XA
transaction between the JMS_ONE and JMS_TWO.

On Wed, Jun 26, 2019 at 3:01 PM sujin sr <[hidden email]> wrote:

> I am facing a issue while trying to implement JMS transaction using Camel.
>
> Here is the scenario
>
> 1. Primary route which read the message from the queue(JMS_IN), pass the
> same exchange to the two sub route(direct route)
> 2. First sub route process the message successfully and send to the another
> queue(JMS_ONE)
> 3. Second sub route process the message and send to the another
> queue(JMS_TWO).
> 4. If any error occurred during the sub route processing all the message
> should rollback and original message sent to another queue(ERROR) that is
> dead letter queue.
> 5. In the example Context I have created throw RuntimeException during
> second sub route processing.
> 6. So expected behavior is to move the original message to ERROR queue,
> same time no message should send to JMS_ONE & JMS_TWO
> 7. But actual behavior is original message was sent to the ERROR queue, but
> message sent the JMS_ONE.
>
> I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> manager.
>
> Kindly help me on this, I am struck at this for couple of days
>
> Camel Context Below
>
> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
>         <property name="environment">
>             <props>
>                 <prop
>
> key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
>                 <prop
> key="java.naming.provider.url">http-remoting://localhost:9089</prop>
>                 <!--<prop
>
> key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
>                 <prop key="java.naming.security.principal">TESTUSR</prop>
>                 <prop key="java.naming.security.credentials">TESTUSR</prop>
>             </props>
>         </property>
>     </bean>
>
>     <bean id="jmsTemplate"
> class="org.springframework.jms.core.JmsTemplate">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConnectionFactory"
> class="org.springframework.jndi.JndiObjectFactoryBean">
>         <property name="jndiTemplate" ref="jndiTemplate"/>
>         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsTransactionManager"
> class="org.springframework.jms.connection.JmsTransactionManager">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>         <property name="transactionManager" ref="jmsTransactionManager"/>
>         <property name="transacted" value="true"/>
>     </bean>
>
>     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>         <property name="configuration" ref="jmsConfig"/>
>     </bean>
>
>     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
>     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
>     <bean id="deadChannelProcessor"
> class="com.test.DeadChannelTestProcessor"/>
>
>
>     <bean id="myDeadLetterErrorHandler"
> class="org.apache.camel.builder.DeadLetterChannelBuilder">
>         <property name="deadLetterUri" value="direct:dead_letter_channel"/>
>         <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
>     </bean>
>
>     <bean id="myRedeliveryPolicyConfig"
> class="org.apache.camel.processor.RedeliveryPolicy">
>         <property name="maximumRedeliveries" value="0"/>
>     </bean>
>
>     <camelContext xmlns="http://camel.apache.org/schema/spring"
> errorHandlerRef="myDeadLetterErrorHandler">
>
>         <route id="route-one" >
>             <from uri="jms:queue:t24IFInboundQueue"/>
>             <transacted/>
>             <to uri="direct:success-route"/>
>             <to uri="direct:error-route"/>
>         </route>
>
>         <route id="direct-success-route">
>             <from uri="direct:success-route"/>
>             <transacted/>
>             <process ref="successProcessor"/>
>             <to uri="jms:queue:JMS_ONE"/>
>         </route>
>
>         <route id="direct-error-route">
>             <from uri="direct:error-route"/>
>             <transacted/>
>             <process ref="errorProcessor"/>
>             <to uri="jms:queue:JMS_TWO"/>
>         </route>
>
>         <route id="direct_dead_letter_channel">
>             <from uri="direct:dead_letter_channel"/>
>             <process ref="deadChannelProcessor"/>
>             <to uri="jms:queue:ERROR"/>
>         </route>
>
>     </camelContext>
>
> Thanks!!!
>
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

Claus Ibsen-2
In reply to this post by sujinsr
Hi

Its likely better to use just the brokers error handling with
transaction (transacted JMS acknowledge).
Then you can configure the broker with redelivery and its dead letter queue.
Then you dont need any Camel error handler, and only need to setup JMS
component for transacted JMS ack mode.

Otherwise in your use case, you cannot both rollback sending to ONE
and TWO but send to ERROR as they are all in the same transaction.
So in this example you need to setup a 2nd JMS component for ERROR, so
the JMS can rollback, and ERROR can commit. Also mind that the
incoming endpoint is also JMS and it will also rollback as part of ONE
and TWO. So you will get the message redelibered again from the
broker.

So try instead to just use broker error handling.




On Wed, Jun 26, 2019 at 9:01 AM sujin sr <[hidden email]> wrote:

>
> I am facing a issue while trying to implement JMS transaction using Camel.
>
> Here is the scenario
>
> 1. Primary route which read the message from the queue(JMS_IN), pass the
> same exchange to the two sub route(direct route)
> 2. First sub route process the message successfully and send to the another
> queue(JMS_ONE)
> 3. Second sub route process the message and send to the another
> queue(JMS_TWO).
> 4. If any error occurred during the sub route processing all the message
> should rollback and original message sent to another queue(ERROR) that is
> dead letter queue.
> 5. In the example Context I have created throw RuntimeException during
> second sub route processing.
> 6. So expected behavior is to move the original message to ERROR queue,
> same time no message should send to JMS_ONE & JMS_TWO
> 7. But actual behavior is original message was sent to the ERROR queue, but
> message sent the JMS_ONE.
>
> I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> manager.
>
> Kindly help me on this, I am struck at this for couple of days
>
> Camel Context Below
>
> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
>         <property name="environment">
>             <props>
>                 <prop
> key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
>                 <prop
> key="java.naming.provider.url">http-remoting://localhost:9089</prop>
>                 <!--<prop
> key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
>                 <prop key="java.naming.security.principal">TESTUSR</prop>
>                 <prop key="java.naming.security.credentials">TESTUSR</prop>
>             </props>
>         </property>
>     </bean>
>
>     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConnectionFactory"
> class="org.springframework.jndi.JndiObjectFactoryBean">
>         <property name="jndiTemplate" ref="jndiTemplate"/>
>         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsTransactionManager"
> class="org.springframework.jms.connection.JmsTransactionManager">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>         <property name="transactionManager" ref="jmsTransactionManager"/>
>         <property name="transacted" value="true"/>
>     </bean>
>
>     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>         <property name="configuration" ref="jmsConfig"/>
>     </bean>
>
>     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
>     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
>     <bean id="deadChannelProcessor"
> class="com.test.DeadChannelTestProcessor"/>
>
>
>     <bean id="myDeadLetterErrorHandler"
> class="org.apache.camel.builder.DeadLetterChannelBuilder">
>         <property name="deadLetterUri" value="direct:dead_letter_channel"/>
>         <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
>     </bean>
>
>     <bean id="myRedeliveryPolicyConfig"
> class="org.apache.camel.processor.RedeliveryPolicy">
>         <property name="maximumRedeliveries" value="0"/>
>     </bean>
>
>     <camelContext xmlns="http://camel.apache.org/schema/spring"
> errorHandlerRef="myDeadLetterErrorHandler">
>
>         <route id="route-one" >
>             <from uri="jms:queue:t24IFInboundQueue"/>
>             <transacted/>
>             <to uri="direct:success-route"/>
>             <to uri="direct:error-route"/>
>         </route>
>
>         <route id="direct-success-route">
>             <from uri="direct:success-route"/>
>             <transacted/>
>             <process ref="successProcessor"/>
>             <to uri="jms:queue:JMS_ONE"/>
>         </route>
>
>         <route id="direct-error-route">
>             <from uri="direct:error-route"/>
>             <transacted/>
>             <process ref="errorProcessor"/>
>             <to uri="jms:queue:JMS_TWO"/>
>         </route>
>
>         <route id="direct_dead_letter_channel">
>             <from uri="direct:dead_letter_channel"/>
>             <process ref="deadChannelProcessor"/>
>             <to uri="jms:queue:ERROR"/>
>         </route>
>
>     </camelContext>
>
> Thanks!!!



--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

Claus Ibsen-2
In reply to this post by Zheng Feng
On Wed, Jun 26, 2019 at 9:19 AM Zheng Feng <[hidden email]> wrote:
>
> It looks like you need the JTA transaction manager to handle a XA
> transaction between the JMS_ONE and JMS_TWO.
>

That is only needed if ONE and TWO are 2 different JMS systems. If
they are the same then local JMS transacted ack mode should be fine.
Also if you add for example JDBC with database, then yeah you need XA.

CiA2 book has a full chapter on transactions, so its a good source to
learn and read much more. And try its examples etc.

> On Wed, Jun 26, 2019 at 3:01 PM sujin sr <[hidden email]> wrote:
>
> > I am facing a issue while trying to implement JMS transaction using Camel.
> >
> > Here is the scenario
> >
> > 1. Primary route which read the message from the queue(JMS_IN), pass the
> > same exchange to the two sub route(direct route)
> > 2. First sub route process the message successfully and send to the another
> > queue(JMS_ONE)
> > 3. Second sub route process the message and send to the another
> > queue(JMS_TWO).
> > 4. If any error occurred during the sub route processing all the message
> > should rollback and original message sent to another queue(ERROR) that is
> > dead letter queue.
> > 5. In the example Context I have created throw RuntimeException during
> > second sub route processing.
> > 6. So expected behavior is to move the original message to ERROR queue,
> > same time no message should send to JMS_ONE & JMS_TWO
> > 7. But actual behavior is original message was sent to the ERROR queue, but
> > message sent the JMS_ONE.
> >
> > I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> > manager.
> >
> > Kindly help me on this, I am struck at this for couple of days
> >
> > Camel Context Below
> >
> > <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
> >         <property name="environment">
> >             <props>
> >                 <prop
> >
> > key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
> >                 <prop
> > key="java.naming.provider.url">http-remoting://localhost:9089</prop>
> >                 <!--<prop
> >
> > key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
> >                 <prop key="java.naming.security.principal">TESTUSR</prop>
> >                 <prop key="java.naming.security.credentials">TESTUSR</prop>
> >             </props>
> >         </property>
> >     </bean>
> >
> >     <bean id="jmsTemplate"
> > class="org.springframework.jms.core.JmsTemplate">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsConnectionFactory"
> > class="org.springframework.jndi.JndiObjectFactoryBean">
> >         <property name="jndiTemplate" ref="jndiTemplate"/>
> >         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsTransactionManager"
> > class="org.springframework.jms.connection.JmsTransactionManager">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsConfig"
> > class="org.apache.camel.component.jms.JmsConfiguration">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >         <property name="transactionManager" ref="jmsTransactionManager"/>
> >         <property name="transacted" value="true"/>
> >     </bean>
> >
> >     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
> >         <property name="configuration" ref="jmsConfig"/>
> >     </bean>
> >
> >     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
> >     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
> >     <bean id="deadChannelProcessor"
> > class="com.test.DeadChannelTestProcessor"/>
> >
> >
> >     <bean id="myDeadLetterErrorHandler"
> > class="org.apache.camel.builder.DeadLetterChannelBuilder">
> >         <property name="deadLetterUri" value="direct:dead_letter_channel"/>
> >         <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
> >     </bean>
> >
> >     <bean id="myRedeliveryPolicyConfig"
> > class="org.apache.camel.processor.RedeliveryPolicy">
> >         <property name="maximumRedeliveries" value="0"/>
> >     </bean>
> >
> >     <camelContext xmlns="http://camel.apache.org/schema/spring"
> > errorHandlerRef="myDeadLetterErrorHandler">
> >
> >         <route id="route-one" >
> >             <from uri="jms:queue:t24IFInboundQueue"/>
> >             <transacted/>
> >             <to uri="direct:success-route"/>
> >             <to uri="direct:error-route"/>
> >         </route>
> >
> >         <route id="direct-success-route">
> >             <from uri="direct:success-route"/>
> >             <transacted/>
> >             <process ref="successProcessor"/>
> >             <to uri="jms:queue:JMS_ONE"/>
> >         </route>
> >
> >         <route id="direct-error-route">
> >             <from uri="direct:error-route"/>
> >             <transacted/>
> >             <process ref="errorProcessor"/>
> >             <to uri="jms:queue:JMS_TWO"/>
> >         </route>
> >
> >         <route id="direct_dead_letter_channel">
> >             <from uri="direct:dead_letter_channel"/>
> >             <process ref="deadChannelProcessor"/>
> >             <to uri="jms:queue:ERROR"/>
> >         </route>
> >
> >     </camelContext>
> >
> > Thanks!!!
> >



--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

sujinsr
In reply to this post by Claus Ibsen-2
Thanks for the Response.

Before implementing 'transacted JMS acknowledge' i have tried to create
separate JMS component for ERROR. But still, I see the same behaviour as
message sent to the JMS_ONE not rollbacked

I have added this beans and changed ERROR route like below

<bean id="jmsConfigError"
class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>

<bean id="jmserror" class="org.apache.camel.component.jms.JmsComponent">
    <property name="configuration" ref="jmsConfigError"/>
</bean>


        <route id="direct_dead_letter_channel">
            <from uri="direct:dead_letter_channel"/>
            <transacted/>
            <process ref="deadChannelProcessor"/>
            <to uri="jmserror:queue:ERROR"/>
        </route>

Where i am missing anything here, kindly advise!!!!



On Wed, 26 Jun 2019 at 12:51, Claus Ibsen <[hidden email]> wrote:

> Hi
>
> Its likely better to use just the brokers error handling with
> transaction (transacted JMS acknowledge).
> Then you can configure the broker with redelivery and its dead letter
> queue.
> Then you dont need any Camel error handler, and only need to setup JMS
> component for transacted JMS ack mode.
>
> Otherwise in your use case, you cannot both rollback sending to ONE
> and TWO but send to ERROR as they are all in the same transaction.
> So in this example you need to setup a 2nd JMS component for ERROR, so
> the JMS can rollback, and ERROR can commit. Also mind that the
> incoming endpoint is also JMS and it will also rollback as part of ONE
> and TWO. So you will get the message redelibered again from the
> broker.
>
> So try instead to just use broker error handling.
>
>
>
>
> On Wed, Jun 26, 2019 at 9:01 AM sujin sr <[hidden email]> wrote:
> >
> > I am facing a issue while trying to implement JMS transaction using
> Camel.
> >
> > Here is the scenario
> >
> > 1. Primary route which read the message from the queue(JMS_IN), pass the
> > same exchange to the two sub route(direct route)
> > 2. First sub route process the message successfully and send to the
> another
> > queue(JMS_ONE)
> > 3. Second sub route process the message and send to the another
> > queue(JMS_TWO).
> > 4. If any error occurred during the sub route processing all the message
> > should rollback and original message sent to another queue(ERROR) that is
> > dead letter queue.
> > 5. In the example Context I have created throw RuntimeException during
> > second sub route processing.
> > 6. So expected behavior is to move the original message to ERROR queue,
> > same time no message should send to JMS_ONE & JMS_TWO
> > 7. But actual behavior is original message was sent to the ERROR queue,
> but
> > message sent the JMS_ONE.
> >
> > I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> > manager.
> >
> > Kindly help me on this, I am struck at this for couple of days
> >
> > Camel Context Below
> >
> > <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
> >         <property name="environment">
> >             <props>
> >                 <prop
> >
> key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
> >                 <prop
> > key="java.naming.provider.url">http-remoting://localhost:9089</prop>
> >                 <!--<prop
> >
> key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
> >                 <prop key="java.naming.security.principal">TESTUSR</prop>
> >                 <prop
> key="java.naming.security.credentials">TESTUSR</prop>
> >             </props>
> >         </property>
> >     </bean>
> >
> >     <bean id="jmsTemplate"
> class="org.springframework.jms.core.JmsTemplate">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsConnectionFactory"
> > class="org.springframework.jndi.JndiObjectFactoryBean">
> >         <property name="jndiTemplate" ref="jndiTemplate"/>
> >         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsTransactionManager"
> > class="org.springframework.jms.connection.JmsTransactionManager">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >     </bean>
> >
> >     <bean id="jmsConfig"
> > class="org.apache.camel.component.jms.JmsConfiguration">
> >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> >         <property name="transactionManager" ref="jmsTransactionManager"/>
> >         <property name="transacted" value="true"/>
> >     </bean>
> >
> >     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
> >         <property name="configuration" ref="jmsConfig"/>
> >     </bean>
> >
> >     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
> >     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
> >     <bean id="deadChannelProcessor"
> > class="com.test.DeadChannelTestProcessor"/>
> >
> >
> >     <bean id="myDeadLetterErrorHandler"
> > class="org.apache.camel.builder.DeadLetterChannelBuilder">
> >         <property name="deadLetterUri"
> value="direct:dead_letter_channel"/>
> >         <property name="redeliveryPolicy"
> ref="myRedeliveryPolicyConfig"/>
> >     </bean>
> >
> >     <bean id="myRedeliveryPolicyConfig"
> > class="org.apache.camel.processor.RedeliveryPolicy">
> >         <property name="maximumRedeliveries" value="0"/>
> >     </bean>
> >
> >     <camelContext xmlns="http://camel.apache.org/schema/spring"
> > errorHandlerRef="myDeadLetterErrorHandler">
> >
> >         <route id="route-one" >
> >             <from uri="jms:queue:t24IFInboundQueue"/>
> >             <transacted/>
> >             <to uri="direct:success-route"/>
> >             <to uri="direct:error-route"/>
> >         </route>
> >
> >         <route id="direct-success-route">
> >             <from uri="direct:success-route"/>
> >             <transacted/>
> >             <process ref="successProcessor"/>
> >             <to uri="jms:queue:JMS_ONE"/>
> >         </route>
> >
> >         <route id="direct-error-route">
> >             <from uri="direct:error-route"/>
> >             <transacted/>
> >             <process ref="errorProcessor"/>
> >             <to uri="jms:queue:JMS_TWO"/>
> >         </route>
> >
> >         <route id="direct_dead_letter_channel">
> >             <from uri="direct:dead_letter_channel"/>
> >             <process ref="deadChannelProcessor"/>
> >             <to uri="jms:queue:ERROR"/>
> >         </route>
> >
> >     </camelContext>
> >
> > Thanks!!!
>
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

Claus Ibsen-2
Hi

You are using dead letter channel as Camel's error handler which will
mark the message as succesfull.
Just use a regular error handler

On Wed, Jun 26, 2019 at 9:50 AM sujin sr <[hidden email]> wrote:

>
> Thanks for the Response.
>
> Before implementing 'transacted JMS acknowledge' i have tried to create
> separate JMS component for ERROR. But still, I see the same behaviour as
> message sent to the JMS_ONE not rollbacked
>
> I have added this beans and changed ERROR route like below
>
> <bean id="jmsConfigError"
> class="org.apache.camel.component.jms.JmsConfiguration">
>     <property name="connectionFactory" ref="jmsConnectionFactory"/>
> </bean>
>
> <bean id="jmserror" class="org.apache.camel.component.jms.JmsComponent">
>     <property name="configuration" ref="jmsConfigError"/>
> </bean>
>
>
>         <route id="direct_dead_letter_channel">
>             <from uri="direct:dead_letter_channel"/>
>             <transacted/>
>             <process ref="deadChannelProcessor"/>
>             <to uri="jmserror:queue:ERROR"/>
>         </route>
>
> Where i am missing anything here, kindly advise!!!!
>
>
>
> On Wed, 26 Jun 2019 at 12:51, Claus Ibsen <[hidden email]> wrote:
>
> > Hi
> >
> > Its likely better to use just the brokers error handling with
> > transaction (transacted JMS acknowledge).
> > Then you can configure the broker with redelivery and its dead letter
> > queue.
> > Then you dont need any Camel error handler, and only need to setup JMS
> > component for transacted JMS ack mode.
> >
> > Otherwise in your use case, you cannot both rollback sending to ONE
> > and TWO but send to ERROR as they are all in the same transaction.
> > So in this example you need to setup a 2nd JMS component for ERROR, so
> > the JMS can rollback, and ERROR can commit. Also mind that the
> > incoming endpoint is also JMS and it will also rollback as part of ONE
> > and TWO. So you will get the message redelibered again from the
> > broker.
> >
> > So try instead to just use broker error handling.
> >
> >
> >
> >
> > On Wed, Jun 26, 2019 at 9:01 AM sujin sr <[hidden email]> wrote:
> > >
> > > I am facing a issue while trying to implement JMS transaction using
> > Camel.
> > >
> > > Here is the scenario
> > >
> > > 1. Primary route which read the message from the queue(JMS_IN), pass the
> > > same exchange to the two sub route(direct route)
> > > 2. First sub route process the message successfully and send to the
> > another
> > > queue(JMS_ONE)
> > > 3. Second sub route process the message and send to the another
> > > queue(JMS_TWO).
> > > 4. If any error occurred during the sub route processing all the message
> > > should rollback and original message sent to another queue(ERROR) that is
> > > dead letter queue.
> > > 5. In the example Context I have created throw RuntimeException during
> > > second sub route processing.
> > > 6. So expected behavior is to move the original message to ERROR queue,
> > > same time no message should send to JMS_ONE & JMS_TWO
> > > 7. But actual behavior is original message was sent to the ERROR queue,
> > but
> > > message sent the JMS_ONE.
> > >
> > > I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> > > manager.
> > >
> > > Kindly help me on this, I am struck at this for couple of days
> > >
> > > Camel Context Below
> > >
> > > <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
> > >         <property name="environment">
> > >             <props>
> > >                 <prop
> > >
> > key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
> > >                 <prop
> > > key="java.naming.provider.url">http-remoting://localhost:9089</prop>
> > >                 <!--<prop
> > >
> > key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
> > >                 <prop key="java.naming.security.principal">TESTUSR</prop>
> > >                 <prop
> > key="java.naming.security.credentials">TESTUSR</prop>
> > >             </props>
> > >         </property>
> > >     </bean>
> > >
> > >     <bean id="jmsTemplate"
> > class="org.springframework.jms.core.JmsTemplate">
> > >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> > >     </bean>
> > >
> > >     <bean id="jmsConnectionFactory"
> > > class="org.springframework.jndi.JndiObjectFactoryBean">
> > >         <property name="jndiTemplate" ref="jndiTemplate"/>
> > >         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
> > >     </bean>
> > >
> > >     <bean id="jmsTransactionManager"
> > > class="org.springframework.jms.connection.JmsTransactionManager">
> > >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> > >     </bean>
> > >
> > >     <bean id="jmsConfig"
> > > class="org.apache.camel.component.jms.JmsConfiguration">
> > >         <property name="connectionFactory" ref="jmsConnectionFactory"/>
> > >         <property name="transactionManager" ref="jmsTransactionManager"/>
> > >         <property name="transacted" value="true"/>
> > >     </bean>
> > >
> > >     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
> > >         <property name="configuration" ref="jmsConfig"/>
> > >     </bean>
> > >
> > >     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
> > >     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
> > >     <bean id="deadChannelProcessor"
> > > class="com.test.DeadChannelTestProcessor"/>
> > >
> > >
> > >     <bean id="myDeadLetterErrorHandler"
> > > class="org.apache.camel.builder.DeadLetterChannelBuilder">
> > >         <property name="deadLetterUri"
> > value="direct:dead_letter_channel"/>
> > >         <property name="redeliveryPolicy"
> > ref="myRedeliveryPolicyConfig"/>
> > >     </bean>
> > >
> > >     <bean id="myRedeliveryPolicyConfig"
> > > class="org.apache.camel.processor.RedeliveryPolicy">
> > >         <property name="maximumRedeliveries" value="0"/>
> > >     </bean>
> > >
> > >     <camelContext xmlns="http://camel.apache.org/schema/spring"
> > > errorHandlerRef="myDeadLetterErrorHandler">
> > >
> > >         <route id="route-one" >
> > >             <from uri="jms:queue:t24IFInboundQueue"/>
> > >             <transacted/>
> > >             <to uri="direct:success-route"/>
> > >             <to uri="direct:error-route"/>
> > >         </route>
> > >
> > >         <route id="direct-success-route">
> > >             <from uri="direct:success-route"/>
> > >             <transacted/>
> > >             <process ref="successProcessor"/>
> > >             <to uri="jms:queue:JMS_ONE"/>
> > >         </route>
> > >
> > >         <route id="direct-error-route">
> > >             <from uri="direct:error-route"/>
> > >             <transacted/>
> > >             <process ref="errorProcessor"/>
> > >             <to uri="jms:queue:JMS_TWO"/>
> > >         </route>
> > >
> > >         <route id="direct_dead_letter_channel">
> > >             <from uri="direct:dead_letter_channel"/>
> > >             <process ref="deadChannelProcessor"/>
> > >             <to uri="jms:queue:ERROR"/>
> > >         </route>
> > >
> > >     </camelContext>
> > >
> > > Thanks!!!
> >
> >
> >
> > --
> > Claus Ibsen
> > -----------------
> > http://davsclaus.com @davsclaus
> > Camel in Action 2: https://www.manning.com/ibsen2
> >



--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

sujinsr
Hi,

I have tried with OnException and doTry/doCatch error handler still I am
getting the same behaviour as message sends to JMS_ONE.

error handler

        <onException redeliveryPolicyRef="myRedelivery">
            <exception>java.lang.RuntimeException</exception>
            <exception>java.lang.IllegalArgumentException</exception>
            <handled>
                <constant>true</constant>
            </handled>
            <!--<rollback markRollbackOnly="true"/>-->
            <to uri="direct:dead_letter_channel"/>
        </onException>

        <route id="direct_dead_letter_channel">
            <from uri="direct:dead_letter_channel"/>
            <transacted/>
            <process ref="deadChannelProcessor"/>
            <to uri="jmserror:queue:ERROR"/>
        </route>

I have tried with adding rollback in error handler, in that case message
not written to JMS_ONE queue, it has redelivered message to source queue
JMS_IN for some count but finally, it has not sent the message to ERROR.

Kindly advise if I miss anything!!!


On Wed, 26 Jun 2019 at 13:25, Claus Ibsen <[hidden email]> wrote:

> Hi
>
> You are using dead letter channel as Camel's error handler which will
> mark the message as succesfull.
> Just use a regular error handler
>
> On Wed, Jun 26, 2019 at 9:50 AM sujin sr <[hidden email]> wrote:
> >
> > Thanks for the Response.
> >
> > Before implementing 'transacted JMS acknowledge' i have tried to create
> > separate JMS component for ERROR. But still, I see the same behaviour as
> > message sent to the JMS_ONE not rollbacked
> >
> > I have added this beans and changed ERROR route like below
> >
> > <bean id="jmsConfigError"
> > class="org.apache.camel.component.jms.JmsConfiguration">
> >     <property name="connectionFactory" ref="jmsConnectionFactory"/>
> > </bean>
> >
> > <bean id="jmserror" class="org.apache.camel.component.jms.JmsComponent">
> >     <property name="configuration" ref="jmsConfigError"/>
> > </bean>
> >
> >
> >         <route id="direct_dead_letter_channel">
> >             <from uri="direct:dead_letter_channel"/>
> >             <transacted/>
> >             <process ref="deadChannelProcessor"/>
> >             <to uri="jmserror:queue:ERROR"/>
> >         </route>
> >
> > Where i am missing anything here, kindly advise!!!!
> >
> >
> >
> > On Wed, 26 Jun 2019 at 12:51, Claus Ibsen <[hidden email]> wrote:
> >
> > > Hi
> > >
> > > Its likely better to use just the brokers error handling with
> > > transaction (transacted JMS acknowledge).
> > > Then you can configure the broker with redelivery and its dead letter
> > > queue.
> > > Then you dont need any Camel error handler, and only need to setup JMS
> > > component for transacted JMS ack mode.
> > >
> > > Otherwise in your use case, you cannot both rollback sending to ONE
> > > and TWO but send to ERROR as they are all in the same transaction.
> > > So in this example you need to setup a 2nd JMS component for ERROR, so
> > > the JMS can rollback, and ERROR can commit. Also mind that the
> > > incoming endpoint is also JMS and it will also rollback as part of ONE
> > > and TWO. So you will get the message redelibered again from the
> > > broker.
> > >
> > > So try instead to just use broker error handling.
> > >
> > >
> > >
> > >
> > > On Wed, Jun 26, 2019 at 9:01 AM sujin sr <[hidden email]> wrote:
> > > >
> > > > I am facing a issue while trying to implement JMS transaction using
> > > Camel.
> > > >
> > > > Here is the scenario
> > > >
> > > > 1. Primary route which read the message from the queue(JMS_IN), pass
> the
> > > > same exchange to the two sub route(direct route)
> > > > 2. First sub route process the message successfully and send to the
> > > another
> > > > queue(JMS_ONE)
> > > > 3. Second sub route process the message and send to the another
> > > > queue(JMS_TWO).
> > > > 4. If any error occurred during the sub route processing all the
> message
> > > > should rollback and original message sent to another queue(ERROR)
> that is
> > > > dead letter queue.
> > > > 5. In the example Context I have created throw RuntimeException
> during
> > > > second sub route processing.
> > > > 6. So expected behavior is to move the original message to ERROR
> queue,
> > > > same time no message should send to JMS_ONE & JMS_TWO
> > > > 7. But actual behavior is original message was sent to the ERROR
> queue,
> > > but
> > > > message sent the JMS_ONE.
> > > >
> > > > I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> > > > manager.
> > > >
> > > > Kindly help me on this, I am struck at this for couple of days
> > > >
> > > > Camel Context Below
> > > >
> > > > <bean id="jndiTemplate"
> class="org.springframework.jndi.JndiTemplate">
> > > >         <property name="environment">
> > > >             <props>
> > > >                 <prop
> > > >
> > >
> key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
> > > >                 <prop
> > > > key="java.naming.provider.url">http-remoting://localhost:9089</prop>
> > > >                 <!--<prop
> > > >
> > >
> key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
> > > >                 <prop
> key="java.naming.security.principal">TESTUSR</prop>
> > > >                 <prop
> > > key="java.naming.security.credentials">TESTUSR</prop>
> > > >             </props>
> > > >         </property>
> > > >     </bean>
> > > >
> > > >     <bean id="jmsTemplate"
> > > class="org.springframework.jms.core.JmsTemplate">
> > > >         <property name="connectionFactory"
> ref="jmsConnectionFactory"/>
> > > >     </bean>
> > > >
> > > >     <bean id="jmsConnectionFactory"
> > > > class="org.springframework.jndi.JndiObjectFactoryBean">
> > > >         <property name="jndiTemplate" ref="jndiTemplate"/>
> > > >         <property name="jndiName"
> value="jms/RemoteConnectionFactory"/>
> > > >     </bean>
> > > >
> > > >     <bean id="jmsTransactionManager"
> > > > class="org.springframework.jms.connection.JmsTransactionManager">
> > > >         <property name="connectionFactory"
> ref="jmsConnectionFactory"/>
> > > >     </bean>
> > > >
> > > >     <bean id="jmsConfig"
> > > > class="org.apache.camel.component.jms.JmsConfiguration">
> > > >         <property name="connectionFactory"
> ref="jmsConnectionFactory"/>
> > > >         <property name="transactionManager"
> ref="jmsTransactionManager"/>
> > > >         <property name="transacted" value="true"/>
> > > >     </bean>
> > > >
> > > >     <bean id="jms"
> class="org.apache.camel.component.jms.JmsComponent">
> > > >         <property name="configuration" ref="jmsConfig"/>
> > > >     </bean>
> > > >
> > > >     <bean id="successProcessor"
> class="com.test.SuccessTestProcessor"/>
> > > >     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
> > > >     <bean id="deadChannelProcessor"
> > > > class="com.test.DeadChannelTestProcessor"/>
> > > >
> > > >
> > > >     <bean id="myDeadLetterErrorHandler"
> > > > class="org.apache.camel.builder.DeadLetterChannelBuilder">
> > > >         <property name="deadLetterUri"
> > > value="direct:dead_letter_channel"/>
> > > >         <property name="redeliveryPolicy"
> > > ref="myRedeliveryPolicyConfig"/>
> > > >     </bean>
> > > >
> > > >     <bean id="myRedeliveryPolicyConfig"
> > > > class="org.apache.camel.processor.RedeliveryPolicy">
> > > >         <property name="maximumRedeliveries" value="0"/>
> > > >     </bean>
> > > >
> > > >     <camelContext xmlns="http://camel.apache.org/schema/spring"
> > > > errorHandlerRef="myDeadLetterErrorHandler">
> > > >
> > > >         <route id="route-one" >
> > > >             <from uri="jms:queue:t24IFInboundQueue"/>
> > > >             <transacted/>
> > > >             <to uri="direct:success-route"/>
> > > >             <to uri="direct:error-route"/>
> > > >         </route>
> > > >
> > > >         <route id="direct-success-route">
> > > >             <from uri="direct:success-route"/>
> > > >             <transacted/>
> > > >             <process ref="successProcessor"/>
> > > >             <to uri="jms:queue:JMS_ONE"/>
> > > >         </route>
> > > >
> > > >         <route id="direct-error-route">
> > > >             <from uri="direct:error-route"/>
> > > >             <transacted/>
> > > >             <process ref="errorProcessor"/>
> > > >             <to uri="jms:queue:JMS_TWO"/>
> > > >         </route>
> > > >
> > > >         <route id="direct_dead_letter_channel">
> > > >             <from uri="direct:dead_letter_channel"/>
> > > >             <process ref="deadChannelProcessor"/>
> > > >             <to uri="jms:queue:ERROR"/>
> > > >         </route>
> > > >
> > > >     </camelContext>
> > > >
> > > > Thanks!!!
> > >
> > >
> > >
> > > --
> > > Claus Ibsen
> > > -----------------
> > > http://davsclaus.com @davsclaus
> > > Camel in Action 2: https://www.manning.com/ibsen2
> > >
>
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transaction rollback with dead letter channel using Apache Camel

Claus Ibsen-2
In reply to this post by sujinsr
Hi

We also discussed Camel and transactions within Red Hat with some
customers recently. And Duane Hawkins wrote this nice piece of
response which I am allow to share here in the public with his
permissions


There are a couple of possible gotchas here:

1. It is important to note that Camel redelivery is different and
separate from ActiveMQ redelivery.  Camel redelivery will retry a
failed exchange, but the broker is unaware of these redelivery
attempts, so they don't count against the JMS redelivery maximum.

2. If we mark an exception as "handled" with "<handled>true</handled>
then no exception will be propagated back to the session, so the
default listener will ack the message and as far as the broker is
concerned, the message delivery was successful, so the message will be
dequeued, so if we want the jms subsystem to handle failures, handled
should be marked "false."  If we want Camel to handle redelivery, then
we need to set up a dead-letter channel
(https://camel.apache.org/dead-letter-channel.html) to push the
message to some specific address (and mark handled as "true" to
dequeue the message on the originating broker).

In my experience, the simplest most reliable solution is to use a
transacted session or use CLIENT_ACKNOWLEDGE mode and set handled to
"false" in the errorhandler to let the exception propagate out of the
handler, which should rollback the session and result in an
incremented delivery count at the broker level, then we can set up a
targeted DLQ for the destination in question on the broker.  We can
still use an errorHandler on the client side if we would like to log a
friendly error message or copy the message to another destination, or
send an alert, etc.

If you have 2 transacted resources (an upstream "from" broker and
downstream "to" broker) and don't want to use XA, you can use a client
acknowledgment mode on the source broker (or a local transaction), and
try setting maxReconnectAttempts to "0" or "1" on the CF servicing the
downstream connector to force the connector to get evicted from the
pool on a failure and this should throw out an exception and rollback
the session / prevent acking the message to the upstream broker and
increment the delivery count.

On Wed, Jun 26, 2019 at 9:01 AM sujin sr <[hidden email]> wrote:

>
> I am facing a issue while trying to implement JMS transaction using Camel.
>
> Here is the scenario
>
> 1. Primary route which read the message from the queue(JMS_IN), pass the
> same exchange to the two sub route(direct route)
> 2. First sub route process the message successfully and send to the another
> queue(JMS_ONE)
> 3. Second sub route process the message and send to the another
> queue(JMS_TWO).
> 4. If any error occurred during the sub route processing all the message
> should rollback and original message sent to another queue(ERROR) that is
> dead letter queue.
> 5. In the example Context I have created throw RuntimeException during
> second sub route processing.
> 6. So expected behavior is to move the original message to ERROR queue,
> same time no message should send to JMS_ONE & JMS_TWO
> 7. But actual behavior is original message was sent to the ERROR queue, but
> message sent the JMS_ONE.
>
> I am using Apache Camel 2.24.0, Jboss HornetQ and spring transaction
> manager.
>
> Kindly help me on this, I am struck at this for couple of days
>
> Camel Context Below
>
> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
>         <property name="environment">
>             <props>
>                 <prop
> key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop>
>                 <prop
> key="java.naming.provider.url">http-remoting://localhost:9089</prop>
>                 <!--<prop
> key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>-->
>                 <prop key="java.naming.security.principal">TESTUSR</prop>
>                 <prop key="java.naming.security.credentials">TESTUSR</prop>
>             </props>
>         </property>
>     </bean>
>
>     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConnectionFactory"
> class="org.springframework.jndi.JndiObjectFactoryBean">
>         <property name="jndiTemplate" ref="jndiTemplate"/>
>         <property name="jndiName" value="jms/RemoteConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsTransactionManager"
> class="org.springframework.jms.connection.JmsTransactionManager">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>         <property name="transactionManager" ref="jmsTransactionManager"/>
>         <property name="transacted" value="true"/>
>     </bean>
>
>     <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>         <property name="configuration" ref="jmsConfig"/>
>     </bean>
>
>     <bean id="successProcessor" class="com.test.SuccessTestProcessor"/>
>     <bean id="errorProcessor" class="com.test.ErrorTestProcessor"/>
>     <bean id="deadChannelProcessor"
> class="com.test.DeadChannelTestProcessor"/>
>
>
>     <bean id="myDeadLetterErrorHandler"
> class="org.apache.camel.builder.DeadLetterChannelBuilder">
>         <property name="deadLetterUri" value="direct:dead_letter_channel"/>
>         <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
>     </bean>
>
>     <bean id="myRedeliveryPolicyConfig"
> class="org.apache.camel.processor.RedeliveryPolicy">
>         <property name="maximumRedeliveries" value="0"/>
>     </bean>
>
>     <camelContext xmlns="http://camel.apache.org/schema/spring"
> errorHandlerRef="myDeadLetterErrorHandler">
>
>         <route id="route-one" >
>             <from uri="jms:queue:t24IFInboundQueue"/>
>             <transacted/>
>             <to uri="direct:success-route"/>
>             <to uri="direct:error-route"/>
>         </route>
>
>         <route id="direct-success-route">
>             <from uri="direct:success-route"/>
>             <transacted/>
>             <process ref="successProcessor"/>
>             <to uri="jms:queue:JMS_ONE"/>
>         </route>
>
>         <route id="direct-error-route">
>             <from uri="direct:error-route"/>
>             <transacted/>
>             <process ref="errorProcessor"/>
>             <to uri="jms:queue:JMS_TWO"/>
>         </route>
>
>         <route id="direct_dead_letter_channel">
>             <from uri="direct:dead_letter_channel"/>
>             <process ref="deadChannelProcessor"/>
>             <to uri="jms:queue:ERROR"/>
>         </route>
>
>     </camelContext>
>
> Thanks!!!



--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2