You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/02/19 18:52:09 UTC

[3/5] camel git commit: CAMEL-10837: Migrate EIP patterns to adoc (squashed)

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/dead-letter-channel.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/dead-letter-channel.adoc b/camel-core/src/main/docs/eips/dead-letter-channel.adoc
new file mode 100644
index 0000000..dc11f9c
--- /dev/null
+++ b/camel-core/src/main/docs/eips/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-Controlifredeliveryisallowedduringstoppingshutdown]]
+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/f0bae85e/camel-core/src/main/docs/eips/delay-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/delay-eip.adoc b/camel-core/src/main/docs/eips/delay-eip.adoc
new file mode 100644
index 0000000..602b3fc
--- /dev/null
+++ b/camel-core/src/main/docs/eips/delay-eip.adoc
@@ -0,0 +1,166 @@
+## Delay EIP
+The Delayer Pattern allows you to delay the delivery of messages to some destination.
+
+[NOTE]
+====
+The expression is a value in millis to wait from the current time, so the expression should just be 3000.
+
+However you can use a long value for a fixed value to indicate the delay in millis.
+
+See the Spring DSL samples for Delayer.
+====
+
+[WARNING]
+.Using Delayer in Java DSL
+====
+See this ticket: link:https://issues.apache.org/jira/browse/CAMEL-2654[https://issues.apache.org/jira/browse/CAMEL-2654]
+====
+
+## Options
+
+// eip options: START
+The Delay EIP supports 3 options which are listed below:
+
+{% raw %}
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Name | Java Type | Description
+| executorServiceRef | String | Refers to a custom Thread Pool if asyncDelay has been enabled.
+| asyncDelayed | Boolean | Enables asynchronous delay which means the thread will noy block while delaying.
+| callerRunsWhenRejected | Boolean | Whether or not the caller should run the task when it was rejected by the thread pool. Is by default true
+|=======================================================================
+{% endraw %}
+// eip options: END
+
+*Using the Fluent Builders*
+The example below will delay all messages received on *seda:b* 1 second before sending them to *mock:result*.
+
+[source,java]
+--------------------------------------------------------
+from("seda:b").delay(1000).to("mock:result");
+--------------------------------------------------------
+
+You can just delay things a fixed amount of time from the point at which the delayer receives the message. For example to delay things 2 seconds
+
+[source,java]
+--------------------------------------------------------
+delayer(2000)
+--------------------------------------------------------
+
+The above assume that the delivery order is maintained and that the messages are delivered in delay order. If you want to reorder the messages based on delivery time, you can use the Resequencer with this pattern. For example
+
+[source,java]
+--------------------------------------------------------
+from("activemq:someQueue").resequencer(header("MyDeliveryTime")).delay("MyRedeliveryTime").to("activemq:aDelayedQueue");
+--------------------------------------------------------
+
+You can of course use many different Expression languages such as XPath, XQuery, SQL or various Scripting Languages. For example to delay the message for the time period specified in the header, use the following syntax:
+
+[source,java]
+--------------------------------------------------------
+from("activemq:someQueue").delay(header("delayValue")).to("activemq:aDelayedQueue");
+--------------------------------------------------------
+
+And to delay processing using the Simple language you can use the following DSL:
+
+[source,java]
+--------------------------------------------------------
+from("activemq:someQueue").delay(simple("${body.delayProperty}")).to("activemq:aDelayedQueue");
+--------------------------------------------------------
+
+## Spring DSL
+The sample below demonstrates the delay in Spring DSL:
+
+[source,xml]
+--------------------------------------------------------
+<bean id="myDelayBean" class="org.apache.camel.processor.MyDelayCalcBean"/>
+<bean id="exchangeAwareBean" class="org.apache.camel.processor.ExchangeAwareDelayCalcBean"/>
+
+<camelContext xmlns="http://camel.apache.org/schema/spring">
+    <route>
+        <from uri="seda:a"/>
+        <delay>
+            <header>MyDelay</header>
+        </delay>
+        <to uri="mock:result"/>
+    </route>
+    <route>
+        <from uri="seda:b"/>
+        <delay>
+            <constant>1000</constant>
+        </delay>
+        <to uri="mock:result"/>
+    </route>
+    <route>
+        <from uri="seda:c"/>
+        <delay>
+            <method ref="myDelayBean" method="delayMe"/>
+        </delay>
+        <to uri="mock:result"/>
+    </route>
+    <route>
+        <from uri="seda:d"/>
+        <delay>
+            <method ref="exchangeAwareBean" method="delayMe"/>
+        </delay>
+        <to uri="mock:result"/>
+    </route>
+</camelContext>
+--------------------------------------------------------
+
+For further examples of this pattern in use you could look at the link:http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DelayerTest.java?view=markup[junit test case].
+
+## Asynchronous delaying
+*Available as of Camel 2.4*
+You can let the Delayer use non blocking asynchronous delaying, which means Camel will use a scheduler to schedule a task to be executed in the future. The task will then continue routing. This allows the caller thread to not block and be able to service other messages etc.
+
+### From Java DSL
+You use the `asyncDelayed()` to enable the async behavior.
+
+[source,java]
+--------------------------------------------------------
+from("activemq:queue:foo").delay(1000).asyncDelayed().to("activemq:aDelayedQueue");
+--------------------------------------------------------
+
+### From Spring XML
+You use the `asyncDelayed="true"` attribute to enable the async behavior.
+
+[source,xml]
+--------------------------------------------------------
+<route>
+   <from uri="activemq:queue:foo"/>
+   <delay asyncDelayed="true">
+       <constant>1000</constant>
+   </delay>
+   <to uri="activemq:aDealyedQueue"/>
+</route>
+--------------------------------------------------------
+
+### Creating a custom delay
+You can use an expression to determine when to send a message using something like this
+
+[source,java]
+--------------------------------------------------------
+from("activemq:foo").
+  delay().method("someBean", "computeDelay").
+  to("activemq:bar");
+--------------------------------------------------------
+
+then the bean would look like this...
+
+[source,java]
+--------------------------------------------------------
+public class SomeBean {
+  public long computeDelay() {
+     long delay = 0;
+     // use java code to compute a delay value in millis
+     return delay;
+ }
+}
+--------------------------------------------------------
+
+## Using This Pattern
+If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.
+
+## See Also
+Delay Interceptor

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/dynamicRouter-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/dynamicRouter-eip.adoc b/camel-core/src/main/docs/eips/dynamicRouter-eip.adoc
new file mode 100644
index 0000000..e72e913
--- /dev/null
+++ b/camel-core/src/main/docs/eips/dynamicRouter-eip.adoc
@@ -0,0 +1,185 @@
+## Dynamic Router EIP
+The link:http://www.enterpriseintegrationpatterns.com/DynamicRouter.html[Dynamic Router] from the link:../../../../readme-eip.adoc[EIP patterns] allows you to route messages while avoiding the dependency of the router on all possible destinations while maintaining its efficiency.
+
+image:http://www.enterpriseintegrationpatterns.com/img/DynamicRouter.gif[image]
+
+In *Camel 2.5* we introduced a dynamicRouter in the DSL which is like a dynamic Routing Slip which evaluates the slip _on-the-fly_.
+
+[WARNING]
+.Beware
+====
+You must ensure the expression used for the `dynamicRouter` such as a bean, will return `null` to indicate the end. Otherwise the `dynamicRouter` will keep repeating endlessly.
+====
+
+## Options
+
+// eip options: START
+The Dynamic Router EIP supports 3 options which are listed below:
+
+{% raw %}
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Name | Java Type | Description
+| uriDelimiter | String | Sets the uri delimiter to use
+| ignoreInvalidEndpoints | Boolean | Ignore the invalidate endpoint exception when try to create a producer with that endpoint
+| cacheSize | Integer | Sets the maximum size used by the org.apache.camel.impl.ProducerCache which is used to cache and reuse producers when using this recipient list when uris are reused.
+|=======================================================================
+{% endraw %}
+// eip options: END
+
+## Dynamic Router in Camel 2.5 onwards
+From Camel 2.5 the Dynamic Router will set a property (Exchange.SLIP_ENDPOINT) on the Exchange which contains the current endpoint as it advanced though the slip. This allows you to know how far we have processed in the slip. (It's a slip because the Dynamic Router implementation is based on top of Routing Slip).
+
+### Java DSL
+In Java DSL you can use the `dynamicRouter` as shown below:
+
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+    // use a bean as the dynamic router
+    .dynamicRouter(method(DynamicRouterTest.class, "slip"));
+--------------------------------------------------------
+
+Which will leverage a Bean to compute the slip _on-the-fly_, which could be implemented as follows:
+
+[source,java]
+--------------------------------------------------------
+/**
+ * Use this method to compute dynamic where we should route next.
+ *
+ * @param body the message body
+ * @return endpoints to go, or <tt>null</tt> to indicate the end
+ */
+public String slip(String body) {
+    bodies.add(body);
+    invoked++;
+
+    if (invoked == 1) {
+        return "mock:a";
+    } else if (invoked == 2) {
+        return "mock:b,mock:c";
+    } else if (invoked == 3) {
+        return "direct:foo";
+    } else if (invoked == 4) {
+        return "mock:result";
+    }
+
+    // no more so return null
+    return null;
+}
+--------------------------------------------------------
+
+Mind that this example is only for show and tell. The current implementation is not thread safe. You would have to store the state on the Exchange, to ensure thread safety, as shown below:
+
+[source,java]
+--------------------------------------------------------
+/**
+ * Use this method to compute dynamic where we should route next.
+ *
+ * @param body the message body
+ * @param properties the exchange properties where we can store state between invocations
+ * @return endpoints to go, or <tt>null</tt> to indicate the end
+ */
+public String slip(String body, @Properties Map<String, Object> properties) {
+    bodies.add(body);
+
+    // get the state from the exchange properties and keep track how many times
+    // we have been invoked
+    int invoked = 0;
+    Object current = properties.get("invoked");
+    if (current != null) {
+        invoked = Integer.valueOf(current.toString());
+    }
+    invoked++;
+    // and store the state back on the properties
+    properties.put("invoked", invoked);
+
+    if (invoked == 1) {
+        return "mock:a";
+    } else if (invoked == 2) {
+        return "mock:b,mock:c";
+    } else if (invoked == 3) {
+        return "direct:foo";
+    } else if (invoked == 4) {
+        return "mock:result";
+    }
+
+    // no more so return null
+    return null;
+}
+--------------------------------------------------------
+
+You could also store state as message headers, but they are not guaranteed to be preserved during routing, where as properties on the Exchange are. Although there was a bug in the method call expression, see the warning below.
+
+[WARNING]
+.Using beans to store state
+====
+Mind that in Camel 2.9.2 or older, when using a Bean the state is not propagated, so you will have to use a Processor instead. This is fixed in Camel 2.9.3 onwards.
+====
+
+### Spring XML
+The same example in Spring XML would be:
+
+[source,xml]
+--------------------------------------------------------
+<bean id="mySlip" class="org.apache.camel.processor.DynamicRouterTest"/>
+
+<camelContext xmlns="http://camel.apache.org/schema/spring">
+    <route>
+        <from uri="direct:start"/>
+        <dynamicRouter>
+            <!-- use a method call on a bean as dynamic router -->
+            <method ref="mySlip" method="slip"/>
+        </dynamicRouter>
+    </route>
+
+    <route>
+        <from uri="direct:foo"/>
+        <transform><constant>Bye World</constant></transform>
+    </route>
+
+</camelContext>
+--------------------------------------------------------
+
+### @DynamicRouter annotation
+You can also use the `@DynamicRouter` annotation, for example the Camel 2.4 example below could be written as follows. The `route` method would then be invoked repeatedly as the message is processed dynamically.
+The idea is to return the next endpoint uri where to go. Return `null` to indicate the end. You can return multiple endpoints if you like, just as the Routing Slip, where each endpoint is separated by a delimiter.
+
+[source,java]
+--------------------------------------------------------
+public class MyDynamicRouter {
+
+    @Consume(uri = "activemq:foo")
+    @DynamicRouter
+    public String route(@XPath("/customer/id") String customerId, @Header("Location") String location, Document body) {
+        // query a database to find the best match of the endpoint based on the input parameteres
+        // return the next endpoint uri, where to go. Return null to indicate the end.
+    }
+}
+--------------------------------------------------------
+
+## Dynamic Router in Camel 2.4 or older
+The simplest way to implement this is to use the RecipientList Annotation on a Bean method to determine where to route the message.
+
+[source,java]
+--------------------------------------------------------
+public class MyDynamicRouter {
+
+    @Consume(uri = "activemq:foo")
+    @RecipientList
+    public List<String> route(@XPath("/customer/id") String customerId, @Header("Location") String location, Document body) {
+        // query a database to find the best match of the endpoint based on the input parameteres
+        ...
+    }
+}
+--------------------------------------------------------
+
+In the above we can use the Parameter Binding Annotations to bind different parts of the Message to method parameters or use an Expression such as using XPath or XQuery.
+The method can be invoked in a number of ways as described in the Bean Integration such as
+
+* POJO Producing
+* Spring Remoting
+* Bean component
+
+## Using This Pattern
+If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/enrich-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/enrich-eip.adoc b/camel-core/src/main/docs/eips/enrich-eip.adoc
new file mode 100644
index 0000000..8dfe4ba
--- /dev/null
+++ b/camel-core/src/main/docs/eips/enrich-eip.adoc
@@ -0,0 +1,370 @@
+## Enrich EIP
+Camel supports the Content Enricher from the EIP patterns using a Message Translator, an arbitrary Processor in the routing logic, or using the enrich DSL element to enrich the message.
+
+image:http://www.enterpriseintegrationpatterns.com/img/DataEnricher.gif[image]
+
+### Content enrichment using a Message Translator or a Processor
+
+*Using the Fluent Builders*
+You can use Templating to consume a message from one destination, transform it with something like Velocity or XQuery, and then send it on to another destination. For example using InOnly (one way messaging)
+
+[source,java]
+--------------------------------------------------------
+from("activemq:My.Queue").
+  to("velocity:com/acme/MyResponse.vm").
+  to("activemq:Another.Queue");
+--------------------------------------------------------
+
+If you want to use InOut (request-reply) semantics to process requests on the *My.Queue* queue on ActiveMQ with a template generated response, then sending responses back to the JMSReplyTo Destination you could use this:
+
+[source,java]
+--------------------------------------------------------
+from("activemq:My.Queue").
+  to("velocity:com/acme/MyResponse.vm");
+--------------------------------------------------------
+
+Here is a simple example using the DSL directly to transform the message body
+
+[source,java]
+--------------------------------------------------------
+from("direct:start").setBody(body().append(" World!")).to("mock:result");
+--------------------------------------------------------
+
+In this example we add our own Processor using explicit Java code
+
+[source,java]
+--------------------------------------------------------
+from("direct:start").process(new Processor() {
+    public void process(Exchange exchange) {
+        Message in = exchange.getIn();
+        in.setBody(in.getBody(String.class) + " World!");
+    }
+}).to("mock:result");
+--------------------------------------------------------
+
+Finally we can use Bean Integration to use any Java method on any bean to act as the transformer
+
+[source,java]
+--------------------------------------------------------
+from("activemq:My.Queue").
+  beanRef("myBeanName", "myMethodName").
+  to("activemq:Another.Queue");
+--------------------------------------------------------
+
+For further examples of this pattern in use you could look at one of the JUnit tests
+
+* TransformTest
+* TransformViaDSLTest
+
+*Using Spring XML*
+
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="activemq:Input"/>
+  <bean ref="myBeanName" method="doTransform"/>
+  <to uri="activemq:Output"/>
+</route>
+--------------------------------------------------------
+
+### Content enrichment using the `enrich` DSL element
+
+Camel comes with two flavors of content enricher in the DSL
+
+* `enrich`
+* `pollEnrich`
+
+`enrich` uses a Producer to obtain the additional data. It is usually used for Request Reply messaging, for instance to invoke an external web service.
+
+`pollEnrich` on the other hand uses a Polling Consumer to obtain the additional data. It is usually used for Event Message messaging, for instance to read a file or download a FTP file.
+
+[WARNING]
+.Camel 2.15 or older - Data from current Exchange not used
+====
+`pollEnrich` or `enrich` does *not* access any data from the current Exchange which means when polling it cannot use any of the existing headers you may have set on the Exchange. For example you cannot set a filename in the `Exchange.FILE_NAME` header and use `pollEnrich` to consume only that file. For that you *must* set the filename in the endpoint URI.
+
+Instead of using enrich you can use Recipient List and have dynamic endpoints and define an `AggregationStrategy` on the Recipient List which then would work as a enrich would do.
+
+`pollEnrich` only accept one message as response. That means that if you target to enrich your original message with the enricher collecting messages from a seda, ... components using an aggregation strategy. Only one response message will be aggregated with the original message.
+
+From *Camel 2.16* onwards both `enrich` and `pollEnrich` supports dynamic endpoints that uses an Expression to compute the uri, which allows to use data from the current Exchange. In other words all what is told above no longer apply and it just works.
+====
+
+### Enrich Options
+[width="100%",cols="3,2,6",options="header"]
+|=======================================================================
+| Option | Default Value | Description
+| `uri` |  | The endpoint uri for the external service to enrich from. You must use either uri or ref. *Important:* From Camel 2.16 onwards, this option is removed, and you use an Expression to configure the uri, such as Simple or Constant or any other dynamic language that can compute the uri dynamically using values from the current Exchange.
+| `ref` |  | Refers to the endpoint for the external service to enrich from. You must use either `uri` or `ref`.  *Important:* From *Camel 2.16* onwards, this option is removed, and you use an Expression to configure the uri, such as Simple or Constant or any other dynamic language that can compute the uri dynamically using values from the current  Exchange.
+| `expression` |  | *Camel 2.16*: Mandatory. The Expression to configure the uri, such as Simple or Constant or any other dynamic language that can compute the uri dynamically using values from the current  Exchange.
+| `strategyRef` |  | Refers to an `AggregationStrategy` to be used to merge the reply from the external service, into a single outgoing message. By default Camel will use the reply from the external service as outgoing message. From *Camel 2.12* onwards you can also use a POJO as the AggregationStrategy, see the Aggregate page for more details.
+| `strategyMethodName` |  | *Camel 2.12*: This option can be used to explicit declare the method name to use, when using POJOs as the `AggregationStrategy`. See the Aggregate page for more details.
+| `strategyMethodAllowNull` | `false` | *Camel 2.12*: If this option is `false` then the aggregate method is *not* used if there was no data to enrich. If this option is `true` then `null` values is used as the `oldExchange` (when no data to enrich), when using POJOs as the `AggregationStrategy`. See the Aggregate page for more details.
+| `aggregateOnException` | `false` | *Camel 2.14*: If this option is `false` then the aggregate method is *not* used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end users to control what to do if there was an exception in the aggregate method. For example to suppress the exception or set a custom message body etc.
+| `shareUnitOfWork` | `false` | *Camel 2.16*:  Shares the unit of work with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resource exchange has its own individual unit of work. See Splitter for more information and example.
+| `cacheSize` |  | *Camel 2.16*: Allows to configure the cache size for the ProducerCache which caches producers for reuse in the enrich. Will by default use the default cache size which is 1000. Setting the value to -1 allows to turn off the cache all together.
+| `ignoreInvalidEndpoint` | false | *Camel 2.16*: Whether to ignore an endpoint URI that could not be resolved. If disabled, Camel will throw an exception identifying the invalid endpoint URI.
+|=======================================================================
+
+*Using the Fluent Builders*
+
+[source,java]
+--------------------------------------------------------
+AggregationStrategy aggregationStrategy = ...
+
+from("direct:start")
+.enrich("direct:resource", aggregationStrategy)
+.to("direct:result");
+
+from("direct:resource")
+...
+--------------------------------------------------------
+
+The content enricher (`enrich`) retrieves additional data from a _resource endpoint_ in order to enrich an incoming message (contained in the _original exchange_).
+An aggregation strategy is used to combine the original exchange and the _resource exchange_. The first parameter of the `AggregationStrategy.aggregate(Exchange, Exchange)` method corresponds to the the original exchange, the second parameter the resource exchange.
+The results from the resource endpoint are stored in the resource exchange's out-message. Here's an example template for implementing an aggregation strategy:
+
+[source,java]
+--------------------------------------------------------
+public class ExampleAggregationStrategy implements AggregationStrategy {
+
+    public Exchange aggregate(Exchange original, Exchange resource) {
+        Object originalBody = original.getIn().getBody();
+        Object resourceResponse = resource.getIn().getBody();
+        Object mergeResult = ... // combine original body and resource response
+        if (original.getPattern().isOutCapable()) {
+            original.getOut().setBody(mergeResult);
+        } else {
+            original.getIn().setBody(mergeResult);
+        }
+        return original;
+    }
+
+}
+--------------------------------------------------------
+
+Using this template the original exchange can be of any pattern. The resource exchange created by the enricher is always an in-out exchange.
+
+*Using Spring XML*
+The same example in the Spring DSL (Camel 2.15 or older)
+[source,xml]
+--------------------------------------------------------
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="direct:start"/>
+    <enrich uri="direct:resource" strategyRef="aggregationStrategy"/>
+    <to uri="direct:result"/>
+  </route>
+  <route>
+    <from uri="direct:resource"/>
+    ...
+  </route>
+</camelContext>
+
+<bean id="aggregationStrategy" class="..." />
+--------------------------------------------------------
+
+The same example in the Spring DSL (Camel 2.16 or newer)
+[source,xml]
+--------------------------------------------------------
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="direct:start"/>
+    <enrich strategyRef="aggregationStrategy">
+      <constant>direct:resource</constant>
+    </enrich>
+    <to uri="direct:result"/>
+  </route>
+  <route>
+    <from uri="direct:resource"/>
+    ...
+  </route>
+</camelContext>
+
+<bean id="aggregationStrategy" class="..." />
+--------------------------------------------------------
+
+### Aggregation strategy is optional
+The aggregation strategy is optional. If you do not provide it Camel will by default just use the body obtained from the resource.
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+  .enrich("direct:resource")
+  .to("direct:result");
+--------------------------------------------------------
+
+In the route above the message sent to the direct:result endpoint will contain the output from the direct:resource as we do not use any custom aggregation.
+And for Spring DSL (Camel 2.15 or older) just omit the strategyRef attribute:
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <enrich uri="direct:resource"/>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+And for Spring DSL (Camel 2.16 or newer) just omit the strategyRef attribute:
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <enrich>
+    <constant>direct:resource</constant>
+  </enrich>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+### Using dynamic uris
+*Available as of Camel 2.16*
+From Camel 2.16 onwards `enrich` and `pollEnrich` supports using dynamic uris computed based on information from the current Exchange. For example to enrich from a HTTP endpoint where the header with key orderId is used as part of the content-path of the HTTP url:
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+  .enrich().simple("http:myserver/${header.orderId}/order")
+  .to("direct:result");
+--------------------------------------------------------
+
+And in XML DSL
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <enrich>
+    <simple>http:myserver/${header.orderId}/order</simple>
+  </enrich>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+### Content enrichment using `pollEnrich`
+The `pollEnrich` works just as the `enrich` however as it uses a Polling Consumer we have 3 methods when polling
+
+* `receive`
+* `receiveNoWait`
+* `receive(timeout)`
+
+### PollEnrich Options
+
+// eip options: START
+The Enrich EIP supports 7 options which are listed below:
+
+{% raw %}
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Name | Java Type | Description
+| strategyRef | String | Refers to an AggregationStrategy to be used to merge the reply from the external service into a single outgoing message. By default Camel will use the reply from the external service as outgoing message.
+| strategyMethodName | String | This option can be used to explicit declare the method name to use when using POJOs as the AggregationStrategy.
+| strategyMethodAllowNull | Boolean | If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich) when using POJOs as the AggregationStrategy.
+| aggregateOnException | Boolean | If this option is false then the aggregate method is not used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end users to control what to do if there was an exception in the aggregate method. For example to suppress the exception or set a custom message body etc.
+| shareUnitOfWork | Boolean | Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resource exchange has its own individual unit of work.
+| cacheSize | Integer | Sets the maximum size used by the org.apache.camel.impl.ProducerCache which is used to cache and reuse producer when uris are reused.
+| ignoreInvalidEndpoint | Boolean | Ignore the invalidate endpoint exception when try to create a producer with that endpoint
+|=======================================================================
+{% endraw %}
+// eip options: END
+
+[NOTE]
+.Good practice to use timeout value
+====
+By default Camel will use the receive. Which may block until there is a message available. It is therefore recommended to always provide a timeout value, to make this clear that we may wait for a message, until the timeout is hit.
+====
+
+If there is no data then the `newExchange` in the aggregation strategy is `null`.
+
+You can pass in a timeout value that determines which method to use
+
+* if timeout is -1 or other negative number then `receive` is selected (*Important:* the `receive` method may block if there is no message)
+* if timeout is 0 then `receiveNoWait` is selected
+* otherwise `receive(timeout)` is selected
+
+The timeout values is in millis.
+
+[IMPORTANT]
+.Camel 2.15 or older - Data from current Exchange not used
+====
+`pollEnrich` does *not* access any data from the current Exchange which means when polling it cannot use any of the existing headers you may have set on the Exchange. For example you cannot set a filename in the `Exchange.FILE_NAME` header and use `pollEnrich` to consume only that file. For that you *must* set the filename in the endpoint URI.
+From *Camel 2.16* onwards both `enrich` and `pollEnrich` supports dynamic endpoints that uses an Expression to compute the uri, which allows to use data from the current Exchange. In other words all what is told above no longer apply and it just works.
+====
+
+### Example
+
+In this example we enrich the message by loading the content from the file named inbox/data.txt.
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+  .pollEnrich("file:inbox?fileName=data.txt")
+  .to("direct:result");
+--------------------------------------------------------
+
+And in XML DSL (Camel 2.15 or older) you do:
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <pollEnrich uri="file:inbox?fileName=data.txt"/>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+And in XML DSL (Camel 2.16 or newer) you do:
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <pollEnrich>
+    <constant>file:inbox?fileName=data.txt</constant>
+  </pollEnrich>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+If there is no file then the message is empty. We can use a timeout to either wait (potentially forever) until a file exists, or use a timeout to wait a certain period.
+
+For example to wait up to 5 seconds you can do (Camel 2.15 or older):
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <pollEnrich uri="file:inbox?fileName=data.txt" timeout="5000"/>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+For example to wait up to 5 seconds you can do (Camel 2.16 or newer):
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <pollEnrich timeout="5000">
+    <constant>file:inbox?fileName=data.txt</constant>
+  </pollEnrich>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+### Using dynamic uris
+*Available as of Camel 2.16*
+From Camel 2.16 onwards `enrich` and `pollEnrich` supports using dynamic uris computed based on information from the current Exchange. For example to `pollEnrich` from an endpoint that uses a header to indicate a SEDA queue name:
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+  .pollEnrich().simple("seda:${header.name}")
+  .to("direct:result");
+--------------------------------------------------------
+
+And in XML DSL
+[source,xml]
+--------------------------------------------------------
+<route>
+  <from uri="direct:start"/>
+  <pollEnrich>
+    <simple>seda:${header.name}</simple>
+  </pollEnrich>
+  <to uri="direct:result"/>
+</route>
+--------------------------------------------------------
+
+### Using This Pattern
+If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/event-message.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/event-message.adoc b/camel-core/src/main/docs/eips/event-message.adoc
new file mode 100644
index 0000000..a25cf8f
--- /dev/null
+++ b/camel-core/src/main/docs/eips/event-message.adoc
@@ -0,0 +1,86 @@
+[[EventMessage-EventMessage]]
+Event Message
+~~~~~~~~~~~~~
+
+Camel supports the
+http://www.enterpriseintegrationpatterns.com/EventMessage.html[Event
+Message] from the link:enterprise-integration-patterns.html[EIP
+patterns] by supporting the link:exchange-pattern.html[Exchange Pattern]
+on a link:message.html[Message] which can be set to *InOnly* to indicate
+a oneway event message. Camel link:components.html[Components] then
+implement this pattern using the underlying transport or protocols.
+
+image:http://www.enterpriseintegrationpatterns.com/img/EventMessageSolution.gif[image]
+
+The default behaviour of many link:components.html[Components] is InOnly
+such as for link:jms.html[JMS], link:file2.html[File] or
+link:seda.html[SEDA]
+
+[TIP]
+====
+*Related*
+
+See the related link:request-reply.html[Request Reply] message.
+====
+
+[[EventMessage-ExplicitlyspecifyingInOnly]]
+Explicitly specifying InOnly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you are using a component which defaults to InOut you can override
+the link:exchange-pattern.html[Exchange Pattern] for an endpoint using
+the pattern property.
+
+[source,java]
+------------------------------
+foo:bar?exchangePattern=InOnly
+------------------------------
+
+From 2.0 onwards on Camel you can specify the
+link:exchange-pattern.html[Exchange Pattern] using the DSL.
+
+*Using the link:fluent-builders.html[Fluent Builders]*
+
+[source,java]
+---------------------------------------------
+from("mq:someQueue").
+  setExchangePattern(ExchangePattern.InOnly).
+  bean(Foo.class);
+---------------------------------------------
+
+or you can invoke an endpoint with an explicit pattern
+
+[source,java]
+----------------------------
+from("mq:someQueue").
+  inOnly("mq:anotherQueue");
+----------------------------
+
+*Using the link:spring-xml-extensions.html[Spring XML Extensions]*
+
+[source,java]
+------------------------------
+<route>
+    <from uri="mq:someQueue"/>
+    <inOnly uri="bean:foo"/>
+</route>
+------------------------------
+
+[source,java]
+-----------------------------------
+<route>
+    <from uri="mq:someQueue"/>
+    <inOnly uri="mq:anotherQueue"/>
+</route>
+-----------------------------------
+
+[[EventMessage-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.

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/guaranteed-delivery.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/guaranteed-delivery.adoc b/camel-core/src/main/docs/eips/guaranteed-delivery.adoc
new file mode 100644
index 0000000..7620c9b
--- /dev/null
+++ b/camel-core/src/main/docs/eips/guaranteed-delivery.adoc
@@ -0,0 +1,64 @@
+[[GuaranteedDelivery-GuaranteedDelivery]]
+Guaranteed Delivery
+^^^^^^^^^^^^^^^^^^^
+
+Camel supports the
+http://www.enterpriseintegrationpatterns.com/GuaranteedMessaging.html[Guaranteed
+Delivery] from the link:enterprise-integration-patterns.html[EIP
+patterns] using among others the following components:
+
+* link:file2.html[File] for using file systems as a persistent store of
+messages
+* link:jms.html[JMS] when using persistent delivery (the default) for
+working with JMS Queues and Topics for high performance, clustering and
+load balancing
+* link:jpa.html[JPA] for using a database as a persistence layer, or use
+any of the many other database component such as link:sql.html[SQL],
+link:jdbc.html[JDBC],
+link:ibatis.html[iBATIS]/link:mybatis.html[MyBatis],
+link:hibernate.html[Hibernate]
+* link:hawtdb.html[HawtDB] for a lightweight key-value persistent store
+
+image:http://www.enterpriseintegrationpatterns.com/img/GuaranteedMessagingSolution.gif[image]
+
+[[GuaranteedDelivery-Example]]
+Example
++++++++
+
+The following example demonstrates illustrates the use
+of�http://www.enterpriseintegrationpatterns.com/GuaranteedMessaging.html[Guaranteed
+Delivery]�within the�link:jms.html[JMS]�component. By default, a message
+is not considered successfully delivered until the recipient has
+persisted the message locally guaranteeing its receipt in the event the
+destination becomes unavailable.
+
+*Using the�link:fluent-builders.html[Fluent Builders]*
+
+[source,java]
+-------------------------
+from("direct:start")
+    .to("jms:queue:foo");
+-------------------------
+
+�
+
+**Using the�link:spring-xml-extensions.html[Spring XML Extensions]**
+
+[source,xml]
+------------------------------
+<route>
+    <from uri="direct:start"/>
+    <to uri="jms:queue:foo"/>
+</route>
+------------------------------
+
+[[GuaranteedDelivery-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.

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/hystrix-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/hystrix-eip.adoc b/camel-core/src/main/docs/eips/hystrix-eip.adoc
new file mode 100644
index 0000000..0e1f732
--- /dev/null
+++ b/camel-core/src/main/docs/eips/hystrix-eip.adoc
@@ -0,0 +1,129 @@
+## Hystrix EIP
+
+Available as of Camel 2.18
+
+The hystrix EIP provides integration with Netflix link:https://github.com/Netflix/Hystrix[Hystrix] to be used as circuit breaker in the Camel routes. Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
+
+Maven users will need to add the following dependency to their pom.xml to use this EIP:
+
+[source,java]
+---------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-hystrix</artifactId>
+    <version>x.x.x</version><!-- use the same version as your Camel core version -->
+</dependency>
+---------------------
+
+### Configuration options
+
+// eip options: START
+The Hystrix EIP supports 2 options which are listed below:
+
+{% raw %}
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Name | Java Type | Description
+| hystrixConfiguration | HystrixConfigurationDefinition | Configures the Hystrix EIP Use end when configuration is complete to return back to the Hystrix EIP.
+| hystrixConfigurationRef | String | Refers to a Hystrix configuration to use for configuring the Hystrix EIP.
+|=======================================================================
+{% endraw %}
+// eip options: END
+
+### Example
+Below is an example route showing an Hystrix endpoint that protects against slow operation by falling back to the in-lined fallback route. By default the timeout request is just *1000ms* so the HTTP endpoint has to be fairly quick to succeed.
+[source,java]
+---------------------
+from("direct:start")
+    .hystrix()
+        .to("http://fooservice.com/slow")
+    .onFallback()
+        .transform().constant("Fallback message")
+    .end()
+    .to("mock:result");
+---------------------
+
+And in XML DSL:
+[source,xml]
+---------------------
+<camelContext xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="direct:start"/>
+    <hystrix>
+      <to uri="http://fooservice.com/slow"/>
+      <onFallback>
+        <transform>
+          <constant>Fallback message</constant>
+        </transform>
+      </onFallback>
+    </hystrix>
+    <to uri="mock:result"/>
+  </route>
+</camelContext>
+---------------------
+
+### onFallback vs onFallbackViaNetwork
+If you are using *onFallback* then that is intended to be local processing only where you can do a message transformation or call a bean or something as the fallback. If you need to call an external service over the network then you should use *onFallbackViaNetwork* that runs in another independent *HystrixCommand* that uses its own thread pool to not exhaust the first command.
+Configuring Hystrix Example
+Hystrix has many options as listed in the table above. For example to set a higher timeout to *5* seconds, and also let the circuit breaker wait *10* seconds before attempting a request again when the state was tripped to be open.
+[source,java]
+---------------------
+from("direct:start")
+    .hystrix()
+        .hystrixConfiguration()
+             .executionTimeoutInMilliseconds(5000).circuitBreakerSleepWindowInMilliseconds(10000)
+        .end()
+        .to("http://fooservice.com/slow")
+    .onFallback()
+        .transform().constant("Fallback message")
+    .end()
+    .to("mock:result");
+---------------------
+
+And in XML DSL:
+[source,xml]
+---------------------
+<camelContext xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="direct:start"/>
+    <hystrix>
+      <hystrixConfiguration executionTimeoutInMilliseconds="5000" circuitBreakerSleepWindowInMilliseconds="10000"/>
+      <to uri="http://fooservice.com/slow"/>
+      <onFallback>
+        <transform>
+          <constant>Fallback message</constant>
+        </transform>
+      </onFallback>
+    </hystrix>
+    <to uri="mock:result"/>
+  </route>
+</camelContext>
+---------------------
+
+
+You can also configure hystrix globally and then refer to that configuration:
+
+[source,xml]
+---------------------
+<camelContext xmlns="http://camel.apache.org/schema/spring">
+
+  <!-- a shared config which you can refer to from all your hystrix EIPs -->
+  <hystrixConfiguration id="sharedConfig" executionTimeoutInMilliseconds="5000" circuitBreakerSleepWindowInMilliseconds="10000"/>
+
+  <route>
+    <from uri="direct:start"/>
+    <hystrix hystrixConfigurationRef="sharedConfig">
+      <to uri="http://fooservice.com/slow"/>
+      <onFallback>
+        <transform>
+          <constant>Fallback message</constant>
+        </transform>
+      </onFallback>
+    </hystrix>
+    <to uri="mock:result"/>
+  </route>
+</camelContext>
+---------------------
+
+### Example
+You can find an example in the source code: link:https://github.com/apache/camel/tree/master/examples/camel-example-hystrix[camel-example-hystrix].

http://git-wip-us.apache.org/repos/asf/camel/blob/f0bae85e/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc b/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
new file mode 100644
index 0000000..6d9fb8d
--- /dev/null
+++ b/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
@@ -0,0 +1,44 @@
+## Hystrix Configuration EIP
+
+
+// eip options: START
+The Hystrix Configuration EIP supports 31 options which are listed below:
+
+{% raw %}
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Name | Java Type | Description
+| groupKey | String | Sets the group key to use. The default value is CamelHystrix.
+| threadPoolKey | String | Sets the thread pool key to use. Will by default use the same value as groupKey has been configured to use.
+| circuitBreakerEnabled | Boolean | Whether to use a HystrixCircuitBreaker or not. If false no circuit-breaker logic will be used and all requests permitted. This is similar in effect to circuitBreakerForceClosed() except that continues tracking metrics and knowing whether it should be open/closed this property results in not even instantiating a circuit-breaker.
+| circuitBreakerErrorThresholdPercentage | Integer | Error percentage threshold (as whole number such as 50) at which point the circuit breaker will trip open and reject requests. It will stay tripped for the duration defined in circuitBreakerSleepWindowInMilliseconds; The error percentage this is compared against comes from HystrixCommandMetrics.getHealthCounts().
+| circuitBreakerForceClosed | Boolean | If true the HystrixCircuitBreakerallowRequest() will always return true to allow requests regardless of the error percentage from HystrixCommandMetrics.getHealthCounts(). The circuitBreakerForceOpen() property takes precedence so if it set to true this property does nothing.
+| circuitBreakerForceOpen | Boolean | If true the HystrixCircuitBreaker.allowRequest() will always return false causing the circuit to be open (tripped) and reject all requests. This property takes precedence over circuitBreakerForceClosed();
+| circuitBreakerRequestVolumeThreshold | Integer | Minimum number of requests in the metricsRollingStatisticalWindowInMilliseconds() that must exist before the HystrixCircuitBreaker will trip. If below this number the circuit will not trip regardless of error percentage.
+| circuitBreakerSleepWindowInMilliseconds | Integer | The time in milliseconds after a HystrixCircuitBreaker trips open that it should wait before trying requests again.
+| executionIsolationSemaphoreMaxConcurrentRequests | Integer | Number of concurrent requests permitted to HystrixCommand.run(). Requests beyond the concurrent limit will be rejected. Applicable only when executionIsolationStrategy == SEMAPHORE.
+| executionIsolationStrategy | String | What isolation strategy HystrixCommand.run() will be executed with. If THREAD then it will be executed on a separate thread and concurrent requests limited by the number of threads in the thread-pool. If SEMAPHORE then it will be executed on the calling thread and concurrent requests limited by the semaphore count.
+| executionIsolationThreadInterruptOnTimeout | Boolean | Whether the execution thread should attempt an interrupt (using link Futurecancel) when a thread times out. Applicable only when executionIsolationStrategy() == THREAD.
+| executionTimeoutInMilliseconds | Integer | Time in milliseconds at which point the command will timeout and halt execution. If link executionIsolationThreadInterruptOnTimeout == true and the command is thread-isolated the executing thread will be interrupted. If the command is semaphore-isolated and a HystrixObservableCommand that command will get unsubscribed.
+| executionTimeoutEnabled | Boolean | Whether the timeout mechanism is enabled for this command
+| fallbackIsolationSemaphoreMaxConcurrentRequests | Integer | Number of concurrent requests permitted to HystrixCommand.getFallback(). Requests beyond the concurrent limit will fail-fast and not attempt retrieving a fallback.
+| fallbackEnabled | Boolean | Whether HystrixCommand.getFallback() should be attempted when failure occurs.
+| metricsHealthSnapshotIntervalInMilliseconds | Integer | Time in milliseconds to wait between allowing health snapshots to be taken that calculate success and error percentages and affect HystrixCircuitBreaker.isOpen() status. On high-volume circuits the continual calculation of error percentage can become CPU intensive thus this controls how often it is calculated.
+| metricsRollingPercentileBucketSize | Integer | Maximum number of values stored in each bucket of the rolling percentile. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
+| metricsRollingPercentileEnabled | Boolean | Whether percentile metrics should be captured using HystrixRollingPercentile inside HystrixCommandMetrics.
+| metricsRollingPercentileWindowInMilliseconds | Integer | Duration of percentile rolling window in milliseconds. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
+| metricsRollingPercentileWindowBuckets | Integer | Number of buckets the rolling percentile window is broken into. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
+| metricsRollingStatisticalWindowInMilliseconds | Integer | This property sets the duration of the statistical rolling window in milliseconds. This is how long metrics are kept for the thread pool. The window is divided into buckets and rolls by those increments.
+| metricsRollingStatisticalWindowBuckets | Integer | Number of buckets the rolling statistical window is broken into. This is passed into HystrixRollingNumber inside HystrixCommandMetrics.
+| requestLogEnabled | Boolean | Whether HystrixCommand execution and events should be logged to HystrixRequestLog.
+| corePoolSize | Integer | Core thread-pool size that gets passed to link java.util.concurrent.ThreadPoolExecutorsetCorePoolSize(int)
+| maximumSize | Integer | Maximum thread-pool size that gets passed to link ThreadPoolExecutorsetMaximumPoolSize(int). This is the maximum amount of concurrency that can be supported without starting to reject HystrixCommands. Please note that this setting only takes effect if you also set allowMaximumSizeToDivergeFromCoreSize
+| keepAliveTime | Integer | Keep-alive time in minutes that gets passed to link ThreadPoolExecutorsetKeepAliveTime(long TimeUnit)
+| maxQueueSize | Integer | Max queue size that gets passed to BlockingQueue in HystrixConcurrencyStrategy.getBlockingQueue(int) This should only affect the instantiation of a threadpool - it is not eliglible to change a queue size on the fly. For that use queueSizeRejectionThreshold().
+| queueSizeRejectionThreshold | Integer | Queue size rejection threshold is an artificial max size at which rejections will occur even if link maxQueueSize has not been reached. This is done because the link maxQueueSize of a BlockingQueue can not be dynamically changed and we want to support dynamically changing the queue size that affects rejections. This is used by HystrixCommand when queuing a thread for execution.
+| threadPoolRollingNumberStatisticalWindowInMilliseconds | Integer | Duration of statistical rolling window in milliseconds. This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
+| threadPoolRollingNumberStatisticalWindowBuckets | Integer | Number of buckets the rolling statistical window is broken into. This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
+| allowMaximumSizeToDivergeFromCoreSize | Boolean | Allows the configuration for maximumSize to take effect. That value can then be equal to or higher than coreSize
+|=======================================================================
+{% endraw %}
+// eip options: END