You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "E.Gherardini" <e....@hotmail.com> on 2012/06/23 13:11:08 UTC

Camel 2.9.1 DeadLetterChannel infinite loop

Hello ,
I am struggling with a strange issue using a simple deadLetterChannel error
handler with some onException clauses.

The route goes into an infinite loop, and debugging (going step by step in
the method "RedeliveryErrorHandler.processErrorHandler(exchange,
asynchcallback, data) ) 
I observe that the redelivery counter gets always reset to 0.

Here is my route:
{code}



	@Override
	public void configure() throws Exception {
		
		from(Constants.INBOUND_QUEUE)
		
			.errorHandler(dlcb
				.maximumRedeliveries(redeliveriesCount)
				.useOriginalMessage()
				.redeliveryDelay(redeliveryDelay)
				.onRedelivery(
						new MyOwnLoggerProcessor(
								"Message Redelivery in progress.")))

		
		.onException(MessageOutOfSyncException.class)
				.useOriginalMessage()
				.handled(true)
				.maximumRedeliveries(redeliveriesCountOutOfSync)
				.onRedelivery(
						new MyOwnLoggerProcessor("Requeueing message to "
								+ Constants.RDBMS_WRITES_INBOUND_QUEUE))

				.to(Constants.INBOUND_QUEUE)
			.end()

		// this message is duplicated, discard it to dead letter queue
		.onException(DuplicatedEventMessageException.class)
				.useOriginalMessage()
				.handled(true)
				.process(
						new MyOwnLoggerProcessor(
								"Sending duplicated message to dead letter queue"))
				.to(dlcb.getDeadLetterUri())
			.end()
			
		.threads(routeExecutionThreadCountCount)

		.choice()
				.when(body().isInstanceOf(Test1.class))
					.process(test1Processor)
				
				// otherwhise we send it to dead letter queue
				.otherwise()
					.process(new MyOwnLoggerProcessor("Unhandled Message: "))
					.to(dlcb.getDeadLetterUri()).stop()

		;

	}

{code}

The Dead Letter Queue Builder is constructed in the constructor of my class,
in this way:
{code}
dlcb = new DeadLetterChannelBuilder(
				Constants.INBOUND_QUEUE + "/deadLetter");
		dlcb.setFailureProcessor(new MyOwnLoggerProcessor(
				"Message Delivery Failure"));

{code}

Can someone help me figuring out what's happening ?

