Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DA022113B6 for ; Fri, 2 May 2014 17:22:08 +0000 (UTC) Received: (qmail 78004 invoked by uid 500); 2 May 2014 17:22:07 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 77876 invoked by uid 500); 2 May 2014 17:22:06 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 77858 invoked by uid 99); 2 May 2014 17:22:05 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 02 May 2014 17:22:05 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 02 May 2014 17:21:57 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DC07C2388B34 for ; Fri, 2 May 2014 17:21:36 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r907787 [4/6] - in /websites/production/camel/content: ./ 2014/05/ 2014/05/02/ cache/ Date: Fri, 02 May 2014 17:21:35 -0000 To: commits@camel.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140502172136.DC07C2388B34@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: websites/production/camel/content/book-pattern-appendix.html ============================================================================== --- websites/production/camel/content/book-pattern-appendix.html (original) +++ websites/production/camel/content/book-pattern-appendix.html Fri May 2 17:21:34 2014 @@ -1195,51 +1195,22 @@ from("direct:start")

Knowing if Exchange was filtered or not

Available as of Camel 2.5

The Message Filter EIP will add a property on the Exchange that states if it was filtered or not.

The property has the key Exchange.FILTER_MATCHED, which has the String value of CamelFilterMatched. Its value is a boolean indicating true or false. If the value is true then the Exchange was routed in the filter block. This property will be visible within the Message Filter block who's Predicate matches (value set to true), and to the steps immediately following the Message Filter with the value set based on the results of the last Message Filter Predicate evaluated.

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.

-

Dynamic Router

- -

The Dynamic Router from the EIP patterns allows you to route messages while avoiding the dependency of the router on all possible destinations while maintaining its efficiency.

- -

- -

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.

- -
+

Dynamic Router

The Dynamic Router from the EIP patterns allows you to route messages while avoiding the dependency of the router on all possible destinations while maintaining its efficiency.

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.

Beware

Icon
- -

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.

+

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

- -
-

Name

Default Value

Description

uriDelimiter

,

Delimiter used if the 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.

-
- - -

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:

- -
+

Options

+

Name

Default Value

Description

uriDelimiter

,

Delimiter used if the 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.

+

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:

-
- -

Which will leverage a Bean to compute the slip on-the-fly, which could be implemented as follows:

- -
+

Which will leverage a Bean to compute the slip on-the-fly, which could be implemented as follows:

-
- -

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:

-
+

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:

-
- -

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.

- -
+

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.

Using beans to store state

Icon
- -

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.

+

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:

- -
+

Spring XML

The same example in Spring XML would be:

-
- -

@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.

-
- -
- -

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.

- -
- -
- -

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

- - - - -

Using This Pattern

+

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

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.

Recipient List

The Recipient List from the EIP patterns allows you to route messages to a number of dynamically specified recipients.

The recipients will receive a copy of the same Exchange, and Camel will execute them sequentially.

Options

-

Name

Default Value

Description

delimiter

,

Delimiter used if the Expression returned multiple endpoints. Camel 2.13 can be disabled using "false"

strategyRef

 

An AggregationStrategy that will assemble the replies from recipients into a single outgoing message from the Recipient List. By default Camel will use the last reply as the 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 Aggregat e 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.

parallelProcessing

false

Camel 2.2: If enabled, messages are sent to the recipients concurrently. Note that the calling thread will still wait until all messages have been fully processed before it continues; it's the sending and processing of replies from recipients which happens in parallel.

executorServiceRef

 

Camel 2.2: A custom Thread Pool to use for parallel processing. Note that enabling this option implies parallel processing, so you need not enable that option as well.

stopOnException

false

Camel 2.2: Whether to immediately stop processing when an exception occurs. If disabled, Camel will send the message to all recipients regardless of any individual failures. You can process exceptions in an AggregationStrategy implementation, which supports full control of error handling.

ignoreInvalidEndpoints

false

Camel 2.3: Whether to ignore an endpoint URI that could not be resolved. If disabled, Camel will throw an exception identifying the invalid endpoint URI.

streaming

false

Camel 2.5: If enabled, Camel will process replies out-of-order - that is, in the order received in reply from each recipient. If disabled, Camel will process replies in the same order as specified by the Expression.

