camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From efender <>
Subject Re: Saving original destination when sending to DLQ
Date Tue, 09 Dec 2008 14:36:58 GMT

Here's my entire spring context.  What I'm trying to implement is a form of
guaranteed message processing.  This is just a proof of concept, so ignore
the Foo/Bar/Baz names and such.

User requests to block another user.
BlockUserRequest is created and sent to
com.webshots.messaging.ContentEnricher simulates DB lookup of the blocked
user's e-mail and other user IDs with the same e-mail
enriched BlockUserRequest is sent to jms:queue:dynamicQueues/Bar (handled by
com.webshots.messaging.Bar) and jms:queue:dynamicQueues/Baz (handled by
com.webshots.messaging.Baz) to perform part of the functionality
com.webshots.messaging.Baz always throws an Exception, just for testing
message sent to jms:queue:dynamicQueues/Baz ends up in
jms:queue:dynamicQueues/DLQ and
com.webshots.messaging.DeadLetterPersistanceProcessor mocks saving it to a
DB (and possibly sends an e-mail)

In com.webshots.messaging.DeadLetterPersistanceProcessor I need to know what
Exception caused the message to be routed to the DLQ and what the original
destination was.  Then I can create a web interface to the stored dead
letters where an administrator can view/edit the message and exception
contents and resend or discard.

If there's a better way to implement this, please feel free to let me know. 

<beans xmlns=""

	<context:component-scan base-package="com.webshots.messaging"/>

	<camel:camelContext id="camel">


		<camel:template id="camelTemplate"/>

		<camel:route errorHandlerRef="deadLetterErrorHandler">
			<camel:from uri="jms:queue:dynamicQueues/BlockUserQueue"/>
			<!--  EIP Content Enricher Pattern -->
			<camel:bean ref="contentEnricher"/>
			<!--  EIP Splitter Pattern -->
			<camel:multicast parallelProcessing="true">
				<camel:to uri="jms:queue:dynamicQueues/Bar"/>
				<camel:to uri="jms:queue:dynamicQueues/Baz"/>
		<camel:route errorHandlerRef="deadLetterErrorHandler">
			<camel:from uri="jms:queue:dynamicQueues/Bar"/>
			<camel:bean ref="bar"/>
		<camel:route errorHandlerRef="deadLetterErrorHandler">
			<camel:from uri="jms:queue:dynamicQueues/Baz"/>
			<camel:bean ref="baz"/>
		<camel:route errorHandlerRef="infiniteRetryErrorHandler">
			<camel:from uri="jms:queue:dynamicQueues/DLQ"/>
			<camel:process ref="deadLetterPersistanceHandler"/>

	<bean id="contentEnricher" class="com.webshots.messaging.ContentEnricher"/>
	<bean id="bar" class="com.webshots.messaging.Bar"/>
	<bean id="baz" class="com.webshots.messaging.Baz"/>
	<bean id="deadLetterPersistanceHandler"

	<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
	    <property name="connectionFactory">
	        <bean class="org.apache.activemq.ActiveMQConnectionFactory">
			<property name="brokerURL" value="tcp://localhost:61616"/>

	<bean id="headerCopyProcessor"

	<bean id="deadLetterRecipientsExpression"
		<constructor-arg value="jms:queue:dynamicQueues/DLQ"/>

	<bean id="deadLetterRecipientList"
		<constructor-arg ref="deadLetterRecipientsExpression"/>

	<bean id="deadLetterProcessor"
				<ref bean="headerCopyProcessor"/>
				<ref bean="deadLetterRecipientList"/>

	<bean id="deadLetterFactory"
		<constructor-arg ref="deadLetterProcessor"/>

	<bean id="deadLetterErrorHandler"
		<property name="redeliveryPolicy" ref="redeliveryPolicy"/>
		<property name="deadLetterFactory" ref="deadLetterFactory"/>

	<bean id="redeliveryPolicy"
		<property name="delay" value="1000"/>
		<property name="backOffMultiplier" value="2"/>
		<property name="useExponentialBackOff" value="true"/>
		<!-- this should make it retry 1s, 2s, 4s, 8s, 16s, 32s, ~1m, ~2m, ~4m,
~9m, ~17m, ~34m, ~68m, ~137m for a total of ~4.5h -->
		<!--<property name="maximumRedeliveries" value="14"/>-->
		<property name="maximumRedeliveries" value="1"/>

	<bean id="infiniteRetryErrorHandler"
		<property name="redeliveryPolicy" ref="infiniteRetryPolicy"/>

	<!-- TODO don't retry for NPE, etc. -->
	<bean id="infiniteRetryPolicy"
		<property name="delay" value="60000"/>
		<property name="maximumRedeliveries" value="-1"/>
		<property name="useCollisionAvoidance" value="true"/>

	<bean id="blockUserRequest" scope="prototype"
		<property name="destinationUri"
		<property name="camelTemplate" ref="camelTemplate"/>


Claus Ibsen-2 wrote:
> Hi
> Could you post your route, to help get a view of your problem?
> To my knowledge the Exchange that is routed to DLC is the "original"
> exchange as it was before it was processed by the node in the route
> graph that failed. So if this node is a JMS producer the exchange
> should have the JMS headers as well?
> For example:
> from(x).process(y).to("jms:zzz");
> If the error happens in the (to jms:zzz) the Exchange that is routed
> to DLQ is how the exchange looks like from the output of the
> process(y) node.
> But it helps if you could show the route and pin point where the error
> happens
> /Claus Ibsen
> Apache Camel Committer
> Blog:
> On Tue, Dec 9, 2008 at 2:07 PM, efender <> wrote:
>> How can I record the original destination when routing to my DLQ?
>> I've tried a custom processor which does this:
>> public void process(Exchange exchange) throws Exception {
>>        org.apache.camel.Message in = exchange.getIn();
>>        org.apache.camel.Message out = in.copy();
>>        out.setHeader("originalDestination",
>> in.getHeader("JMSDestination"));
>>        exchange.setProperty("originalDestination",
>> in.getHeader("JMSDestination"));
>>        exchange.setOut(out);
>> }
>> But neither the property nor the header is set in my bean which listens
>> to
>> the DLQ.  Do I need to modify/subclass
>> org.apache.camel.processor.DeadLetterChannel to get this behavior?
>> Also, I'd like to save the original Exception that caused the message to
>> get
>> routed to the DLQ as well.  I see that it is stored in
>> org.apache.camel.processor.DeadLetterChannel.FAILURE_HANDLED and
>> CamelCauseException, but those properties disappear by the time the
>> message
>> gets to the DLQ.
>> Any recommendations on how to save this info in a best practice sort of
>> way?
>> Thanks.
>> --
>> View this message in context:
>> Sent from the Camel - Users mailing list archive at

View this message in context:
Sent from the Camel - Users mailing list archive at

View raw message