You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2018/08/03 09:51:06 UTC

[camel] branch master updated: CAMEL-11497: Migrate error handling related guides and EIPs

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 2e69ead  CAMEL-11497: Migrate error handling related guides and EIPs
2e69ead is described below

commit 2e69eadf0e08e16f8ca35ba3e0aea518ca2fb56d
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Fri Aug 3 18:46:19 2018 +0900

    CAMEL-11497: Migrate error handling related guides and EIPs
---
 .../main/docs/eips/content-based-router-eip.adoc   |  79 +++
 .../src/main/docs/eips/dead-letter-channel.adoc    |  18 +-
 .../src/main/docs/eips/transactional-client.adoc   | 265 +++++++
 components/camel-cdi/src/main/docs/cdi.adoc        |   1 +
 components/camel-spring/src/main/docs/spring.adoc  |   1 +
 docs/user-manual/en/SUMMARY.md                     |   4 +-
 docs/user-manual/en/async.adoc                     |   2 +-
 docs/user-manual/en/camel-boot.adoc                |   6 +-
 docs/user-manual/en/defaulterrorhandler.adoc       |  66 ++
 docs/user-manual/en/error-handling-in-camel.adoc   | 109 ++-
 docs/user-manual/en/exception-clause.adoc          | 766 +++++++++++++++++++++
 docs/user-manual/en/predicate.adoc                 | 222 ++++++
 docs/user-manual/en/transactionerrorhandler.adoc   | 178 +++++
 docs/user-manual/en/try-catch-finally.adoc         | 132 ++++
 14 files changed, 1773 insertions(+), 76 deletions(-)

diff --git a/camel-core/src/main/docs/eips/content-based-router-eip.adoc b/camel-core/src/main/docs/eips/content-based-router-eip.adoc
new file mode 100644
index 0000000..1c52c63
--- /dev/null
+++ b/camel-core/src/main/docs/eips/content-based-router-eip.adoc
@@ -0,0 +1,79 @@
+[[contentBasedRouter-eip]]
+== Content Based Router
+
+The
+http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html[Content
+Based Router] from the link:enterprise-integration-patterns.html[EIP
+patterns] allows you to route messages to the correct destination based
+on the contents of the message exchanges.
+
+image:http://www.enterpriseintegrationpatterns.com/img/ContentBasedRouter.gif[image]
+
+The following example shows how to route a request from an input
+*seda:a* endpoint to either *seda:b*, *seda:c* or *seda:d* depending on
+the evaluation of various link:predicate.html[Predicate] expressions
+
+=== Using the link:fluent-builders.html[Fluent Builders]
+
+[source,java]
+----
+RouteBuilder builder = new RouteBuilder() {
+    public void configure() {
+        errorHandler(deadLetterChannel("mock:error"));
+ 
+        from("direct:a")
+            .choice()
+                .when(header("foo").isEqualTo("bar"))
+                    .to("direct:b")
+                .when(header("foo").isEqualTo("cheese"))
+                    .to("direct:c")
+                .otherwise()
+                    .to("direct:d");
+    }
+};
+----
+
+[TIP]
+====
+See
+link:why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.html[Why
+can I not use when or otherwise in a Java Camel route] if you have
+problems with the Java DSL, accepting using `when` or `otherwise`.
+====
+
+=== Using the link:spring-xml-extensions.html[Spring XML Extensions]
+
+[source,java]
+----
+<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/spring">
+    <route>
+        <from uri="direct:a"/>
+        <choice>
+            <when>
+                <xpath>$foo = 'bar'</xpath>
+                <to uri="direct:b"/>
+            </when>
+            <when>
+                <xpath>$foo = 'cheese'</xpath>
+                <to uri="direct:c"/>
+            </when>
+            <otherwise>
+                <to uri="direct:d"/>
+            </otherwise>
+        </choice>
+    </route>
+</camelContext>
+----
+
+For further examples of this pattern in use you could look at the
+https://github.com/apache/camel/blob/master/camel-core/src/test/java/org/apache/camel/processor/ChoiceTest.java[junit test case].
+
+[[ContentBasedRouter-UsingThisPattern]]
+=== Using This Pattern
+
+If you would like to use this EIP Pattern then please read the
+<<GettingStarted-GettingStarted,Getting Started>>. You may also find the
+<<Architecture-Architecture,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.
diff --git a/camel-core/src/main/docs/eips/dead-letter-channel.adoc b/camel-core/src/main/docs/eips/dead-letter-channel.adoc
index 5137011..1f44700 100644
--- a/camel-core/src/main/docs/eips/dead-letter-channel.adoc
+++ b/camel-core/src/main/docs/eips/dead-letter-channel.adoc
@@ -67,13 +67,13 @@ 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]
+*Handled* on <<DeadLetterChannel-DeadLetterChannel,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
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> have handled the
 link:exchange.html[Exchange].
 
 For instance configuring the dead letter channel as:
@@ -103,7 +103,7 @@ And in XML:
 </bean>
 ----
 
-The link:dead-letter-channel.html[Dead Letter Channel] above will clear
+The <<DeadLetterChannel-DeadLetterChannel,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]
@@ -131,7 +131,7 @@ 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
+<<DeadLetterChannel-DeadLetterChannel,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
@@ -154,7 +154,7 @@ original we received.
 [[DeadLetterChannel-OnRedelivery]]
 === OnRedelivery
 
-When link:dead-letter-channel.html[Dead Letter Channel] is doing
+When <<DeadLetterChannel-DeadLetterChannel,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
@@ -164,7 +164,7 @@ 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
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> can be viewed as a
 global scope.
 
 
@@ -384,7 +384,7 @@ The onPrepare is also available using the default error handler.
 *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
+<<DeadLetterChannel-DeadLetterChannel,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
@@ -444,13 +444,13 @@ 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
+When <<DeadLetterChannel-DeadLetterChannel,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]
+Here we configure the <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>
 to use our processor `MyRedeliveryProcessor` to be executed before each
 redelivery.
 
