Modified: websites/production/camel/content/dead-letter-channel.html
==============================================================================
--- websites/production/camel/content/dead-letter-channel.html (original)
+++ websites/production/camel/content/dead-letter-channel.html Fri Aug 25
10:20:13 2017
@@ -36,17 +36,6 @@
<![endif]-->
- <link href='//camel.apache.org/styles/highlighter/styles/shCoreCamel.css'
rel='stylesheet' type='text/css' />
- <link href='//camel.apache.org/styles/highlighter/styles/shThemeCamel.css'
rel='stylesheet' type='text/css' />
- <script src='//camel.apache.org/styles/highlighter/scripts/shCore.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushJava.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushXml.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushPlain.js'
type='text/javascript'></script>
-
- <script type="text/javascript">
- SyntaxHighlighter.defaults['toolbar'] = false;
- SyntaxHighlighter.all();
- </script>
<title>
Apache Camel: Dead Letter Channel
@@ -86,158 +75,45 @@
<tbody>
<tr>
<td valign="top" width="100%">
-<div class="wiki-content maincontent"><h2
id="DeadLetterChannel-DeadLetterChannel">Dead Letter Channel</h2><p>Camel
supports the <a shape="rect" class="external-link"
href="http://www.enterpriseintegrationpatterns.com/DeadLetterChannel.html"
rel="nofollow">Dead Letter Channel</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> using the <a
shape="rect" class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html">DeadLetterChannel</a>
processor which is an <a shape="rect" href="error-handler.html">Error
Handler</a>.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/DeadLetterChannelSolution.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/DeadLetterChannelSolution.gif"></span></p><div
class="confluence-information-macro confluenc
e-information-macro-tip"><p class="title">Differences Between The
DeadLetterChannel And The DefaultErrorHandler</p><span class="aui-icon
aui-icon-small aui-iconfont-approve
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>The <strong><code>DefaultErrorHandler</code></strong>
does very little: it ends the Exchange immediately and propagates the thrown
Exception back to the
caller.</p><p>The <strong><code>DeadLetterChannel</code></strong> lets you
control behaviors including redelivery, whether to propagate the thrown
Exception to the caller (the <strong><code>handled</code></strong>
option), and where the (failed) Exchange should now be routed
to.</p><p>The <strong><code>DeadLetterChannel</code></strong> is also by
default configured to not be verbose in the logs, so when a message is handled
and moved to the dead letter endpoint, then there is nothing logged. If you
want some level of logging you can use the various opti
ons on the redelivery policy / dead letter channel to configure this. For
example if you want the message history then
set <strong><code>logExhaustedMessageHistory=true</code></strong>
(and <strong><code>logHandled=true</code></strong> for <strong>Camel
2.15.x</strong> or older).</p><p>When
the <strong><code>DeadLetterChannel</code></strong> moves a message to the
dead letter endpoint, any new Exception thrown is by default handled by the
dead letter channel as well. This ensures that
the <strong><code>DeadLetterChannel</code></strong> will always succeed.
From <strong>Camel 2.15</strong>: this behavior can be changed by setting the
option <strong><code>deadLetterHandleNewException=false</code></strong>. Then
if a new Exception is thrown, then the dead letter channel will fail and
propagate back that new Exception (which is the behavior of the default error
handler). When a new Exception occurs then the dead letter channel logs this
at <strong><code>WARN</co
de></strong> level. This can be turned off by setting
<strong><code>logNewException=false</code></strong>.</p></div></div><h3
id="DeadLetterChannel-Redelivery">Redelivery</h3><p>It is common for a
temporary outage or database deadlock to cause a message to fail to process;
but the chances are if its tried a few more times with some time delay then it
will complete fine. So we typically wish to use some kind of redelivery policy
to decide how many times to try redeliver a message and how long to wait before
redelivery attempts.</p><p>The <a shape="rect" class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html">RedeliveryPolicy</a>
defines how the message is to be redelivered. You can customize things
like</p><ul><li>The number of times a message is attempted to be redelivered
before it is considered a failure and sent to the dead letter
channel.</li><li>The initial redelivery timeout.</li><li>Whether or not
exponential backoff is used, i.e., the time between retries increases using a
backoff multiplier.</li><li>Whether to use collision avoidance to add some
randomness to the timings.</li><li>Delay pattern (see below for
details).</li><li><strong>Camel 2.11:</strong> Whether to allow redelivery
during stopping/shutdown.</li></ul><p>Once all attempts at redelivering the
message fails then the message is forwarded to the dead letter queue.</p><h3
id="DeadLetterChannel-AboutMovingExchangetoDeadLetterQueueandUsinghandled()">About
Moving Exchange to Dead Letter Queue and
Using <strong><code>handled()</code></strong></h3><p><strong><code>handled()</code></strong>
on <a shape="rect" href="dead-letter-channel.html">Dead Letter
Channel</a></p><p>When all attempts of redelivery have failed the <a
shape="rect" href="exchange.html">Exchange</a> is moved to the dead letter
queue (the dead letter endpoint). The exchange is then complete and from the
client point of view it was processed. As such
the <a shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a>
have handled the <a shape="rect" href="exchange.html">Exchange</a>.</p><p>For
instance configuring the dead letter channel as:</p><p><strong>Using the <a
shape="rect" href="fluent-builders.html">Fluent Builders</a></strong></p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[errorHandler(deadLetterChannel("jms:queue:dead")
+<div class="wiki-content maincontent"><h2
id="DeadLetterChannel-DeadLetterChannel">Dead Letter Channel</h2><p>Camel
supports the <a shape="rect" class="external-link"
href="http://www.enterpriseintegrationpatterns.com/DeadLetterChannel.html"
rel="nofollow">Dead Letter Channel</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> using the <a
shape="rect" class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html">DeadLetterChannel</a>
processor which is an <a shape="rect" href="error-handler.html">Error
Handler</a>.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/DeadLetterChannelSolution.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/DeadLetterChannelSolution.gif"></span></p><parameter
ac:name="title">Differences Between The
DeadLetterChannel And The
DefaultErrorHandler</parameter><rich-text-body><p>The <strong><code>DefaultErrorHandler</code></strong>
does very little: it ends the Exchange immediately and propagates the thrown
Exception back to the
caller.</p><p>The <strong><code>DeadLetterChannel</code></strong> lets you
control behaviors including redelivery, whether to propagate the thrown
Exception to the caller (the <strong><code>handled</code></strong>
option), and where the (failed) Exchange should now be routed
to.</p><p>The <strong><code>DeadLetterChannel</code></strong> is also by
default configured to not be verbose in the logs, so when a message is handled
and moved to the dead letter endpoint, then there is nothing logged. If you
want some level of logging you can use the various options on the redelivery
policy / dead letter channel to configure this. For example if you want the
message history then
set <strong><code>logExhaustedMessageHistory=true</code></strong
> (and <strong><code>logHandled=true</code></strong> for <strong>Camel
> 2.15.x</strong> or older).</p><p>When
> the <strong><code>DeadLetterChannel</code></strong> moves a message to
> the dead letter endpoint, any new Exception thrown is by default handled by
> the dead letter channel as well. This ensures that
> the <strong><code>DeadLetterChannel</code></strong> will always
> succeed. From <strong>Camel 2.15</strong>: this behavior can be changed by
> setting the option
> <strong><code>deadLetterHandleNewException=false</code></strong>. Then if a
> new Exception is thrown, then the dead letter channel will fail and
> propagate back that new Exception (which is the behavior of the default
> error handler). When a new Exception occurs then the dead letter channel
> logs this at <strong><code>WARN</code></strong> level. This can be
> turned off by setting
> <strong><code>logNewException=false</code></strong>.</p></rich-text-body><h3
> id="DeadLetterChannel-Redelivery">Redelivery</h3><p>It is
common for a temporary outage or database deadlock to cause a message to fail
to process; but the chances are if its tried a few more times with some time
delay then it will complete fine. So we typically wish to use some kind of
redelivery policy to decide how many times to try redeliver a message and how
long to wait before redelivery attempts.</p><p>The <a shape="rect"
class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html">RedeliveryPolicy</a>
defines how the message is to be redelivered. You can customize things
like</p><ul><li>The number of times a message is attempted to be redelivered
before it is considered a failure and sent to the dead letter
channel.</li><li>The initial redelivery timeout.</li><li>Whether or not
exponential backoff is used, i.e., the time between retries increases using a
backoff multiplier.</li><li>Whether to use collision avoidance to add some
randomness to the timings.</li
><li>Delay pattern (see below for details).</li><li><strong>Camel
>2.11:</strong> Whether to allow redelivery during
>stopping/shutdown.</li></ul><p>Once all attempts at redelivering the message
>fails then the message is forwarded to the dead letter queue.</p><h3
>id="DeadLetterChannel-AboutMovingExchangetoDeadLetterQueueandUsinghandled()">About
> Moving Exchange to Dead Letter Queue and
>Using <strong><code>handled()</code></strong></h3><p><strong><code>handled()</code></strong>
> on <a shape="rect" href="dead-letter-channel.html">Dead Letter
>Channel</a></p><p>When all attempts of redelivery have failed the <a
>shape="rect" href="exchange.html">Exchange</a> is moved to the dead letter
>queue (the dead letter endpoint). The exchange is then complete and from the
>client point of view it was processed. As such the <a shape="rect"
>href="dead-letter-channel.html">Dead Letter Channel</a> have handled the <a
>shape="rect" href="exchange.html">Exchange</a>.</p><p>For instance
>configuring the dea
d letter channel as:</p><p><strong>Using the <a shape="rect"
href="fluent-builders.html">Fluent Builders</a></strong></p><parameter
ac:name="language">java</parameter><plain-text-body>errorHandler(deadLetterChannel("jms:queue:dead")
.maximumRedeliveries(3).redeliveryDelay(5000));
-]]></script>
-</div></div><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML Extensions</a></strong></p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: xml; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[<route
errorHandlerRef="myDeadLetterErrorHandler">
+</plain-text-body><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML
Extensions</a></strong></p><parameter
ac:name="language">xml</parameter><plain-text-body><route
errorHandlerRef="myDeadLetterErrorHandler">
<!-- ... -->
</route>
-<bean id="myDeadLetterErrorHandler"
class="org.apache.camel.builder.DeadLetterChannelBuilder">
- <property name="deadLetterUri"
value="jms:queue:dead"/>
- <property name="redeliveryPolicy"
ref="myRedeliveryPolicyConfig"/>
+<bean id="myDeadLetterErrorHandler"
class="org.apache.camel.builder.DeadLetterChannelBuilder">
+ <property name="deadLetterUri" value="jms:queue:dead"/>
+ <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
</bean>
-<bean id="myRedeliveryPolicyConfig"
class="org.apache.camel.processor.RedeliveryPolicy">
- <property name="maximumRedeliveries" value="3"/>
- <property name="redeliveryDelay" value="5000"/>
+<bean id="myRedeliveryPolicyConfig"
class="org.apache.camel.processor.RedeliveryPolicy">
+ <property name="maximumRedeliveries" value="3"/>
+ <property name="redeliveryDelay" value="5000"/>
</bean>
-]]></script>
-</div></div><p>The <a shape="rect" href="dead-letter-channel.html">Dead Letter
Channel</a> above will clear the caused exception
<strong><code>setException(null)</code></strong>, by moving the caused
exception to a property on the <a shape="rect"
href="exchange.html">Exchange</a>, with the key
<strong><code>Exchange.EXCEPTION_CAUGHT</code></strong>. Then the <a
shape="rect" href="exchange.html">Exchange</a> is moved to the
<strong><code>jms:queue:dead</code></strong> destination and the client will
not notice the failure.</p><h3
id="DeadLetterChannel-AboutMovingExchangetoDeadLetterQueueandUsingtheOriginalMessage">About
Moving Exchange to Dead Letter Queue and Using the Original Message</h3><p>The
option <strong><code>useOriginalMessage</code></strong> is used for routing the
original input message instead of the current message that potentially is
modified during routing.</p><p>For instance if you have this route:</p><div
class="code panel pdl" style="border-width: 1px;"><div class=
"codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[ from("jms:queue:order:input")
- .to("bean:validateOrder")
- .to("bean:transformOrder")
- .to("bean:handleOrder");
-]]></script>
-</div></div><p>The route listen for JMS messages and validates, transforms and
handle it. During this the <a shape="rect" href="exchange.html">Exchange</a>
payload is transformed/modified. So in case something goes wrong and we want to
move the message to another JMS destination, then we can configure our <a
shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a> with
the <strong><code>useOriginalMessage</code></strong> option. But when we
move the <a shape="rect" href="exchange.html">Exchange</a> to this destination
we do not know in which state the message is in. Did the error happen in before
the <strong><code>transformOrder</code></strong> or after? So to be sure
we want to move the original input message we received from
<strong><code>jms:queue:order:input</code></strong>. So we can do this by
enabling the <strong><code>useOriginalMessage</code></strong> option as
shown below:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="code
Content panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[// will use original body
-errorHandler(deadLetterChannel("jms:queue:dead")
+</plain-text-body><p>The <a shape="rect" href="dead-letter-channel.html">Dead
Letter Channel</a> above will clear the caused exception
<strong><code>setException(null)</code></strong>, by moving the caused
exception to a property on the <a shape="rect"
href="exchange.html">Exchange</a>, with the key
<strong><code>Exchange.EXCEPTION_CAUGHT</code></strong>. Then the <a
shape="rect" href="exchange.html">Exchange</a> is moved to the
<strong><code>jms:queue:dead</code></strong> destination and the client will
not notice the failure.</p><h3
id="DeadLetterChannel-AboutMovingExchangetoDeadLetterQueueandUsingtheOriginalMessage">About
Moving Exchange to Dead Letter Queue and Using the Original Message</h3><p>The
option <strong><code>useOriginalMessage</code></strong> is used for routing the
original input message instead of the current message that potentially is
modified during routing.</p><p>For instance if you have this
route:</p><parameter ac:name="language">java</parameter><plain-text-bo
dy> from("jms:queue:order:input")
+ .to("bean:validateOrder")
+ .to("bean:transformOrder")
+ .to("bean:handleOrder");
+</plain-text-body><p>The route listen for JMS messages and validates,
transforms and handle it. During this the <a shape="rect"
href="exchange.html">Exchange</a> payload is transformed/modified. So in case
something goes wrong and we want to move the message to another JMS
destination, then we can configure our <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> with
the <strong><code>useOriginalMessage</code></strong> option. But when we
move the <a shape="rect" href="exchange.html">Exchange</a> to this destination
we do not know in which state the message is in. Did the error happen in before
the <strong><code>transformOrder</code></strong> or after? So to be sure
we want to move the original input message we received from
<strong><code>jms:queue:order:input</code></strong>. So we can do this by
enabling the <strong><code>useOriginalMessage</code></strong> option as
shown below:</p><parameter
ac:name="language">java</parameter><plain-text-body>//
will use original body
+errorHandler(deadLetterChannel("jms:queue:dead")
.useOriginalMessage()
.maximumRedeliveries(5)
.redeliverDelay(5000);
-]]></script>
-</div></div><p>Then the messages routed to the
<strong><code>jms:queue:dead</code></strong> is the original input. If we want
to manually retry we can move the JMS message from the failed to the input
queue, with no problem as the message is the same as the original we
received.</p><h3 id="DeadLetterChannel-OnRedelivery">OnRedelivery</h3><p>When
<a shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a> is
doing redeliver its possible to configure a <a shape="rect"
href="processor.html">Processor</a> that is executed just
<strong>before</strong> every redelivery attempt. This can be used for the
situations where you need to alter the message before its redelivered. See
below for sample.</p><div class="confluence-information-macro
confluence-information-macro-tip"><p class="title">onException and
onRedeliver</p><span class="aui-icon aui-icon-small aui-iconfont-approve
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>We also supp
ort for per <a shape="rect"
href="exception-clause.html"><strong>onException</strong></a> to set an
<strong><code>onRedeliver</code></strong>. That means you can do special on
redelivery for different exceptions, as opposed
to <strong><code>onRedelivery</code></strong> set on <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> can be viewed as a
global scope.</p></div></div><h3
id="DeadLetterChannel-RedeliveryDefaultValues">Redelivery Default
Values</h3><p>Redelivery is disabled by default.</p><p>The default redeliver
policy will use the following
values:</p><ul><li><strong><code>maximumRedeliveries=0</code></strong></li><li><strong><code>redeliverDelay=1000L</code></strong>
(1 second)</li><li><strong><code>maximumRedeliveryDelay = 60 *
1000L</code></strong> (60
seconds)</li><li><strong><code>backOffMultiplier</code></strong> and
<strong><code>useExponentialBackOff</code></strong> are
ignored.</li><li><strong><code>retriesExhaustedLogLevel=LoggingLevel.ERROR
</code></strong></li><li><strong><code>retryAttemptedLogLevel=LoggingLevel.DEBUG</code></strong></li><li>Stack
traces are logged for exhausted messages, from <strong>Camel
2.2</strong>.</li><li>Handled exceptions are not logged, from <strong>Camel
2.3</strong>.</li><li><strong><code>logExhaustedMessageHistory</code></strong>
is true for default error handler, and false for dead letter
channel.</li><li><strong><code>logExhaustedMessageBody</code></strong>
<strong>Camel 2.17:</strong> is disabled by default to avoid logging
sensitive message body/header details. If this option is
<strong><code>true</code></strong>,
then <strong><code>logExhaustedMessageHistory</code></strong> must also be
<strong><code>true</code></strong>.</li></ul><p>The maximum redeliver delay
ensures that a delay is never longer than the value, default 1 minute. This can
happen when
<strong><code>useExponentialBackOff=true</code></strong>.</p><p>The <strong><code>maximumRedeliveries</code></strong>
is the number of <strong>re</strong>-delivery attempts. By default Camel will
try to process the exchange 1 + 5 times. 1 time for the normal attempt and then
5 attempts as redeliveries.<br clear="none"> Setting
the <strong><code>maximumRedeliveries=-1 </code></strong>(or
< <strong><code>-1</code></strong>) will then always redelivery
(unlimited).<br clear="none"> Setting
the <strong><code>maximumRedeliveries=0</code></strong> will disable
re-delivery.</p><p>Camel will log delivery failures at
the <strong><code>DEBUG</code></strong> logging level by default. You can
change this by
specifying <strong><code>retriesExhaustedLogLevel</code></strong> and/or
<strong><code>retryAttemptedLogLevel</code></strong>. See <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExceptionBuilderWithRetryLoggingLevelSetTest.java">ExceptionBuilderWithRetryLoggingLevelSetTest</a>
for an exampl
e.</p><p>You can turn logging of stack traces on/off. If turned off Camel will
still log the redelivery attempt. It's just much less verbose.</p><h4
id="DeadLetterChannel-RedeliverDelayPattern">Redeliver Delay
Pattern</h4><p>Delay pattern is used as a single option to set a range pattern
for delays. When a delay pattern is in use the following options no longer
apply:</p><ul><li><strong><code>delay</code></strong></li><li><strong><code>backOffMultiplier</code></strong></li><li><strong><code>useExponentialBackOff</code></strong></li><li><strong><code>useCollisionAvoidance</code></strong></li><li><strong><code>maximumRedeliveryDelay</code></strong></li></ul><p>The
idea is to set groups of ranges using the following syntax:
<strong><code>limit:delay;limit 2:delay 2;limit 3:delay 3;...;limit N:delay
N</code></strong></p><p>Each group has two values separated with colon:</p><ul
class="alternate"><li><strong><code>limit</code></strong> = upper
limit</li><li><strong><code>delay</code></str
ong> = delay in milliseconds<br clear="none"> And the groups is again
separated with semi-colon. The rule of thumb is that the next groups should
have a higher limit than the previous group.</li></ul><p>Lets clarify this with
an example:<br clear="none">
<strong><code>delayPattern=5:1000;10:5000;20:20000</code></strong></p><p>That
gives us three groups:</p><ul
class="alternate"><li><strong><code>5:1000</code></strong></li><li><strong><code>10:5000</code></strong></li><li><strong><code>20:20000</code></strong></li></ul><p>Resulting
in these delays between redelivery attempts:</p><ul
class="alternate"><li>Redelivery attempt number <strong><code>1..4 =
0ms</code></strong> (as the first group start with 5)</li><li>Redelivery
attempt number <strong><code>5..9 = 1000ms</code></strong> (the first
group)</li><li>Redelivery attempt number <strong><code>10..19 =
5000ms</code></strong> (the second group)</li><li>Redelivery attempt
number <strong><code>20.. = 20000ms</c
ode></strong> (the last group)</li></ul><p>Note: The first redelivery attempt
is <strong><code>1</code></strong>, so the first group should start
with <strong><code>1</code></strong> or higher.</p><p>You can start a
group with limit <strong><code>1</code></strong> to e.g., have a starting
delay: <strong><code>delayPattern=1:1000;5:5000</code></strong></p><ul
class="alternate"><li>Redelivery attempt number <strong><code>1..4 =
1000ms</code></strong> (the first group)</li><li>Redelivery attempt
number <strong><code>5.. = 5000ms</code></strong> (the last
group)</li></ul><p>There is no requirement that the next delay should be higher
than the previous. You can use any delay value you like. For example with
<strong><code>delayPattern=1:5000;3:1000</code></strong> we start with 5 sec
delay and then later reduce that to <strong><code>1</code></strong>
second.</p><h3 id="DeadLetterChannel-Redeliveryheader">Redelivery
header</h3><p>When a message is redelivered the <
a shape="rect" class="external-link"
href="http://camel.apache.org/maven/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html">DeadLetterChannel</a>
will append a customizable header to the message to indicate how many times
its been redelivered. <br clear="none"> Before <strong>Camel 2.6</strong>: The
header is <strong><code>CamelRedeliveryCounter</code></strong>, which is also
defined on the <strong><code>Exchange.REDELIVERY_COUNTER</code></strong>.<br
clear="none"> From <strong>Camel 2.6</strong>: The
header <strong><code>CamelRedeliveryMaxCounter</code></strong>, which is
also defined on the
<strong><code>Exchange.REDELIVERY_MAX_COUNTER</code></strong>, contains the
maximum redelivery setting. This header is absent if you use
<strong><code>retryWhile</code></strong> or have unlimited maximum redelivery
configured.</p><p>And a boolean flag whether it is being redelivered or not
(first attempt). The header <strong><code>CamelRedelivered</code></strong>
co
ntains a boolean if the message is redelivered or not, which is also defined
on the <strong><code>Exchange.REDELIVERED</code></strong>.</p><h3
id="DeadLetterChannel-DynamicallyCalculatedDelayFromtheExchange">Dynamically
Calculated Delay From the Exchange</h3><p>In <strong>Camel 2.9</strong> and
<strong>2.8.2</strong>: The header
is <strong><code>CamelRedeliveryDelay</code></strong>, which is also
defined on the <strong><code>Exchange.REDELIVERY_DELAY</code></strong>. If this
header is absent, normal redelivery rules apply.</p><h4
id="DeadLetterChannel-WhichEndpointFailed">Which Endpoint
Failed</h4><p><strong>Available as of Camel 2.1</strong></p><p>When Camel
routes messages it will decorate the <a shape="rect"
href="exchange.html">Exchange</a> with a property that contains the
<strong>last</strong> endpoint Camel send the <a shape="rect"
href="exchange.html">Exchange</a> to:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[String lastEndpointUri =
exchange.getProperty(Exchange.TO_ENDPOINT, String.class);
-]]></script>
-</div></div><p>The <strong><code>Exchange.TO_ENDPOINT</code></strong> have the
constant value <strong><code>CamelToEndpoint</code></strong>. This information
is updated when Camel sends a message to any endpoint. So if it exists its the
<strong>last</strong> endpoint which Camel send the Exchange to.</p><p>When for
example processing the <a shape="rect" href="exchange.html">Exchange</a> at a
given <a shape="rect" href="endpoint.html">Endpoint</a> and the message is to
be moved into the dead letter queue, then Camel also decorates the Exchange
with another property that contains that <strong>last</strong>
endpoint:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[String failedEndpointUri =
exchange.getProperty(Exchange.FAILURE_ENDPOINT, String.class);
-]]></script>
-</div></div><p>The <strong><code>Exchange.FAILURE_ENDPOINT</code></strong>
have the constant value
<strong><code>CamelFailureEndpoint</code></strong>.</p><p>This allows for
example you to fetch this information in your dead letter queue and use that
for error reporting. This is usable if the Camel route is a bit dynamic such as
the dynamic <a shape="rect" href="recipient-list.html">Recipient List</a> so
you know which endpoints failed.</p><p><strong>Note:</strong> this information
is retained on the Exchange even if the message is subsequently processed
successfully by a given endpoint only to fail, for example, in local <a
shape="rect" href="bean.html">Bean</a> processing instead. So, beware that this
is a hint that helps pinpoint errors.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("activemq:queue:foo")
- .to("http://someserver/somepath")
- .beanRef("foo");
-]]></script>
-</div></div><p>Now suppose the route above and a failure happens in the
<code>foo</code> bean. Then the
<strong><code>Exchange.TO_ENDPOINT</code></strong> and
<strong><code>Exchange.FAILURE_ENDPOINT</code></strong> will still contain the
value of <code><a shape="rect" class="external-link"
href="http://someserver/somepath"
rel="nofollow">http://someserver/somepath</a></code>.</p><h3
id="DeadLetterChannel-OnPrepareFailure"><code>OnPrepareFailure</code></h3><p><strong>Available
as of Camel 2.16</strong></p><p>Before the exchange is sent to the dead letter
queue, you can use <strong><code>onPrepare</code></strong> to allow a
custom <strong><code>Processor</code></strong> to prepare the exchange,
such as adding information why the Exchange failed.</p><p>For example, the
following processor adds a header with the exception message:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[ public static class MyPrepareProcessor
implements Processor {
+</plain-text-body><p>Then the messages routed to the
<strong><code>jms:queue:dead</code></strong> is the original input. If we want
to manually retry we can move the JMS message from the failed to the input
queue, with no problem as the message is the same as the original we
received.</p><h3 id="DeadLetterChannel-OnRedelivery">OnRedelivery</h3><p>When
<a shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a> is
doing redeliver its possible to configure a <a shape="rect"
href="processor.html">Processor</a> that is executed just
<strong>before</strong> every redelivery attempt. This can be used for the
situations where you need to alter the message before its redelivered. See
below for sample.</p><parameter ac:name="title">onException and
onRedeliver</parameter><rich-text-body><p>We also support for per <a
shape="rect" href="exception-clause.html"><strong>onException</strong></a> to
set an <strong><code>onRedeliver</code></strong>. That means you can do special
on redeli
very for different exceptions, as opposed
to <strong><code>onRedelivery</code></strong> set on <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> can be viewed as a
global scope.</p></rich-text-body><h3
id="DeadLetterChannel-RedeliveryDefaultValues">Redelivery Default
Values</h3><p>Redelivery is disabled by default.</p><p>The default redeliver
policy will use the following
values:</p><ul><li><strong><code>maximumRedeliveries=0</code></strong></li><li><strong><code>redeliverDelay=1000L</code></strong>
(1 second)</li><li><strong><code>maximumRedeliveryDelay = 60 *
1000L</code></strong> (60
seconds)</li><li><strong><code>backOffMultiplier</code></strong> and
<strong><code>useExponentialBackOff</code></strong> are
ignored.</li><li><strong><code>retriesExhaustedLogLevel=LoggingLevel.ERROR</code></strong></li><li><strong><code>retryAttemptedLogLevel=LoggingLevel.DEBUG</code></strong></li><li>Stack
traces are logged for exhausted messages, from <strong>Camel 2.2</
strong>.</li><li>Handled exceptions are not logged, from <strong>Camel
2.3</strong>.</li><li><strong><code>logExhaustedMessageHistory</code></strong>
is true for default error handler, and false for dead letter
channel.</li><li><strong><code>logExhaustedMessageBody</code></strong>
<strong>Camel 2.17:</strong> is disabled by default to avoid logging
sensitive message body/header details. If this option is
<strong><code>true</code></strong>,
then <strong><code>logExhaustedMessageHistory</code></strong> must also be
<strong><code>true</code></strong>.</li></ul><p>The maximum redeliver delay
ensures that a delay is never longer than the value, default 1 minute. This can
happen when
<strong><code>useExponentialBackOff=true</code></strong>.</p><p>The <strong><code>maximumRedeliveries</code></strong>
is the number of <strong>re</strong>-delivery attempts. By default Camel will
try to process the exchange 1 + 5 times. 1 time for the normal attempt and then
5 attempts as redel
iveries.<br clear="none"> Setting
the <strong><code>maximumRedeliveries=-1 </code></strong>(or
< <strong><code>-1</code></strong>) will then always redelivery
(unlimited).<br clear="none"> Setting
the <strong><code>maximumRedeliveries=0</code></strong> will disable
re-delivery.</p><p>Camel will log delivery failures at
the <strong><code>DEBUG</code></strong> logging level by default. You can
change this by
specifying <strong><code>retriesExhaustedLogLevel</code></strong> and/or
<strong><code>retryAttemptedLogLevel</code></strong>. See <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExceptionBuilderWithRetryLoggingLevelSetTest.java">ExceptionBuilderWithRetryLoggingLevelSetTest</a>
for an example.</p><p>You can turn logging of stack traces on/off. If turned
off Camel will still log the redelivery attempt. It's just much less
verbose.</p><h4 id="DeadLetterChannel-Redeli
verDelayPattern">Redeliver Delay Pattern</h4><p>Delay pattern is used as a
single option to set a range pattern for delays. When a delay pattern is in use
the following options no longer
apply:</p><ul><li><strong><code>delay</code></strong></li><li><strong><code>backOffMultiplier</code></strong></li><li><strong><code>useExponentialBackOff</code></strong></li><li><strong><code>useCollisionAvoidance</code></strong></li><li><strong><code>maximumRedeliveryDelay</code></strong></li></ul><p>The
idea is to set groups of ranges using the following syntax:
<strong><code>limit:delay;limit 2:delay 2;limit 3:delay 3;...;limit N:delay
N</code></strong></p><p>Each group has two values separated with colon:</p><ul
class="alternate"><li><strong><code>limit</code></strong> = upper
limit</li><li><strong><code>delay</code></strong> = delay in
milliseconds<br clear="none"> And the groups is again separated with
semi-colon. The rule of thumb is that the next groups should have a higher
limit than t
he previous group.</li></ul><p>Lets clarify this with an example:<br
clear="none">
<strong><code>delayPattern=5:1000;10:5000;20:20000</code></strong></p><p>That
gives us three groups:</p><ul
class="alternate"><li><strong><code>5:1000</code></strong></li><li><strong><code>10:5000</code></strong></li><li><strong><code>20:20000</code></strong></li></ul><p>Resulting
in these delays between redelivery attempts:</p><ul
class="alternate"><li>Redelivery attempt number <strong><code>1..4 =
0ms</code></strong> (as the first group start with 5)</li><li>Redelivery
attempt number <strong><code>5..9 = 1000ms</code></strong> (the first
group)</li><li>Redelivery attempt number <strong><code>10..19 =
5000ms</code></strong> (the second group)</li><li>Redelivery attempt
number <strong><code>20.. = 20000ms</code></strong> (the last
group)</li></ul><p>Note: The first redelivery attempt is
<strong><code>1</code></strong>, so the first group should start
with <strong><code>1</code
></strong> or higher.</p><p>You can start a group with
>limit <strong><code>1</code></strong> to e.g., have a starting delay:
><strong><code>delayPattern=1:1000;5:5000</code></strong></p><ul
>class="alternate"><li>Redelivery attempt number <strong><code>1..4 =
>1000ms</code></strong> (the first group)</li><li>Redelivery attempt
>number <strong><code>5.. = 5000ms</code></strong> (the last
>group)</li></ul><p>There is no requirement that the next delay should be
>higher than the previous. You can use any delay value you like. For example
>with <strong><code>delayPattern=1:5000;3:1000</code></strong> we start with 5
>sec delay and then later reduce that to <strong><code>1</code></strong>
>second.</p><h3 id="DeadLetterChannel-Redeliveryheader">Redelivery
>header</h3><p>When a message is redelivered the <a shape="rect"
>class="external-link"
>href="http://camel.apache.org/maven/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html">DeadLetterChannel</a>
> will append
a customizable header to the message to indicate how many times its been
redelivered. <br clear="none"> Before <strong>Camel 2.6</strong>: The header is
<strong><code>CamelRedeliveryCounter</code></strong>, which is also defined on
the <strong><code>Exchange.REDELIVERY_COUNTER</code></strong>.<br clear="none">
From <strong>Camel 2.6</strong>: The
header <strong><code>CamelRedeliveryMaxCounter</code></strong>, which is
also defined on the
<strong><code>Exchange.REDELIVERY_MAX_COUNTER</code></strong>, contains the
maximum redelivery setting. This header is absent if you use
<strong><code>retryWhile</code></strong> or have unlimited maximum redelivery
configured.</p><p>And a boolean flag whether it is being redelivered or not
(first attempt). The header <strong><code>CamelRedelivered</code></strong>
contains a boolean if the message is redelivered or not, which is also defined
on the <strong><code>Exchange.REDELIVERED</code></strong>.</p><h3
id="DeadLetterChannel-DynamicallyC
alculatedDelayFromtheExchange">Dynamically Calculated Delay From the
Exchange</h3><p>In <strong>Camel 2.9</strong> and <strong>2.8.2</strong>: The
header is <strong><code>CamelRedeliveryDelay</code></strong>, which is
also defined on the <strong><code>Exchange.REDELIVERY_DELAY</code></strong>. If
this header is absent, normal redelivery rules apply.</p><h4
id="DeadLetterChannel-WhichEndpointFailed">Which Endpoint
Failed</h4><p><strong>Available as of Camel 2.1</strong></p><p>When Camel
routes messages it will decorate the <a shape="rect"
href="exchange.html">Exchange</a> with a property that contains the
<strong>last</strong> endpoint Camel send the <a shape="rect"
href="exchange.html">Exchange</a> to:</p><parameter
ac:name="language">java</parameter><plain-text-body>String lastEndpointUri =
exchange.getProperty(Exchange.TO_ENDPOINT, String.class);
+</plain-text-body><p>The <strong><code>Exchange.TO_ENDPOINT</code></strong>
have the constant value <strong><code>CamelToEndpoint</code></strong>. This
information is updated when Camel sends a message to any endpoint. So if it
exists its the <strong>last</strong> endpoint which Camel send the Exchange
to.</p><p>When for example processing the <a shape="rect"
href="exchange.html">Exchange</a> at a given <a shape="rect"
href="endpoint.html">Endpoint</a> and the message is to be moved into the dead
letter queue, then Camel also decorates the Exchange with another property that
contains that <strong>last</strong> endpoint:</p><parameter
ac:name="language">java</parameter><plain-text-body>String failedEndpointUri =
exchange.getProperty(Exchange.FAILURE_ENDPOINT, String.class);
+</plain-text-body><p>The
<strong><code>Exchange.FAILURE_ENDPOINT</code></strong> have the constant value
<strong><code>CamelFailureEndpoint</code></strong>.</p><p>This allows for
example you to fetch this information in your dead letter queue and use that
for error reporting. This is usable if the Camel route is a bit dynamic such as
the dynamic <a shape="rect" href="recipient-list.html">Recipient List</a> so
you know which endpoints failed.</p><p><strong>Note:</strong> this information
is retained on the Exchange even if the message is subsequently processed
successfully by a given endpoint only to fail, for example, in local <a
shape="rect" href="bean.html">Bean</a> processing instead. So, beware that this
is a hint that helps pinpoint errors.</p><parameter
ac:name="language">java</parameter><plain-text-body>from("activemq:queue:foo")
+ .to("http://someserver/somepath")
+ .beanRef("foo");
+</plain-text-body><p>Now suppose the route above and a failure happens in the
<code>foo</code> bean. Then the
<strong><code>Exchange.TO_ENDPOINT</code></strong> and
<strong><code>Exchange.FAILURE_ENDPOINT</code></strong> will still contain the
value of <code><a shape="rect" class="external-link"
href="http://someserver/somepath"
rel="nofollow">http://someserver/somepath</a></code>.</p><h3
id="DeadLetterChannel-OnPrepareFailure"><code>OnPrepareFailure</code></h3><p><strong>Available
as of Camel 2.16</strong></p><p>Before the exchange is sent to the dead letter
queue, you can use <strong><code>onPrepare</code></strong> to allow a
custom <strong><code>Processor</code></strong> to prepare the exchange,
such as adding information why the Exchange failed.</p><p>For example, the
following processor adds a header with the exception message:</p><parameter
ac:name="language">java</parameter><plain-text-body> public static class
MyPrepareProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
Exception cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT,
Exception.class);
- exchange.getIn().setHeader("FailedBecause",
cause.getMessage());
+ exchange.getIn().setHeader("FailedBecause", cause.getMessage());
}
- }]]></script>
-</div></div><p>Then configure the error handler to use the processor as
follows:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[errorHandler(deadLetterChannel("jms:dead").onPrepareFailure(new
MyPrepareProcessor()));]]></script>
-</div></div><p> </p><p>Configuring this from XML DSL is as
follows:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<script class="brush: xml; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[<bean id="myPrepare"
class="org.apache.camel.processor.DeadLetterChannelOnPrepareTest.MyPrepareProcessor"/>
-
-<errorHandler id="dlc" type="DeadLetterChannel"
deadLetterUri="jms:dead"
onPrepareFailureRef="myPrepare"/>]]></script>
-</div></div><p> </p><p>The <strong><code>onPrepare</code></strong>
is also available using the default error handler.</p><h3
id="DeadLetterChannel-WhichRouteFailed">Which Route
Failed</h3><p><strong>Available as of Camel 2.10.4/2.11</strong></p><p>When
Camel error handler handles an error such as <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> or using <a
shape="rect" href="exception-clause.html">Exception Clause</a> with
<strong><code>handled=true</code></strong>, then Camel will decorate the <a
shape="rect" href="exchange.html">Exchange</a> with the route id where the
error occurred.</p><p>Example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[String failedRouteId =
exchange.getProperty(Exchange.FAILURE_ROUTE_ID, String.class);
-]]></script>
-</div></div><p>The <strong><code>Exchange.FAILURE_ROUTE_ID</code></strong>
have the constant value <strong><code>CamelFailureRouteId</code></strong>. This
allows for example you to fetch this information in your dead letter queue and
use that for error reporting.</p><h3
id="DeadLetterChannel-ControlifRedeliveryisAllowedDuringStopping/Shutdown">Control
if Redelivery is Allowed During Stopping/Shutdown</h3><p><strong>Available as
of Camel 2.11</strong></p><p>Before <strong>Camel 2.10</strong>, Camel would
perform redelivery while stopping a route, or shutting down Camel. This has
improved a bit in <strong>Camel 2.10</strong>: Camel will no longer perform
redelivery attempts when shutting down aggressively, e.g., during <a
shape="rect" href="graceful-shutdown.html">Graceful Shutdown</a> and timeout
hit.</p><p>From <strong>Camel 2.11</strong>: there is a new option
<strong><code>allowRedeliveryWhileStopping</code></strong> which you can use to
control if redelivery is allowed or not; no
tice that any in progress redelivery will still be executed. This option can
only disallow any redelivery to be executed <em><strong>after</strong></em> the
stopping of a route/shutdown of Camel has been triggered. If a redelivery is
disallowed then a <strong><code>RejectedExcutionException</code></strong> is
set on the <a shape="rect" href="exchange.html">Exchange</a> and the processing
of the <a shape="rect" href="exchange.html">Exchange</a> stops. This means any
consumer will see the <a shape="rect" href="exchange.html">Exchange</a> as
failed due the <strong><code>RejectedExcutionException</code></strong>. The
default value is <strong><code>true</code></strong> for backward
compatibility.</p><p>For example, the following snippet shows how to do this
with Java DSL and XML DSL:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-
-// this error handler will try up till 20 redelivery attempts with 1 second
between.
-// however if we are stopping then do not allow any redeliver attempts.
-errorHandler(defaultErrorHandler()
- .allowRedeliveryWhileStopping(false)
-
.maximumRedeliveries(20).redeliveryDelay(1000).retryAttemptedLogLevel(LoggingLevel.INFO));
-
-from("seda:foo").routeId("foo")
- .to("mock:foo")
- .throwException(new IllegalArgumentException("Forced"));
-]]></script>
-</div></div>And the sample sample with XML DSL<div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: xml; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-<!-- notice we use the errorHandlerRef attribute to refer to the error
handler to use as default -->
- <camelContext errorHandlerRef="myErrorHandler"
xmlns="http://camel.apache.org/schema/spring">
-
- <!-- configure error handler, to redeliver up till 10 times, with 1
sec delay
- and if we are stopping then do not allow redeliveries, to stop
faster -->
- <errorHandler id="myErrorHandler"
type="DefaultErrorHandler">
- <redeliveryPolicy maximumRedeliveries="20"
redeliveryDelay="1000" allowRedeliveryWhileStopping="false"
retryAttemptedLogLevel="INFO"/>
- </errorHandler>
-
- <route id="foo">
- <from uri="seda:foo"/>
- <to uri="mock:foo"/>
- <throwException ref="forced"/>
- </route>
-
- </camelContext>
-]]></script>
-</div></div><h3 id="DeadLetterChannel-Samples">Samples</h3><p>The following
example shows how to configure the Dead Letter Channel configuration using the
<a shape="rect" href="dsl.html">DSL</a></p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-RouteBuilder builder = new RouteBuilder() {
- public void configure() {
- // using dead letter channel with a seda queue for errors
- errorHandler(deadLetterChannel("seda:errors"));
-
- // here is our route
- from("seda:a").to("seda:b");
- }
-};
-]]></script>
-</div></div>You can also configure the <a shape="rect" class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html">RedeliveryPolicy</a>
as this example shows<div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-RouteBuilder builder = new RouteBuilder() {
- public void configure() {
- // configures dead letter channel to use seda queue for errors and use
at most 2 redelveries
- // and exponential backoff
-
errorHandler(deadLetterChannel("seda:errors").maximumRedeliveries(2).useExponentialBackOff());
-
- // here is our route
- from("seda:a").to("seda:b");
- }
-};
-]]></script>
-</div></div><h3
id="DeadLetterChannel-HowCanIModifytheExchangeBeforeRedelivery?">How Can I
Modify the Exchange Before Redelivery?</h3><p>We support directly in <a
shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a> to set a
<a shape="rect" href="processor.html">Processor</a> that is executed
<strong>before</strong> each redelivery attempt. When <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> is doing redeliver its
possible to configure a <a shape="rect" href="processor.html">Processor</a>
that is executed just <strong>before</strong> every redelivery attempt. This
can be used for the situations where you need to alter the message before its
redelivered. Here we configure the <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> to use our processor
<strong><code>MyRedeliveryProcessor</code></strong> to be executed before each
redelivery.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelC
ontent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-// we configure our Dead Letter Channel to invoke
-// MyRedeliveryProcessor before a redelivery is
-// attempted. This allows us to alter the message before
-errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(5)
- .onRedelivery(new MyRedeliverProcessor())
- // setting delay to zero is just to make unit testing faster
- .redeliveryDelay(0L));
-]]></script>
-</div></div>And this is the processor
<strong><code>MyRedeliveryProcessor</code></strong> where we alter the
message.<div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-// This is our processor that is executed before every redelivery attempt
-// here we can do what we want in the java code, such as altering the message
-public class MyRedeliverProcessor implements Processor {
-
- public void process(Exchange exchange) throws Exception {
- // the message is being redelivered so we can alter it
-
- // we just append the redelivery counter to the body
- // you can of course do all kind of stuff instead
- String body = exchange.getIn().getBody(String.class);
- int count = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER,
Integer.class);
-
- exchange.getIn().setBody(body + count);
-
- // the maximum redelivery was set to 5
- int max = exchange.getIn().getHeader(Exchange.REDELIVERY_MAX_COUNTER,
Integer.class);
- assertEquals(5, max);
- }
-}
-]]></script>
-</div></div><h3
id="DeadLetterChannel-HowCanILogWhatCausedtheDeadLetterChanneltobeInvoked?">How
Can I Log What Caused the Dead Letter Channel to be Invoked?</h3><p>You often
need to know what went wrong that caused the Dead Letter Channel to be used and
it does not offer logging for this purpose. So the Dead Letter Channel's
endpoint can be set to a endpoint of our own (such
as <strong><code>direct:deadLetterChannel</code></strong>). We write a
route to accept this Exchange and log the Exception, then forward on to where
we want the failed Exchange moved to (which might be a DLQ queue for instance).
See also <a shape="rect" class="external-link"
href="http://stackoverflow.com/questions/13711462/logging-camel-exceptions-and-sending-to-the-dead-letter-channel"
rel="nofollow">http://stackoverflow.com/questions/13711462/logging-camel-exceptions-and-sending-to-the-dead-letter-channel</a></p><p></p><h4
id="DeadLetterChannel-UsingThisPattern">Using This Pattern</h4>
+ }</plain-text-body><p>Then configure the error handler to use the
processor as follows:</p><parameter
ac:name="language">java</parameter><plain-text-body>errorHandler(deadLetterChannel("jms:dead").onPrepareFailure(new
MyPrepareProcessor()));</plain-text-body><p> </p><p>Configuring this from
XML DSL is as follows:</p><parameter
ac:name="language">xml</parameter><plain-text-body><bean id="myPrepare"
class="org.apache.camel.processor.DeadLetterChannelOnPrepareTest.MyPrepareProcessor"/>
-<p>If you would like to use this EIP Pattern then please read the <a
shape="rect" href="getting-started.html">Getting Started</a>, you may also find
the <a shape="rect" href="architecture.html">Architecture</a> useful
particularly the description of <a shape="rect"
href="endpoint.html">Endpoint</a> and <a shape="rect"
href="uris.html">URIs</a>. Then you could try out some of the <a shape="rect"
href="examples.html">Examples</a> first before trying this pattern out.</p><ul
class="alternate"><li><a shape="rect" href="error-handler.html">Error
Handler</a></li><li><a shape="rect" href="exception-clause.html">Exception
Clause</a></li></ul></div>
+<errorHandler id="dlc" type="DeadLetterChannel" deadLetterUri="jms:dead"
onPrepareFailureRef="myPrepare"/></plain-text-body><p> </p><p>The <strong><code>onPrepare</code></strong>
is also available using the default error handler.</p><h3
id="DeadLetterChannel-WhichRouteFailed">Which Route
Failed</h3><p><strong>Available as of Camel 2.10.4/2.11</strong></p><p>When
Camel error handler handles an error such as <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> or using <a
shape="rect" href="exception-clause.html">Exception Clause</a> with
<strong><code>handled=true</code></strong>, then Camel will decorate the <a
shape="rect" href="exchange.html">Exchange</a> with the route id where the
error occurred.</p><p>Example:</p><parameter
ac:name="language">java</parameter><plain-text-body>String failedRouteId =
exchange.getProperty(Exchange.FAILURE_ROUTE_ID, String.class);
+</plain-text-body><p>The
<strong><code>Exchange.FAILURE_ROUTE_ID</code></strong> have the constant value
<strong><code>CamelFailureRouteId</code></strong>. This allows for example you
to fetch this information in your dead letter queue and use that for error
reporting.</p><h3
id="DeadLetterChannel-ControlifRedeliveryisAllowedDuringStopping/Shutdown">Control
if Redelivery is Allowed During Stopping/Shutdown</h3><p><strong>Available as
of Camel 2.11</strong></p><p>Before <strong>Camel 2.10</strong>, Camel would
perform redelivery while stopping a route, or shutting down Camel. This has
improved a bit in <strong>Camel 2.10</strong>: Camel will no longer perform
redelivery attempts when shutting down aggressively, e.g., during <a
shape="rect" href="graceful-shutdown.html">Graceful Shutdown</a> and timeout
hit.</p><p>From <strong>Camel 2.11</strong>: there is a new option
<strong><code>allowRedeliveryWhileStopping</code></strong> which you can use to
control if redelivery is allowed or n
ot; notice that any in progress redelivery will still be executed. This option
can only disallow any redelivery to be executed <em><strong>after</strong></em>
the stopping of a route/shutdown of Camel has been triggered. If a redelivery
is disallowed then a <strong><code>RejectedExcutionException</code></strong> is
set on the <a shape="rect" href="exchange.html">Exchange</a> and the processing
of the <a shape="rect" href="exchange.html">Exchange</a> stops. This means any
consumer will see the <a shape="rect" href="exchange.html">Exchange</a> as
failed due the <strong><code>RejectedExcutionException</code></strong>. The
default value is <strong><code>true</code></strong> for backward
compatibility.</p><p>For example, the following snippet shows how to do this
with Java DSL and XML
DSL:<plain-text-body>{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerNoRedeliveryOnShutdownTest.java}</plain-text-body>And
the sample sampl
e with XML
DSL<plain-text-body>{snippet:id=e1|lang=xml|url=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringRedeliveryErrorHandlerNoRedeliveryOnShutdownTest.xml}</plain-text-body></p><h3
id="DeadLetterChannel-Samples">Samples</h3><p>The following example shows how
to configure the Dead Letter Channel configuration using the <a shape="rect"
href="dsl.html">DSL</a><plain-text-body>{snippet:id=e3|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ErrorHandlerTest.java}</plain-text-body>You
can also configure the <a shape="rect" class="external-link"
href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html">RedeliveryPolicy</a>
as this example
shows<plain-text-body>{snippet:id=e4|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ErrorHandlerTest.java}</plain-text-body></p><h3
id="DeadLetterChannel-HowCanIModifytheExchangeBeforeRedelivery
?">How Can I Modify the Exchange Before Redelivery?</h3><p>We support directly
in <a shape="rect" href="dead-letter-channel.html">Dead Letter Channel</a> to
set a <a shape="rect" href="processor.html">Processor</a> that is executed
<strong>before</strong> each redelivery attempt. When <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> is doing redeliver its
possible to configure a <a shape="rect" href="processor.html">Processor</a>
that is executed just <strong>before</strong> every redelivery attempt. This
can be used for the situations where you need to alter the message before its
redelivered. Here we configure the <a shape="rect"
href="dead-letter-channel.html">Dead Letter Channel</a> to use our processor
<strong><code>MyRedeliveryProcessor</code></strong> to be executed before each
redelivery.<plain-text-body>{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnRedeliveryTest.java}</plain-text-body>
And this is the processor <strong><code>MyRedeliveryProcessor</code></strong>
where we alter the
message.<plain-text-body>{snippet:id=e2|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnRedeliveryTest.java}</plain-text-body></p><h3
id="DeadLetterChannel-HowCanILogWhatCausedtheDeadLetterChanneltobeInvoked?">How
Can I Log What Caused the Dead Letter Channel to be Invoked?</h3><p>You often
need to know what went wrong that caused the Dead Letter Channel to be used and
it does not offer logging for this purpose. So the Dead Letter Channel's
endpoint can be set to a endpoint of our own (such
as <strong><code>direct:deadLetterChannel</code></strong>). We write a
route to accept this Exchange and log the Exception, then forward on to where
we want the failed Exchange moved to (which might be a DLQ queue for instance).
See also <a shape="rect" class="external-link"
href="http://stackoverflow.com/questions/13711462/logging-camel-excep
tions-and-sending-to-the-dead-letter-channel"
rel="nofollow">http://stackoverflow.com/questions/13711462/logging-camel-exceptions-and-sending-to-the-dead-letter-channel</a></p><p><parameter
ac:name=""><a shape="rect" href="using-this-pattern.html">Using This
Pattern</a></parameter></p><ul class="alternate"><li><a shape="rect"
href="error-handler.html">Error Handler</a></li><li><a shape="rect"
href="exception-clause.html">Exception Clause</a></li></ul></div>
</td>
<td valign="top">
<div class="navigation">