timeout

 

Camel 2.5: Specifies a processing timeout milliseconds. If the Recipient List hasn't been able to send and process all replies within this timeframe, then the timeout triggers and the Recipient List breaks out, with message flow continuing to the next element. Note that if you provide a TimeoutAwareAggregationStrategy, its timeout method is invoked before breaking out. Beware: If the timeout is reached with running tasks still remaining, certain tasks for which it is difficult for Camel to shut down in a graceful manner may continue to run. So use this option with a bit of care. We may be able to improve this functionality in future Camel releases.

onPrepareRef

 

Camel 2.8: A custom Processor t o prepare the copy of the Exchange each recipient will receive. This allows you to perform arbitrary transformations, such as deep-cloning the message payload (or any other custom logic).

shareUnitOfWork

false

Camel 2.8: Whether the unit of work should be shared. See the same option on Splitter for more details.

+

Name

Default Value

Description

delimiter

,

Delimiter used if the Expression returned multiple endpoints. Camel 2.13 can be disabled using "false"

strategyRef

 

An AggregationStrategy that will assemble the replies from recipients into a single outgoing message from the Recipient List. By default Camel will use the last reply as the 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 Aggregat e 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.

parallelProcessing

false

Camel 2.2: If enabled, messages are sent to the recipients concurrently. Note that the calling thread will still wait until all messages have been fully processed before it continues; it's the sending and processing of replies from recipients which happens in parallel.

executorServiceRef

 

Camel 2.2: A custom Thread Pool to use for parallel processing. Note that enabling this option implies parallel processing, so you need not enable that option as well.

stopOnException

false

Camel 2.2: Whether to immediately stop processing when an exception occurs. If disabled, Camel will send the message to all recipients regardless of any individual failures. You can process exceptions in an AggregationStrategy implementation, which supports full control of error handling.

ignoreInvalidEndpoints

false

Camel 2.3: Whether to ignore an endpoint URI that could not be resolved. If disabled, Camel will throw an exception identifying the invalid endpoint URI.

streaming

false

Camel 2.5: If enabled, Camel will process replies out-of-order - that is, in the order received in reply from each recipient. If disabled, Camel will process replies in the same order as specified by the Expression.

timeout

 

Camel 2.5: Specifies a processing timeout milliseconds. If the Recipient List hasn't been able to send and process all replies within this timeframe, then the timeout triggers and the Recipient List breaks out, with message flow continuing to the next element. Note that if you provide a TimeoutAwareAggregationStrategy, its timeout method is invoked before breaking out. Beware: If the timeout is reached with running tasks still remaining, certain tasks for which it is difficult for Camel to shut down in a graceful manner may continue to run. So use this option with a bit of care. We may be able to improve this functionality in future Camel releases.

onPrepareRef

 

Camel 2.8: A custom Processor t o prepare the copy of the Exchange each recipient will receive. This allows you to perform arbitrary transformations, such as deep-cloning the message payload (or any other custom logic).

shareUnitOfWork

false

Camel 2.8: Whether the unit of work should be shared. See the same option on Splitter for more details.

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.

Static Recipient List

The following example shows how to route a request from an input queue:a endpoint to a static list of destinations

Using Annotations
You can use the RecipientList Annotation on a POJO to create a Dynamic Recipient List. For more details see the Bean Integration.

Using the Fluent Builders

-
- -

The splitter can use any Expression language so you could use any of the Languages Supported such as XPath, XQuery, SQL or one of the Scripting Languages to perform the split. e.g.

- -
- -
- -

Using the Spring XML Extensions

-
+

Using the Spring XML Extensions

-
- -

For further examples of this pattern in use you could look at one of the junit test case

- -

Using Tokenizer from Spring XML Extensions*

- -

You can use the tokenizer expression in the Spring DSL to split bodies or headers using a token. This is a common use-case, so we provided a special tokenizer tag for this.
-In the sample below we split the body using a @ as separator. You can of course use comma or space or even a regex pattern, also set regex=true.

-
+

For further examples of this pattern in use you could look at one of the junit test case

Using Tokenizer from Spring XML Extensions*