Thanks a lot in advance.

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Ah i forgot to mention that the above route is preceeded by another route,
with its own errorHandler:
[code]
dlcb = new
DeadLetterChannelBuilder(Constants.MAIN_INBONUND_QUEUE+"/deadLetter");
		dlcb.setFailureProcessor(new MyLoggingProcessor("Message Delivery
Failure"));
...
@Override
		public void configure() throws Exception {
			
			from(Constants.MAIN_INBONUND_QUEUE)
			
.errorHandler(dlcb.maximumRedeliveries(redeliveriesCount).redeliveryDelay(redeliveryDelay).onRedelivery(new
MyLoggingProcessor("Message redelivery in progress.")))
				.threads(routeExecutionThreadCountCount)
				.multicast().parallelProcessing().to(Constants.ANOTHER_QUEUE,
Constants.INBOUND_QUEUE)
				
				;
			
[code]

and that even if the failure occurs on the second route (the one described
in the previous message) I notice this error handler is also involved, and I
can't figure out why really...

The error I situation I am testing is the "DuplicatedMessageException" one.

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714963.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Henryk Konsek <he...@gmail.com>.
> Consider sending the message to the persistent DLC

With something like deadLetterChannel("jms:persistentQueue") of course :) .

-- 
Henryk Konsek
http://henryk-konsek.blogspot.com

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Henryk Konsek <he...@gmail.com>.
> What I am trying to achieve is a redelivery happening from the beginning of
> the route, putting the message back on the inbound queue (which lives in a
> distributed message broker) so to reduce at minimum the possibility of
> loosing the message in case the JVM performing the camel retries fails.

Consider sending the message to the persistent DLC [1] (like
persistent JMS queue [2], JDBC [3], db4o [4], Hibernate [5], HawtDB
[5] and so forth). Then you can read from the DLC by yourself and try
to redeliver the message.

[1] http://camel.apache.org/dead-letter-channel.html
[2] http://camel.apache.org/jms.html
[3] http://camel.apache.org/jdbc.html
[4] http://camel.apache.org/db4o.html
[5] http://camel.apache.org/hibernate.html
[6] http://camel.apache.org/hawtdb.html

-- 
Henryk Konsek
http://henryk-konsek.blogspot.com

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Hello sarfarj,
this is the doTry() doCatch() solution I've found. I remark that the
approach suggested by Claus (which is basically using the Recipient List EIP
to choose the dead letter queue at runtime) is much more cleaner.

	@Override
	public void configure() throws Exception {
		
		from(INBOUND_QUEUE)
			
			.threads(routeExecutionThreadCount)
		
			.doTry()
				
				.to(DEST_1, DEST_2)			
				
			.doCatch(Exception.class)
			
				.process(new
CounterHeaderIncrementorProcessor(Constants.MY_REDELIVERIES_COUNTER_HEADER,
1))
				
				.choice()
				
				
.when(header(Constants.MY_REDELIVERIES_COUNTER_HEADER).isLessThanOrEqualTo(redeliveriesCount))
						// redeliver 'redeliveriesCount' times
						.log(LoggingLevel.ERROR, exceptionMessage().toString())
						
						.to(INBOUND_QUEUE).stop()
						
					.otherwise()
					
						.log(LoggingLevel.ERROR,"Message <${body}> sent to deadLetterQueue <"+
DEAD_LETTER_QUEUE + ">")
						
						.to(DEAD_LETTER_QUEUE).stop()
						
				.end()
				
			.end()
		;

	}

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715422.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by sarfaraj <sa...@gmail.com>.
Could you please paste the code here? what you did to resolved?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715399.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Thanks a lot Claus,
I was able to achieve the same result with the doTry() doCatch() approach,
but your solution is much cleaner since it leverages already existing Camel.

Thanks a lot again.

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715021.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Thanks a lot Claus.

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715765.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Claus Ibsen <cl...@gmail.com>.
On Mon, Jul 9, 2012 at 4:49 PM, E.Gherardini <e....@hotmail.com> wrote:
> Hello Claus,
> I am getting problems in running this inside an OSGi context.
>
> In my opinion this should work registering the bean as a Service in the OSGi
> context, from the same bundle which adds the route to the CamelContext, but
> in such way when the BeanProcessor gets the message it cannot load the bean
> implementing the RecipientList EIP.
>

In the blueprint XML file, you need to have a <bean> for your bean,
and refer to this bean id in the Camel route.
And have the bean code in the same bundle.


> Any suggestion ?
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715743.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Hello Claus,
I am getting problems in running this inside an OSGi context.

In my opinion this should work registering the bean as a Service in the OSGi
context, from the same bundle which adds the route to the CamelContext, but
in such way when the BeanProcessor gets the message it cannot load the bean
implementing the RecipientList EIP.

Any suggestion ?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5715743.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Claus Ibsen <cl...@gmail.com>.
On Sun, Jun 24, 2012 at 1:53 PM, E.Gherardini <e....@hotmail.com> wrote:
> Hello Claus,
> thanks for answering.
> unfortunately clients of these routes can't be transactional, they can only
> be fire-and-forget, that is why I am implementing this logic.
>
> Could a doTry / doCatch route be a reasonable approach in your opinion ?
>

I have created an unit test that shows how you could do this.
http://svn.apache.org/viewvc?rev=1353280&view=rev


> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714990.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Hello Claus,
thanks for answering.
unfortunately clients of these routes can't be transactional, they can only
be fire-and-forget, that is why I am implementing this logic.

Could a doTry / doCatch route be a reasonable approach in your opinion ?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714990.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Claus Ibsen <cl...@gmail.com>.
On Sun, Jun 24, 2012 at 11:38 AM, E.Gherardini <e....@hotmail.com> wrote:
> Hello Filippo,
> thanks again for replying me.
>
> You caught exactly my point: I do not want to loose messages: unfortunately
> my application cannot use transactions, that's why I am handling this by
> hand.
>
> I am starting to think that the only possible way is writing my own error
> handler using standard camel processors, but before starting it by hand I
> want to make sure I am not "reinventing the wheel": is it possible to
> achieve what I want using some existing came feature ?
>

The redelivery functionality in Camel is designed to execute from the
point of error, and *not* from the beginning of the route.

If you want to restart all over, then you need to propagate the error
back to the calle (client) and let it re-submit, eg like transaction
can do - the transactional client EIP.




> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714986.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Hello Filippo,
thanks again for replying me.

You caught exactly my point: I do not want to loose messages: unfortunately
my application cannot use transactions, that's why I am handling this by
hand.

I am starting to think that the only possible way is writing my own error
handler using standard camel processors, but before starting it by hand I
want to make sure I am not "reinventing the wheel": is it possible to
achieve what I want using some existing came feature ?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714986.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Filippo Balicchia <fb...@gmail.com>.
According with dead letter channel definition if you can't deliver
message, it may be elect to move the message to a dead letter channel.
With camel you can use different redelivery policy to do it .


>From your message seems to understand that you don't want loose
message when something bad happens.
I this case http://www.enterpriseintegrationpatterns.com/TransactionalClient.html
can help you to resolve your need

Is it ok for you ?

Chees

--Filippo



2012/6/23 E.Gherardini <e....@hotmail.com>:
> Or, to better say, I would like to instruct the Camel
> DeadletterChannelErrorHandler to resent the message to the inbound queue
> when redelivering, and to the dead letter queue when all redeliveries
> failed.
>
> is this possible ?
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714970.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Or, to better say, I would like to instruct the Camel
DeadletterChannelErrorHandler to resent the message to the inbound queue
when redelivering, and to the dead letter queue when all redeliveries
failed.

is this possible ?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714970.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
Hello Filippo,
thanks for replying.

What I am trying to achieve is a redelivery happening from the beginning of
the route, putting the message back on the inbound queue (which lives in a
distributed message broker) so to reduce at minimum the possibility of
loosing the message in case the JVM performing the camel retries fails.

It seems to me there isn't a way to customize Camel RedeliveryErrorHandler
with such a behaviour, what do you think ?

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714969.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by Filippo Balicchia <fb...@gmail.com>.
Hello,
It's correct.
>From my point of view to break infinite loop you need configure your
RedeliveryPolicy  without
.to(Constants.INBOUND_QUEUE) instruction


--Filippo


2012/6/23 E.Gherardini <e....@hotmail.com>:
> My question lies behind the fact that I understood onException clause is used
> until the set maximumRedelivery is reached, and then the DLC would come in.
>
> Is this correct?
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714967.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel 2.9.1 DeadLetterChannel infinite loop

Posted by "E.Gherardini" <e....@hotmail.com>.
My question lies behind the fact that I understood onException clause is used
until the set maximumRedelivery is reached, and then the DLC would come in.

Is this correct? 

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-2-9-1-DeadLetterChannel-infinite-loop-tp5714961p5714967.html
Sent from the Camel - Users mailing list archive at Nabble.com.