You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Ilya S <de...@gmail.com> on 2009/08/25 01:55:39 UTC

JMS transactions between multiple routes

Hi All,

I'm using Camel 1.6.1 (cannot use 2.0) , with Spring 2.5.6, and ActiveMQ 5.2.

I'm trying to set up Transaction Manager so that my transactions are
rolled back on error.
Here is my camel xml config adopted from the examples:
=========================================================================

    <context:component-scan base-package="org.apache.camel.example.server"/>

    <camel:camelContext id="camel">
        <camel:package>org.apache.camel.example.server</camel:package>
        <camel:jmxAgent id="agent" createConnector="true"/>
    </camel:camelContext>

    <broker:broker useJmx="false" persistent="false" brokerName="localhost">
        <broker:transportConnectors>
            <broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
        </broker:transportConnectors>
    </broker:broker>

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

	<bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
		<property name="maximumRedeliveries" value="-1"/>
	</bean>

	<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
		<!-- use the vm protocol as the JMS broker is running in the same
jvm as Camel -->
		<property name="brokerURL" value="vm://localhost"/>
		<property name="redeliveryPolicy" ref="redeliveryPolicy"/>
	</bean>

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

	<bean id="PROPAGATION_REQUIRED"
class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="jmsTransactionManager"/>
	</bean>

	<bean id="transactionErrorHandler"
class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
		 <property name="transactionTemplate" ref="PROPAGATION_REQUIRED"/>
	</bean>
====================================================================

I have 2 routes.
Route 1 (extends from SpringRouteBuilder)

    	TransactionTemplate template =
bean(org.springframework.transaction.support.TransactionTemplate.class,
"PROPAGATION_REQUIRED");
    	Policy<TransactionTemplate> pp = new
SpringTransactionPolicy<TransactionTemplate>(template);

        from("jms:queue:numbers")
        .policy(pp)
        .to("jms:queue:mybadqueue?transactedInOut=true")
        .to("multiplier");


Route 2:
        from("jms:queue:mybadqueue")
        .process(new Processor() {
			public void process(Exchange arg0) throws Exception {
				throw new Exception("Hello World Exception");
			}
        	
        })
       .to("multiplier");


With this configuration I never get messages sent to "jms:queue:mybadqueue".
Could someone point me in the right direction? Please, advise.

Thank you.
Ilya.

Re: JMS transactions between multiple routes

Posted by Ilya S <de...@gmail.com>.
Claus,

I think 'transferException' option is only available in Camel 2.0? I
have to use 1.6.1...

