Added Dead Letter Channel docs to Gitbook

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1489eb81
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1489eb81
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1489eb81

Branch: refs/heads/master
Commit: 1489eb8124b48cc49df2b7aa4c3b84dc93c17f0c
Parents: 91d0c70
Author: Andrea Cosentino <anco...@gmail.com>
Authored: Wed Oct 26 13:29:05 2016 +0200
Committer: Andrea Cosentino <anco...@gmail.com>
Committed: Wed Oct 26 13:29:05 2016 +0200

----------------------------------------------------------------------
 .../src/main/docs/dead-letter-channel.adoc      | 507 +++++++++++++++++++
 docs/user-manual/en/SUMMARY.md                  |   3 +-
 2 files changed, 509 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1489eb81/camel-core/src/main/docs/dead-letter-channel.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/dead-letter-channel.adoc 
b/camel-core/src/main/docs/dead-letter-channel.adoc
new file mode 100644
index 0000000..286a72c
--- /dev/null
+++ b/camel-core/src/main/docs/dead-letter-channel.adoc
@@ -0,0 +1,507 @@
+[[DeadLetterChannel-DeadLetterChannel]]
+Dead Letter Channel
+~~~~~~~~~~~~~~~~~~~
+
+Camel supports the
+http://www.enterpriseintegrationpatterns.com/DeadLetterChannel.html[Dead
+Letter Channel] from the link:enterprise-integration-patterns.html[EIP
+patterns] using the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html[DeadLetterChannel]
+processor which is an link:error-handler.html[Error Handler].
+
+image:http://www.enterpriseintegrationpatterns.com/img/DeadLetterChannelSolution.gif[image]
+
+TIP:*Difference between Dead Letter Channel and Default Error
+Handler*
+
+The Default Error Handler does very little: it ends the Exchange
+immediately and propagates the thrown Exception back to the caller.
+
+The Dead Letter Channel lets you control behaviors including redelivery,
+whether to propagate the thrown Exception to the caller (the *handled*
+option), and where the (failed) Exchange should now be routed to.
+
+The Dead Letter Channel 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 logExhaustedMessageHistory=true (and logHandled=true
+for Camel 2.15.x or older).
+
+When the DeadLetterChannel 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 DeadLetterChannel will always
+succeed. From *Camel 2.15* onwards this behavior can be changed by
+setting the option deadLetterHandleNewException=false. 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 WARN level. This can be turned off by setting
+logNewException=false.
+
+[[DeadLetterChannel-Redelivery]]
+Redelivery
+^^^^^^^^^^
+
+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.
+
+The
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html[RedeliveryPolicy]
+defines how the message is to be redelivered. You can customize things
+like
+
+* how many times a message is attempted to be redelivered before it is
+considered a failure and sent to the dead letter channel
+* the initial redelivery timeout
+* whether or not exponential backoff is used (i.e. the time between
+retries increases using a backoff multiplier)
+* whether to use collision avoidance to add some randomness to the
+timings
+* delay pattern (see below for details)
+* *Camel 2.11:* whether to allow redelivery during stopping/shutdown
+
+Once all attempts at redelivering the message fails then the message is
+forwarded to the dead letter queue.
+
+[[DeadLetterChannel-AboutmovingExchangetodeadletterqueueandusinghandled]]
+About moving Exchange to dead letter queue and using handled
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Handled* on link:dead-letter-channel.html[Dead Letter Channel]
+
+When all attempts of redelivery have failed the
+link:exchange.html[Exchange] 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
+link:dead-letter-channel.html[Dead Letter Channel] have handled the
+link:exchange.html[Exchange].
+
+For instance configuring the dead letter channel as:
+
+*Using the link:fluent-builders.html[Fluent Builders]*
+
+[source,java]
+---------------------------------------------------
+errorHandler(deadLetterChannel("jms:queue:dead")
+    .maximumRedeliveries(3).redeliveryDelay(5000));
+---------------------------------------------------
+
+*Using the link:spring-xml-extensions.html[Spring XML Extensions]*
+
+[source,xml]
+----------------------------------------------------------------------------------------------
+<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>
+
+<bean id="myRedeliveryPolicyConfig" 
class="org.apache.camel.processor.RedeliveryPolicy">
+    <property name="maximumRedeliveries" value="3"/>
+    <property name="redeliveryDelay" value="5000"/>
+</bean>
+----------------------------------------------------------------------------------------------
+
+The link:dead-letter-channel.html[Dead Letter Channel] above will clear
+the caused exception (`setException(null)`), by moving the caused
+exception to a property on the link:exchange.html[Exchange], with the
+key `Exchange.EXCEPTION_CAUGHT`. Then the link:exchange.html[Exchange]
+is moved to the `"jms:queue:dead"` destination and the client will not
+notice the failure.
+
+[[DeadLetterChannel-AboutmovingExchangetodeadletterqueueandusingtheoriginalmessage]]
+About moving Exchange to dead letter queue and using the original
+message
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The option *useOriginalMessage* is used for routing the original input
+message instead of the current message that potentially is modified
+during routing.
+
+For instance if you have this route:
+
+[source,java]
+---------------------------------
+   from("jms:queue:order:input")
+       .to("bean:validateOrder")
+       .to("bean:transformOrder")
+       .to("bean:handleOrder");
+---------------------------------
+
+The route listen for JMS messages and validates, transforms and handle
+it. During this the link:exchange.html[Exchange] 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
+link:dead-letter-channel.html[Dead Letter Channel] with the
+*useOriginalMessage* option. But when we move the
+link:exchange.html[Exchange] to this destination we do not know in which
+state the message is in. Did the error happen in before the
+transformOrder or after? So to be sure we want to move the original
+input message we received from `jms:queue:order:input`. So we can do
+this by enabling the *useOriginalMessage* option as shown below:
+
+[source,java]
+-------------------------------------------------------------------------
+    // will use original body
+    errorHandler(deadLetterChannel("jms:queue:dead")
+       .useOriginalMessage().maximumRedeliveries(5).redeliverDelay(5000);
+-------------------------------------------------------------------------
+
+Then the messages routed to the `jms:queue:dead` 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.
+
+[[DeadLetterChannel-OnRedelivery]]
+OnRedelivery
+^^^^^^^^^^^^
+
+When link:dead-letter-channel.html[Dead Letter Channel] is doing
+redeliver its possible to configure a link:processor.html[Processor]
+that is executed just *before* every redelivery attempt. This can be
+used for the situations where you need to alter the message before its
+redelivered. See below for sample.
+
+TIP:*onException and onRedeliver*
+We also support for per link:exception-clause.html[*onException*] to set
+a *onRedeliver*. That means you can do special on redelivery for
+different exceptions, as opposed to onRedelivery set on
+link:dead-letter-channel.html[Dead Letter Channel] can be viewed as a
+global scope.
+
+
+[[DeadLetterChannel-Redeliverydefaultvalues]]
+Redelivery default values
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Redelivery is disabled by default.
+
+The default redeliver policy will use the following values:
+
+* maximumRedeliveries=0
+* redeliverDelay=1000L (1 second)
+* maximumRedeliveryDelay = 60 * 1000L (60 seconds)
+* And the exponential backoff and collision avoidance is turned off.
+* The retriesExhaustedLogLevel are set to LoggingLevel.ERROR
+* The retryAttemptedLogLevel are set to LoggingLevel.DEBUG
+* Stack traces is logged for exhausted messages from Camel 2.2 onwards.
+* Handled exceptions is not logged from Camel 2.3 onwards
+* logExhaustedMessageHistory is true for default error handler, and
+false for dead letter channel.
+* logExhaustedMessageBody *Camel 2.17:* is disabled by default to avoid
+logging sensitive message body/header details. If this option is true,
+then logExhaustedMessageHistory must also be true.
+
+The maximum redeliver delay ensures that a delay is never longer than
+the value, default 1 minute. This can happen if you turn on the
+exponential backoff.
+
+The maximum redeliveries is the number of *re* 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. +
+ Setting the maximumRedeliveries to a negative value such as -1 will
+then always redelivery (unlimited). +
+ Setting the maximumRedeliveries to 0 will disable any re delivery
+attempt.
+
+Camel will log delivery failures at the DEBUG logging level by default.
+You can change this by specifying retriesExhaustedLogLevel and/or
+retryAttemptedLogLevel. See
+http://svn.apache.org/repos/asf/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExceptionBuilderWithRetryLoggingLevelSetTest.java[ExceptionBuilderWithRetryLoggingLevelSetTest]
+for an example.
+
+You can turn logging of stack traces on/off. If turned off Camel will
+still log the redelivery attempt. Its just much less verbose.
+
+[[DeadLetterChannel-RedeliverDelayPattern]]
+Redeliver Delay Pattern
++++++++++++++++++++++++
+
+Delay pattern is used as a single option to set a range pattern for
+delays. If used then the following options does not apply: (delay,
+backOffMultiplier, useExponentialBackOff, useCollisionAvoidance,
+maximumRedeliveryDelay).
+
+The idea is to set groups of ranges using the following syntax:
+`limit:delay;limit 2:delay 2;limit 3:delay 3;...;limit N:delay N`
+
+Each group has two values separated with colon
+
+* limit = upper limit
+* delay = delay in millis 
+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.
+
+Lets clarify this with an example: 
+ 
+`delayPattern=5:1000;10:5000;20:20000`
+
+That gives us 3 groups:
+
+* 5:1000
+* 10:5000
+* 20:20000
+
+Resulting in these delays for redelivery attempt:
+
+* Redelivery attempt number 1..4 = 0 millis (as the first group start
+with 5)
+* Redelivery attempt number 5..9 = 1000 millis (the first group)
+* Redelivery attempt number 10..19 = 5000 millis (the second group)
+* Redelivery attempt number 20.. = 20000 millis (the last group)
+
+Note: The first redelivery attempt is 1, so the first group should start
+with 1 or higher.
+
+You can start a group with limit 1 to eg have a starting delay:
+`delayPattern=1:1000;5:5000`
+
+* Redelivery attempt number 1..4 = 1000 millis (the first group)
+* Redelivery attempt number 5.. = 5000 millis (the last group)
+
+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
+`delayPattern=1:5000;3:1000` we start with 5 sec delay and then later
+reduce that to 1 second.
+
+[[DeadLetterChannel-Redeliveryheader]]
+Redelivery header
+^^^^^^^^^^^^^^^^^
+
+When a message is redelivered the
+http://camel.apache.org/maven/camel-core/apidocs/org/apache/camel/processor/DeadLetterChannel.html[DeadLetterChannel]
+will append a customizable header to the message to indicate how many
+times its been redelivered.  
+Before Camel 2.6: The header is *CamelRedeliveryCounter*, which is also
+defined on the `Exchange.REDELIVERY_COUNTER`. 
+Starting with 2.6: The header *CamelRedeliveryMaxCounter*, which is
+also defined on the `Exchange.REDELIVERY_MAX_COUNTER`, contains the
+maximum redelivery setting. This header is absent if you use
+`retryWhile` or have unlimited maximum redelivery configured.
+
+And a boolean flag whether it is being redelivered or not (first
+attempt) 
+The header *CamelRedelivered* contains a boolean if the message is
+redelivered or not, which is also defined on the `Exchange.REDELIVERED`.
+
+Dynamically calculated delay from the exchange 
+In Camel 2.9 and 2.8.2: The header is *CamelRedeliveryDelay*, which is
+also defined on the `Exchange.REDELIVERY_DELAY`. 
+Is this header is absent, normal redelivery rules apply.
+
+[[DeadLetterChannel-Whichendpointfailed]]
+Which endpoint failed
++++++++++++++++++++++
+
+*Available as of Camel 2.1*
+
+When Camel routes messages it will decorate the
+link:exchange.html[Exchange] with a property that contains the *last*
+endpoint Camel send the link:exchange.html[Exchange] to:
+
+[source,java]
+----------------------------------------------------------------------------------
+String lastEndpointUri = exchange.getProperty(Exchange.TO_ENDPOINT, 
String.class);
+----------------------------------------------------------------------------------
+
+The `Exchange.TO_ENDPOINT` have the constant value `CamelToEndpoint`.
+
+This information is updated when Camel sends a message to any endpoint.
+So if it exists its the *last* endpoint which Camel send the Exchange
+to.
+
+When for example processing the link:exchange.html[Exchange] at a given
+link:endpoint.html[Endpoint] and the message is to be moved into the
+dead letter queue, then Camel also decorates the Exchange with another
+property that contains that *last* endpoint:
+
+[source,java]
+-----------------------------------------------------------------------------------------
+String failedEndpointUri = exchange.getProperty(Exchange.FAILURE_ENDPOINT, 
String.class);
+-----------------------------------------------------------------------------------------
+
+The `Exchange.FAILURE_ENDPOINT` have the constant value
+`CamelFailureEndpoint`.
+
+This allows for example you to fetch this information in your dead
+letter queue and use that for error reporting. +
+ This is useable if the Camel route is a bit dynamic such as the dynamic
+link:recipient-list.html[Recipient List] so you know which endpoints
+failed.
+
+*Notice:* These information is kept on the Exchange even if the message
+was successfully processed by a given endpoint, and then later fails for
+example in a local link:bean.html[Bean] processing instead. So beware
+that this is a hint that helps pinpoint errors.
+
+[source,java]
+-------------------------------------
+from("activemq:queue:foo")
+    .to("http://someserver/somepath";)
+    .beanRef("foo");
+-------------------------------------
+
+Now suppose the route above and a failure happens in the `foo` bean.
+Then the `Exchange.TO_ENDPOINT` and `Exchange.FAILURE_ENDPOINT` will
+still contain the value of `http://someserver/somepath`.
+
+[[DeadLetterChannel-OnPrepareFailure]]
+OnPrepareFailure
+^^^^^^^^^^^^^^^^
+
+*Available as of Camel 2.16*
+
+Before the exchange is sent to the dead letter queue, you can use
+onPrepare to allow a custom `Processor` to prepare the exchange, such as
+adding information why the Exchange failed. For example the following
+processor adds a header with the exception message
+
+[source,java]
+-----------------------------------------------------------------------------------------------
+    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());
+        }
+    }
+-----------------------------------------------------------------------------------------------
+
+Then configure the error handler to use the processor as follows:
+
+[source,java]
+---------------------------------------------------------------------------------------
+errorHandler(deadLetterChannel("jms:dead").onPrepareFailure(new 
MyPrepareProcessor()));
+---------------------------------------------------------------------------------------
+
+Configuring this from XML DSL is as shown:
+
+[source,java]
+--------------------------------------------------------------------------------------------------------------
+  <bean id="myPrepare"
+        
class="org.apache.camel.processor.DeadLetterChannelOnPrepareTest.MyPrepareProcessor"/>
+
+
+    <errorHandler id="dlc" type="DeadLetterChannel" deadLetterUri="jms:dead" 
onPrepareFailureRef="myPrepare"/>
+--------------------------------------------------------------------------------------------------------------
+
+The onPrepare is also available using the default error handler.
+
+[[DeadLetterChannel-Whichroutefailed]]
+Which route failed
+^^^^^^^^^^^^^^^^^^
+
+*Available as of Camel 2.10.4/2.11*
+
+When Camel error handler handles an error such as
+link:dead-letter-channel.html[Dead Letter Channel] or using
+link:exception-clause.html[Exception Clause] with handled=true, then
+Camel will decorate +
+ the link:exchange.html[Exchange] with the route id where the error
+occurred.
+
+[source,java]
+-------------------------------------------------------------------------------------
+String failedRouteId = exchange.getProperty(Exchange.FAILURE_ROUTE_ID, 
String.class);
+-------------------------------------------------------------------------------------
+
+The `Exchange.FAILURE_ROUTE_ID` have the constant value
+`CamelFailureRouteId`.
+
+This allows for example you to fetch this information in your dead
+letter queue and use that for error reporting.
+
+[[DeadLetterChannel-Controlifredeliveryisallowedduringstopping/shutdown]]
+Control if redelivery is allowed during stopping/shutdown
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Available as of Camel 2.11*
+
+Prior to Camel 2.10, Camel will perform redelivery while stopping a
+route, or shutting down Camel. This has improved a bit in Camel 2.10
+onwards, as Camel will not perform redelivery attempts when shutting
+down aggressively (eg during link:graceful-shutdown.html[Graceful
+Shutdown] and timeout hit). From Camel 2.11 onwards there is a new
+option `allowRedeliveryWhileStopping` which you can use to control if
+redelivery is allowed or not; notice that any in progress redelivery
+will still be executed. This option can only disallow any redelivery to
+be executed *after* the stopping of a route/shutdown of Camel has been
+triggered. If a redelivery is dissallowed then a
+`RejectedExcutionException` is set on the link:exchange.html[Exchange]
+and the processing of the link:exchange.html[Exchange] stops. This means
+any consumer will see the link:exchange.html[Exchange] as failed due the
+`RejectedExecutionException`.
+
+The default value is `true` to be backwards compatible as before. For
+example the following sample shows how to do this with Java DSL and XML
+DSL
+
+And the sample sample with XML DSL
+
+[[DeadLetterChannel-Samples]]
+Samples
+^^^^^^^
+
+The following example shows how to configure the Dead Letter Channel
+configuration using the link:dsl.html[DSL]
+
+You can also configure the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html[RedeliveryPolicy]
+as this example shows
+
+[[DeadLetterChannel-HowcanImodifytheExchangebeforeredelivery?]]
+How can I modify the Exchange before redelivery?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We support directly in link:dead-letter-channel.html[Dead Letter
+Channel] to set a link:processor.html[Processor] that is executed
+*before* each redelivery attempt.
+
+When link:dead-letter-channel.html[Dead Letter Channel] is doing
+redeliver its possible to configure a link:processor.html[Processor]
+that is executed just *before* every redelivery attempt. This can be
+used for the situations where you need to alter the message before its
+redelivered.
+
+Here we configure the link:dead-letter-channel.html[Dead Letter Channel]
+to use our processor `MyRedeliveryProcessor` to be executed before each
+redelivery.
+
+And this is the processor `MyRedeliveryProcessor` where we alter the
+message.
+
+[[DeadLetterChannel-HowcanIlogwhatcausedtheDeadLetterChanneltobeinvoked?]]
+How can I log what caused the Dead Letter Channel to be invoked?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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 `direct:deadLetterChannel`). 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 
http://stackoverflow.com/questions/13711462/logging-camel-exceptions-and-sending-to-the-dead-letter-channel[http://stackoverflow.com/questions/13711462/logging-camel-exceptions-and-sending-to-the-dead-letter-channel]
+
+[[DeadLetterChannel-UsingThisPattern]]
+Using This Pattern
+++++++++++++++++++
+
+If you would like to use this EIP Pattern then please read the
+link:getting-started.html[Getting Started], you may also find the
+link:architecture.html[Architecture] useful particularly the description
+of link:endpoint.html[Endpoint] and link:uris.html[URIs]. Then you could
+try out some of the link:examples.html[Examples] first before trying
+this pattern out.
+
+* link:error-handler.html[Error Handler]
+* link:exception-clause.html[Exception Clause]
+

http://git-wip-us.apache.org/repos/asf/camel/blob/1489eb81/docs/user-manual/en/SUMMARY.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index d04baee..a7d5631 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -83,7 +83,8 @@
         * [Pipes and Filter](pipes-and-filters.adoc)
     * Messaging Channels
         * [Point to Point Channel](point-to-point-channel.adoc)
-        * [Publish Subscribe Channel](point-to-point-channel.adoc)
+        * [Publish Subscribe Channel](publish-subscribe-channel.adoc)
+        * [Dead Letter Channel](dead-letter-channel.adoc)
     * Message Construction
         * [Correlation Identifier](correlation-identifier.adoc)
         * [Event Message](event-message.adoc)

Reply via email to