Author: buildbot
Date: Tue Mar 26 22:22:28 2019
New Revision: 1042574
Log:
Production update by buildbot for camel
Modified:
websites/production/camel/content/activemq-camel-tomcat.html
websites/production/camel/content/advanced-configuration-of-camelcontext-using-spring.html
websites/production/camel/content/aggregate-example.html
websites/production/camel/content/aggregator.html
websites/production/camel/content/bam-example.html
websites/production/camel/content/book-component-appendix.html
websites/production/camel/content/book-dataformat-appendix.html
websites/production/camel/content/book-in-one-page.html
websites/production/camel/content/book-pattern-appendix.html
websites/production/camel/content/cache/main.pageCache
websites/production/camel/content/cafe-example.html
websites/production/camel/content/composed-message-processor.html
websites/production/camel/content/content-filter.html
websites/production/camel/content/custom-dataformat.html
websites/production/camel/content/cxf-tomcat-example.html
websites/production/camel/content/data-format.html
websites/production/camel/content/detour.html
websites/production/camel/content/ejb.html
websites/production/camel/content/eventnotifier-to-log-details-about-all-sent-exchanges.html
websites/production/camel/content/jackson-xml.html
websites/production/camel/content/jing.html
websites/production/camel/content/language.html
websites/production/camel/content/loadbalancing-mina-example.html
websites/production/camel/content/msv.html
websites/production/camel/content/predicate.html
websites/production/camel/content/processorfactory.html
websites/production/camel/content/quartz.html
websites/production/camel/content/ref.html
websites/production/camel/content/request-reply.html
websites/production/camel/content/route-throttling-example.html
websites/production/camel/content/scatter-gather.html
websites/production/camel/content/servlet-tomcat-example.html
websites/production/camel/content/servlet-tomcat-no-spring-example.html
websites/production/camel/content/simple-jira-bot.html
websites/production/camel/content/siteindex.html
websites/production/camel/content/spring-remoting.html
websites/production/camel/content/spring-security-example.html
websites/production/camel/content/spring-xquery-example.html
websites/production/camel/content/stax.html
websites/production/camel/content/transactionerrorhandler.html
websites/production/camel/content/tutorial-example-reportincident-part6.html
Modified: websites/production/camel/content/activemq-camel-tomcat.html
==============================================================================
--- websites/production/camel/content/activemq-camel-tomcat.html (original)
+++ websites/production/camel/content/activemq-camel-tomcat.html Tue Mar 26
22:22:28 2019
@@ -99,7 +99,7 @@ Then another Camel route will route mess
<h3 id="ActiveMQCamelTomcat-BuildingandRunningexample">Building and Running
example</h3>
<p>You will need to build this example first:</p>
-<div class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<div class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">
mvn install
</pre>
@@ -108,14 +108,14 @@ Then another Camel route will route mess
<p>Which will create a .war file in the target directly. You can then deploy
this .war file in any web container such as Apache Tomcat, by copying the .war
file to its /webapp directory.</p>
<p>For example to start Apache Tomcat</p>
-<div class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<div class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">
bin/catalina.sh run
</pre>
</div></div>
<p>And then build the example and deploy to Apache Tomcat</p>
-<div class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<div class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">
mvn install
cp target/camel-example-activemq-tomcat.war /opt/apache-tomcat-7.0.26/webapps/
Modified:
websites/production/camel/content/advanced-configuration-of-camelcontext-using-spring.html
==============================================================================
---
websites/production/camel/content/advanced-configuration-of-camelcontext-using-spring.html
(original)
+++
websites/production/camel/content/advanced-configuration-of-camelcontext-using-spring.html
Tue Mar 26 22:22:28 2019
@@ -147,7 +147,7 @@ public class ContainerWideInterceptor im
return count;
}
}
-</pre>When Camel boots up it logs at <code>INFO</code> level the container
wide interceptors it have found:<div class="code panel pdl conf-macro
output-block" data-hasbody="true" data-macro-name="code" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+</pre>When Camel boots up it logs at <code>INFO</code> level the container
wide interceptors it have found:<div class="code panel pdl conf-macro
output-block" style="border-width: 1px;" data-hasbody="true"
data-macro-name="code"><div class="codeContent panelContent pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">INFO
CamelContextFactoryBean - Using custom intercept strategy with id:
myInterceptor and
implementation:org.apache.camel.spring.interceptor.ContainerWideInterceptor@b84c44
</pre>
</div></div><p><strong>Notice:</strong> If we have more than 1 container wide
interceptor, we can just define them as spring bean. Camel will find and use
them.</p><h2 id="AdvancedconfigurationofCamelContextusingSpring-SeeAlso">See
Also</h2><ul><li><a shape="rect" href="spring.html">Spring</a></li><li><a
shape="rect" href="tutorial-jmsremoting.html">Spring JMS
Tutorial</a></li><li><a shape="rect"
href="creating-a-new-spring-based-camel-route.html">Creating a new Spring based
Camel Route</a></li><li><a shape="rect" href="spring-example.html">Spring
example</a></li><li><a shape="rect" href="xml-reference.html">Xml
Reference</a></li></ul></div>
Modified: websites/production/camel/content/aggregate-example.html
==============================================================================
--- websites/production/camel/content/aggregate-example.html (original)
+++ websites/production/camel/content/aggregate-example.html Tue Mar 26
22:22:28 2019
@@ -107,7 +107,7 @@
<h3 id="AggregateExample-Example">Example</h3>
<p>For example we start the example for the first time using <code>mvn
camel:run</code> and then we enter the two numbers 5 and 7 before we shutdown
using <code>ctrl + c</code>. The relevant console output:</p>
-<div class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<div class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">
[pache.camel.spring.Main.main()] DefaultCamelContext INFO Apache
Camel 2.3-SNAPSHOT (CamelContext:camel) started
Enter a number to be added (use STOP to end, and ctrl c to shutdown Camel): 5
@@ -118,7 +118,7 @@ Enter a number to be added (use STOP to
</div></div>
<p>Now we start the example again using <code>mvn camel:run</code> and enter
the number 3 and then enter <code>STOP</code> to see the result. As expected
the result is 5+7+3 = 15 as outputted on the console. As you can see the
persistence of the aggregated messages ensures we could continue where we
stopped.</p>
-<div class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<div class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">
[pache.camel.spring.Main.main()] DefaultCamelContext INFO Apache
Camel 2.3-SNAPSHOT (CamelContext:camel) started
Enter a number to be added (use STOP to end, and ctrl c to shutdown Camel): 3
Modified: websites/production/camel/content/aggregator.html
==============================================================================
--- websites/production/camel/content/aggregator.html (original)
+++ websites/production/camel/content/aggregator.html Tue Mar 26 22:22:28 2019
@@ -89,27 +89,12 @@
<tbody>
<tr>
<td valign="top" width="100%">
-<div class="wiki-content maincontent"><h3
id="Aggregator-Aggregator">Aggregator</h3><p><strong>This applies for Camel
version 2.2 or older. If you use a newer version then the Aggregator has been
rewritten from Camel 2.3 on and you should use this <a shape="rect"
href="aggregator2.html">Aggregator2</a> link instead.</strong></p><p>The <a
shape="rect" class="external-link"
href="http://www.enterpriseintegrationpatterns.com/Aggregator.html"
rel="nofollow">Aggregator</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> allows you to
combine a number of messages together into a single message.</p><p><span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/Aggregator.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/Aggregator.gif"></span></p><p>A
correlation <a shape="rect" href="expression.html">Expression</a> is used t
o determine the messages which should be aggregated together. If you want to
aggregate all messages into a single message, just use a constant expression.
An <strong><code>AggregationStrategy</code></strong> is used to combine
all the message exchanges for a single correlation key into a single message
exchange. The default strategy just chooses the latest message; so its ideal
for throttling messages.</p><p>For example, imagine a stock market data system;
you are receiving 30,000 messages per second; you may want to throttle down the
updates as, say, a GUI cannot cope with such massive update rates. So you may
want to aggregate these messages together so that within a window (defined by a
maximum number of messages or a timeout), messages for the same stock are
aggregated together; by just choosing the latest message and discarding the
older prices. (You could apply a delta processing algorithm if you prefer to
capture some of the history).</p><div class="confluence-informatio
n-macro confluence-information-macro-tip conf-macro output-block"
data-hasbody="true" data-macro-name="tip"><p class="title">Using the aggregator
correctly</p><span class="aui-icon aui-icon-small aui-iconfont-approve
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>Torsten Mielke wrote a nice <a
shape="rect" class="external-link"
href="http://tmielke.blogspot.com/2009/01/using-camel-aggregator-correctly.html"
rel="nofollow">blog entry</a> with his thoughts and experience on using the
aggreagator. Its a well worth read.</p></div></div><div
class="confluence-information-macro confluence-information-macro-information
conf-macro output-block" data-hasbody="true" data-macro-name="info"><p
class="title">AggregationStrategy changed in Camel 2.0</p><span class="aui-icon
aui-icon-small aui-iconfont-info confluence-information-macro-icon">
</span><div class="confluence-information-macro-body"><p>In Camel 2.0 the
<strong><code>AggregationStrategy</co
de></strong> callback have been changed to also be invoked on the very first
Exchange.</p><p>On the first invocation of the
<strong><code>aggregate</code></strong> method the
<strong><code>oldExchange</code></strong> parameter is
<strong><code>null</code></strong>. The reason is that we have not aggregated
anything yet.<br clear="none"> So its only the
<strong><code>newExchange</code></strong> that has a value. Usually you just
return the <strong><code>newExchange</code></strong> in this situation. But you
still have the power to decide what to do, for example you can do some
alternation on the exchange or remove some headers. And a more common use case
is for instance to count some values from the body payload. That could be to
sum up a total amount etc.</p></div></div><div
class="confluence-information-macro confluence-information-macro-warning
conf-macro output-block" data-hasbody="true" data-macro-name="warning"><p
class="title">BatchTimeout and CompletionPredicate</p><span clas
s="aui-icon aui-icon-small aui-iconfont-error
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>You cannot use
both <strong><code>batchTimeout</code></strong>
and <strong><code>completionPredicate</code></strong> to trigger a
completion based on either on reaching its goal first. The batch timeout will
always trigger first, at that given interval.</p></div></div><p><strong>Using
the <a shape="rect" href="fluent-builders.html">Fluent
Builders</a></strong></p><p>The following example shows how to aggregate
messages so that only the latest message for a specific value of the
<strong><code>cheese</code></strong> header are sent.Error rendering macro
'code': Invalid value specified for parameter
'java.lang.NullPointerException'</p><pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-// in this route we aggregate all from direct:state based on the header id
cheese
-from("direct:start").aggregate(header("cheese")).to("mock:result");
-
-from("seda:header").setHeader("visited",
constant(true)).aggregate(header("cheese")).to("mock:result");
-
-// in this sample we aggregate using our own strategy with a completion
predicate
-// stating that the aggregated header is equal to 5.
-from("direct:predicate").aggregate(header("cheese"), new
MyAggregationStrategy()).
-
completionPredicate(header("aggregated").isEqualTo(5)).to("mock:result");
-
-// this sample is similar to the one above but it also illustrates the use of
outBatchSize
-// to send exchanges to mock:endpoint in batches of 10.
-from("direct:outBatchPredicate").aggregate(header("cheese"), new
MyAggregationStrategy()).
-
completionPredicate(header("aggregated").isEqualTo(5)).outBatchSize(10).to("mock:result");
-</pre>If you were using JMS then you may wish to use
the <strong><code>JMSDestination</code></strong> header as the correlation
key; or some custom header for the stock symbol (using the above stock market
example).<div class="code panel pdl conf-macro output-block"
data-hasbody="true" data-macro-name="code" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<div class="wiki-content maincontent"><h3
id="Aggregator-Aggregator">Aggregator</h3><p><strong>This applies for Camel
version 2.2 or older. If you use a newer version then the Aggregator has been
rewritten from Camel 2.3 on and you should use this <a shape="rect"
href="aggregator2.html">Aggregator2</a> link instead.</strong></p><p>The <a
shape="rect" class="external-link"
href="http://www.enterpriseintegrationpatterns.com/Aggregator.html"
rel="nofollow">Aggregator</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> allows you to
combine a number of messages together into a single message.</p><p><span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/Aggregator.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/Aggregator.gif"></span></p><p>A
correlation <a shape="rect" href="expression.html">Expression</a> is used t
o determine the messages which should be aggregated together. If you want to
aggregate all messages into a single message, just use a constant expression.
An <strong><code>AggregationStrategy</code></strong> is used to combine
all the message exchanges for a single correlation key into a single message
exchange. The default strategy just chooses the latest message; so its ideal
for throttling messages.</p><p>For example, imagine a stock market data system;
you are receiving 30,000 messages per second; you may want to throttle down the
updates as, say, a GUI cannot cope with such massive update rates. So you may
want to aggregate these messages together so that within a window (defined by a
maximum number of messages or a timeout), messages for the same stock are
aggregated together; by just choosing the latest message and discarding the
older prices. (You could apply a delta processing algorithm if you prefer to
capture some of the history).</p><div class="confluence-informatio
n-macro confluence-information-macro-tip conf-macro output-block"
data-hasbody="true" data-macro-name="tip"><p class="title">Using the aggregator
correctly</p><span class="aui-icon aui-icon-small aui-iconfont-approve
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>Torsten Mielke wrote a nice <a
shape="rect" class="external-link"
href="http://tmielke.blogspot.com/2009/01/using-camel-aggregator-correctly.html"
rel="nofollow">blog entry</a> with his thoughts and experience on using the
aggreagator. Its a well worth read.</p></div></div><div
class="confluence-information-macro confluence-information-macro-information
conf-macro output-block" data-hasbody="true" data-macro-name="info"><p
class="title">AggregationStrategy changed in Camel 2.0</p><span class="aui-icon
aui-icon-small aui-iconfont-info confluence-information-macro-icon">
</span><div class="confluence-information-macro-body"><p>In Camel 2.0 the
<strong><code>AggregationStrategy</co
de></strong> callback have been changed to also be invoked on the very first
Exchange.</p><p>On the first invocation of the
<strong><code>aggregate</code></strong> method the
<strong><code>oldExchange</code></strong> parameter is
<strong><code>null</code></strong>. The reason is that we have not aggregated
anything yet.<br clear="none"> So its only the
<strong><code>newExchange</code></strong> that has a value. Usually you just
return the <strong><code>newExchange</code></strong> in this situation. But you
still have the power to decide what to do, for example you can do some
alternation on the exchange or remove some headers. And a more common use case
is for instance to count some values from the body payload. That could be to
sum up a total amount etc.</p></div></div><div
class="confluence-information-macro confluence-information-macro-warning
conf-macro output-block" data-hasbody="true" data-macro-name="warning"><p
class="title">BatchTimeout and CompletionPredicate</p><span clas
s="aui-icon aui-icon-small aui-iconfont-error
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>You cannot use
both <strong><code>batchTimeout</code></strong>
and <strong><code>completionPredicate</code></strong> to trigger a
completion based on either on reaching its goal first. The batch timeout will
always trigger first, at that given interval.</p></div></div><p><strong>Using
the <a shape="rect" href="fluent-builders.html">Fluent
Builders</a></strong></p><p>The following example shows how to aggregate
messages so that only the latest message for a specific value of the
<strong><code>cheese</code></strong> header are sent.</p><div class="error
conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>If you were using JMS then you may wish to use
the <strong><code>JMS
Destination</code></strong> header as the correlation key; or some custom
header for the stock symbol (using the above stock market example).<div
class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default"
data-theme="Default">from("activemq:someReallyFastTopic")
.aggregator(header("JMSDestination"))
.to("activemq:someSlowTopicForGuis");
</pre>
-</div></div><p>You can of course use many different <a shape="rect"
href="expression.html">Expression</a> languages such as <a shape="rect"
href="xpath.html">XPath</a>, <a shape="rect" href="xquery.html">XQuery</a>, <a
shape="rect" href="sql.html">SQL</a> or various <a shape="rect"
href="scripting-languages.html">Scripting Languages</a>. <br clear="none"> Here
is an example using <strong>XPath</strong>:</p><div class="code panel pdl
conf-macro output-block" data-hasbody="true" data-macro-name="code"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>You can of course use many different <a shape="rect"
href="expression.html">Expression</a> languages such as <a shape="rect"
href="xpath.html">XPath</a>, <a shape="rect" href="xquery.html">XQuery</a>, <a
shape="rect" href="sql.html">SQL</a> or various <a shape="rect"
href="scripting-languages.html">Scripting Languages</a>. <br clear="none"> Here
is an example using <strong>XPath</strong>:</p><div class="code panel pdl
conf-macro output-block" style="border-width: 1px;" data-hasbody="true"
data-macro-name="code"><div class="codeContent panelContent pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">//aggregate based on the
message content using an XPath expression
//example assumes an XML document starting with <stockQuote symbol='...'>
//aggregate messages based on their symbol attribute within the
<stockQuote> element
@@ -119,285 +104,22 @@ from("seda:start").aggregate().xpath("/s
//one exchange and all the other messages (different symbol or different root
element) into another exchange.
from("seda:start").aggregate().xpath("name(/stockQuote[@symbol='APACHE'])",
String.class).batchSize(5).to("mock:result");
</pre>
-</div></div><p>For further examples of this pattern in use you could look at
the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/camel/tags/camel-2.2.0/camel-core/src/test/java/org/apache/camel/processor/AggregatorTest.java?view=markup">junit
test case</a></p><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML Extensions</a></strong></p><div
class="confluence-information-macro confluence-information-macro-information
conf-macro output-block" data-hasbody="true" data-macro-name="info"><span
class="aui-icon aui-icon-small aui-iconfont-info
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>The <strong><code>correlationExpression</code></strong>
element is in Camel 2.0. For earlier versions of Camel you will need to
specify your expression without the
enclosing <strong><code>correlationExpression</code></strong>
element.</p><div class="code panel pdl conf-macro output-block" data-
hasbody="true" data-macro-name="code" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>For further examples of this pattern in use you could look at
the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/camel/tags/camel-2.2.0/camel-core/src/test/java/org/apache/camel/processor/AggregatorTest.java?view=markup">junit
test case</a></p><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML Extensions</a></strong></p><div
class="confluence-information-macro confluence-information-macro-information
conf-macro output-block" data-hasbody="true" data-macro-name="info"><span
class="aui-icon aui-icon-small aui-iconfont-info
confluence-information-macro-icon"> </span><div
class="confluence-information-macro-body"><p>The <strong><code>correlationExpression</code></strong>
element is in Camel 2.0. For earlier versions of Camel you will need to
specify your expression without the
enclosing <strong><code>correlationExpression</code></strong>
element.</p><div class="code panel pdl conf-macro output-block" style
="border-width: 1px;" data-hasbody="true" data-macro-name="code"><div
class="codeContent panelContent pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"><aggregator>
<simple>header.cheese</simple>
<to uri="mock:result"/>
</aggregator>
</pre>
-</div></div></div></div><p>The following example shows how to create a simple
aggregator using the XML notation; using an <a shape="rect"
href="expression.html">Expression</a> for the correlation value used to
aggregate messages together.Error rendering macro 'code': Invalid value
specified for parameter 'java.lang.NullPointerException'</p><pre
class="conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
- <route>
- <from uri="direct:start"/>
- <aggregate>
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- </aggregate>
- </route>
-
- <route>
- <from uri="seda:header"/>
- <process ref="setHeaderProcessor"/>
- <to uri="direct:temp"/>
- </route>
-
- <route>
- <from uri="direct:temp"/>
- <aggregate>
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- </aggregate>
- </route>
-
- <route>
- <from uri="direct:predicate"/>
- <aggregate strategyRef="myAggregatorStrategy">
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- <completionPredicate>
- <method bean="myAggregatorStrategy" method="isCompleted"/>
- </completionPredicate>
- </aggregate>
- </route>
-
- <route>
- <from uri="direct:outBatchPredicate"/>
- <aggregate strategyRef="myAggregatorStrategy" outBatchSize="10">
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- <completionPredicate>
- <method bean="myAggregatorStrategy" method="isCompleted"/>
- </completionPredicate>
- </aggregate>
- </route>
-
- <!-- This route turns off in batching by setting batchSize to 1 to run
unit test for out batching.
- Normal use cases may not want to disable in batching
- -->
- <route>
- <from uri="direct:outBatchNoInBatching"/>
- <aggregate strategyRef="myAggregatorStrategy" batchSize="1"
outBatchSize="10">
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- <completionPredicate>
- <method bean="myAggregatorStrategy" method="isCompleted"/>
- </completionPredicate>
- </aggregate>
- </route>
-</camelContext>
-</pre>You can specify your
own <strong><code>AggregationStrategy</code></strong> if you prefer as
shown in the following exampleError rendering macro 'code': Invalid value
specified for parameter 'java.lang.NullPointerException'<pre class="conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
- <route>
- <from uri="direct:start"/>
- <aggregate strategyRef="aggregatorStrategy">
- <correlationExpression>
- <simple>header.cheese</simple>
- </correlationExpression>
- <to uri="mock:result"/>
- </aggregate>
- </route>
-</camelContext>
-
-<bean id="aggregatorStrategy"
class="org.apache.camel.spring.processor.MyAggregator"/>
-</pre>Notice how the <strong><code>strategyRef</code></strong> attribute
is used on the <strong><code><aggregator></code></strong> element to
refer to the custom strategy in Spring.<h3
id="Aggregator-ExchangeProperties">Exchange Properties</h3><p>The following
properties is set on each Exchange that are aggregated:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>header</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>type</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>description</p></th></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>org.apache.camel.Exchange.AggregatedCount</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>int</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Camel 1.x: The total number of Exchanges
aggregated in this combined Exchange.</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><co
de>CamelAggregatedSize</code></p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>int</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Camel 2.0: The total number of Exchanges aggregated
into this combined Exchange.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>CamelAggregatedIndex</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>int</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Camel 2.0: The current index of this
Exchange in the batch.</p></td></tr></tbody></table></div><h3
id="Aggregator-Batchoptions">Batch options</h3><p>The aggregator supports the
following batch options:</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>Option</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>Default</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"
><p><code>batchSize</code></p></td><td colspan="1" rowspan="1"
>class="confluenceTd"><p><code>100</code></p></td><td colspan="1" rowspan="1"
>class="confluenceTd"><p>The <strong>in</strong> batch size. This is the
>number of incoming exchanges that is processed by the aggregator and when
>this threshold is reached the batch is completed and send.
></p><p><strong>Camel 1.6.2/2.0:</strong> You can disable the batch size so
>the Aggregator is only triggered by timeout by setting the
><strong><code>batchSize</code></strong> to 0 (or negative).</p><p>In
><strong>Camel 1.6.1</strong> or older you can set the
><strong><code>batchSize</code></strong> to a very large number to archive the
>same.</p></td></tr><tr><td colspan="1" rowspan="1"
>class="confluenceTd"><p><code>outBatchSize</code></p></td><td colspan="1"
>rowspan="1" class="confluenceTd"><p><code>0</code></p></td><td colspan="1"
>rowspan="1" class="confluenceTd"><p><strong>Camel 1.5:</strong> The
><strong>out</strong> batch size. This is the numb
er of exchanges currently aggregated in the
<strong><code>AggregationCollection</code></strong>. When this threshold is
reached the batch is completed and send. By default this option is disabled.
The difference to the <strong><code>batchSize</code></strong> options is that
this is for outgoing, so setting this size to e.g. 50 ensures that this batch
will at maximum contain 50 exchanges when its sent.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><code>batchTimeout</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>1000L</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Timeout in millis. How long should the
aggregator wait before its completed and sends whatever it has currently
aggregated.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>groupExchanges</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>false</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><
p><strong>Camel 2.0</strong>: If enabled then Camel will group all aggregated
Exchanges into a single combined
<strong><code>org.apache.camel.impl.GroupedExchange</code></strong> holder
class that holds all the aggregated Exchanges. And as a result only one
Exchange is being sent out from the aggregator. Can be used to combine many
incoming Exchanges into a single output Exchange without coding a
custom <strong><code>AggregationStrategy</code></strong>
yourself.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>batchConsumer</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>false</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Camel 2.0</strong>: This option is
if the exchanges is coming from a <a shape="rect"
href="batch-consumer.html">Batch Consumer</a>. Then when enabled the <a
shape="rect" href="aggregator.html">Aggregator</a> will use the batch size
determined by the <a shape="rect" href="batch-cons
umer.html">Batch Consumer</a> in the message header
<strong><code>CamelBatchSize</code></strong>. See more details at <a
shape="rect" href="batch-consumer.html">Batch Consumer</a>. This can be used to
aggregate all files consumed from a <a shape="rect" href="file2.html">File</a>
endpoint in that given poll.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>completionPredicate</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Allows you to use a <a
shape="rect" href="predicate.html">Predicate</a> to signal when an aggregation
is complete. See <strong>warning</strong> in top of this
page.</p></td></tr></tbody></table></div><h3
id="Aggregator-AggregationCollectionandAggregationStrategy"><code>AggregationCollection</code>
and <code>AggregationStrategy</code></h3><p>This aggregator uses
a <strong><code>AggregationCollection</code></strong> to store the exchang
es that is currently aggregated.
The <strong><code>AggregationCollection</code></strong> uses a correlation
<a shape="rect" href="expression.html">Expression</a> and an
<strong><code>AggregationStrategy</code></strong>.</p><ul
class="alternate"><li>The correlation <a shape="rect"
href="expression.html">Expression</a> is used to correlate the incoming
exchanges. The default implementation will group messages based on the
correlation expression. Other implementations could for instance just add all
exchanges as a batch.</li><li>The strategy is used for aggregate the old
(lookup by its correlation id) and the new exchanges together into a single
exchange. Possible implementations include performing some kind of combining or
delta processing, such as adding line items together into an invoice or just
using the newest exchange and removing old exchanges such as for state tracking
or market data prices; where old values are of little use.</li></ul><p>Camel
provides these implementati
ons:</p><ul
class="alternate"><li><strong><code>DefaultAggregationCollection</code></strong></li><li><strong><code>PredicateAggregationCollection</code></strong></li><li><strong><code>UseLatestAggregationStrategy</code></strong></li></ul><h3
id="Aggregator-Examples">Examples</h3><h4
id="Aggregator-Defaultexample">Default example</h4><p>By default Camel uses
<strong><code>DefaultAggregationCollection</code></strong> and
<strong><code>UseLatestAggregationStrategy</code></strong>, so this simple
example will just keep the latest received exchange for the given correlation
<a shape="rect" href="expression.html">Expression</a>:Error rendering macro
'code': Invalid value specified for parameter
'java.lang.NullPointerException'</p><pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-// our route is aggregating from the direct queue and sending the response to
the mock
-from("direct:start")
- // aggregated by header id
- // as we have not configured more on the aggregator it will default to
aggregate the
- // latest exchange only
- .aggregate().header("id")
- // wait for 0.5 seconds to aggregate
- .batchTimeout(500L)
- .to("mock:result");
-</pre><h4
id="Aggregator-UsingPredicateAggregationCollection">Using <code>PredicateAggregationCollection</code></h4><p>The <strong><code>PredicateAggregationCollection</code></strong>
is an extension
to <strong><code>DefaultAggregationCollection</code></strong> that uses a
<a shape="rect" href="predicate.html">Predicate</a> as well to determine the
completion. For instance the <a shape="rect"
href="predicate.html">Predicate</a> can test for a special header value, a
number of maximum aggregated so far etc. To use this the routing is a bit more
complex as we need to create
our <strong><code>AggregationCollection</code></strong> object as
follows:Error rendering macro 'code': Invalid value specified for parameter
'java.lang.NullPointerException'</p><pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-// create the aggregation collection we will use.
-// - we will correlate the received message based on the id header
-// - as we will just keep the latest message we use the latest strategy
-// - and finally we stop aggregate if we receive 2 or more messages
-AggregationCollection ag = new PredicateAggregationCollection(header("id"),
- new UseLatestAggregationStrategy(),
- property(Exchange.AGGREGATED_SIZE).isEqualTo(3));
-
-// our route is aggregating from the direct queue and sending the response to
the mock
-from("direct:start")
- // we use the collection based aggregator we already have configured
- .aggregate(ag)
- // wait for 0.5 seconds to aggregate
- .batchTimeout(500L)
- .to("mock:result");
-</pre>In this sample we use the predicate that we want at most 3 exchanges
aggregated by the same correlation id, this is defined as:<div class="code
panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div></div></div><p>The following example shows how to create a simple
aggregator using the XML notation; using an <a shape="rect"
href="expression.html">Expression</a> for the correlation value used to
aggregate messages together.</p><div class="error conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup"><span
class="error">Error formatting macro: snippet:
java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>You can
specify your own <strong><code>AggregationStrategy</code></strong> if you
prefer as shown in the following example<div class="error conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>Notice how
the <strong><code>strategyRef</code></strong> attribute is used on
the <strong><code><aggregator></code></strong> element to refer
to the custom strategy in Spring.<h3
id="Aggregator-ExchangeProperties">Exchange Properties</h3><p>The following
properties is set on each Exchange that are aggregated:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>header</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>type</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>description</p></th></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>org.apache.camel.Exchange.AggregatedCount</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>int</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Camel 1.x: The total number of Exchanges
aggregated in this combined Exchange.</p></td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>CamelAggregatedSize</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>int</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Camel 2.0:
The total number of Exchanges aggregated into this combined
Exchange.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>CamelAggregatedIndex</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>int</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Camel 2.0: The current index of this
Exchange in the batch.</p></td></tr></tbody></table></div><h3
id="Aggregator-Batchoptions">Batch options</h3><p>The aggregator supports the
following batch options:</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>Option</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>Default</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>batchSize</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p><code>100</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>
The <strong>in</strong> batch size. This is the number of incoming exchanges
that is processed by the aggregator and when this threshold is reached the
batch is completed and send. </p><p><strong>Camel 1.6.2/2.0:</strong> You can
disable the batch size so the Aggregator is only triggered by timeout by
setting the <strong><code>batchSize</code></strong> to 0 (or
negative).</p><p>In <strong>Camel 1.6.1</strong> or older you can set the
<strong><code>batchSize</code></strong> to a very large number to archive the
same.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>outBatchSize</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>0</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Camel 1.5:</strong> The
<strong>out</strong> batch size. This is the number of exchanges currently
aggregated in the <strong><code>AggregationCollection</code></strong>. When
this threshold is reached the batch is completed and send. By
default this option is disabled. The difference to the
<strong><code>batchSize</code></strong> options is that this is for outgoing,
so setting this size to e.g. 50 ensures that this batch will at maximum contain
50 exchanges when its sent.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>batchTimeout</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>1000L</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Timeout in millis. How long should the
aggregator wait before its completed and sends whatever it has currently
aggregated.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>groupExchanges</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>false</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Camel 2.0</strong>: If enabled then
Camel will group all aggregated Exchanges into a single combined
<strong><code>org.apache.camel.impl.GroupedExchange</
code></strong> holder class that holds all the aggregated Exchanges. And as a
result only one Exchange is being sent out from the aggregator. Can be used to
combine many incoming Exchanges into a single output Exchange without coding a
custom <strong><code>AggregationStrategy</code></strong>
yourself.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>batchConsumer</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><code>false</code></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Camel 2.0</strong>: This option is
if the exchanges is coming from a <a shape="rect"
href="batch-consumer.html">Batch Consumer</a>. Then when enabled the <a
shape="rect" href="aggregator.html">Aggregator</a> will use the batch size
determined by the <a shape="rect" href="batch-consumer.html">Batch Consumer</a>
in the message header <strong><code>CamelBatchSize</code></strong>. See more
details at <a shape="rect" href="batch-consumer.html">Bat
ch Consumer</a>. This can be used to aggregate all files consumed from a <a
shape="rect" href="file2.html">File</a> endpoint in that given
poll.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>completionPredicate</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Allows you to use a <a
shape="rect" href="predicate.html">Predicate</a> to signal when an aggregation
is complete. See <strong>warning</strong> in top of this
page.</p></td></tr></tbody></table></div><h3
id="Aggregator-AggregationCollectionandAggregationStrategy"><code>AggregationCollection</code>
and <code>AggregationStrategy</code></h3><p>This aggregator uses
a <strong><code>AggregationCollection</code></strong> to store the
exchanges that is currently aggregated.
The <strong><code>AggregationCollection</code></strong> uses a correlation
<a shape="rect" href="expression.html">Expression</
a> and an <strong><code>AggregationStrategy</code></strong>.</p><ul
class="alternate"><li>The correlation <a shape="rect"
href="expression.html">Expression</a> is used to correlate the incoming
exchanges. The default implementation will group messages based on the
correlation expression. Other implementations could for instance just add all
exchanges as a batch.</li><li>The strategy is used for aggregate the old
(lookup by its correlation id) and the new exchanges together into a single
exchange. Possible implementations include performing some kind of combining or
delta processing, such as adding line items together into an invoice or just
using the newest exchange and removing old exchanges such as for state tracking
or market data prices; where old values are of little use.</li></ul><p>Camel
provides these implementations:</p><ul
class="alternate"><li><strong><code>DefaultAggregationCollection</code></strong></li><li><strong><code>PredicateAggregationCollection</code></strong></l
i><li><strong><code>UseLatestAggregationStrategy</code></strong></li></ul><h3
id="Aggregator-Examples">Examples</h3><h4
id="Aggregator-Defaultexample">Default example</h4><p>By default Camel uses
<strong><code>DefaultAggregationCollection</code></strong> and
<strong><code>UseLatestAggregationStrategy</code></strong>, so this simple
example will just keep the latest received exchange for the given correlation
<a shape="rect" href="expression.html">Expression</a>:</p><div class="error
conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><h4
id="Aggregator-UsingPredicateAggregationCollection">Using <code>PredicateAggregationCollection</code></h4><p>The <strong><code>PredicateAggregationCollection</code></strong>
is an extension
to <strong><code>DefaultAggregationCollection</code></strong> that uses a
<a shape=
"rect" href="predicate.html">Predicate</a> as well to determine the
completion. For instance the <a shape="rect"
href="predicate.html">Predicate</a> can test for a special header value, a
number of maximum aggregated so far etc. To use this the routing is a bit more
complex as we need to create
our <strong><code>AggregationCollection</code></strong> object as
follows:</p><div class="error conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>In this sample we use the predicate that we want at most
3 exchanges aggregated by the same correlation id, this is defined as:<div
class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default"
data-theme="Default">header(Exchange.AGGREGATED_COUNT).isEqualTo(3)
</pre>
-</div></div><p>Using this the aggregator will complete if we receive 3
exchanges with the same correlation id or when the specified timeout of 500
msecs has elapsed (whichever criteria is met first).</p><h4
id="Aggregator-UsingCustomAggregationStrategy">Using Custom Aggregation
Strategy</h4><p>In this example we will aggregate incoming bids and want to
aggregate the highest bid. So we provide our own strategy where we implement
the code logic:Error rendering macro 'code': Invalid value specified for
parameter 'java.lang.NullPointerException'</p><pre class="conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-private static class MyAggregationStrategy implements AggregationStrategy {
-
- public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
- if (oldExchange == null) {
- // the first time we only have the new exchange so it wins the
first round
- return newExchange;
- }
- int oldPrice = oldExchange.getIn().getBody(Integer.class);
- int newPrice = newExchange.getIn().getBody(Integer.class);
- // return the "winner" that has the highest price
- return newPrice > oldPrice ? newExchange : oldExchange;
- }
-}
-</pre>Then we setup the routing as follows:Error rendering macro 'code':
Invalid value specified for parameter 'java.lang.NullPointerException'<pre
class="conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-// our route is aggregating from the direct queue and sending the response to
the mock
-from("direct:start")
- // aggregated by header id and use our own strategy how to aggregate
- .aggregate(new MyAggregationStrategy()).header("id")
- // wait for 0.5 seconds to aggregate
- .batchTimeout(500L)
- .to("mock:result");
-</pre>And since this is based on an unit test we show the test code that send
the bids and what is expected as the
<strong><code>winners</code></strong>:Error rendering macro 'code': Invalid
value specified for parameter 'java.lang.NullPointerException'<pre
class="conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-MockEndpoint result = getMockEndpoint("mock:result");
-
-// we expect to find the two winners with the highest bid
-result.expectedMessageCount(2);
-result.expectedBodiesReceived("200", "150");
-
-// then we sent all the message at once
-template.sendBodyAndHeader("direct:start", "100", "id", "1");
-template.sendBodyAndHeader("direct:start", "150", "id", "2");
-template.sendBodyAndHeader("direct:start", "130", "id", "2");
-template.sendBodyAndHeader("direct:start", "200", "id", "1");
-template.sendBodyAndHeader("direct:start", "190", "id", "1");
-
-assertMockEndpointsSatisfied();
-</pre><h4 id="Aggregator-UsingCustomAggregationCollection">Using Custom
Aggregation Collection</h4><p>In this example we will aggregate incoming bids
and want to aggregate the bids in reverse order (this is just an example). So
we provide our own collection where we implement the code logic:Error rendering
macro 'code': Invalid value specified for parameter
'java.lang.NullPointerException'</p><pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-class MyReverseAggregationCollection extends
AbstractCollection<Exchange> implements AggregationCollection {
-
- private List<Exchange> collection = new ArrayList<Exchange>();
- private Expression correlation;
- private AggregationStrategy strategy;
-
- public Expression getCorrelationExpression() {
- return correlation;
- }
-
- public void setCorrelationExpression(Expression correlationExpression) {
- this.correlation = correlationExpression;
- }
-
- public AggregationStrategy getAggregationStrategy() {
- return strategy;
- }
-
- public void setAggregationStrategy(AggregationStrategy
aggregationStrategy) {
- this.strategy = aggregationStrategy;
- }
-
- public boolean add(Exchange exchange) {
- return collection.add(exchange);
- }
-
- public Iterator<Exchange> iterator() {
- // demonstrate the we can do something with this collection, so we
reverse it
- Collections.reverse(collection);
-
- return collection.iterator();
- }
-
- public int size() {
- return collection.size();
- }
-
- public void clear() {
- collection.clear();
- }
-
- public void onAggregation(Object correlationKey, Exchange newExchange) {
- add(newExchange);
- }
-}
-</pre>Then we setup the routing as follows:Error rendering macro 'code':
Invalid value specified for parameter 'java.lang.NullPointerException'<pre
class="conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-// our route is aggregating from the direct queue and sending the response to
the mock
-from("direct:start")
- // use our own collection for aggregation
- .aggregate(new MyReverseAggregationCollection())
- // wait for 0.5 seconds to aggregate
- .batchTimeout(500L)
- .to("mock:result");
-</pre>And since this is based on an unit test we show the test code that send
the bids and what is expected as the expected reverse order:Error rendering
macro 'code': Invalid value specified for parameter
'java.lang.NullPointerException'<pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-MockEndpoint result = getMockEndpoint("mock:result");
-
-// we expect 5 messages since our custom aggregation collection just gets it
all
-// but returns them in reverse order
-result.expectedMessageCount(5);
-result.expectedBodiesReceived("190", "200", "130", "150", "100");
-
-// then we sent all the message at once
-template.sendBodyAndHeader("direct:start", "100", "id", "1");
-template.sendBodyAndHeader("direct:start", "150", "id", "2");
-template.sendBodyAndHeader("direct:start", "130", "id", "2");
-template.sendBodyAndHeader("direct:start", "200", "id", "1");
-template.sendBodyAndHeader("direct:start", "190", "id", "1");
-
-assertMockEndpointsSatisfied();
-</pre><h5 id="Aggregator-CustomaggregationcollectioninSpringDSL">Custom
aggregation collection in Spring DSL</h5><p>You can also specify a custom
aggregation collection in the Spring DSL. Here is an example for Camel 2.0Error
rendering macro 'code': Invalid value specified for parameter
'java.lang.NullPointerException'</p><pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
- <route>
- <from uri="direct:start"/>
- <aggregate batchTimeout="500" collectionRef="aggregatorCollection">
- <to uri="mock:result"/>
- </aggregate>
- </route>
-</camelContext>
-
-<bean id="aggregatorCollection"
class="org.apache.camel.processor.aggregator.MyReverseAggregationCollection"/>
-</pre>In Camel 1.5.1 you will need to specify the aggregator as:<div
class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>Using this the aggregator will complete if we receive 3
exchanges with the same correlation id or when the specified timeout of 500
msecs has elapsed (whichever criteria is met first).</p><h4
id="Aggregator-UsingCustomAggregationStrategy">Using Custom Aggregation
Strategy</h4><p>In this example we will aggregate incoming bids and want to
aggregate the highest bid. So we provide our own strategy where we implement
the code logic:</p><div class="error conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup"><span
class="error">Error formatting macro: snippet:
java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Then we
setup the routing as follows:<div class="error conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup"><span
class="error">Error formatting macro: snippet:
java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And since
this is based on an unit test
we show the test code that send the bids and what is expected as the
<strong><code>winners</code></strong>:<div class="error conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><h4
id="Aggregator-UsingCustomAggregationCollection">Using Custom Aggregation
Collection</h4><p>In this example we will aggregate incoming bids and want to
aggregate the bids in reverse order (this is just an example). So we provide
our own collection where we implement the code logic:</p><div class="error
conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>Then we setup the routing as follows:<div class="error
conf-macro output-inline" data-hasbody="true" data-macro-name="unmigrated-
inline-wiki-markup"><span class="error">Error formatting macro: snippet:
java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And since
this is based on an unit test we show the test code that send the bids and what
is expected as the expected reverse order:<div class="error conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><h5
id="Aggregator-CustomaggregationcollectioninSpringDSL">Custom aggregation
collection in Spring DSL</h5><p>You can also specify a custom aggregation
collection in the Spring DSL. Here is an example for Camel 2.0</p><div
class="error conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>In Camel 1.5.1 you will need to sp
ecify the aggregator as:<div class="code panel pdl conf-macro output-block"
style="border-width: 1px;" data-hasbody="true" data-macro-name="code"><div
class="codeContent panelContent pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"><aggregator
batchTimeout="500" collectionRef="aggregatorCollection">
<expression/>
<to uri="mock:result"/>
</aggregator>
</pre>
-</div></div><h4 id="Aggregator-UsingGroupedExchanges">Using Grouped
Exchanges</h4><p><strong>Available as of Camel 2.0</strong></p><p>You can
enable grouped exchanges to combine all aggregated exchanges into a single
<strong><code>org.apache.camel.impl.GroupedExchange</code></strong> holder
class that contains all the individual aggregated exchanges. This allows you to
process a single Exchange containing all the aggregated exchange. Lets start
with how to configure this in the router:Error rendering macro 'code': Invalid
value specified for parameter 'java.lang.NullPointerException'</p><pre
class="conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup">
-// our route is aggregating from the direct queue and sending the response to
the mock
-from("direct:start")
- // aggregate all using same expression
- .aggregate().constant(true)
- // wait for 0.5 seconds to aggregate
- .batchTimeout(500L)
- // group the exchanges so we get one single exchange containing all the
others
- .groupExchanges()
- .to("mock:result");
-</pre>And the next part is part of an unit code that demonstrates this feature
as we send in 5 exchanges each with a different value in the body. And we will
only get 1 exchange out of the aggregator, but we can access all the individual
aggregated exchanges from the List which we can extract as a property from the
Exchange using the key
<strong><code>Exchange.GROUPED_EXCHANGE</code></strong>.Error rendering macro
'code': Invalid value specified for parameter
'java.lang.NullPointerException'<pre class="conf-macro output-inline"
data-hasbody="true" data-macro-name="unmigrated-inline-wiki-markup">
-MockEndpoint result = getMockEndpoint("mock:result");
-
-// we expect 1 messages since we group all we get in using the same
correlation key
-result.expectedMessageCount(1);
-
-// then we sent all the message at once
-template.sendBody("direct:start", "100");
-template.sendBody("direct:start", "150");
-template.sendBody("direct:start", "130");
-template.sendBody("direct:start", "200");
-template.sendBody("direct:start", "190");
-
-assertMockEndpointsSatisfied();
-
-Exchange out = result.getExchanges().get(0);
-List<Exchange> grouped = out.getProperty(Exchange.GROUPED_EXCHANGE,
List.class);
-
-assertEquals(5, grouped.size());
-
-assertEquals("100", grouped.get(0).getIn().getBody(String.class));
-assertEquals("150", grouped.get(1).getIn().getBody(String.class));
-assertEquals("130", grouped.get(2).getIn().getBody(String.class));
-assertEquals("200", grouped.get(3).getIn().getBody(String.class));
-assertEquals("190", grouped.get(4).getIn().getBody(String.class));
-</pre><h4 id="Aggregator-UsingBatchConsumer">Using Batch
Consumer</h4><p><strong>Available as of Camel 2.0</strong></p><p>The <a
shape="rect" href="aggregator.html">Aggregator</a> can work together with the
<a shape="rect" href="batch-consumer.html">Batch Consumer</a> to aggregate the
total number of messages that the <a shape="rect"
href="batch-consumer.html">Batch Consumer</a> have reported. This allows you
for instance to aggregate all files polled using the <a shape="rect"
href="file2.html">File</a> consumer.</p><p>For example:</p><div class="code
panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><h4 id="Aggregator-UsingGroupedExchanges">Using Grouped
Exchanges</h4><p><strong>Available as of Camel 2.0</strong></p><p>You can
enable grouped exchanges to combine all aggregated exchanges into a single
<strong><code>org.apache.camel.impl.GroupedExchange</code></strong> holder
class that contains all the individual aggregated exchanges. This allows you to
process a single Exchange containing all the aggregated exchange. Lets start
with how to configure this in the router:</p><div class="error conf-macro
output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div>And the next part is part of an unit code that
demonstrates this feature as we send in 5 exchanges each with a different value
in the body. And we will only get 1 exchange out of the aggregator, but we can
access all the individual aggregated exchanges from the List w
hich we can extract as a property from the Exchange using the key
<strong><code>Exchange.GROUPED_EXCHANGE</code></strong>.<div class="error
conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><h4 id="Aggregator-UsingBatchConsumer">Using Batch
Consumer</h4><p><strong>Available as of Camel 2.0</strong></p><p>The <a
shape="rect" href="aggregator.html">Aggregator</a> can work together with the
<a shape="rect" href="batch-consumer.html">Batch Consumer</a> to aggregate the
total number of messages that the <a shape="rect"
href="batch-consumer.html">Batch Consumer</a> have reported. This allows you
for instance to aggregate all files polled using the <a shape="rect"
href="file2.html">File</a> consumer.</p><p>For example:</p><div class="code
panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-m
acro-name="code"><div class="codeContent panelContent pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">from("file://inbox")
.aggregate(xpath("//order/@customerId"), new
AggregateCustomerOrderStrategy()).batchConsumer().batchTimeout(60000).to("bean:processOrder");
</pre>
Modified: websites/production/camel/content/bam-example.html
==============================================================================
--- websites/production/camel/content/bam-example.html (original)
+++ websites/production/camel/content/bam-example.html Tue Mar 26 22:22:28 2019
@@ -89,11 +89,11 @@
<tbody>
<tr>
<td valign="top" width="100%">
-<div class="wiki-content maincontent"><h2
id="BAMExample-BusinessActivityMonitor(BAM)Example">Business Activity Monitor
(BAM) Example</h2><p>The <a shape="rect" href="bam.html">BAM</a> (Business
Activity Monitor) example shows how to monitor your transaction flows using
Camel.</p><p>In this example we will use Camel to monitor a business process
consisting of</p><ul><li>purchase orders</li><li>invoices</li></ul><p>Then we
will check to see that for every purchase order created by system A, that
system B will generate an invoice within the specified amount of time (2
seconds in this example). If an invoice is not generated within the allowed
amount of time and error is generated and sent to an <a shape="rect"
href="endpoint.html">Endpoint</a>.</p><h3
id="BAMExample-Overview">Overview</h3><p>This example lives in the
<em>examples/camel-example-bam</em> directory. It will poll the following
directories</p><ul><li>the child <em>src/data/purchaseOrders</em> directory for
XML purchase ord
ers</li><li>the child <em>src/data/invoices</em> directory for XML
invoices</li></ul><p>The <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/java/org/apache/camel/example/bam/MyActivities.java">MyActivities</a>
class defines the <a shape="rect" href="bam.html">BAM</a> activities; that
is</p><ul><li>the input sources (the two directories above) which could be any
of the supported camel <a shape="rect" href="uris.html">URIs</a></li><li>how
the activities relate to each other - namely the <a shape="rect"
href="correlation-identifier.html">Correlation Identifier</a>
pattern</li><li>the maixmum amount of time allowed from the time a purchase
order is received when if an invoice is not received an error should be
raised.</li></ul><p>There is also a spring configuration file in <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/resources/META-I
NF/spring/camel-context.xml">src/resources/META-INF/services/camel-context.xml</a>
which defines the JPA <code>EntityManagerFactory</code> and tells Camel to
look in the <strong>org.apache.camel.example.bam</strong> package to find its
routes.</p><h3 id="BAMExample-Codewalkthrough">Code walkthrough</h3><p>So lets
start with the activities definition in <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/java/org/apache/camel/example/bam/MyActivities.java">MyActivities</a></p><div
class="error conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><p>The first two lines of code sets up the inputs for the
<a shape="rect" href="bam.html">BAM</a> activities via the
<strong>activity()</strong> method which defines</p><ul><li>the <a shape="rect"
href="uris.ht
ml">URIs</a> of the inputs (which could come from any of the Camel <a
shape="rect" href="components.html">Components</a></li><li>the <a shape="rect"
href="correlation-identifier.html">Correlation Identifier</a> used to correlate
together the purchase order and invoice messages which can be any <a
shape="rect" href="expression.html">Expression</a> via any of the <a
shape="rect" href="languages-supported.html">Languages Supported</a>. In this
case we are using <a shape="rect" href="xpath.html">XPath</a>.</li></ul><p>Then
the final line of code defines the temporal rules to use; namely that it is
considered to be an error if an invoice is not received within 2 seconds of a
purchase order being received. When a failure occurs in this example we just
send it to the <a shape="rect" href="log.html">Log</a> component to log out an
error level message to commons-logging / log4j. You could change this to use
some of the other <a shape="rect" href="components.html">Components</a> such as
<a sh
ape="rect" href="activemq.html">ActiveMQ</a>, <a shape="rect"
href="jms.html">JMS</a>, <a shape="rect" href="irc.html">IRC</a>, <a
shape="rect" href="mail.html">Mail</a>, <a shape="rect"
href="xmpp.html">XMPP</a> etc.</p><h3 id="BAMExample-Runningtheexample">Running
the example</h3><p>To run the example we use the <a shape="rect"
href="camel-maven-plugin.html">Camel Maven Plugin</a>. For example from the
source or binary distribution the following should work</p><div class="code
panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<div class="wiki-content maincontent"><h2
id="BAMExample-BusinessActivityMonitor(BAM)Example">Business Activity Monitor
(BAM) Example</h2><p>The <a shape="rect" href="bam.html">BAM</a> (Business
Activity Monitor) example shows how to monitor your transaction flows using
Camel.</p><p>In this example we will use Camel to monitor a business process
consisting of</p><ul><li>purchase orders</li><li>invoices</li></ul><p>Then we
will check to see that for every purchase order created by system A, that
system B will generate an invoice within the specified amount of time (2
seconds in this example). If an invoice is not generated within the allowed
amount of time and error is generated and sent to an <a shape="rect"
href="endpoint.html">Endpoint</a>.</p><h3
id="BAMExample-Overview">Overview</h3><p>This example lives in the
<em>examples/camel-example-bam</em> directory. It will poll the following
directories</p><ul><li>the child <em>src/data/purchaseOrders</em> directory for
XML purchase ord
ers</li><li>the child <em>src/data/invoices</em> directory for XML
invoices</li></ul><p>The <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/java/org/apache/camel/example/bam/MyActivities.java">MyActivities</a>
class defines the <a shape="rect" href="bam.html">BAM</a> activities; that
is</p><ul><li>the input sources (the two directories above) which could be any
of the supported camel <a shape="rect" href="uris.html">URIs</a></li><li>how
the activities relate to each other - namely the <a shape="rect"
href="correlation-identifier.html">Correlation Identifier</a>
pattern</li><li>the maixmum amount of time allowed from the time a purchase
order is received when if an invoice is not received an error should be
raised.</li></ul><p>There is also a spring configuration file in <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/resources/META-I
NF/spring/camel-context.xml">src/resources/META-INF/services/camel-context.xml</a>
which defines the JPA <code>EntityManagerFactory</code> and tells Camel to
look in the <strong>org.apache.camel.example.bam</strong> package to find its
routes.</p><h3 id="BAMExample-Codewalkthrough">Code walkthrough</h3><p>So lets
start with the activities definition in <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-bam/src/main/java/org/apache/camel/example/bam/MyActivities.java">MyActivities</a></p><div
class="error conf-macro output-inline" data-hasbody="true"
data-macro-name="unmigrated-inline-wiki-markup"><span class="error">Error
formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20,
Size: 20</span> </div><p>The first two lines of code sets up the inputs for the
<a shape="rect" href="bam.html">BAM</a> activities via the
<strong>activity()</strong> method which defines</p><ul><li>the <a shape="rect"
href="uris.ht
ml">URIs</a> of the inputs (which could come from any of the Camel <a
shape="rect" href="components.html">Components</a></li><li>the <a shape="rect"
href="correlation-identifier.html">Correlation Identifier</a> used to correlate
together the purchase order and invoice messages which can be any <a
shape="rect" href="expression.html">Expression</a> via any of the <a
shape="rect" href="languages-supported.html">Languages Supported</a>. In this
case we are using <a shape="rect" href="xpath.html">XPath</a>.</li></ul><p>Then
the final line of code defines the temporal rules to use; namely that it is
considered to be an error if an invoice is not received within 2 seconds of a
purchase order being received. When a failure occurs in this example we just
send it to the <a shape="rect" href="log.html">Log</a> component to log out an
error level message to commons-logging / log4j. You could change this to use
some of the other <a shape="rect" href="components.html">Components</a> such as
<a sh
ape="rect" href="activemq.html">ActiveMQ</a>, <a shape="rect"
href="jms.html">JMS</a>, <a shape="rect" href="irc.html">IRC</a>, <a
shape="rect" href="mail.html">Mail</a>, <a shape="rect"
href="xmpp.html">XMPP</a> etc.</p><h3 id="BAMExample-Runningtheexample">Running
the example</h3><p>To run the example we use the <a shape="rect"
href="camel-maven-plugin.html">Camel Maven Plugin</a>. For example from the
source or binary distribution the following should work</p><div class="code
panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">cd
examples/camel-example-bam
mvn camel:run
</pre>
-</div></div><p>If you prefer you can just run the Main directly using</p><div
class="code panel pdl conf-macro output-block" data-hasbody="true"
data-macro-name="code" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>If you prefer you can just run the Main directly using</p><div
class="code panel pdl conf-macro output-block" style="border-width: 1px;"
data-hasbody="true" data-macro-name="code"><div class="codeContent panelContent
pdl">
<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">mvn compile exec:java
</pre>
</div></div><p>Failing that you can run the Main from inside your IDE if you
prefer. Follow the <a shape="rect" href="building.html">Building</a>
instructions to create an Eclipse/IDEA project to import</p></div>