On Tue, Aug 25, 2009 at 8:50 AM, Claus Ibsen<cl...@gmail.com> wrote:
> See transferException option on Camel JMS
>
>
> On Tue, Aug 25, 2009 at 5:47 PM, Ilya S<de...@gmail.com> wrote:
>> Hi Claus,
>>
>> Yes, I believe I am using request/reply over JMS.
>>
>> Is there a way to ask Camel to commit a TX at some point in my route?
>>
>> I just sent a clarification on what I'm actually trying to accomplish:
>> if some endpoint in the middle failed, I would the the error to be
>> propagated back to the original producer, and I was hoping that this
>> can be done.
>>
>> Thank you.
>>
>> On Mon, Aug 24, 2009 at 10:49 PM, Claus Ibsen<cl...@gmail.com> wrote:
>>> Hi
>>>
>>> Are you doing request/reply over JMS and want to do that with transactions?
>>> If so that is not possible as messages are not commited to the JMS
>>> queue before the TX is comitted.
>>>
>>>
>>>
>>> On Tue, Aug 25, 2009 at 1:55 AM, Ilya S<de...@gmail.com> wrote:
>>>> Hi All,
>>>>
>>>> I'm using Camel 1.6.1 (cannot use 2.0) , with Spring 2.5.6, and ActiveMQ 5.2.
>>>>
>>>> I'm trying to set up Transaction Manager so that my transactions are
>>>> rolled back on error.
>>>> Here is my camel xml config adopted from the examples:
>>>> =========================================================================
>>>>
>>>>    <context:component-scan base-package="org.apache.camel.example.server"/>
>>>>
>>>>    <camel:camelContext id="camel">
>>>>        <camel:package>org.apache.camel.example.server</camel:package>
>>>>        <camel:jmxAgent id="agent" createConnector="true"/>
>>>>    </camel:camelContext>
>>>>
>>>>    <broker:broker useJmx="false" persistent="false" brokerName="localhost">
>>>>        <broker:transportConnectors>
>>>>            <broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
>>>>        </broker:transportConnectors>
>>>>    </broker:broker>
>>>>
>>>>    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>>>>        <property name="connectionFactory" ref="jmsConnectionFactory"/>
>>>>        <property name="transacted" value="true"/>
>>>>        <property name="transactionManager" ref="jmsTransactionManager"/>
>>>>        <property name="transactionTimeout" value="50000"></property>
>>>>    </bean>
>>>>
>>>>        <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
>>>>                <property name="maximumRedeliveries" value="-1"/>
>>>>        </bean>
>>>>
>>>>        <bean id="jmsConnectionFactory"
>>>> class="org.apache.activemq.ActiveMQConnectionFactory">
>>>>                <!-- use the vm protocol as the JMS broker is running in the same
>>>> jvm as Camel -->
>>>>                <property name="brokerURL" value="vm://localhost"/>
>>>>                <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
>>>>        </bean>
>>>>
>>>>        <bean id="jmsTransactionManager"
>>>> class="org.springframework.jms.connection.JmsTransactionManager">
>>>>                <property name="connectionFactory" ref="jmsConnectionFactory" />
>>>>        </bean>
>>>>
>>>>        <bean id="PROPAGATION_REQUIRED"
>>>> class="org.springframework.transaction.support.TransactionTemplate">
>>>>                <property name="transactionManager" ref="jmsTransactionManager"/>
>>>>        </bean>
>>>>
>>>>        <bean id="transactionErrorHandler"
>>>> class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
>>>>                 <property name="transactionTemplate" ref="PROPAGATION_REQUIRED"/>
>>>>        </bean>
>>>> ====================================================================
>>>>
>>>> I have 2 routes.
>>>> Route 1 (extends from SpringRouteBuilder)
>>>>
>>>>        TransactionTemplate template =
>>>> bean(org.springframework.transaction.support.TransactionTemplate.class,
>>>> "PROPAGATION_REQUIRED");
>>>>        Policy<TransactionTemplate> pp = new
>>>> SpringTransactionPolicy<TransactionTemplate>(template);
>>>>
>>>>        from("jms:queue:numbers")
>>>>        .policy(pp)
>>>>        .to("jms:queue:mybadqueue?transactedInOut=true")
>>>>        .to("multiplier");
>>>>
>>>>
>>>> Route 2:
>>>>        from("jms:queue:mybadqueue")
>>>>        .process(new Processor() {
>>>>                        public void process(Exchange arg0) throws Exception {
>>>>                                throw new Exception("Hello World Exception");
>>>>                        }
>>>>
>>>>        })
>>>>       .to("multiplier");
>>>>
>>>>
>>>> With this configuration I never get messages sent to "jms:queue:mybadqueue".
>>>> Could someone point me in the right direction? Please, advise.
>>>>
>>>> Thank you.
>>>> Ilya.
>>>>
>>>
>>>
>>>
>>> --
>>> Claus Ibsen
>>> Apache Camel Committer
>>>
>>> Open Source Integration: http://fusesource.com
>>> Blog: http://davsclaus.blogspot.com/
>>> Twitter: http://twitter.com/davsclaus
>>>
>>
>
>
>
> --
> Claus Ibsen
> Apache Camel Committer
>
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> Twitter: http://twitter.com/davsclaus
>

Re: JMS transactions between multiple routes

Posted by Claus Ibsen <cl...@gmail.com>.
See transferException option on Camel JMS