You can use the tokenizer expression in the Spring DSL to split bodies or headers using a token. This is a common use-case, so we provided a special tokenizer tag for this.
In the sample below we split the body using a @ as separator. You can of course use comma or space or even a regex pattern, also set regex=true.

-
- -

Splitting the body in Spring XML is a bit harder as you need to use the Simple language to dictate this

-
- -
- -

What the Splitter returns

-

Camel 2.2 or older:
-The Splitter will by default return the last splitted message.

- -

Camel 2.3 and newer
-The Splitter will by default return the original input message.

- -

For all versions
-You can override this by suppling your own strategy as an AggregationStrategy. There is a sample on this page (Split aggregate request/reply sample). Notice its the same strategy as the Aggregator supports. This Splitter can be viewed as having a build in light weight Aggregator.

- -

Parallel execution of distinct 'parts'

-

If you want to execute all parts in parallel you can use special notation of split() with two arguments, where the second one is a boolean flag if processing should be parallel. e.g.

- -
- -
- -

The boolean option has been refactored into a builder method parallelProcessing so its easier to understand what the route does when we use a method instead of true|false.

-
- -
- -

Stream based

-
+

Stream based

Splitting big XML payloads

Icon
- -

The XPath engine in Java and saxon will load the entire XML content into memory. And thus they are not well suited for very big XML payloads.
-Instead you can use a custom Expression which will iterate the XML payload in a streamed fashion. From Camel 2.9 onwards you can use the Tokenizer language
-which supports this when you supply the start and end tokens.

+

The XPath engine in Java and saxon will load the entire XML content into memory. And thus they are not well suited for very big XML payloads.
Instead you can use a custom Expression which will iterate the XML payload in a streamed fashion. From Camel 2.9 onwards you can use the Tokenizer language
which supports this when you supply the start and end tokens.

- - -

You can split streams by enabling the streaming mode using the streaming builder method.

-
- -
- -

You can also supply your custom splitter to use with streaming like this:

-
- -
- -

Streaming big XML payloads using Tokenizer language

-

Available as of Camel 2.9
-If you have a big XML payload, from a file source, and want to split it in streaming mode, then you can use the Tokenizer language with start/end tokens to do this with low memory footprint.

- -
+

Streaming big XML payloads using Tokenizer language

Available as of Camel 2.9
If you have a big XML payload, from a file source, and want to split it in streaming mode, then you can use the Tokenizer language with start/end tokens to do this with low memory footprint.

StAX component

Icon
- -

The Camel StAX component can also be used to split big XML files in a streaming mode. See more details at StAX.

+

The Camel StAX component can also be used to split big XML files in a streaming mode. See more details at StAX.

- - -

For example you may have a XML payload structured as follows

-
- -
- -

Now to split this big file using XPath would cause the entire content to be loaded into memory. So instead we can use the Tokenizer language to do this as follows:

-
- -
- -

In XML DSL the route would be as follows:

-
- -
- -

Notice the tokenizeXML method which will split the file using the tag name of the child node, which mean it will grab the content between the <order> and </order> tags (incl. the tokens). So for example a splitted message would be as follows:

-
- -
- -

If you want to inherit namespaces from a root/parent tag, then you can do this as well by providing the name of the root/parent tag:

-
- -
- -

And in Java DSL its as follows:

-
- -
- - -

Splitting files by grouping N lines together

-

Available as of Camel 2.10

- -

The Tokenizer language has a new option group that allows you to group N parts together, for example to split big files into chunks of 1000 lines.

-
- -
- -

And in XML DSL

-
- -
- -

The group option is a number that must be a positive number that dictates how many groups to combine together. Each part will be combined using the token.
-So in the example above the message being sent to the activemq order queue, will contain 1000 lines, and each line separated by the token (which is a new line token).
-The output when using the group option is always a java.lang.String type.

- - - -

Specifying a custom aggregation strategy

- -

This is specified similar to the Aggregator.

- -

Specifying a custom ThreadPoolExecutor

-

You can customize the underlying ThreadPoolExecutor used in the parallel splitter. In the Java DSL try something like this:

- -
- -
- -

Using a Pojo to do the splitting

-