diff --git a/camel-core/src/main/docs/eips/transactional-client.adoc b/camel-core/src/main/docs/eips/transactional-client.adoc
new file mode 100644
index 0000000..f460ed2
--- /dev/null
+++ b/camel-core/src/main/docs/eips/transactional-client.adoc
@@ -0,0 +1,265 @@
+[[TransactionalClient-TransactionalClient]]
+== Transactional Client
+
+Camel recommends supporting the
+http://www.enterpriseintegrationpatterns.com/TransactionalClient.html[Transactional
+Client] from the link:enterprise-integration-patterns.html[EIP patterns]
+using spring transactions.
+
+image:http://www.enterpriseintegrationpatterns.com/img/TransactionalClientSolution.gif[image]
+
+Transaction Oriented Endpoints like <<jms-component,JMS>> support using a
+transaction for both inbound and outbound message exchanges. Endpoints
+that support transactions will participate in the current transaction
+context that they are called from.
+
+===== Configuration of Redelivery
+
+The redelivery in transacted mode is *not* handled by Camel but by the
+backing system (the transaction manager). In such cases you should
+resort to the backing system how to configure the redelivery.
+
+You should use the
+http://camel.apache.org/maven/current/camel-spring/apidocs/org/apache/camel/spring/SpringRouteBuilder.html[SpringRouteBuilder]
+to setup the routes since you will need to setup the spring context with
+the TransactionTemplates that will define the transaction manager
+configuration and policies.
+
+For inbound endpoint to be transacted, they normally need to be
+configured to use a Spring PlatformTransactionManager. In the case of
+the JMS component, this can be done by looking it up in the spring
+context.
+
+You first define needed object in the spring configuration.
+
+[source,xml]
+----
+<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
+    <property name="connectionFactory" ref="jmsConnectionFactory" />
+</bean>
+
+<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
+    <property name="brokerURL" value="tcp://localhost:61616"/>
+</bean>
+----
+
+Then you look them up and use them to create the JmsComponent.
+
+[source,java]
+----
+PlatformTransactionManager transactionManager = (PlatformTransactionManager) spring.getBean("jmsTransactionManager");
+ConnectionFactory connectionFactory = (ConnectionFactory) spring.getBean("jmsConnectionFactory");
+JmsComponent component = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
+component.getConfiguration().setConcurrentConsumers(1);
+ctx.addComponent("activemq", component);
+----
+
+[[TransactionalClient-TransactionPolicies]]
+=== Transaction Policies
+
+Outbound endpoints will automatically enlist in the current transaction
+context. But what if you do not want your outbound endpoint to enlist in
+the same transaction as your inbound endpoint? The solution is to add a
+Transaction Policy to the processing route. You first have to define
+transaction policies that you will be using. The policies use a spring
+TransactionTemplate under the covers for declaring the transaction
+demarcation to use. So you will need to add something like the following
+to your spring xml:
+
+[source,xml]
+----
+<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+</bean>
+
+<bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
+</bean>
+----
+
+Then in your
+http://camel.apache.org/maven/current/camel-spring/apidocs/org/apache/camel/spring/SpringRouteBuilder.html[SpringRouteBuilder],
+you just need to create new SpringTransactionPolicy objects for each of
+the templates.
+
+[source,java]
+----
+public void configure() {
+    ...
+    Policy requried = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRED"));
+    Policy requirenew = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRES_NEW"));
+    ...
+}
+----
+
+Once created, you can use the Policy objects in your processing routes:
+
+[source,java]
+----
+// Send to bar in a new transaction
+from("activemq:queue:foo").policy(requirenew)
+    .to("activemq:queue:bar");
+
+// Send to bar without a transaction.
+from("activemq:queue:foo").policy(notsupported)
+    .to("activemq:queue:bar");
+----
+
+[[TransactionalClient-OSGiBlueprint]]
+=== OSGi Blueprint
+
+If you are using
+<<UsingOSGiblueprintwithCamel-UsingOSGiblueprintwithCamel,OSGi Blueprint>>
+then you most likely have to explicit declare a policy and
+refer to the policy from the transacted in the route.
+
+[source,xml]
+----
+<bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
+</bean>
+----
+
+And then refer to "required" from the route:
+
+[source,xml]
+----
+<route>
+    <from uri="activemq:queue:foo"/>
+    <transacted ref="required"/>
+    <to uri="activemq:queue:bar"/>
+</route>
+----
+
+[[TransactionalClient-DatabaseSample]]
+=== Database Sample
+
+In this sample we want to ensure that two endpoints is under transaction
+control. These two endpoints inserts data into a database.
+The sample is in its full as a
+https://github.com/apache/camel/tree/master/components/camel-spring/src/test/java/org/apache/camel/spring/interceptor/TransactionalClientDataSourceMinimalConfigurationTest.java[unit test].
+
+First of all we setup the usual spring stuff in its configuration file.
+Here we have defined a DataSource to the HSQLDB and a most
+importantly the Spring DataSource TransactionManager that is doing the
+heavy lifting of ensuring our transactional policies. You are of course
+free to use any of the Spring based TransactionManager, eg. if you are
+in a full blown J2EE container you could use JTA or the WebLogic or
+WebSphere specific managers.
+
+As we use the new convention over configuration we do *not* need to
+configure a transaction policy bean, so we do not have any
+`PROPAGATION_REQUIRED` beans. All the beans needed to be configured is
+*standard* Spring beans only, eg. there are no Camel specific
+configuration at all.
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/interceptor/springTransactionalClientDataSourceMinimalConfiguration.xml
+
+Then we are ready to define our Camel routes. We have two routes: 1 for
+success conditions, and 1 for a forced rollback condition.
+
+This is after all based on a unit test. Notice that we mark each route
+as transacted using the *transacted* tag.
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/interceptor/springTransactionalClientDataSourceMinimalConfiguration.xml
+
+That is all that is needed to configure a Camel route as being transacted.
+Just remember to use the *transacted* DSL. The rest is standard Spring
+XML to setup the transaction manager.
+
+[[TransactionalClient-JMSSample]]
+=== JMS Sample
+
+In this sample we want to listen for messages on a queue and process the
+messages with our business logic java code and send them along. Since
+it is based on a
+https://github.com/apache/camel/tree/master/components/camel-jms/src/test/java/org/apache/camel/component/jms/tx/TransactionMinimalConfigurationTest.java[unit test]
+the destination is a mock endpoint.
+
+First we configure the standard Spring XML to declare a JMS connection
+factory, a JMS transaction manager and our ActiveMQ component that we
+use in our routing.
+
+/components/camel-jms/src/test/resources/org/apache/camel/component/jms/tx/TransactionMinimalConfigurationTest.xml
+
+And then we configure our routes. Notice that all we have to do is mark the
+route as transacted using the *transacted* tag.
+
+/components/camel-jms/src/test/resources/org/apache/camel/component/jms/tx/TransactionMinimalConfigurationTest.xml
+
+===== Transaction error handler
+
+When a route is marked as transacted using *transacted* Camel will
+automatic use the
+<<TransactionErrorHandler-TransactionErrorHandler,TransactionErrorHandler>>
+as <<ErrorHandler-ErrorHandler,Error Handler>>.
+It supports basically the same feature set as the
+<<DefaultErrorHandler-DefaultErrorHandler,DefaultErrorHandler>>,
+so you can for instance use
+<<ExceptionClause-ExceptionClause,Exception Clause>>
+as well.
+
+[[TransactionalClient-IntegrationTestingwithSpring]]
+=== Integration Testing with Spring
+
+An Integration Test here means a test runner class annotated
+`@RunWith(SpringJUnit4ClassRunner.class).`
+
+When following the Spring Transactions documentation it is tempting to
+annotate your integration test with `@Transactional` then seed your
+database before firing up the route to be tested and sending a message
+in. This is incorrect as Spring will have an in-progress transaction,
+and Camel will wait on this before proceeding, leading to the route
+timing out.
+
+Instead, remove the `@Transactional` annotation from the test method and
+seed the test data within a `TransactionTemplate` execution which will
+ensure the data is committed to the database before Camel attempts to
+pick up and use the transaction manager. A simple
+example https://github.com/rajivj2/example2/blob/master/src/test/java/com/example/NotificationRouterIT.java[can
+be found on GitHub].
+
+Spring's transactional model ensures each transaction is bound to one
+thread. A Camel route may invoke additional threads which is where the
+blockage may occur. This is not a fault of Camel but as the programmer
+you must be aware of the consequences of beginning a transaction in a
+test thread and expecting a separate thread created by your Camel route
+to be participate, which it cannot. You can, in your test, mock the
+parts that cause separate threads to avoid this issue.
+
+[[TransactionalClient-Usingmultiplerouteswithdifferentpropagationbehaviors]]
+=== Using multiple routes with different propagation behaviors
+
+*Available as of Camel 2.2*
+
+Suppose you want to route a message through two routes and by which the
+2nd route should run in its own transaction. How do you do that? You use
+propagation behaviors for that where you configure it as follows:
+
+* The first route use `PROPAGATION_REQUIRED`
+* The second route use `PROPAGATION_REQUIRES_NEW`
+
+This is configured in the Spring XML file:
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/interceptor/MixedTransactionPropagationTest.xml
+
+Then in the routes you use transacted DSL to indicate which of these two
+propagations it uses.
+
+/components/camel-spring/src/test/java/org/apache/camel/spring/interceptor/MixedTransactionPropagationTest.java
+
+Notice how we have configured the `onException` in the 2nd route to indicate in
+case of any exceptions we should handle it and just rollback this
+transaction. This is done using the `markRollbackOnlyLast` which tells
+Camel to only do it for the current transaction and not globally.
+
+[[TransactionalClient-SeeAlso]]
+=== See Also
+
+* <<ErrorhandlinginCamel-ErrorhandlinginCamel,Error handling in Camel>>
+* <<TransactionErrorHandler-TransactionErrorHandler,TransactionErrorHandler>>
+* <<ErrorHandler-ErrorHandler,Error Handler>>
+* <<jms-component,JMS>>
+* link:using-this-pattern.html[Using This Pattern]
diff --git a/components/camel-cdi/src/main/docs/cdi.adoc b/components/camel-cdi/src/main/docs/cdi.adoc
index 6374291..0b85d64 100644
--- a/components/camel-cdi/src/main/docs/cdi.adoc
+++ b/components/camel-cdi/src/main/docs/cdi.adoc
@@ -1,3 +1,4 @@
+[[cdi-component]]
 == Camel CDI
 
 The Camel CDI component provides auto-configuration for Apache Camel
diff --git a/components/camel-spring/src/main/docs/spring.adoc b/components/camel-spring/src/main/docs/spring.adoc
index bb2ee03..fc2c18d 100644
--- a/components/camel-spring/src/main/docs/spring.adoc
+++ b/components/camel-spring/src/main/docs/spring.adoc
@@ -1,3 +1,4 @@
+[[SpringSupport-SpringSupport]]
 ## Spring Support
 
 Apache Camel is designed to work nicely with the
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index 6118d66..aa072f9 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -39,12 +39,12 @@
     * [Inversion Of Control With Smart Defaults](inversion-of-control-with-smart-defaults.adoc)
     * [Lifecycle](lifecycle.adoc)
     * [OnCompletion](oncompletion.adoc)
+    * [Predicate](predicate.adoc)
     * [Registry](registry.adoc)
     * [Scala DSL](scala-dsl.adoc)
 
 <!--
     * [Pluggable Class Resolvers](.adoc)
-    * [Predicate](.adoc)
     * [Processor](.adoc)
     * [RouteBuilder](.adoc)
     * [RoutePolicy](.adoc)
@@ -579,5 +579,5 @@
     * [How to run Camel in a osgi container]
     * [Using OSGi blueprint with Camel]
     * [Working with Camel and SCR]
-    * Working with REST and link:rest-dsl.html[Rest DSL]
+    * Working with REST and [Rest DSL]
     * [JSSE Utility](camel-configuration-utilities.adoc)
diff --git a/docs/user-manual/en/async.adoc b/docs/user-manual/en/async.adoc
index 2e6809a..2e0bf3f 100644
--- a/docs/user-manual/en/async.adoc
+++ b/docs/user-manual/en/async.adoc
@@ -215,7 +215,7 @@ just use plain Java but invoke `get()` on the `Future` handle.
 
 [[Async-TheClientAPIwithcallbacks]]
 The Async Client API with callbacks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In addition to the Client API from above Camel provides a variation that
 uses callbacks when the message
diff --git a/docs/user-manual/en/camel-boot.adoc b/docs/user-manual/en/camel-boot.adoc
index ee2927b..c3c01ff 100644
--- a/docs/user-manual/en/camel-boot.adoc
+++ b/docs/user-manual/en/camel-boot.adoc
@@ -17,14 +17,14 @@ The following camel boot options are supported:
 CDI
 ^^^
 
-Using the link:cdi.html[camel-cdi module] you can boot up your Camel
+Using the <<cdi-component,camel-cdi module>> you can boot up your Camel
 Java process using the *org.apache.camel.cdi.Main* class
 
 [[CamelBoot-Spring]]
 Spring
 ^^^^^^
 
-Using the link:spring.html[camel-spring module] you can boot you your
+Using the <<SpringSupport-SpringSupport,camel-spring module>> you can boot your
 Camel Java process using the *org.apache.camel.spring.Main* class
 
 [[CamelBoot-SpringBoot]]
@@ -32,6 +32,6 @@ Spring Boot
 ^^^^^^^^^^^
 
 You can combine Spring Boot with Camel using