On Tue, Aug 25, 2009 at 5:47 PM, Ilya S<de...@gmail.com> wrote:
> Hi Claus,
>
> Yes, I believe I am using request/reply over JMS.
>
> Is there a way to ask Camel to commit a TX at some point in my route?
>
> I just sent a clarification on what I'm actually trying to accomplish:
> if some endpoint in the middle failed, I would the the error to be
> propagated back to the original producer, and I was hoping that this
> can be done.
>
> Thank you.
>
> On Mon, Aug 24, 2009 at 10:49 PM, Claus Ibsen<cl...@gmail.com> wrote:
>> Hi
>>
>> Are you doing request/reply over JMS and want to do that with transactions?
>> If so that is not possible as messages are not commited to the JMS
>> queue before the TX is comitted.
>>
>>
>>
>> On Tue, Aug 25, 2009 at 1:55 AM, Ilya S<de...@gmail.com> wrote:
>>> Hi All,
>>>
>>> I'm using Camel 1.6.1 (cannot use 2.0) , with Spring 2.5.6, and ActiveMQ 5.2.
>>>
>>> I'm trying to set up Transaction Manager so that my transactions are
>>> rolled back on error.
>>> Here is my camel xml config adopted from the examples:
>>> =========================================================================
>>>
>>>    <context:component-scan base-package="org.apache.camel.example.server"/>
>>>
>>>    <camel:camelContext id="camel">
>>>        <camel:package>org.apache.camel.example.server</camel:package>
>>>        <camel:jmxAgent id="agent" createConnector="true"/>
>>>    </camel:camelContext>
>>>
>>>    <broker:broker useJmx="false" persistent="false" brokerName="localhost">
>>>        <broker:transportConnectors>
>>>            <broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
>>>        </broker:transportConnectors>
>>>    </broker:broker>
>>>
>>>    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>>>        <property name="connectionFactory" ref="jmsConnectionFactory"/>
>>>        <property name="transacted" value="true"/>
>>>        <property name="transactionManager" ref="jmsTransactionManager"/>
>>>        <property name="transactionTimeout" value="50000"></property>
>>>    </bean>
>>>
>>>        <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
>>>                <property name="maximumRedeliveries" value="-1"/>
>>>        </bean>
>>>
>>>        <bean id="jmsConnectionFactory"
>>> class="org.apache.activemq.ActiveMQConnectionFactory">
>>>                <!-- use the vm protocol as the JMS broker is running in the same
>>> jvm as Camel -->
>>>                <property name="brokerURL" value="vm://localhost"/>
>>>                <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
>>>        </bean>
>>>
>>>        <bean id="jmsTransactionManager"
>>> class="org.springframework.jms.connection.JmsTransactionManager">
>>>                <property name="connectionFactory" ref="jmsConnectionFactory" />
>>>        </bean>
>>>
>>>        <bean id="PROPAGATION_REQUIRED"
>>> class="org.springframework.transaction.support.TransactionTemplate">
>>>                <property name="transactionManager" ref="jmsTransactionManager"/>
>>>        </bean>
>>>
>>>        <bean id="transactionErrorHandler"
>>> class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
>>>                 <property name="transactionTemplate" ref="PROPAGATION_REQUIRED"/>
>>>        </bean>
>>> ====================================================================
>>>
>>> I have 2 routes.
>>> Route 1 (extends from SpringRouteBuilder)
>>>
>>>        TransactionTemplate template =
>>> bean(org.springframework.transaction.support.TransactionTemplate.class,
>>> "PROPAGATION_REQUIRED");
>>>        Policy<TransactionTemplate> pp = new
>>> SpringTransactionPolicy<TransactionTemplate>(template);
>>>
>>>        from("jms:queue:numbers")
>>>        .policy(pp)
>>>        .to("jms:queue:mybadqueue?transactedInOut=true")
>>>        .to("multiplier");
>>>
>>>
>>> Route 2:
>>>        from("jms:queue:mybadqueue")
>>>        .process(new Processor() {
>>>                        public void process(Exchange arg0) throws Exception {
>>>                                throw new Exception("Hello World Exception");
>>>                        }
>>>
>>>        })
>>>       .to("multiplier");
>>>
>>>
>>> With this configuration I never get messages sent to "jms:queue:mybadqueue".
>>> Could someone point me in the right direction? Please, advise.
>>>
>>> Thank you.
>>> Ilya.
>>>
>>
>>
>>
>> --
>> Claus Ibsen
>> Apache Camel Committer
>>
>> Open Source Integration: http://fusesource.com
>> Blog: http://davsclaus.blogspot.com/
>> Twitter: http://twitter.com/davsclaus
>>
>



-- 
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: JMS transactions between multiple routes

Posted by Ilya S <de...@gmail.com>.
Hi Claus,

Yes, I believe I am using request/reply over JMS.

Is there a way to ask Camel to commit a TX at some point in my route?

I just sent a clarification on what I'm actually trying to accomplish:
if some endpoint in the middle failed, I would the the error to be
propagated back to the original producer, and I was hoping that this
can be done.

Thank you.