As the Splitter can use any Expression to do the actual splitting we leverage this fact and use a method expression to invoke a Bean to get the splitted parts.
-The Bean should return a value that is iterable such as: java.util.Collection, java.util.Iterator or an array.
-So the returned value, will then be used by Camel at runtime, to split the message.

- -
+

Using a Pojo to do the splitting

As the Splitter can use any Expression to do the actual splitting we leverage this fact and use a method expression to invoke a Bean to get the splitted parts.
The Bean should return a value that is iterable such as: java.util.Collection, java.util.Iterator or an array.
So the returned value, will then be used by Camel at runtime, to split the message.

Streaming mode and using pojo

Icon
- -

When you have enabled the streaming mode, then you should return a Iterator to ensure streamish fashion. For example if the message is a big file, then by using an iterator, that returns a piece of the file in chunks, in the next method of the Iterator ensures low memory footprint. This avoids the need for reading the entire content into memory. For an example see the source code for the TokenizePair implementation.

+

When you have enabled the streaming mode, then you should return a Iterator to ensure streamish fashion. For example if the message is a big file, then by using an iterator, that returns a piece of the file in chunks, in the next method of the Iterator ensures low memory footprint. This avoids the need for reading the entire content into memory. For an example see the source code for the TokenizePair implementation.

- - -

In the route we define the Expression as a method call to invoke our Bean that we have registered with the id mySplitterBean in the Registry.

-
+

In the route we define the Expression as a method call to invoke our Bean that we have registered with the id mySplitterBean in the Registry.

-
- -

And the logic for our Bean is as simple as. Notice we use Camel Bean Binding to pass in the message body as a String object.

-
+

And the logic for our Bean is as simple as. Notice we use Camel Bean Binding to pass in the message body as a String object.

-
- -

Split aggregate request/reply sample

-

This sample shows how you can split an Exchange, process each splitted message, aggregate and return a combined response to the original caller using request/reply.

- -

The route below illustrates this and how the split supports a aggregationStrategy to hold the in progress processed messages:

-
+

Split aggregate request/reply sample

This sample shows how you can split an Exchange, process each splitted message, aggregate and return a combined response to the original caller using request/reply.

The route below illustrates this and how the split supports a aggregationStrategy to hold the in progress processed messages:

-
- -

And the OrderService bean is as follows:

-
+

And the OrderService bean is as follows:

-
- -

And our custom aggregationStrategy that is responsible for holding the in progress aggregated message that after the splitter is ended will be sent to the buildCombinedResponse method for final processing before the combined response can be returned to the waiting caller.

-
+

And our custom aggregationStrategy that is responsible for holding the in progress aggregated message that after the splitter is ended will be sent to the buildCombinedResponse method for final processing before the combined response can be returned to the waiting caller.

-
- -

So lets run the sample and see how it works.
-We send an Exchange to the direct:start endpoint containing a IN body with the String value: A@B@C. The flow is:

-
- -
- -

Stop processing in case of exception

-

Available as of Camel 2.1

- -

The Splitter will by default continue to process the entire Exchange even in case of one of the splitted message will thrown an exception during routing.
-For example if you have an Exchange with 1000 rows that you split and route each sub message. During processing of these sub messages an exception is thrown at the 17th. What Camel does by default is to process the remainder 983 messages. You have the chance to remedy or handle this in the AggregationStrategy.

- -

But sometimes you just want Camel to stop and let the exception be propagated back, and let the Camel error handler handle it. You can do this in Camel 2.1 by specifying that it should stop in case of an exception occurred. This is done by the stopOnException option as shown below:

- -
- -
- -

And using XML DSL you specify it as follows:

-
- -
- -

Using onPrepare to execute custom logic when preparing messages

-

Available as of Camel 2.8

- -

See details at Multicast

- - -

Sharing unit of work

-

Available as of Camel 2.8

- -

The Splitter will by default not share unit of work between the parent exchange and each splitted exchange. This means each sub exchange has its own individual unit of work.

- -

For example you may have an use case, where you want to split a big message. And you want to regard that process as an atomic isolated operation that either is a success or failure. In case of a failure you want that big message to be moved into a dead letter queue. To support this use case, you would have to share the unit of work on the Splitter.

- -

Here is an example in Java DSL

-
[... 677 lines stripped ...]