-link:spring-boot.html[Camel's Spring Boot integration]. In this case
+<<SpringBoot-SpringBoot,Camel's Spring Boot integration>>. In this case
 your application looks and feels like a regular Spring Boot application
 but with full Camel integration.
diff --git a/docs/user-manual/en/defaulterrorhandler.adoc b/docs/user-manual/en/defaulterrorhandler.adoc
new file mode 100644
index 0000000..52a27e1
--- /dev/null
+++ b/docs/user-manual/en/defaulterrorhandler.adoc
@@ -0,0 +1,66 @@
+[[DefaultErrorHandler-DefaultErrorHandler]]
+=== DefaultErrorHandler
+
+This is the new default error handler in Camel 2.0 onwards.
+
+It has the same power as the <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>,
+however it does *not* support a _dead letter queue_, which is
+the only difference between the two of them.
+
+The DefaultErrorHandler is configured differently from
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> as
+it is configured to:
+
+* not redeliver
+* not handled
+* no dead letter queue (not possible)
+
+By default, any exception thrown during routing will be propagated back
+to the caller and the link:exchange.adoc[Exchange] ends immediately.
+However, you can use the link:exception-clause.adoc[Exception Clause] to
+catch a given exception and lower the exception by marking it as
+handled. If so, the exception will *not* be sent back to the caller, and
+the link:exchange.adoc[Exchange] continues to be routed.
+
+[[DefaultErrorHandler-Example]]
+==== Example
+
+In this route below, any exception thrown in, eg the `validateOrder`
+bean, will be propagated back to the caller via the jetty endpoint. It
+will return an HTTP error message back to the client.
+
+[source,brush:,java;,gutter:,false;,theme:,Default]
+----
+from("jetty:http://localhost/myservice/order")
+  .to("bean:validateOrder")
+  .to("jms:queue:order");
+----
+
+We can add an *onException* in case we want to catch certain exceptions
+and route them differently, for instance to catch a
+*ValidationException* and return a fixed response to the caller.
+
+[source,brush:,java;,gutter:,false;,theme:,Default]
+----
+onException(ValidationException.class)
+  .handled(true)
+  .transform(body(constant("INVALID ORDER")));
+
+from("jetty:http://localhost/myservice/order")
+  .to("bean:validateOrder")
+  .to("jms:queue:order");
+----
+
+When the `ValidationException` is thrown from the `validateOrder` bean,
+it is intercepted by the DefaultErrorHandler that lets the
+`onException(ValidationException.class)` handle it, so the
+link:exchange.adoc[Exchange] is routed to this onException route, and
+since we use `handled(true)`, then the original exception is cleared,
+and we transform the message into a fixed response that is returned to
+jetty endpoint that returns it to the original caller.
+
+[[DefaultErrorHandler-SeeAlso]]
+==== See Also
+
+* link:error-handler.adoc[Error Handler]
+* <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>
diff --git a/docs/user-manual/en/error-handling-in-camel.adoc b/docs/user-manual/en/error-handling-in-camel.adoc
index 42bf1d7..ede8d92 100644
--- a/docs/user-manual/en/error-handling-in-camel.adoc
+++ b/docs/user-manual/en/error-handling-in-camel.adoc
@@ -1,6 +1,5 @@
 [[ErrorhandlinginCamel-ErrorhandlinginCamel]]
-Error handling in Camel
-~~~~~~~~~~~~~~~~~~~~~~~
+=== Error handling in Camel
 
 Error handling in Camel can roughly be separated into two distinct
 types:
@@ -16,31 +15,23 @@ handled by a backing system such as a J2EE application server.
 ====
 **Using try ... catch ... finally**
 
-Related to error handling is the link:try-catch-finally.html[Try Catch
+Related to error handling is the link:try-catch-finally.adoc[Try Catch
 Finally] feature in Camel.
 ====
 
 [[ErrorhandlinginCamel-Whendoesanerrorhappen]]
-When does an error happen
-^^^^^^^^^^^^^^^^^^^^^^^^^
+==== When does an error happen
 
 An error happens when
 
 * any uncaught exception is thrown during routing and processing of
 messages within Camel
-+
-[Tip]
-====
 
-+
-So think of this as a big exception interceptor that catches all
+TIP: So think of this as a big exception interceptor that catches all
 exceptions and handles what to do.
 
-====
-
 [[ErrorhandlinginCamel-Nontransactional]]
-Non transactional
-^^^^^^^^^^^^^^^^^
+==== Non transactional
 
 By default Camel uses the non transaction type and orchestrates the
 error handling during processing and routing.
@@ -50,11 +41,10 @@ uses cases, you should consider altering the default configurations to
 better suit you needs.
 
 [[ErrorhandlinginCamel-Camel1.xdefaulterrorhandler]]
-Camel 1.x default error handler
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==== Camel 1.x default error handler
 
-In Camel 1.x a global link:dead-letter-channel.html[Dead Letter Channel]
-is setup as the link:error-handler.html[Error Handler] by default. It's
+In Camel 1.x a global <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>
+is setup as the link:error-handler.adoc[Error Handler] by default. It's
 configured as:
 
 * redeliver up to 6 times
@@ -69,16 +59,16 @@ ERROR level :star:
 **Dead Letter Queue (*)**
 
 A dead letter queue is like a black hole, it will consume the
-link:exchange.html[Exchange] and the link:exchange.html[Exchange]
+link:exchange.adoc[Exchange] and the link:exchange.adoc[Exchange]
 routing is ended with no indication that it failed. +
-This works great in the link:jms.html[JMS] Messaging world where we
+This works great in the <<jms-component,JMS>> Messaging world where we
 don't want a bad message to cause endless retries and causing the system
 to exhaust. The message is said to be poison and thus we want to move it
 to a dead letter queue so the system can continue to operate and work
 with the next message.
 
 This default does not go well with other transports using in a
-request/reply messaging style. If the link:exchange.html[Exchange]
+request/reply messaging style. If the link:exchange.adoc[Exchange]
 failed then the original caller will still want a response after the
 failure.
 
@@ -87,12 +77,11 @@ handling strategies that suits your business needs.
 ====
 
 [[ErrorhandlinginCamel-Camel2.0onwardsdefaulterrorhandler]]
-Camel 2.0 onwards default error handler
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==== Camel 2.0 onwards default error handler
 
 In Camel 2.0 onwards a global
-link:defaulterrorhandler.html[DefaultErrorHandler] is set up as the
-link:error-handler.html[Error Handler] by default. It's configured as:
+link:defaulterrorhandler.adoc[DefaultErrorHandler] is set up as the
+link:error-handler.adoc[Error Handler] by default. It's configured as:
 
 * no redeliveries
 * no dead letter queue
@@ -100,8 +89,7 @@ link:error-handler.html[Error Handler] by default. It's configured as:
 the original caller wrapped in a `RuntimeCamelException`.
 
 [[ErrorhandlinginCamel-Scopes]]
-Scopes
-^^^^^^
+==== Scopes
 
 Camel supports 2 scopes that is determined by the DSL in use:
 
@@ -131,25 +119,24 @@ multiple RouteBuilder classes. See more details at
 https://issues.apache.org/jira/browse/CAMEL-5456[CAMEL-5456].
 
 [[ErrorhandlinginCamel-Howdoestheerrorhandlerwork]]
-How does the link:dead-letter-channel.html[Dead Letter Channel] error handler work
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+==== How does the <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> error handler work
 
 When Camel is started it will inspect the routes and weave in the error
 handling into the routing. With up to 3 supported scopes, the error
 handling can be quite complex. And on top of that you have inherited
 error handling and you can even configure
-link:exception-clause.html[Exception Clause]s to handle specific
+link:exception-clause.adoc[Exception Clause]s to handle specific
 exception types differently. So yes it's advanced but very powerful when
 you get the grip of it.
 
 To keep things simple we first look at the basic concept how Camel
 orchestrates the redelivery attempt. At any given node in the route
 graph Camel intercepts the current Exchange being routed and wraps it
-with the link:error-handler.html[Error Handler]. This ensures that the
-link:error-handler.html[Error Handler] can kick in, just as the AOP
+with the link:error-handler.adoc[Error Handler]. This ensures that the
+link:error-handler.adoc[Error Handler] can kick in, just as the AOP
 around concept. If the exchange can be routed without any problems then
 it's forwarded to the next node in the route graph, *But* if there was
-an exception thrown, then the link:error-handler.html[Error Handler]
+an exception thrown, then the link:error-handler.adoc[Error Handler]
 kicks in and decides what to do.
 
 An example illustrating this:
@@ -165,19 +152,19 @@ from("seda:newOrder")
 ----
 
 In this route we have 3 nodes (the dots) where the
-link:error-handler.html[Error Handler] is watching us (The AOP around
+link:error-handler.adoc[Error Handler] is watching us (The AOP around
 stuff). So when an order arrives on the seda queue we consume it and
 send it to the validateOrder bean. In case the validation bean processed
 ok, we move on to the next node. In case the storeOrder bean failed and
 throws an exception it's caught by the
-link:dead-letter-channel.html[Dead Letter Channel] that decides what to
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> that decides what to
 do next. Either it does a:
 
 * redeliver
 * or move it to dead letter queue
 
 It will continue to do redeliveries based on the policy configured. By
-default link:dead-letter-channel.html[Dead Letter Channel] will attempt
+default <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> will attempt
 at most 6 redeliveries with 1 second delay. So if the storeOrder bean
 did succeed at the 3rd attempt the routing will continue to the next
 node the confirmOrder bean. In case all redeliveries failed the Exchange
@@ -188,14 +175,13 @@ just a ERROR logger.
 [NOTE]
 ====
 This applies to all kind of link:components.html[Components] in Camel.
-The sample above only uses link:bean.html[Bean] but it's the same for
-link:file2.html[File], link:mail.html[Mail],
-link:velocity.html[Velocity] or whatever component you use.
+The sample above only uses <<bean-component,Bean>> but it's the same for
+<<file-component,File>>, <<mail-component,Mail>>,
+<<velocity-component,Velocity>> or whatever component you use.
 ====
 
 [[ErrorhandlinginCamel-Transactional]]
-Transactional
-^^^^^^^^^^^^^
+==== Transactional
 
 Camel leverages Spring transactions. Usually you can only use this with
 a limited number of transport types such as JMS or JDBC based, that yet
@@ -203,13 +189,13 @@ again requires a transaction manager such as a Spring transaction, a
 J2EE server or a Message Broker.
 
 [[ErrorhandlinginCamel-Howdoesitwork]]
-How does it work
-^^^^^^^^^^^^^^^^
+==== How does it work
+
+*Camel 1.x*
 
-*Camel 1.x* +
 Camel does the same weaving as for the non-transactional type. The
 difference is that for transactional exchanges the
-link:error-handler.html[Error Handler] does *not* kick in. You can say
+link:error-handler.adoc[Error Handler] does *not* kick in. You can say
 the AOP around does not apply. Camel relies solely on the backing system
 to orchestrate the error handling. And as such the when the backing
 system does redeliver it will start all over again. For instance if the
@@ -217,32 +203,33 @@ exchange was started by a JMS consumer then it's started again as the
 JMS message is rolled back on the JMS queue and Camel will re consume
 the JMS message again.
 
-*Camel 2.0* +
+*Camel 2.0*
+
 In Camel 2.0 we have empowered the
-link:transactionerrorhandler.html[TransactionErrorHandler] to build on
+link:transactionerrorhandler.adoc[TransactionErrorHandler] to build on
 top of the same base that
-link:defaulterrorhandler.html[DefaultErrorHandler] does. This allows you
+link:defaulterrorhandler.adoc[DefaultErrorHandler] does. This allows you
 to use Camel redelivery with transactional routes as well. The Spring
 transaction manager is still in charge and have the last say. But you
 can use Camel to do some local redelivery, for instance to upload a file
 to a FTP server, in which Camel can do local redelivery. So this gives
 you the power from both worlds. In case Camel cannot redeliver the
 exchange will be failed and rolled back. By default the
-link:transactionerrorhandler.html[TransactionErrorHandler] does *not*
+link:transactionerrorhandler.adoc[TransactionErrorHandler] does *not*
 attempt any local redeliveries. You have to configure it to do so, for
 instance to set a maximum redelivers to a number > 0.
 
-See link:transactional-client.html[Transactional Client] for more.
+See <<TransactionalClient-TransactionalClient,Transactional Client>>
+for more.
 
 [[ErrorhandlinginCamel-Seealso]]
-See also
-~~~~~~~~
-
-* link:error-handler.html[Error Handler]
-* link:dead-letter-channel.html[Dead Letter Channel]
-* link:exception-clause.html[Exception Clause]
-* link:transactional-client.html[Transactional Client]
-* link:transactionerrorhandler.html[TransactionErrorHandler]
-* link:defaulterrorhandler.html[DefaultErrorHandler]
-* link:try-catch-finally.html[Try Catch Finally]
-* link:load-balancer.html[Failover Load Balancer]
+==== See also
+
+* link:error-handler.adoc[Error Handler]
+* <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>
+* link:exception-clause.adoc[Exception Clause]
+* <<TransactionalClient-TransactionalClient,Transactional Client>>
+* link:transactionerrorhandler.adoc[TransactionErrorHandler]
+* link:defaulterrorhandler.adoc[DefaultErrorHandler]
+* link:try-catch-finally.adoc[Try Catch Finally]
+* <<loadBalancer-eip,Failover Load Balancer>>
diff --git a/docs/user-manual/en/exception-clause.adoc b/docs/user-manual/en/exception-clause.adoc
new file mode 100644
index 0000000..e35fcc7
--- /dev/null
+++ b/docs/user-manual/en/exception-clause.adoc
@@ -0,0 +1,766 @@
+[[ExceptionClause-ExceptionClause]]
+=== Exception Clause
+
+You can use the _Exception Clause_ in the Java link:dsl.adoc[DSL] to
+specify the error handling you require on a per exception type basis
+using the *`onException()`* method. To get started we give quick sample
+before digging into how it works.
+
+For example if you want to perform a specific piece of processing if a
+certain exception is raised you can do this simply via:
+
+[source,java]
+----
+onException(ValidationException.class)
+    .to("activemq:validationFailed");
+
+from("seda:inputA")
+    .to("validation:foo/bar.xsd", "activemq:someQueue");
+
+from("seda:inputB")
+    .to("direct:foo")
+    .to("rnc:mySchema.rnc", "activemq:anotherQueue");
+----
+
+Here if the processing of *`seda:inputA`* or *`seda:inputB`* cause
+a *`ValidationException`* to be thrown (such as due to the XSD
+validation of the <<validator-components,Validation>> component or the
+Relax NG Compact syntax validation of the <<jing-component,Jing>>
+component), then the message will be sent to the
+*`activemq:validationFailed`* queue.
+
+You can define multiple *`onException`* clauses for different behavior:
+
+[source,java]
+----
+onException(ValidationException.class)
+    .to("activemq:validationFailed");
+
+onException(ShipOrderException.class)
+    .to("activemq:shipFailed");
+
+from("seda:order")
+    .to("bean:processOrder");
+----
+
+[[ExceptionClause-Scopes]]
+==== Scopes
+
+Exception clauses is scoped as either:
+
+* global (for Java DSL that is per *`RouteBuilder`* instances, to reuse,
+see note below)
+* or route specific
+
+Where the *global* are the simplest and most easy to understand. In the
+advanced section we dig into the route specific and even combining them.
+However
+
+Global scope for Java DSL is per *`RouteBuilder`* instance, so if you
+want to share among multiple *`RouteBuilder`* classes, then create a
+base abstract *`RouteBuilder`* class and put the error handling logic in
+its *`configure`* method. And then extend this class, and make sure to
+class *`super.configure()`*. We are just using the Java inheritance
+technique.
+
+[[ExceptionClause-HowDoesCamelSelectWhichClauseShouldHandleaGivenThrownException]]
+==== How Does Camel Select Which Clause Should Handle a Given Thrown Exception?
+
+Camel uses *`DefaultExceptionPolicyStrategy`* to determine a strategy
+how an exception being thrown should be handled by which *`onException`*
+clause. The strategy is:
+
+* the order in which the *`onException`* is configured takes precedence.
+Camel will test from first...last defined.
+* Camel will start from the bottom (nested caused by) and recursive up
+in the exception hierarchy to find the first matching *`onException`*
+clause.
+* *`instanceof`* test is used for testing the given exception with the
+*`onException`* clause defined exception list. An exact *`instanceof`*
+match will always be used, otherwise the *`onException`* clause that has
+an exception that is the closets super of the thrown exception is
+selected (recurring up the exception hierarchy).
+
+This is best illustrated with an exception:
+
+[source,java]
+----
+onException(IOException.class)
+    .maximumRedeliveries(3);
+
+onException(OrderFailedException.class)
+    .maximumRedeliveries(2);
+----
+
+In the sample above we have defined two exceptions in
+which *`IOException`* is first, so Camel will pickup this exception if
+there is a match. *`IOException`* that is more general is selected then.
+
+So if an exception is thrown with this hierarchy:
+
+....
++ RuntimeCamelException (wrapper exception by Camel)
+    + OrderFailedException
+        + IOException
+            + FileNotFoundException
+....
+
+Then Camel will try testing the exception in this order:
+*`FileNotFoundException`*, *`IOException`*, *`OrderFailedException`* and
+*`RuntimeCamelException`*.
+As we have defined a *`onException(IOException.class)`* Camel will
+select this as it's the *closest* match.
+
+If we add a third *`onException`* clause with the
+*`FileNotFoundException`*
+
+[source,java]
+----
+onException(IOException.class)
+    .maximumRedeliveries(3);
+
+onException(OrderFailedException.class)
+    .maximumRedeliveries(2);
+
+onException(FileNotFoundException.class)
+    .handled(true)
+    .to("log:nofile");
+----
+
+Then with the previous example Camel will now use the last
+*`onException(FileNotFoundException.class)`* as its an *exact* match.
+Since this is an exact match it will override the
+general *`IOException`* that was used before to handle the same
+exception thrown.
+
+Now a new situation if this exception was thrown instead:
+
+....
++ RuntimeCamelException (wrapper exception by Camel)
+    + OrderFailedException
+        + OrderNotFoundException
+....
+
+Then the *`onException(OrderFailedException.class)`* will be selected -
+no surprise here.
+
+And this last sample demonstrates the *`instanceof`* test aspect in
+which Camel will select an exception if it's an instance of the defined
+exception in the *`onException`* clause. Illustrated as:
+
+....
++ RuntimeCamelException (wrapper exception by Camel)
+    + SocketException
+....
+
+Since *`SocketException`* is an *`instanceof IOException`*, Camel will
+select the *`onException(IOException.class)`* clause.
+
+[[ExceptionClause-ConfiguringRedeliveryPolicyredeliveroptions]]
+==== Configuring RedeliveryPolicy (redeliver options)
+
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html[RedeliveryPolicy]
+requires to use the <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>
+as the link:error-handler.adoc[Error Handler]. Dead Letter Channel
+supports attempting to redeliver the message exchange a number of times
+before sending it to a dead letter endpoint. See
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> for further
+information about redeliver and which redeliver options exists.
+
+===== No redelivery is default for onException
+
+By default any link:exception-clause.adoc[Exception Clause] will *not*
+redeliver! (as it sets the `maximumRedeliveries` option to 0).
+
+Sometimes you want to configure the redelivery policy on a per exception
+type basis. By default in the top examples, if an
+*`org.apache.camel.ValidationException`* occurs then the message will
+not be redelivered; however if some other exception occurs, e.g.,
+*`IOException`* or whatever, the route will be retried according to the
+settings from the <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>>.
+
+However if you want to customize any methods on the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html[RedeliveryPolicy]
+object, you can do this via the fluent API. So lets retry in case
+of *`org.apache.camel.ValidationException`* up till two times.
+
+*Java DSL*:
+
+[source,java]
+----
+onException(ValidationException.class)
+    .maximumRedeliveries(2);
+----
+
+*Spring XML DSL*:
+
+[source,xml]
+----
+<onException>
+    <exception>com.mycompany.ValidationException</exception>
+    <redeliveryPolicy maximumRedeliveries="2"/>
+</onException>
+----
+
+You can customize any of the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/RedeliveryPolicy.html[RedeliveryPolicy]
+so we can for instance set a different delay of *`5000`* millis:
+
+[source,xml]
+----
+<onException>
+    <exception>com.mycompany.ValidationException</exception>
+    <redeliveryPolicy maximumRedeliveries="2" delay="5000"/>
+</onException>
+----
+
+[[ExceptionClause-PointofEntryforRedeliveryAttempts]]
+==== Point of Entry for Redelivery Attempts
+
+All redelivery attempts start at the point of the failure. So the route:
+
+[source,java]
+----
+onException(ConnectException.class)
+    .from("direct:start")
+    .process("processor1")
+    .process("processor2") // <--- throws a ConnectException
+    .to("mock:theEnd")
+----
+
+Will retry from *`processor2`* - not the complete route.
+
+[[ExceptionClause-ReusingRedeliveryPolicy]]
+==== Reusing RedeliveryPolicy
+
+*Available as of Camel 1.5.1 or later*
+
+You can reference a *`RedeliveryPolicy`* so you can reuse existing
+configurations and use standard spring bean style configuration that
+supports property placeholders.
+
+[source,xml]
+----
+<bean id="myRedeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
+    <property name="maximumRedeliveries" value="${myprop.max}"/>
+</bean>
+
+<!-- here we reference our redelivery policy defined above -->
+<onException redeliveryPolicyRef="myRedeliveryPolicy">
+    <!-- you can define multiple exceptions just adding more exception elements as show below -->
+    <exception>com.mycompany.MyFirstException</exception>
+    <exception>com.mycompany.MySecondException</exception>
+</onException>
+----
+
+[[ExceptionClause-AsynchronousDelayedRedelivery]]
+==== Asynchronous Delayed Redelivery
+
+*Available as of Camel 2.4*
+
+From *Camel 2.4*: Camel has a feature to *not block* while waiting for a
+delayed redelivery to occur. However if you use transacted routes then
+Camel will block as its mandated by the transaction manager to execute
+all the work in the same thread context. You can enable the non blocking
+asynchronous behavior by the *`asyncDelayedRedelivery`* option. This
+option can be set on the *`errorHandler`*, *`onException`* or the
+redelivery policies.
+
+By default the error handler will create and use a scheduled thread pool
+to trigger redelivery in the future. From *Camel 2.8*: you can configure
+the *`executorServiceRef`* on the link:error-handler.adoc[Error Handler]
+to indicate a reference to either a shared thread pool you can enlist in
+the registry, or a thread pool profile in case you want to be able to
+control pool settings.
+
+[[ExceptionClause-CatchingMultipleExceptions]]
+==== Catching Multiple Exceptions
+
+*Available as of Camel 1.5*
+
+In Camel 1.5 the *exception* clauses has been renamed to *`onException`*
+and it also supports multiple exception classes:
+
+[source,java]
+----
+onException(MyBusinessException.class, MyOtherBusinessException.class)
+    .maximumRedeliveries(2)
+    .to("activemq:businessFailed");
+----
+
+And in Spring DSL you just add another exception element:
+
+[source,xml]
+----
+<onException>
+    <exception>com.mycompany.MyBusinessException</exception>
+    <exception>com.mycompany.MyOtherBusinessException</exception>
+    <redeliveryPolicy maximumRedeliveries="2"/>
+    <to uri="activemq:businessFailed"/>
+</onException>
+----
+
+[[ExceptionClause-UsingaProcessorasaFailureHandler]]
+==== Using a Processor as a Failure Handler
+
+We want to handle certain exceptions specially so we add
+a *`onException`* clause for that exception.
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionProcessorInspectCausedExceptionTest.java
+
+So what happens is that whenever a *`MyFunctionalException`* is thrown it
+is being routed to our processor *`MyFunctionFailureHandler`*. So you
+can say that the exchange is diverted when a *`MyFunctionalException`*
+is thrown during processing. It's important to distinct this as perfect
+valid. The default redelivery policy from the
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> will not kick in, so
+our processor receives the Exchange directly, without any redeliver
+attempted. In our processor we need to determine what to do. Camel
+regards the Exchange as *failure handled*. So our processor is the end
+of the route. So lets look the code for our processor.
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionProcessorInspectCausedExceptionTest.java
+
+Notice how we get the *caused by* exception using a property on the Exchange.
+This is where Camel stores any caught exception during processing. So
+you can fetch this property and check what the exception message and do
+what you want. In the code above we just route it to a mock endpoint
+using a producer template from Exchange.
+
+[[ExceptionClause-MarkingExceptionsasHandled]]
+=== Marking Exceptions as Handled
+
+*Available as of Camel 1.5*
+
+===== Continued
+
+See also the section <<ExceptionClause-HandleandContinueExceptions,Handle and continue exceptions>> below.
+
+Using *`onException`* to handle known exceptions is a very powerful
+feature in Camel. However prior to Camel 1.5 you could not mark the
+exception as being handled, so the caller would still receive the caused
+exception as a response. In Camel 1.5 you can now change this behavior
+with the new *handle* DSL. The handle is a
+link:predicate.adoc[Predicate] that is overloaded to accept three types
+of parameters:
+
+* Boolean
+* link:predicate.adoc[Predicate]
+* link:expression.adoc[Expression] that will be evaluates as a
+link:predicate.adoc[Predicate] using this rule set: If the expressions
+returns a Boolean its used directly. For any other response its regarded
+as `true` if the response is `not null`.
+
+For instance to mark all *`ValidationException`* as being handled we can
+do this:
+
+[source,java]
+----
+onException(ValidationException)
+    .handled(true);
+----
+
+[[ExceptionClause-ExampleUsingHandled]]
+==== Example Using Handled
+
+In this route below we want to do special handling of
+all *`OrderFailedException`* as we want to return a customized response
+to the caller. First we setup our routing as:
+
+/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelHandledExampleTest.java
+
+Then we have our service beans that is just plain POJO demonstrating how you
+can use link:bean-integration.adoc[Bean Integration] in Camel to avoid
+being tied to the Camel API:
+
+/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelHandledExampleTest.java
+
+And finally the exception that is being thrown is just a regular exception:
+
+/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelHandledExampleTest.java
+
+So what happens?
+
+If we sent an order that is being processed OK then the caller will
+receive an Exchange as reply containing *`Order OK`* as the payload and
+*`orderid=123`* in a header.
+
+If the order could *not* be processed and thus
+an *`OrderFailedException`* was thrown the caller will *not* receive
+this exception (as opposed to in Camel 1.4, where the caller received
+the *`OrderFailedException`*) but our customized response that we have
+fabricated in the *`orderFailed`* method in our *`OrderService`*. So the
+caller receives an Exchange with the payload *`Order ERROR`* and a
+*`orderid=failed`* in a header.
+
+[[ExceptionClause-UsingHandledwithSpringDSL]]
+==== Using Handled with Spring DSL
+
+The same route as above in Spring DSL:
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/deadLetterChannelHandledExampleTest.xml
+
+[[ExceptionClause-HandlingandSendingaFixedResponseBacktotheClient]]
+==== Handling and Sending a Fixed Response Back to the Client
+
+In the route above we handled the exception but routed it to a different
+endpoint. What if you need to alter the response and send a fixed
+response back to the original caller (the client). No secret here just
+do as you do in normal Camel routing, use
+<<MessageTranslator-MessageTranslator,transform>> to set the response, as shown in
+the sample below:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionHandleAndTransformTest.java
+
+We modify the sample slightly to return the original caused exception
+message instead of the fixed text `Sorry`:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionHandleAndTransformTest.java
+
+And we can use the link:simple-language.adoc[Simple] language to set a readable error
+message with the caused exception message:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionHandleAndTransformTest.java
+
+[[ExceptionClause-HandleandContinueExceptions]]
+=== Handle and Continue Exceptions
+
+*Available as of Camel 2.3*
+
+In Camel 2.3 we introduced a new option `continued` which allows you to
+both *`handle`* and *`continue`* routing in the original route as if the
+exception did not occur.
+
+For example: to ignore and continue when the *`IDontCareException`* was
+thrown we can do this:
+
+[source,java]
+----
+onException(IDontCareException)
+    .continued(true);
+----
+
+You can maybe compare continued with a having a *`try ... catch`* block
+around each step and then just ignore the exception. Using continued
+makes it easier in Camel as you otherwise had to use
+link:try-catch-finally.adoc[Try Catch Finally] style for this kind of
+use case.
+
+[[ExceptionClause-ExampleUsingcontinued]]
+==== Example Using continued
+
+In this route below we want to do special handling of
+all *`IllegalArgumentException`* as we just want to continue routing.
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTest.java
+
+And the same example in Spring XML:
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionContinueTest.xml
+
+[[ExceptionClause-WhatistheDifferenceBetweenHandledandContinued?]]
+==== What is the Difference Between Handled and Continued?
+
+If handled is true, then the thrown exception will be _handled_ and
+Camel will *not* continue routing in the original route, but break out.
+However you can configure a route in the *`onException`* which will be
+used instead. You use this route if you need to create some custom
+response message back to the caller, or do any other processing because
+that exception was thrown.
+
+If continued is true, then Camel will catch the exception and in fact
+just ignore it and continue routing in the original route. However if
+you have a route configured in the *`onException`* it will route that
+route first, before it will continue routing in the original route.
+
+[[ExceptionClause-UsinguseOriginalMessage]]
+==== Using `useOriginalMessage`
+
+*Available as of Camel 2.0*
+
+The option *`useOriginalMessage`* is used for routing the original input
+body instead of the current body that potential is modified during routing.
+
+For example: 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.adoc[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 add an
+*`onException`*. But when we move the link:exchange.adoc[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 input body
+onException(MyOrderException.class)
+    .useOriginalMessage()
+    .handled(true)
+    .to("jms:queue:order:failed");
+----
+
+Then the messages routed to the *`jms:queue:order:failed`* 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.
+
+[[ExceptionClause-useOriginalMessagewithSpringDSL]]
+==== `useOriginalMessage` with Spring DSL
+
+The *`useOriginalMessage`* option is defined as a boolean attribute on
+the *`<onException>`* XML tag in Spring DSL. So the definition above
+would be:
+
+[source,xml]
+----
+<onException useOriginalMessage="true">
+    <exception>com.mycompany.MyOrderException</exception>
+    <handled><constant>true</constant></handled>
+    <to uri="jms:queue:order:failed"/>
+</onException>
+----
+
+[[ExceptionClause-AdvancedUsageofExceptionClause]]
+=== Advanced Usage of link:exception-clause.adoc[Exception Clause]
+
+[[ExceptionClause-UsingGlobalandPerRouteExceptionClauses]]
+==== Using Global and Per Route Exception Clauses
+
+Camel supports quite advanced configuration of exception clauses.
+
+You can define exception clauses either as:
+
+* global
+* or route specific
+
+We start off with the sample sample that we change over time. First off
+we use only global exception clauses:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java
+
+In the next sample we change the global exception policies to be pure route
+specific.
+
+===== Must use `.end()` for route specific exception policies
+
+[IMPORTANT] This requires to end the *`onException`* route with
+*`.end()`* to indicate where it stops and when the regular route
+continues.
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionSubRouteTest.java
+
+And now it gets complex as we combine global and route specific exception
+policies as we introduce a second route in the sample:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionComplexRouteTest.java
+
+Notice that we can define the same exception *`MyFunctionalException`* in both
+routes, but they are configured differently and thus is handled
+different depending on the route. You can of course also add a
+new *`onException`* to one of the routes so it has an additional
+exception policy.
+
+And finally we top this by throwing in a nested error handler as well,
+as we add the 3rd route shown below:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionComplexWithNestedErrorHandlerRouteTest.java
+
+===== Global exception policies and nested error handlers
+
+The sample above with both nested error handlers and both global and per
+route exception clauses is a bit advanced. It's important to get the
+fact straight that the *global* exception clauses is really global so
+they also applies for nested error handlers. So if a
+*`MyTechnicalException`* is thrown then it's the global exception policy
+that is selected.
+
+[[ExceptionClause-UsingFineGrainedSelectionUsingonWhenPredicate]]
+==== Using Fine Grained Selection Using `onWhen` Predicate
+
+*Available as of Camel 1.5.1 or later*
+
+You can attach an link:expression.adoc[Expression] to the exception
+clause to have fine grained control when a clause should be selected or
+not. As it's an link:expression.adoc[Expression] you can use any kind of
+code to perform the test. Here is a sample:
+
+/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyUsingWhenTest.java
+
+In the sample above we have two *`onException`*'s defined. The first has
+an *`onWhen`* expression attached to only trigger if the message has a
+header with the key user that is not null. If so this clause is selected
+and is handling the thrown exception. The second clause is a for coarse
+gained selection to select the same exception being thrown but when the
+expression is evaluated to false.
+
+NOTE: this is not required, if the second clause is omitted, then the
+default error handler will kick in.
+
+[[ExceptionClause-UsingonRedeliveryProcessor]]
+==== Using `onRedelivery` Processor
+
+*Available as of Camel 2.0*
+
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> has support
+for *`onRedelivery`* to allow custom processing of a Message before its
+being redelivered. It can be used to add some customer header or
+whatnot. In Camel 2.0 we have added this feature to
+link:exception-clause.adoc[Exception Clause] as well, so you can use per
+exception scoped on redelivery. Camel will fallback to use the one
+defined on <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> if any, if
+none exists on the link:exception-clause.adoc[Exception Clause]. See
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> for more details on
+*`onRedelivery`*.
+
+In the code below we want to do some custom code before redelivering any
+*`IOException`*. So we configure an *`onException`* for
+the *`IOException`* and set the *`onRedelivery`* to use our custom
+processor:
+
+/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java
+
+And in our custom processor we set a special timeout header to the message.
+You can of course do anything what you like in your code.
+
+/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java
+
+[[ExceptionClause-UsingonRedeliveryinSpringDSL]]
+==== Using `onRedelivery` in Spring DSL
+
+In Spring DSL you need to use the *`onRedeliveryRef`* attribute to refer
+to a spring bean id that is your custom processor:
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml
+
+And our processor is just a regular spring bean (we use *`$`* for the inner
+class as this code is based on unit testing):
+
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml
+
+[[ExceptionClause-UsingonExceptionOccurredProcessor]]
+==== Using `onExceptionOccurred` Processor
+
+*Available as of Camel 2.17*
+
+<<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> has support
+for *`onExceptionOccurred`* to allow custom processing of a Message just
+after the exception was thrown. It can be used to do some custom logging
+or whatnot. The difference between *`onRedelivery`* processor
+and *`onExceptionOccurred`* processor, is that the former is processed
+just before a redelivery attempt is being performed, that means it will
+not happen right after an exception was thrown. For example if the error
+handler has been configured to perform 5 seconds delay between
+redelivery attempts, then the redelivery processor is invoked 5 seconds
+later sine the exception was thrown. On the other hand
+the *`onExceptionOccurred`* processor is always invoked right after the
+exception was thrown, and also if redelivery has been disabled.
+
+NOTE: Any new exceptions thrown from the *`onExceptionOccurred`*
+processor is logged as *`WARN`* and ignored, to not override the
+existing exception. 
+
+In the code below we want to do some custom logging when an exception
+happened. Therefore we configure an *`onExceptionOccurred`* to use our
+custom processor:
+
+[source.java]
+----
+errorHandler(defaultErrorHandler()
+    .maximumRedeliveries(3)
+    .redeliveryDelay(5000)
+    .onExceptionOccurred(myProcessor));
+----
+
+[[ExceptionClause-UsingonRedeliveryinSpringDSL.1]]
+Using `onRedelivery` in Spring DSL
+++++++++++++++++++++++++++++++++++
+
+In Spring DSL you need to use the *`onExceptionOccurredRef`* attribute
+to refer to a spring bean id that is your custom processor:
+
+[source,xml]
+----
+<bean id="myProcessor" class="com.foo.MyExceptionLoggingProcessor"/>
+
+<camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/spring">
+    <errorHandler id="eh" type="DefaultErrorHandler" onExceptionOccurredRef="myProcessor">
+        <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="5000"/>
+    </errorHandler>
+    ...
+</camelContext>
+----
+
+[[ExceptionClause-UsingFineGrainedRetryUsingretryWhilePredicate]]
+==== Using Fine Grained Retry Using `retryWhile` Predicate
+
+*Available as of Camel 2.0*
+
+===== RetryUntil
+
+In Camel 2.0 to 2.3 its called *`retryUntil`*. From *Camel 2.4*: its
+named *`retryWhile`* because Camel will continue doing retries _while_
+the predicate returns true.
+
+When you need fine grained control for determining if an exchange should
+be retried or not you can use the *`retryWhile`* predicate. Camel will
+redeliver until the predicate returns false.
+
+Example:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRetryUntilTest.java
+
+Where the bean *`myRetryHandler`* is computing if we should retry or not:
+
+/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRetryUntilTest.java
+
+[[ExceptionClause-UsingCustomExceptionPolicyStrategy]]
+==== Using Custom `ExceptionPolicyStrategy`
+
+*Available in Camel 1.4*
+
+The default
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.html[ExceptionPolicyStrategy]
+in Camel should be sufficient in nearly all use-cases (see section
+<<ExceptionClause-HowDoesCamelSelectWhichClauseShouldHandleaGivenThrownException,How does Camel select which clause should handle a given thrown Exception>>).
+However, if you need to use your own this can be configured as the
+sample below illustrates:
+
+/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
+
+Using our own strategy *`MyPolicy`* we can change the default behavior of
+Camel with our own code to resolve which
+http://camel.apache.org/maven/camel-core/apidocs/org/apache/camel/model/ExceptionType.html[ExceptionType]
+from above should be handling the given thrown exception.
+
+/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
+
+[[ExceptionClause-UsingtheExceptionClauseinSpringDSL]]
+==== Using the Exception Clause in Spring DSL
+
+You can use all of the above mentioned exception clause features in the
+Spring DSL as well. Here are a few examples:
+
+* Global scoped - *Available in Camel 2.0*
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/deadLetterChannelHandledExampleTest.xml
+
+* Route specific scoped
+/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/onExceptionSubRouteTest.xml
+
+[[ExceptionClause-Seealso]]
+==== See also
+
+* The link:error-handler.adoc[Error Handler] for the general error handling documentation
+* The <<DeadLetterChannel-DeadLetterChannel,Dead Letter Channel>> for further details
+* The <<TransactionalClient-TransactionalClient,Transactional Client>> for transactional behavior
diff --git a/docs/user-manual/en/predicate.adoc b/docs/user-manual/en/predicate.adoc
new file mode 100644
index 0000000..cdc2be0
--- /dev/null
+++ b/docs/user-manual/en/predicate.adoc
@@ -0,0 +1,222 @@
+[[Predicate-Predicates]]
+=== Predicates
+
+Camel supports a pluggable interface called
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/Predicate.html[Predicate]
+which can be used to integrate a dynamic predicate into
+link:enterprise-integration-patterns.adoc[Enterprise Integration
+Patterns] such as when using the <<filter-eip,Message Filter>>
+or <<contentBasedRouter-eip,Content Based Router>>.
+
+A Predicate is being evaluated to a boolean value so the result is
+either `true` or `false`. This makes link:predicate.adoc[Predicate] so
+powerful as it is often used to control the routing of message in which
+path they should be routed.
+
+A simple example is to route an link:exchange.adoc[Exchange] based on a
+header value:
+
+[source,java]
+----
+from("jms:queue:order")
+   .choice()
+      .when(header("type").isEqualTo("widget")).to("bean:widgetOrder")
+      .when(header("type").isEqualTo("wombat")).to("bean:wombatOrder")
+   .otherwise()
+      .to("bean:miscOrder")
+   .end();
+----
+
+In the route above the link:predicate.adoc[Predicate] is the
+`header("type").isEqualTo("widget")` as its constructed as an
+link:expression.adoc[Expression] that is evaluated as a
+link:predicate.adoc[Predicate]. To do this the various Builder classes
+helps us here to create a nice and fluent syntax. `isEqualTo` is a
+builder method that returns a link:predicate.adoc[Predicate] based on
+the input.
+
+Sometimes the fluent builders can get long and a bit complex to read,
+then you can just define your predicate outside the route and then just
+refer to the predicate in the route:
+
+[source,java]
+----
+Predicate isWidget = header("type").isEqualTo("widget");
+----
+
+And then you can refer to it in the route as:
+
+[source,java]
+----
+from("jms:queue:order")
+   .choice()
+      .when(isWidget).to("bean:widgetOrder")
+      .when(isWombat).to("bean:wombatOrder")
+   .otherwise()
+      .to("bean:miscOrder")
+   .end();
+----
+
+[[Predicate-NegatingaPredicate]]
+==== Negating a Predicate
+
+You can use the *not* method on the `PredicateBuilder` to negate a
+predicate.
+
+First we import the not static, so it makes our route nice and easy to
+read:
+
+[source,java]
+----
+import static org.apache.camel.builder.PredicateBuilder.not
+----
+
+And then we can use it to enclose an existing predicate and negate it as
+the example shows:
+
+[source,java]
+----
+from("direct:start")
+    .choice()
+        .when(not(header("username").regex("goofy|pluto"))).to("mock:people")
+        .otherwise().to("mock:animals")
+    .end();
+----
+
+[[Predicate-CompoundPredicates]]
+==== Compound Predicates
+
+You can also create compound predicates using boolean operators such as
+`and, or, not` and many others.
+
+Currently this feature is only available in the Java-based DSLs, but not
+in the Spring nor Blueprint DSLs.
+
+Using the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/builder/PredicateBuilder.html[`PredicateBuilder`]
+class, you can combine predicates *from different Expression Languages*
+based on logical operators and comparison operators:
+
+* `not`, `and`, `or`
+* `isNull`, `isNotNull`
+* `isEqualTo`, `isGreaterThan`, `isLessThan`
+* `startsWith`, `endsWith`
+* `in` ("any of X predicates stands true")
+
+Additionally, with `PredicateBuilder` you can create Regular Expressions
+and use them as predicates, applying them to the result of an
+expression, e.g. `PredicateBuilder.regex(header("foo"), "\d{4}")`
+applies the regular expression to the header = foo.
+
+Combining different Expression Languages is also possible, e.g.:
+
+[source,java]
+----
+PredicateBuilder.and(XPathBuilder.xpath("/bookings/flights"), simple("${property.country = 'Spain'}"))
+----
+
+The sample below demonstrates further use cases:
+
+[source,java]
+----
+// We define 3 predicates based on some user roles
+// we have static imported and/or from org.apache.camel.builder.PredicateBuilder
+
+// First we have a regular user that is just identified having a username header
+Predicate user = header("username").isNotNull();
+
+// The admin user must be a user AND have a admin header as true
+Predicate admin = and(user, header("admin").isEqualTo("true"));
+
+// And God must be an admin and (either have type god or a special message containing Camel Rider)
+Predicate god = and(admin, or(body().contains("Camel Rider"), header("type").isEqualTo("god")));
+
+// As you can see with the predicates above we can stack them to build compound predicates
+
+// In our route below we can create a nice content based router based on the predicates we
+// have defined. Then the route is easy to read and understand.
+// We encourage you to define complex predicates outside the fluent router builder as
+// it will just get a bit complex for humans to read
+from("direct:start").choice()
+    .when(god).to("mock:god")
+    .when(admin).to("mock:admin")
+    .when(user).to("mock:user")
+    .otherwise().to("mock:guest")
+.end();
+----
+
+[[Predicate-ExtensiblePredicates]]
+==== Extensible Predicates
+
+Camel supports extensible Predicates using multiple
+link:languages.adoc[Languages]; the following languages are supported
+out of the box
+
+* link:bean-language.adoc[Bean Language] for using Java for expressions
+* link:constant.adoc[Constant]
+* the unified link:el.adoc[EL] from JSP and JSF
+* link:header.adoc[Header]
+* link:jsonpath.adoc[JSonPath]
+* link:jxpath.adoc[JXPath]
+* link:mvel.adoc[Mvel]
+* link:ognl.adoc[OGNL]
+* link:ref-language.adoc[Ref Language]
+* link:exchangeproperty.adoc[ExchangeProperty] / link:property.adoc[Property]
+* link:scripting-languages.adoc[Scripting Languages] such as
+** link:beanshell.adoc[BeanShell]
+** link:javascript.adoc[JavaScript]
+** link:groovy.adoc[Groovy]
+** link:python.adoc[Python]
+** link:php.adoc[PHP]
+** link:ruby.adoc[Ruby]
+* link:simple.adoc[Simple]
+** link:file-language.adoc[File Language]
+* link:spel.adoc[Spring Expression Language]
+* link:sql.adoc[SQL]
+* link:tokenizer.adoc[Tokenizer]
+* link:xpath.adoc[XPath]
+* link:xquery.adoc[XQuery]
+* link:vtd-xml.adoc[VTD-XML]
+
+Most of these languages is also supported used as
+link:annotation-based-expression-language.adoc[Annotation Based
+Expression Language].
+
+You can easily write your own plugin predicate by implementing the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/Predicate.html[Predicate
+interface].
+
+There are also a number of helper builders available such as the
+http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/builder/PredicateBuilder.html[PredicateBuilder
+class]
+
+[[Predicate-UsingPredicatesinyourIDE]]
+==== Using Predicates in your IDE
+
+To use different expression and predicates in your IDE you need to
+perform a static import of the builder class for the language(s) you
+wish to use.
+
+[width="100%",cols="50%,50%",options="header",]
+|=======================================================================
+|Language(s) |Builder class to import
+|link:scripting-languages.adoc[Scripting Languages] such as
+link:beanshell.adoc[BeanShell], link:javascript.adoc[JavaScript],
+link:groovy.adoc[Groovy], link:php.adoc[PHP], link:python.adoc[Python]
+and link:ruby.adoc[Ruby]
+|http://camel.apache.org/maven/current/camel-script/apidocs/org/apache/camel/builder/script/ScriptBuilder.html[org.apache.camel.builder.script.ScriptBuilder]
+
+|link:sql.adoc[SQL]
+|http://camel.apache.org/maven/current/camel-josql/apidocs/org/apache/camel/builder/sql/SqlBuilder.html[org.apache.camel.builder.josql.SqlBuilder]
+
+|link:xpath.adoc[XPath]
+|http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/builder/xml/XPathBuilder.html[org.apache.camel.builder.xml.XPathBuilder]
+
+|link:xquery.adoc[XQuery]
+|http://camel.apache.org/maven/current/camel-saxon/apidocs/org/apache/camel/builder/saxon/XQueryBuilder.html[org.apache.camel.builder.saxon.XQueryBuilder]
+|=======================================================================
+
+[[Predicate-SeeAlso]]
+==== See Also
+
+* link:expression.adoc[Expression]
diff --git a/docs/user-manual/en/transactionerrorhandler.adoc b/docs/user-manual/en/transactionerrorhandler.adoc
new file mode 100644
index 0000000..8288511
--- /dev/null
+++ b/docs/user-manual/en/transactionerrorhandler.adoc
@@ -0,0 +1,178 @@
+[[TransactionErrorHandler-TransactionErrorHandler]]
+=== TransactionErrorHandler
+
+*Available as of Camel 2.0*
+
+This is the new default transaction error handler in Camel 2.0 onwards,
+used for transacted routes.
+
+It uses the same base as the
+link:defaulterrorhandler.adoc[DefaultErrorHandler] so it has the same
+feature set as this error handler.
+
+By default any exception thrown during routing will be propagated back
+to the caller and the link:exchange.adoc[Exchange] ends immediately.
+However you can use the link:exception-clause.adoc[Exception Clause] to
+catch a given exception and lower the exception by marking it as
+handled. If so the exception will *not* be sent back to the caller and
+the link:exchange.adoc[Exchange] continues to be routed.
+
+[[TransactionErrorHandler-Example]]
+==== Example
+
+In this route below, any exception thrown in eg the `validateOrder` bean
+will be propagated back to the caller, and its the jetty endpoint. It
+will return a HTTP error message back to the client.
+
+[source,java]
+----
+from("jetty:http://localhost/myservice/order").transacted().to("bean:validateOrder").to("jms:queue:order");
+----
+
+We can add a *onException* in case we want to catch certain exceptions
+and route them differently, for instance to catch a
+*ValidationException* and return a fixed response to the caller.
+
+[source,java]
+----
+onException(ValidationException.class).handled(true).transform(body(constant("INVALID ORDER")));
+
+from("jetty:http://localhost/myservice/order").transacted().to("bean:validateOrder").to("jms:queue:order");
+----
+
+When the *ValidationException* is thrown from the validate order bean it
+is intercepted by the
+link:transactionerrorhandler.adoc[TransactionErrorHandler] and it let
+the `onException(ValidationException.class` handle it so the
+link:exchange.adoc[Exchange] is routed to this route and since we use
+*handled(true)* then the original exception is lowered (= cleared) and
+we transform the message into a fixed response that are returned to
+jetty endpoint that returns it to the original caller.
+
+[[TransactionErrorHandler-Conventionoverconfiguration]]
+==== Convention over configuration
+
+When you configure a route to be transacted you just mark it as
+transacted as follows:
+
+[source,java]
+----
+from("jms:queue:foo").transacted().to("bean:handleFoo");
+----
+
+And in Spring DSL:
+
+[source,xml]
+----
+<route>
+   <from uri="jms:queue:foo"/>
+   <transacted/>
+   <to uri="bean:handleFoo"/>
+</route>
+----
+
+What happens is that Camel will automatic lookup the right Spring
+transaction manager. It does using the following rules, in order: +
+1. If there is only 1 bean with the type
+`org.apache.camel.spi.TransactedPolicy` then its used. +
+2. If there is a bean with id `PROPAGATION_REQUIRED` and of type
+`org.apache.camel.spi.TransactedPolicy` then its used. +
+3. If there is only 1 bean with the type
+`org.springframework.transaction.PlatformTransactionManager` then its
+used.
+
+However you can explicit configure what you want to use. For instance
+the *transacted* DSL accepts a String reference parameter to indicate
+the bean id of the `org.apache.camel.spi.TransactedPolicy` bean to use
+in case you have multiple beans. For instance a PROPAGATION_REQUIRES_NEW
+bean.
+
+The *transactionErrorHandler* like the *transacted* also supprts
+convention over configuration and it will also automatic lookup the
+right Spring transaction manager. It does using the following rules, in
+order: +
+1. If there is only 1 bean with the type
+`org.apache.camel.spi.TransactedPolicy` then its used. +
+2. If there is a bean with id `PROPAGATION_REQUIRED` and of type
+`org.apache.camel.spi.TransactedPolicy` then its used. +
+3. If there is only 1 bean with the type
+`org.springframework.transaction.support.TransactionTemplate` then its
+used. +
+4. If there is only 1 bean with the type
+`org.springframework.transaction.PlatformTransactionManager` then its
+used.
+
+However you can explicit configure what you want to use. For instance
+the *transactionErrorHandler* DSL accepts either a TransactedPolicy, a
+TransactionTemplate or a PlatformTransactionManager.
+
+[[TransactionErrorHandler-UsingCameltodoredeliveries]]
+==== Using Camel to do redeliveries
+
+As the link:transactionerrorhandler.adoc[TransactionErrorHandler] also
+supports to let Camel do redeliveries you can use both worlds. Letting
+Camel do some redeliveries and at the end the backing transaction
+manager doing other redeliveries. In fact in the end the transaction
+manager have the final word. That means if Camel cannot process the
+exchange then its thrown back to the transaction manager that will
+perform the rollback, and redelivery.
+
+[[TransactionErrorHandler-ExamplewithusingCameltodoredeliveries]]
+===== Example with using Camel to do redeliveries
+
+In the route below we have configured a transaction error handler. It
+will by default do local redeliveries up till 6 times. In Case Camel
+could not redeliver the message it will be thrown back to the
+transaction manager that will do a rollback, and a redelivery if it was
+configured to do so.
+
+Notice that as we have all the powers from
+link:defaulterrorhandler.adoc[DefaultErrorHandler] we can configure an
+*onException* where we state that in case of this particular exception,
+an IllegalArgumentException we will only do redeliveries up till 4
+times. (Yes the code is based on an unit test).
+
+And also notice that we mark the routes as transacted using
+*transacted*. This is always needed to instruct Camel that these routes
+are transacted.
+
+If you do not provide any Spring TransactionTemplate to either the
+*transactionErrorHandler*, then Camel will automatic lookup in the
+Spring application context for a transaction manager to use. See more in
+the Convention over configuration section on this page.
+
+And now the route:
+
+[source,java]
+----
+// configure transacted error handler to use up till 4 redeliveries
+// we have not passed in any spring TX manager. Camel will automatic
+// find it in the spring application context. You only need to help
+// Camel in case you have multiple TX managers
+errorHandler(transactionErrorHandler().maximumRedeliveries(6));
+
+// speical for this exception we only want to do it at most 4 times
+onException(IllegalArgumentException.class).maximumRedeliveries(4);
+
+from("direct:okay")
+    // marks this route as transacted, and we dont pass in any parameters so we
+    // will auto lookup and use the Policy defined in the spring XML file
+    .transacted()
+    .setBody(constant("Tiger in Action")).bean("bookService")
+    .setBody(constant("Elephant in Action")).bean("bookService");
+
+// marks this route as transacted that will use the single policy defined in the registry
+from("direct:fail")
+    // marks this route as transacted, and we dont pass in any parameters so we
+    // will auto lookup and use the Policy defined in the spring XML file
+    .transacted()
+    .setBody(constant("Tiger in Action")).bean("bookService")
+    .setBody(constant("Donkey in Action")).bean("bookService");
+----
+
+[[TransactionErrorHandler-SeeAlso]]
+==== See Also
+
+* link:error-handler.adoc[Error Handler]
+* link:error-handling-in-camel.adoc[Error handling in Camel]
+* <<TransactionalClient-TransactionalClient,Transactional Client>>
diff --git a/docs/user-manual/en/try-catch-finally.adoc b/docs/user-manual/en/try-catch-finally.adoc
new file mode 100644
index 0000000..2dc011d
--- /dev/null
+++ b/docs/user-manual/en/try-catch-finally.adoc
@@ -0,0 +1,132 @@
+[[TryCatchFinally-TryCatchFinally]]
+=== Try ... Catch ... Finally
+
+Camel supports the Java equivalent of try .. catch and finally directly
+in the DSL.
+It aims to work like its Java sisters but with more power. Especially in
+Camel 2.0 where we gave this feature an overhaul.
+
+In Camel we prefix the keywords with `do` to avoid having same keyword
+as Java. So we have:
+
+* `doTry`
+* `doCatch`
+* `doFinally`
+* `end` to end the block in Java DSL
+
+Notice this document is based on how it works in Camel 2.0. In Camel 1.x
+this feature isn't as powerful and it uses a slight different keyword
+names.
+
+===== Camel error handling is disabled
+
+When using `doTry .. doCatch .. doFinally` then the regular Camel
+link:error-handler.adoc[Error Handler] does not apply. That means any
+`onException` or the likes does not trigger. The reason is that
+`doTry .. doCatch .. doFinally` is in fact its own error handler and
+that it aims to mimic and work like how try/catch/finally works in Java.
+
+[[TryCatchFinally-AboutdoCatchanditspoweroverJava]]
+==== About `doCatch` and its power over Java
+
+The `doCatch` in Camel is empowered over its Java sister.
+
+First of all you can define multiple exceptions to catch in a single
+block.
+
+And second of all an important aspect over the regular Java counter
+parts is that Camel will check in the exception hierarchy when it
+matches a thrown exception against the `doCatch` blocks. The reasons is
+that many times the original caused exceptions is wrapped by other
+wrapper exceptions, typically transposing the exception from a checked
+to a runtime exception.
+Camel for instance does this by wrapped it in a `CamelRuntimeException`.
+So if the original caused exception is an `java.io.IOException` then
+Camel will still match a `doCatch` block defined with an
+`java.io.IOException`. And just like Java the order in which you have
+multiple `doCatch` blocks matter. Camel will iterate from the top going
+down and use the first `doCatch` that matches the exception. The reason
+is to keep it similar to the regular java and how it selects a catch
+block. This differers from the link:exception-clause.adoc[Exception
+Clause] that has a more intelligent exception selection strategy among
+multiple `onException` definitions, where it also consider the delta in
+the exception hierarchy to select the best definition.
+
+A third feature is that you can attach a `onWhen` predicate to signal if
+the catch should trigger or not at runtime.
+
+And to simulate _rethrowing_ an exception from a `doCatch` you should
+use the `handled` predicate. If its evaluated to `false` Camel will
+reattach the exception on the link:exchange.adoc[Exchange].
+
+[[TryCatchFinally-UsingtrycatchfinallyinJavaDSL]]
+==== Using try .. catch .. finally in Java DSL
+
+In the route below we have all keywords in action. As the code is based
+on a unit test we route using <<mock-component,Mock>>.
+
+https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorMultipleExceptionTest.java[TryProcessorMultipleExceptionTest.java]
+
+And in the route below we want to indicate if an IOException occured we
+want to route it elsewhere and at the same time keep the exception so
+the original caller is notified about this exception. To do this we need
+to not _rethrow_ the exception and this is why we use *handled* and set
+it to false to indicate, no we did not handle it so please keep the
+exception.
+The 2nd exception block can be omitted but as the code is based on an
+unit test we want to test the behavior non `IOException` as well.
+
+https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorHandledTest.java[TryProcessorHandledTest.java]
+
+And finally we have an example of the `onWhen` predicate in action. We
+can attach it to a `doCatch` block and at runtime determine if the block
+should be triggered or not.
+In our case we only want to trigger if the caused exception message
+contains the *damn* word.
+
+https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorOnWhenTest.java[TryProcessorOnWhenTest.java]
+
+===== Use end() to end the block
+
+Notice when using Java DSL we must use `end()` to indicate where the try
+.. catch .. finally block ends. As the example above has a finally, then
+the `end()` should be at the end of the finally block. If we are not
+using a finally, then the `end()` should be at the end of the `doCatch`
+to indicate the end there.
+
+[[TryCatchFinally-Usingtry..catch..finallyinSpringDSL]]
+Using try .. catch .. finally in Spring DSL
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We show the three sample samples using Spring DSL instead.
+
+In the route below we have all keywords in action. As the code is based
+on a unit test we route using <<mock-component,Mock>>.
+
+https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorMultipleExceptionTest.xml[SpringTryProcessorMultipleExceptionTest.xml]
+
+And in the route below we want to indicate if an IOException occured we
+want to route it elsewhere and at the same time keep the exception so
+the original caller is notified about this exception. To do this we need
+to not _rethrow_ the exception and this is why we use *handled* and set
+it to false to indicate, no we did not handle it so please keep the
+exception.
+The 2nd exception block can be omitted but as the code is based on an
+unit test we want to test the behavior non `IOException` as well.
+
+https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorHandledTest.xml[SpringTryProcessorHandledTest.xml]
+
+And finally we have an example of the `onWhen` predicate in action. We
+can attach it to a `doCatch` block and at runtime determine if the block
+should be triggered or not.
+In our case we only want to trigger if the caused exception message
+contains the *damn* word.
+
+https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorOnWhenTest.xml[SpringTryProcessorOnWhenTest.xml]
+
+[[TryCatchFinally-SeeAlso]]
+==== See Also
+
+* link:error-handling-in-camel.adoc[Error handling in Camel]
+* link:error-handler.adoc[Error Handler]
+* link:exception-clause.adoc[Exception Clause]