On Mon, Aug 24, 2009 at 10:49 PM, Claus Ibsen<cl...@gmail.com> wrote:
> Hi
>
> Are you doing request/reply over JMS and want to do that with transactions?
> If so that is not possible as messages are not commited to the JMS
> queue before the TX is comitted.
>
>
>
> On Tue, Aug 25, 2009 at 1:55 AM, Ilya S<de...@gmail.com> wrote:
>> Hi All,
>>
>> I'm using Camel 1.6.1 (cannot use 2.0) , with Spring 2.5.6, and ActiveMQ 5.2.
>>
>> I'm trying to set up Transaction Manager so that my transactions are
>> rolled back on error.
>> Here is my camel xml config adopted from the examples:
>> =========================================================================
>>
>>    <context:component-scan base-package="org.apache.camel.example.server"/>
>>
>>    <camel:camelContext id="camel">
>>        <camel:package>org.apache.camel.example.server</camel:package>
>>        <camel:jmxAgent id="agent" createConnector="true"/>
>>    </camel:camelContext>
>>
>>    <broker:broker useJmx="false" persistent="false" brokerName="localhost">
>>        <broker:transportConnectors>
>>            <broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
>>        </broker:transportConnectors>
>>    </broker:broker>
>>
>>    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>>        <property name="connectionFactory" ref="jmsConnectionFactory"/>
>>        <property name="transacted" value="true"/>
>>        <property name="transactionManager" ref="jmsTransactionManager"/>
>>        <property name="transactionTimeout" value="50000"></property>
>>    </bean>
>>
>>        <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
>>                <property name="maximumRedeliveries" value="-1"/>
>>        </bean>
>>
>>        <bean id="jmsConnectionFactory"
>> class="org.apache.activemq.ActiveMQConnectionFactory">
>>                <!-- use the vm protocol as the JMS broker is running in the same
>> jvm as Camel -->
>>                <property name="brokerURL" value="vm://localhost"/>
>>                <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
>>        </bean>
>>
>>        <bean id="jmsTransactionManager"
>> class="org.springframework.jms.connection.JmsTransactionManager">
>>                <property name="connectionFactory" ref="jmsConnectionFactory" />
>>        </bean>
>>
>>        <bean id="PROPAGATION_REQUIRED"
>> class="org.springframework.transaction.support.TransactionTemplate">
>>                <property name="transactionManager" ref="jmsTransactionManager"/>
>>        </bean>
>>
>>        <bean id="transactionErrorHandler"
>> class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
>>                 <property name="transactionTemplate" ref="PROPAGATION_REQUIRED"/>
>>        </bean>
>> ====================================================================
>>
>> I have 2 routes.
>> Route 1 (extends from SpringRouteBuilder)
>>
>>        TransactionTemplate template =
>> bean(org.springframework.transaction.support.TransactionTemplate.class,
>> "PROPAGATION_REQUIRED");
>>        Policy<TransactionTemplate> pp = new
>> SpringTransactionPolicy<TransactionTemplate>(template);
>>
>>        from("jms:queue:numbers")
>>        .policy(pp)
>>        .to("jms:queue:mybadqueue?transactedInOut=true")
>>        .to("multiplier");
>>
>>
>> Route 2:
>>        from("jms:queue:mybadqueue")
>>        .process(new Processor() {
>>                        public void process(Exchange arg0) throws Exception {
>>                                throw new Exception("Hello World Exception");
>>                        }
>>
>>        })
>>       .to("multiplier");
>>
>>
>> With this configuration I never get messages sent to "jms:queue:mybadqueue".
>> Could someone point me in the right direction? Please, advise.
>>
>> Thank you.
>> Ilya.
>>
>
>
>
> --
> Claus Ibsen
> Apache Camel Committer
>
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> Twitter: http://twitter.com/davsclaus
>

Re: JMS transactions between multiple routes

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Are you doing request/reply over JMS and want to do that with transactions?
If so that is not possible as messages are not commited to the JMS
queue before the TX is comitted.



On Tue, Aug 25, 2009 at 1:55 AM, Ilya S<de...@gmail.com> wrote:
> Hi All,
>
> I'm using Camel 1.6.1 (cannot use 2.0) , with Spring 2.5.6, and ActiveMQ 5.2.
>
> I'm trying to set up Transaction Manager so that my transactions are
> rolled back on error.
> Here is my camel xml config adopted from the examples:
> =========================================================================
>
>    <context:component-scan base-package="org.apache.camel.example.server"/>
>
>    <camel:camelContext id="camel">
>        <camel:package>org.apache.camel.example.server</camel:package>
>        <camel:jmxAgent id="agent" createConnector="true"/>
>    </camel:camelContext>
>
>    <broker:broker useJmx="false" persistent="false" brokerName="localhost">
>        <broker:transportConnectors>
>            <broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
>        </broker:transportConnectors>
>    </broker:broker>
>
>    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>        <property name="connectionFactory" ref="jmsConnectionFactory"/>
>        <property name="transacted" value="true"/>
>        <property name="transactionManager" ref="jmsTransactionManager"/>
>        <property name="transactionTimeout" value="50000"></property>
>    </bean>
>
>        <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
>                <property name="maximumRedeliveries" value="-1"/>
>        </bean>
>
>        <bean id="jmsConnectionFactory"
> class="org.apache.activemq.ActiveMQConnectionFactory">
>                <!-- use the vm protocol as the JMS broker is running in the same
> jvm as Camel -->
>                <property name="brokerURL" value="vm://localhost"/>
>                <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
>        </bean>
>
>        <bean id="jmsTransactionManager"
> class="org.springframework.jms.connection.JmsTransactionManager">
>                <property name="connectionFactory" ref="jmsConnectionFactory" />
>        </bean>
>
>        <bean id="PROPAGATION_REQUIRED"
> class="org.springframework.transaction.support.TransactionTemplate">
>                <property name="transactionManager" ref="jmsTransactionManager"/>
>        </bean>
>
>        <bean id="transactionErrorHandler"
> class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
>                 <property name="transactionTemplate" ref="PROPAGATION_REQUIRED"/>
>        </bean>
> ====================================================================
>
> I have 2 routes.
> Route 1 (extends from SpringRouteBuilder)
>
>        TransactionTemplate template =
> bean(org.springframework.transaction.support.TransactionTemplate.class,
> "PROPAGATION_REQUIRED");
>        Policy<TransactionTemplate> pp = new
> SpringTransactionPolicy<TransactionTemplate>(template);
>
>        from("jms:queue:numbers")
>        .policy(pp)
>        .to("jms:queue:mybadqueue?transactedInOut=true")
>        .to("multiplier");
>
>
> Route 2:
>        from("jms:queue:mybadqueue")
>        .process(new Processor() {
>                        public void process(Exchange arg0) throws Exception {
>                                throw new Exception("Hello World Exception");
>                        }
>
>        })
>       .to("multiplier");
>
>
> With this configuration I never get messages sent to "jms:queue:mybadqueue".
> Could someone point me in the right direction? Please, advise.
>
> Thank you.
> Ilya.
>



