camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acosent...@apache.org
Subject [3/3] camel git commit: Added Dynamic Router docs to Gitbook
Date Fri, 28 Oct 2016 10:00:59 GMT
Added Dynamic Router docs to Gitbook


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

Branch: refs/heads/master
Commit: cbebae831aebf8c25741e34dc58fc5362a54d64d
Parents: 8349ee7
Author: Andrea Cosentino <ancosen@gmail.com>
Authored: Fri Oct 28 11:59:59 2016 +0200
Committer: Andrea Cosentino <ancosen@gmail.com>
Committed: Fri Oct 28 11:59:59 2016 +0200

----------------------------------------------------------------------
 camel-core/src/main/docs/dynamic-router.adoc | 246 ++++++++++++++++++++++
 docs/user-manual/en/SUMMARY.md               |   1 +
 2 files changed, 247 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cbebae83/camel-core/src/main/docs/dynamic-router.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/dynamic-router.adoc b/camel-core/src/main/docs/dynamic-router.adoc
new file mode 100644
index 0000000..e97b900
--- /dev/null
+++ b/camel-core/src/main/docs/dynamic-router.adoc
@@ -0,0 +1,246 @@
+[[DynamicRouter-DynamicRouter]]
+Dynamic Router
+~~~~~~~~~~~~~~
+
+The
+http://www.enterpriseintegrationpatterns.com/DynamicRouter.html[Dynamic
+Router] from the link:enterprise-integration-patterns.html[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 link:routing-slip.html[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.
+
+[[DynamicRouter-Options]]
+Options
+^^^^^^^
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Name |Default Value |Description
+
+|`uriDelimiter` |`,` |Delimiter used if the link:expression.html[Expression] returned multiple
+endpoints.
+
+|`ignoreInvalidEndpoints` |`false` |If an endpoint uri could not be resolved, should it be
ignored.
+Otherwise Camel will thrown an exception stating the endpoint uri is not
+valid.
+
+|`cacheSize` |`1000` |*Camel 2.13.1/2.12.4:* Allows to configure the cache size for the
+`ProducerCache` which caches producers for reuse in the routing slip.
+Will by default use the default cache size which is 1000. Setting the
+value to -1 allows to turn off the cache all together.
+|=======================================================================
+
+[[DynamicRouter-DynamicRouterinCamel2.5onwards]]
+Dynamic Router in Camel 2.5 onwards
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+From Camel 2.5 the link:dynamic-router.html[Dynamic Router] will set a
+property (Exchange.SLIP_ENDPOINT) on the link:exchange.html[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 link:dynamic-router.html[Dynamic Router] implementation is
+based on top of link:routing-slip.html[Routing Slip]).
+
+[[DynamicRouter-JavaDSL]]
+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 link:bean.html[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 link:exchange.html[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
+link:exchange.html[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 link:bean.html[Bean] the
+state is not propagated, so you will have to use a
+link:processor.html[Processor] instead. This is fixed in Camel 2.9.3
+onwards.
+
+[[DynamicRouter-SpringXML]]
+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-DynamicRouterannotation]]
+@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 link:routing-slip.html[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.
+    }
+}
+-----------------------------------------------------------------------------------------------------------------------
+
+[[DynamicRouter-DynamicRouterinCamel2.4orolder]]
+Dynamic Router in Camel 2.4 or older
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The simplest way to implement this is to use the
+link:recipientlist-annotation.html[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
+link:parameter-binding-annotations.html[Parameter Binding Annotations]
+to bind different parts of the link:message.html[Message] to method
+parameters or use an link:expression.html[Expression] such as using
+link:xpath.html[XPath] or link:xquery.html[XQuery].
+
+The method can be invoked in a number of ways as described in the
+link:bean-integration.html[Bean Integration] such as
+
+* link:pojo-producing.html[POJO Producing]
+* link:spring-remoting.html[Spring Remoting]
+* link:bean.html[Bean] component
+
+[[DynamicRouter-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/cbebae83/docs/user-manual/en/SUMMARY.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index bf4fef1..6d74c3f 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -95,6 +95,7 @@
     * Message Routing
         * [Content Based Router](content-based-router.adoc)
         * [Message Filter](message-filter.adoc)
+        * [Dynamic Router](dynamic-router.adoc)
 
 * Community
     * FAQ


Mime
View raw message