-- 
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: JMS transactions between multiple routes

Posted by Ilya S <de...@gmail.com>.
Hi Fintan,

Thanks for clarifying. I thought that when TransactionErrorHandler is
used, there is no dead letter queue, and when exception is thrown it
is propagated back.

Claus has suggested to use 'transferException=true' param to
accomplish what I want, however I think it is available only since
Camel 2, and not in 1.6.1.

Do you know of any other way to propagate exceptions to original producer?

Thank you very much,
Ilya.


On Tue, Aug 25, 2009 at 9:43 AM, Fintan Bolton<fb...@progress.com> wrote:
>
> Hi Ilya,
>
>>>Route 2:
>>>...
>>>I was hoping this exception will be propagated up to my producer.
>>>However, by default, with deadLetterQueue, the exception does not seem
>>>to be propageted.
>
> Oh, if the exception in this route actually gets raised, it looks like the
> message is progressing further than I thought! But I don't think it is
> possible for the exception to be propagated all the way back to the producer
> (by which I believe you mean the endpoint,
> jms:queue:mybadqueue?transactedInOut=true, in Route 1). Both the
> transactions and the error handling in Routes 1 & 2 are completely separate.
> The JMS queue, being an asynchronous endpoint, completely decouples the two
> routes. Transmission through the mybadqueue queue proceeds as follows:
>
> i. Transaction 1 in Route 1 commits, causing a message to be Enqueued on
> mybadqueue.
>
> ii. Transaction 2 in Route 2 starts, causing a message to be
> (provisionally!) read from the queue. When the exception is thrown, the
> transaction rolls back and un-dispatches the message (pushing it back into
> the queue again).
>
> iii. Step ii. repeats a few times until maximumRedeliveries is reached, and
> then the message gets transferred to the dead letter queue.
>
> There is no mechanism here for propagating the exception all the way back to
> the original producer endpoint. I hope I haven't misunderstood what you are
> trying to do!
>
> Cheers,
> Fintan
>
>
> Ili Statistical wrote:
>>
>> Hi Fintan,
>>
>>
>> I basically took Camel spring example from 1.6.1
>> (apache-camel-1.6.1\examples\camel-example-spring-jms) and modified
>> it.
>> I would like camel to propagate my exception (or jms fault) that
>> happen in some nested route up to the original producer(client). I
>> thought I can do this with transactions.
>>
>>
>> My producer code looks like this:
>> ===================
>>         // get the camel template for Spring template style sending of
>> messages (= producer)
>>         ProducerTemplate<Exchange> camelTemplate =
>> (ProducerTemplate<Exchange>) context.getBean("camelTemplate");
>>
>>         System.out.println("Invoking the multiply with 22");
>>
>>         Exchange exch = null;
>>         try {
>>               exch = camelTemplate.send("jms:queue:numbers", new Processor(){
>>                               public void process(Exchange exchange) throws Exception {
>>                                       exchange.setPattern(ExchangePattern.InOut);
>>                                       Message in = exchange.getIn();
>>                                       in.setBody("22");
>>                               }
>>               });
>>
>>
>>               int response =
>> (Integer)camelTemplate.sendBody("jms:queue:numbers",
>> ExchangePattern.InOut, 22);
>> ========================================
>>
>> So, yes, it is InOut.
>>
>>
>> The multiplier endpoint simply multiplies the body by 3, and puts the
>> result into exchange.
>> However, the execution should not get to the multiplier, since the
>> very first thing I do in Route 2 is to throw an exception:
>>
>> Route 2:
>>        from("jms:queue:mybadqueue")
>>        .process(new Processor() {
>>                        public void process(Exchange arg0) throws Exception
>> {
>>                                throw new Exception("Hello World
>> Exception");
>>                        }
>>
>>        })
>>       .to("multiplier");
>>
>> I was hoping this exception will be propagated up to my producer.
>> However, by default, with deadLetterQueue, the exception does not seem
>> to be propageted.
>> I thought this could be done with transactional error handler, and
>> that's why I'm trying to understand how it works.
>> Please, let me know what is the right way to do this?
>>
>>
>> Thanks,
>> Ilya.
>>
>>
>>
>>
>>
>>
>> On Tue, Aug 25, 2009 at 2:14 AM, Fintan Bolton<fb...@progress.com>
>> wrote:
>>>
>>> Hi Ilya,
>>>
>>> That's an interesting routing example. I have a couple of observations
>>> about
>>> your routes, based on my understanding of Camel transactions (which is by
>>> no
>>> means perfect!).
>>>
>>> Route 1:
>>>
>>>        from("jms:queue:numbers")
>>>        .policy(pp)
>>>        .to("jms:queue:mybadqueue?transactedInOut=true")
>>>        .to("multiplier");
>>>
>>> I believe that the call, policy(pp), in this route is unnecessary. The
>>> transaction has already been kicked off by the jms:queue:numbers
>>> endpoint,
>>> so there is no need to start it again. What policy(pp) actually does
>>> (where
>>> pp represents the PROPAGATION_REQUIRED policy) is to check whether a
>>> transaction has already started on this thread. It has, so policy(pp)
>>> does
>>> nothing.
>>>
>>> I suspect that the transactedInOut setting is ignored in this context. My
>>> understanding is that the options, transacted and transactedInOut, apply
>>> only to consumer endpoints, not producer endpoints. Or, if
>>> transactedInOut
>>> is not being ignored, perhaps it is causing some unexpected behavior?
>>>
>>> A key point about the two routes in your example is that each of the
>>> routes
>>> are processed in separate transactions. A message will not be available
>>> to
>>> pull from the mybadqueue queue (Route 2) until the transaction in Route 1
>>> has committed. So, if you are not seeing any messages in mybadqueue, that
>>> implies that the transaction in Route 1 has not committed.
>>>
>>> Perhaps some part of Route 1 is hanging, thus preventing a commit? Could
>>> you
>>> clarify a couple of points:
>>>
>>> 1. Do the incoming messages (from jms:queue:numbers) have their JMS
>>> ReplyTo
>>> header set? As Claus says, if you are processing InOut exchanges, this is
>>> a
>>> special case.
>>>
>>> 2. What does the multiplier endpoint do? Could it be hanging (thus
>>> preventing a commit)?
>>>
>>> 3. What happens when you remove the transactedInOut="true" setting? I
>>> suspect that this setting is incorrect and might cause problems.
>>>
>>> -
>>> Cheers,
>>> Fintan
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25130955.html
>>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>>
>>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25137993.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>

Re: JMS transactions between multiple routes

Posted by Fintan Bolton <fb...@progress.com>.
Hi Ilya,

>>Route 2:
>>...
>>I was hoping this exception will be propagated up to my producer.
>>However, by default, with deadLetterQueue, the exception does not seem
>>to be propageted.

Oh, if the exception in this route actually gets raised, it looks like the
message is progressing further than I thought! But I don't think it is
possible for the exception to be propagated all the way back to the producer
(by which I believe you mean the endpoint,
jms:queue:mybadqueue?transactedInOut=true, in Route 1). Both the
transactions and the error handling in Routes 1 & 2 are completely separate.
The JMS queue, being an asynchronous endpoint, completely decouples the two
routes. Transmission through the mybadqueue queue proceeds as follows:

i. Transaction 1 in Route 1 commits, causing a message to be Enqueued on
mybadqueue.

ii. Transaction 2 in Route 2 starts, causing a message to be
(provisionally!) read from the queue. When the exception is thrown, the
transaction rolls back and un-dispatches the message (pushing it back into
the queue again).

iii. Step ii. repeats a few times until maximumRedeliveries is reached, and
then the message gets transferred to the dead letter queue.

There is no mechanism here for propagating the exception all the way back to
the original producer endpoint. I hope I haven't misunderstood what you are
trying to do!

Cheers,
Fintan


Ili Statistical wrote:
> 
> Hi Fintan,
> 
> 
> I basically took Camel spring example from 1.6.1
> (apache-camel-1.6.1\examples\camel-example-spring-jms) and modified
> it.
> I would like camel to propagate my exception (or jms fault) that
> happen in some nested route up to the original producer(client). I
> thought I can do this with transactions.
> 
> 
> My producer code looks like this:
> ===================
>         // get the camel template for Spring template style sending of
> messages (= producer)
>         ProducerTemplate<Exchange> camelTemplate =
> (ProducerTemplate<Exchange>) context.getBean("camelTemplate");
> 
>         System.out.println("Invoking the multiply with 22");
> 
>         Exchange exch = null;
>         try {
>         	exch = camelTemplate.send("jms:queue:numbers", new Processor(){
> 				public void process(Exchange exchange) throws Exception {
> 					exchange.setPattern(ExchangePattern.InOut);
> 					Message in = exchange.getIn();
> 					in.setBody("22");
> 				}
>         	});
>         	
>         	
> 	        int response =
> (Integer)camelTemplate.sendBody("jms:queue:numbers",
> ExchangePattern.InOut, 22);
> ========================================
> 
> So, yes, it is InOut.
> 
> 
> The multiplier endpoint simply multiplies the body by 3, and puts the
> result into exchange.
> However, the execution should not get to the multiplier, since the
> very first thing I do in Route 2 is to throw an exception:
> 
> Route 2:
>        from("jms:queue:mybadqueue")
>        .process(new Processor() {
>                        public void process(Exchange arg0) throws Exception
> {
>                                throw new Exception("Hello World
> Exception");
>                        }
> 
>        })
>       .to("multiplier");
> 
> I was hoping this exception will be propagated up to my producer.
> However, by default, with deadLetterQueue, the exception does not seem
> to be propageted.
> I thought this could be done with transactional error handler, and
> that's why I'm trying to understand how it works.
> Please, let me know what is the right way to do this?
> 
> 
> Thanks,
> Ilya.
> 
> 
> 
> 
> 
> 
> On Tue, Aug 25, 2009 at 2:14 AM, Fintan Bolton<fb...@progress.com>
> wrote:
>>
>> Hi Ilya,
>>
>> That's an interesting routing example. I have a couple of observations
>> about
>> your routes, based on my understanding of Camel transactions (which is by
>> no
>> means perfect!).
>>
>> Route 1:
>>
>>        from("jms:queue:numbers")
>>        .policy(pp)
>>        .to("jms:queue:mybadqueue?transactedInOut=true")
>>        .to("multiplier");
>>
>> I believe that the call, policy(pp), in this route is unnecessary. The
>> transaction has already been kicked off by the jms:queue:numbers
>> endpoint,
>> so there is no need to start it again. What policy(pp) actually does
>> (where
>> pp represents the PROPAGATION_REQUIRED policy) is to check whether a
>> transaction has already started on this thread. It has, so policy(pp)
>> does
>> nothing.
>>
>> I suspect that the transactedInOut setting is ignored in this context. My
>> understanding is that the options, transacted and transactedInOut, apply
>> only to consumer endpoints, not producer endpoints. Or, if
>> transactedInOut
>> is not being ignored, perhaps it is causing some unexpected behavior?
>>
>> A key point about the two routes in your example is that each of the
>> routes
>> are processed in separate transactions. A message will not be available
>> to
>> pull from the mybadqueue queue (Route 2) until the transaction in Route 1
>> has committed. So, if you are not seeing any messages in mybadqueue, that
>> implies that the transaction in Route 1 has not committed.
>>
>> Perhaps some part of Route 1 is hanging, thus preventing a commit? Could
>> you
>> clarify a couple of points:
>>
>> 1. Do the incoming messages (from jms:queue:numbers) have their JMS
>> ReplyTo
>> header set? As Claus says, if you are processing InOut exchanges, this is
>> a
>> special case.
>>
>> 2. What does the multiplier endpoint do? Could it be hanging (thus
>> preventing a commit)?
>>
>> 3. What happens when you remove the transactedInOut="true" setting? I
>> suspect that this setting is incorrect and might cause problems.
>>
>> -
>> Cheers,
>> Fintan
>>
>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25130955.html
>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25137993.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: JMS transactions between multiple routes

Posted by Ilya S <de...@gmail.com>.
Hi Fintan,


I basically took Camel spring example from 1.6.1
(apache-camel-1.6.1\examples\camel-example-spring-jms) and modified
it.
I would like camel to propagate my exception (or jms fault) that
happen in some nested route up to the original producer(client). I
thought I can do this with transactions.


My producer code looks like this:
===================
        // get the camel template for Spring template style sending of
messages (= producer)
        ProducerTemplate<Exchange> camelTemplate =
(ProducerTemplate<Exchange>) context.getBean("camelTemplate");

        System.out.println("Invoking the multiply with 22");

        Exchange exch = null;
        try {
        	exch = camelTemplate.send("jms:queue:numbers", new Processor(){
				public void process(Exchange exchange) throws Exception {
					exchange.setPattern(ExchangePattern.InOut);
					Message in = exchange.getIn();
					in.setBody("22");
				}
        	});
        	
        	
	        int response =
(Integer)camelTemplate.sendBody("jms:queue:numbers",
ExchangePattern.InOut, 22);
========================================

So, yes, it is InOut.


The multiplier endpoint simply multiplies the body by 3, and puts the
result into exchange.
However, the execution should not get to the multiplier, since the
very first thing I do in Route 2 is to throw an exception:

Route 2:
       from("jms:queue:mybadqueue")
       .process(new Processor() {
                       public void process(Exchange arg0) throws Exception {
                               throw new Exception("Hello World Exception");
                       }

       })
      .to("multiplier");

I was hoping this exception will be propagated up to my producer.
However, by default, with deadLetterQueue, the exception does not seem
to be propageted.
I thought this could be done with transactional error handler, and
that's why I'm trying to understand how it works.
Please, let me know what is the right way to do this?


Thanks,
Ilya.






On Tue, Aug 25, 2009 at 2:14 AM, Fintan Bolton<fb...@progress.com> wrote:
>
> Hi Ilya,
>
> That's an interesting routing example. I have a couple of observations about
> your routes, based on my understanding of Camel transactions (which is by no
> means perfect!).
>
> Route 1:
>
>        from("jms:queue:numbers")
>        .policy(pp)
>        .to("jms:queue:mybadqueue?transactedInOut=true")
>        .to("multiplier");
>
> I believe that the call, policy(pp), in this route is unnecessary. The
> transaction has already been kicked off by the jms:queue:numbers endpoint,
> so there is no need to start it again. What policy(pp) actually does (where
> pp represents the PROPAGATION_REQUIRED policy) is to check whether a
> transaction has already started on this thread. It has, so policy(pp) does
> nothing.
>
> I suspect that the transactedInOut setting is ignored in this context. My
> understanding is that the options, transacted and transactedInOut, apply
> only to consumer endpoints, not producer endpoints. Or, if transactedInOut
> is not being ignored, perhaps it is causing some unexpected behavior?
>
> A key point about the two routes in your example is that each of the routes
> are processed in separate transactions. A message will not be available to
> pull from the mybadqueue queue (Route 2) until the transaction in Route 1
> has committed. So, if you are not seeing any messages in mybadqueue, that
> implies that the transaction in Route 1 has not committed.
>
> Perhaps some part of Route 1 is hanging, thus preventing a commit? Could you
> clarify a couple of points:
>
> 1. Do the incoming messages (from jms:queue:numbers) have their JMS ReplyTo
> header set? As Claus says, if you are processing InOut exchanges, this is a
> special case.
>
> 2. What does the multiplier endpoint do? Could it be hanging (thus
> preventing a commit)?
>
> 3. What happens when you remove the transactedInOut="true" setting? I
> suspect that this setting is incorrect and might cause problems.
>
> -
> Cheers,
> Fintan
>
>
>
> --
> View this message in context: http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25130955.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>

Re: JMS transactions between multiple routes

Posted by Fintan Bolton <fb...@progress.com>.
Hi Ilya,

That's an interesting routing example. I have a couple of observations about
your routes, based on my understanding of Camel transactions (which is by no
means perfect!).

Route 1:

        from("jms:queue:numbers")
        .policy(pp)
        .to("jms:queue:mybadqueue?transactedInOut=true")
        .to("multiplier");

I believe that the call, policy(pp), in this route is unnecessary. The
transaction has already been kicked off by the jms:queue:numbers endpoint,
so there is no need to start it again. What policy(pp) actually does (where
pp represents the PROPAGATION_REQUIRED policy) is to check whether a
transaction has already started on this thread. It has, so policy(pp) does
nothing.

I suspect that the transactedInOut setting is ignored in this context. My
understanding is that the options, transacted and transactedInOut, apply
only to consumer endpoints, not producer endpoints. Or, if transactedInOut
is not being ignored, perhaps it is causing some unexpected behavior?

A key point about the two routes in your example is that each of the routes
are processed in separate transactions. A message will not be available to
pull from the mybadqueue queue (Route 2) until the transaction in Route 1
has committed. So, if you are not seeing any messages in mybadqueue, that
implies that the transaction in Route 1 has not committed.

Perhaps some part of Route 1 is hanging, thus preventing a commit? Could you
clarify a couple of points:

1. Do the incoming messages (from jms:queue:numbers) have their JMS ReplyTo
header set? As Claus says, if you are processing InOut exchanges, this is a
special case.

2. What does the multiplier endpoint do? Could it be hanging (thus
preventing a commit)?

3. What happens when you remove the transactedInOut="true" setting? I
suspect that this setting is incorrect and might cause problems.

-
Cheers,
Fintan



-- 
View this message in context: http://www.nabble.com/JMS-transactions-between-multiple-routes-tp25126004p25130955.html
Sent from the Camel - Users mailing list archive at Nabble.com.