Modified: websites/production/camel/content/resequencer.html
==============================================================================
--- websites/production/camel/content/resequencer.html (original)
+++ websites/production/camel/content/resequencer.html Fri Aug 25 09:20:43 2017
@@ -36,17 +36,6 @@
<![endif]-->
- <link href='//camel.apache.org/styles/highlighter/styles/shCoreCamel.css'
rel='stylesheet' type='text/css' />
- <link href='//camel.apache.org/styles/highlighter/styles/shThemeCamel.css'
rel='stylesheet' type='text/css' />
- <script src='//camel.apache.org/styles/highlighter/scripts/shCore.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushJava.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushXml.js'
type='text/javascript'></script>
- <script src='//camel.apache.org/styles/highlighter/scripts/shBrushPlain.js'
type='text/javascript'></script>
-
- <script type="text/javascript">
- SyntaxHighlighter.defaults['toolbar'] = false;
- SyntaxHighlighter.all();
- </script>
<title>
Apache Camel: Resequencer
@@ -86,139 +75,60 @@
<tbody>
<tr>
<td valign="top" width="100%">
-<div class="wiki-content maincontent"><h3
id="Resequencer-Resequencer">Resequencer</h3><p>The <a shape="rect"
class="external-link"
href="http://www.enterpriseintegrationpatterns.com/Resequencer.html"
rel="nofollow">Resequencer</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> allows you to
reorganise messages based on some comparator. By default in Camel we use an <a
shape="rect" href="expression.html">Expression</a> to create the comparator; so
that you can compare by a message header or the body or a piece of a message
etc.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/Resequencer.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/Resequencer.gif"></span></p><div
class="confluence-information-macro confluence-information-macro-tip"><p
class="title">Change in Camel 2.7</p><span class="aui-icon au
i-icon-small aui-iconfont-approve
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>The
<code><batch-config></code> and <code><stream-config></code> tags
in XML DSL in the Resequencer EIP must now be configured in the top, and not in
the bottom. So if you use those, then move them up just below the
<code><resequence></code> EIP starts in the XML. If you are using Camel
older than 2.7, then those configs should be at the
bottom.</p></div></div><p>Camel supports two resequencing
algorithms:</p><ul><li><strong>Batch resequencing</strong> collects messages
into a batch, sorts the messages and sends them to their
output.</li><li><strong>Stream resequencing</strong> re-orders (continuous)
message streams based on the detection of gaps between messages.</li></ul><p>By
default the <a shape="rect" href="resequencer.html">Resequencer</a> does not
support duplicate messages and will only keep the last message, in case a
message arrive
s with the same message expression. However in the batch mode you can enable
it to allow duplicates.</p><h3 id="Resequencer-BatchResequencing">Batch
Resequencing</h3><p>The following example shows how to use the batch-processing
resequencer so that messages are sorted in order of the <strong>body()</strong>
expression. That is messages are collected into a batch (either by a maximum
number of messages per batch or using a timeout) then they are sorted in order
and then sent out to their output.</p><p><strong>Using the <a shape="rect"
href="fluent-builders.html">Fluent Builders</a></strong></p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-from("direct:start")
- .resequence().body().timeout(50)
- .to("mock:result");
-]]></script>
-</div></div>This is equivalent to<div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
+<div class="wiki-content maincontent"><h3
id="Resequencer-Resequencer">Resequencer</h3><p>The <a shape="rect"
class="external-link"
href="http://www.enterpriseintegrationpatterns.com/Resequencer.html"
rel="nofollow">Resequencer</a> from the <a shape="rect"
href="enterprise-integration-patterns.html">EIP patterns</a> allows you to
reorganise messages based on some comparator. By default in Camel we use an <a
shape="rect" href="expression.html">Expression</a> to create the comparator; so
that you can compare by a message header or the body or a piece of a message
etc.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://www.enterpriseintegrationpatterns.com/img/Resequencer.gif"
data-image-src="http://www.enterpriseintegrationpatterns.com/img/Resequencer.gif"></span></p><parameter
ac:name="title">Change in Camel 2.7</parameter><rich-text-body><p>The
<code><batch-config></code> and <code><stream-con
fig></code> tags in XML DSL in the Resequencer EIP must now be configured
in the top, and not in the bottom. So if you use those, then move them up just
below the <code><resequence></code> EIP starts in the XML. If you are
using Camel older than 2.7, then those configs should be at the
bottom.</p></rich-text-body><p>Camel supports two resequencing
algorithms:</p><ul><li><strong>Batch resequencing</strong> collects messages
into a batch, sorts the messages and sends them to their
output.</li><li><strong>Stream resequencing</strong> re-orders (continuous)
message streams based on the detection of gaps between messages.</li></ul><p>By
default the <a shape="rect" href="resequencer.html">Resequencer</a> does not
support duplicate messages and will only keep the last message, in case a
message arrives with the same message expression. However in the batch mode you
can enable it to allow duplicates.</p><h3
id="Resequencer-BatchResequencing">Batch Resequencing</h3><p>The following
example shows how to use the batch-processing resequencer so that messages are
sorted in order of the <strong>body()</strong> expression. That is messages are
collected into a batch (either by a maximum number of messages per batch or
using a timeout) then they are sorted in order and then sent out to their
output.</p><p><strong>Using the <a shape="rect"
href="fluent-builders.html">Fluent
Builders</a></strong><plain-text-body>{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java}</plain-text-body>This
is equivalent to</p><plain-text-body>from("direct:start")
.resequence(body()).batch()
- .to("mock:result");
-]]></script>
-</div></div><p>The batch-processing resequencer can be further configured via
the <code>size()</code> and <code>timeout()</code> methods.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
+ .to("mock:result");
+</plain-text-body><p>The batch-processing resequencer can be further
configured via the <code>size()</code> and <code>timeout()</code>
methods.</p><plain-text-body>from("direct:start")
.resequence(body()).batch().size(300).timeout(4000L)
- .to("mock:result")
-]]></script>
-</div></div><p>This sets the batch size to 300 and the batch timeout to 4000
ms (by default, the batch size is 100 and the timeout is 1000 ms).
Alternatively, you can provide a configuration object.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
+ .to("mock:result")
+</plain-text-body><p>This sets the batch size to 300 and the batch timeout to
4000 ms (by default, the batch size is 100 and the timeout is 1000 ms).
Alternatively, you can provide a configuration
object.</p><plain-text-body>from("direct:start")
.resequence(body()).batch(new BatchResequencerConfig(300, 4000L))
- .to("mock:result")
-]]></script>
-</div></div><p>So the above example will reorder messages from endpoint
<strong>direct:a</strong> in order of their bodies, to the endpoint
<strong>mock:result</strong>. <br clear="none"> Typically you'd use a header
rather than the body to order things; or maybe a part of the body. So you could
replace this expression with</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[resequencer(header("mySeqNo"))
-]]></script>
-</div></div><p>for example to reorder messages using a custom sequence number
in the header <code>mySeqNo</code>.</p><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>.</p><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML Extensions</a></strong></p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: xml; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[<camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
+ .to("mock:result")
+</plain-text-body><p>So the above example will reorder messages from endpoint
<strong>direct:a</strong> in order of their bodies, to the endpoint
<strong>mock:result</strong>. <br clear="none"> Typically you'd use a header
rather than the body to order things; or maybe a part of the body. So you could
replace this expression with</p><plain-text-body>resequencer(header("mySeqNo"))
+</plain-text-body><p>for example to reorder messages using a custom sequence
number in the header <code>mySeqNo</code>.</p><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>.</p><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML
Extensions</a></strong></p><parameter
ac:name="">xml</parameter><plain-text-body><camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
<route>
- <from uri="direct:start" />
+ <from uri="direct:start" />
<resequence>
<simple>body</simple>
- <to uri="mock:result" />
+ <to uri="mock:result" />
<!--
batch-config can be ommitted for default (batch) resequencer settings
-->
- <batch-config batchSize="300" batchTimeout="4000"
/>
+ <batch-config batchSize="300" batchTimeout="4000" />
</resequence>
</route>
</camelContext>
-]]></script>
-</div></div><h4 id="Resequencer-AllowDuplicates">Allow
Duplicates</h4><p><strong>Available as of Camel 2.4</strong></p><p>In the
<code>batch</code> mode, you can now allow duplicates. In Java DSL there is a
<code>allowDuplicates()</code> method and in Spring XML there is an
<code>allowDuplicates=true</code> attribute on the
<code><batch-config/></code> you can use to enable it.</p><h4
id="Resequencer-Reverse">Reverse</h4><p><strong>Available as of Camel
2.4</strong></p><p>In the <code>batch</code> mode, you can now reverse the
expression ordering. By default the order is based on 0..9,A..Z, which would
let messages with low numbers be ordered first, and thus also also outgoing
first. In some cases you want to reverse order, which is now possible.</p><p>In
Java DSL there is a <code>reverse()</code> method and in Spring XML there is an
<code>reverse=true</code> attribute on the <code><batch-config/></code>
you can use to enable it.</p><h4 id="Resequencer-ResequenceJMSmessa
gesbasedonJMSPriority">Resequence JMS messages based on
JMSPriority</h4><p><strong>Available as of Camel 2.4</strong></p><p>It's now
much easier to use the <a shape="rect" href="resequencer.html">Resequencer</a>
to resequence messages from <a shape="rect" href="jms.html">JMS</a> queues
based on <code>JMSPriority</code>. For that to work you need to use the two new
options <code>allowDuplicates</code> and <code>reverse</code>.</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-from("jms:queue:foo")
- // sort by JMSPriority by allowing duplicates (message can have same
JMSPriority)
- // and use reverse ordering so 9 is first output (most important), and 0
is last
- // use batch mode and fire every 3th second
-
.resequence(header("JMSPriority")).batch().timeout(3000).allowDuplicates().reverse()
- .to("mock:result");
-]]></script>
-</div></div>Notice this is <strong>only</strong> possible in the
<code>batch</code> mode of the <a shape="rect"
href="resequencer.html">Resequencer</a>.<h4
id="Resequencer-Ignoreinvalidexchanges">Ignore invalid
exchanges</h4><p><strong>Available as of Camel 2.9</strong></p><p>The <a
shape="rect" href="resequencer.html">Resequencer</a> EIP will from Camel 2.9
onwards throw a <code>CamelExchangeException</code> if the incoming <a
shape="rect" href="exchange.html">Exchange</a> is not valid for the resequencer
- ie. the expression cannot be evaluated, such as a missing header. You can use
the option <code>ignoreInvalidExchanges</code> to ignore these exceptions which
means the <a shape="rect" href="resequencer.html">Resequencer</a> will then
skip the invalid <a shape="rect" href="exchange.html">Exchange</a>.</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-from("direct:start")
- .resequence(header("seqno")).batch().timeout(250)
- // ignore invalid exchanges (they are discarded)
- .ignoreInvalidExchanges()
- .to("mock:result");
-]]></script>
-</div></div>This option is available for both batch and stream resequencer.<h4
id="Resequencer-RejectOldExchanges">Reject Old
Exchanges</h4><p><strong>Available as of Camel 2.11</strong></p><p>This option
can be used to prevent out of order messages from being sent regardless of the
event that delivered messages downstream (capacity, timeout, etc). If enabled
using <code>rejectOld()</code>, the <a shape="rect"
href="resequencer.html">Resequencer</a> will throw a
<code>MessageRejectedException</code> when an incoming <a shape="rect"
href="exchange.html">Exchange</a> is "older" (based on the Comparator) than the
last delivered message. This provides an extra level of control with regards to
delayed message ordering.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
-
.onException(MessageRejectedException.class).handled(true).to("mock:error").end()
- .resequence(header("seqno")).stream().timeout(1000).rejectOld()
- .to("mock:result");
-]]></script>
-</div></div><p>This option is available for the stream resequencer
only.</p><h3 id="Resequencer-StreamResequencing">Stream Resequencing</h3><p>The
next example shows how to use the stream-processing resequencer. Messages are
re-ordered based on their sequence numbers given by a <code>seqnum</code>
header using gap detection and timeouts on the level of individual
messages.</p><p><strong>Using the <a shape="rect"
href="fluent-builders.html">Fluent Builders</a></strong></p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-from("direct:start").resequence(header("seqnum")).stream().timeout(100).deliveryAttemptInterval(10).to("mock:result");
-]]></script>
-</div></div>The stream-processing resequencer can be further configured via
the <code>capacity()</code> and <code>timeout()</code> methods.<div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
-
.resequence(header("seqnum")).stream().capacity(5000).timeout(4000L)
- .to("mock:result")
-]]></script>
-</div></div><p>This sets the resequencer's capacity to 5000 and the timeout to
4000 ms (by default, the capacity is 1000 and the timeout is 1000 ms).
Alternatively, you can provide a configuration object.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[from("direct:start")
- .resequence(header("seqnum")).stream(new
StreamResequencerConfig(5000, 4000L))
- .to("mock:result")
-]]></script>
-</div></div><p>The stream-processing resequencer algorithm is based on the
detection of gaps in a message stream rather than on a fixed batch size. Gap
detection in combination with timeouts removes the constraint of having to know
the number of messages of a sequence (i.e. the batch size) in advance. Messages
must contain a unique sequence number for which a predecessor and a successor
is known. For example a message with the sequence number 3 has a predecessor
message with the sequence number 2 and a successor message with the sequence
number 4. The message sequence 2,3,5 has a gap because the successor of 3 is
missing. The resequencer therefore has to retain message 5 until message 4
arrives (or a timeout occurs).</p><p>If the maximum time difference between
messages (with successor/predecessor relationship with respect to the sequence
number) in a message stream is known, then the resequencer's timeout parameter
should be set to this value. In this case it is guaranteed that all
messages of a stream are delivered in correct order to the next processor.
The lower the timeout value is compared to the out-of-sequence time difference
the higher is the probability for out-of-sequence messages delivered by this
resequencer. Large timeout values should be supported by sufficiently high
capacity values. The capacity parameter is used to prevent the resequencer from
running out of memory.</p><p>By default, the stream resequencer expects
<code>long</code> sequence numbers but other sequence numbers types can be
supported as well by providing a custom expression.</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-public class MyFileNameExpression implements Expression {
-
- public String getFileName(Exchange exchange) {
- return exchange.getIn().getBody(String.class);
- }
-
- public Object evaluate(Exchange exchange) {
- // parser the file name with YYYYMMDD-DNNN pattern
- String fileName = getFileName(exchange);
- String[] files = fileName.split("-D");
- Long answer = Long.parseLong(files[0]) * 1000 +
Long.parseLong(files[1]);
- return answer;
- }
-
-
- public <T> T evaluate(Exchange exchange, Class<T> type) {
- Object result = evaluate(exchange);
- return exchange.getContext().getTypeConverter().convertTo(type,
result);
- }
-
-}
-]]></script>
-</div></div><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[
-from("direct:start").resequence(new
MyFileNameExpression()).stream().timeout(100).to("mock:result");
-]]></script>
-</div></div>or custom comparator via the <code>comparator()</code> method<div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[ExpressionResultComparator<Exchange>
comparator = new MyComparator();
-from("direct:start")
- .resequence(header("seqnum")).stream().comparator(comparator)
- .to("mock:result");
-]]></script>
-</div></div><p>or via a <code>StreamResequencerConfig</code> object.</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[ExpressionResultComparator<Exchange>
comparator = new MyComparator();
+</plain-text-body><h4 id="Resequencer-AllowDuplicates">Allow
Duplicates</h4><p><strong>Available as of Camel 2.4</strong></p><p>In the
<code>batch</code> mode, you can now allow duplicates. In Java DSL there is a
<code>allowDuplicates()</code> method and in Spring XML there is an
<code>allowDuplicates=true</code> attribute on the
<code><batch-config/></code> you can use to enable it.</p><h4
id="Resequencer-Reverse">Reverse</h4><p><strong>Available as of Camel
2.4</strong></p><p>In the <code>batch</code> mode, you can now reverse the
expression ordering. By default the order is based on 0..9,A..Z, which would
let messages with low numbers be ordered first, and thus also also outgoing
first. In some cases you want to reverse order, which is now possible.</p><p>In
Java DSL there is a <code>reverse()</code> method and in Spring XML there is an
<code>reverse=true</code> attribute on the <code><batch-config/></code>
you can use to enable it.</p><h4 id="Resequencer-ResequenceJM
SmessagesbasedonJMSPriority">Resequence JMS messages based on
JMSPriority</h4><p><strong>Available as of Camel 2.4</strong></p><p>It's now
much easier to use the <a shape="rect" href="resequencer.html">Resequencer</a>
to resequence messages from <a shape="rect" href="jms.html">JMS</a> queues
based on <code>JMSPriority</code>. For that to work you need to use the two new
options <code>allowDuplicates</code> and
<code>reverse</code>.<plain-text-body>{snippet:id=e1|lang=java|url=camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsBatchResequencerJMSPriorityTest.java}</plain-text-body>Notice
this is <strong>only</strong> possible in the <code>batch</code> mode of the
<a shape="rect" href="resequencer.html">Resequencer</a>.</p><h4
id="Resequencer-Ignoreinvalidexchanges">Ignore invalid
exchanges</h4><p><strong>Available as of Camel 2.9</strong></p><p>The <a
shape="rect" href="resequencer.html">Resequencer</a> EIP will from Camel 2.9
onwards throw a <code>Camel
ExchangeException</code> if the incoming <a shape="rect"
href="exchange.html">Exchange</a> is not valid for the resequencer - ie. the
expression cannot be evaluated, such as a missing header. You can use the
option <code>ignoreInvalidExchanges</code> to ignore these exceptions which
means the <a shape="rect" href="resequencer.html">Resequencer</a> will then
skip the invalid <a shape="rect"
href="exchange.html">Exchange</a>.<plain-text-body>{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ResequenceBatchIgnoreInvalidExchangesTest.java}</plain-text-body>This
option is available for both batch and stream resequencer.</p><h4
id="Resequencer-RejectOldExchanges">Reject Old
Exchanges</h4><p><strong>Available as of Camel 2.11</strong></p><p>This option
can be used to prevent out of order messages from being sent regardless of the
event that delivered messages downstream (capacity, timeout, etc). If enabled
using <code>rejectOld()</code>, the <a sh
ape="rect" href="resequencer.html">Resequencer</a> will throw a
<code>MessageRejectedException</code> when an incoming <a shape="rect"
href="exchange.html">Exchange</a> is "older" (based on the Comparator) than the
last delivered message. This provides an extra level of control with regards to
delayed message ordering.</p><plain-text-body>from("direct:start")
+
.onException(MessageRejectedException.class).handled(true).to("mock:error").end()
+ .resequence(header("seqno")).stream().timeout(1000).rejectOld()
+ .to("mock:result");
+</plain-text-body><p>This option is available for the stream resequencer
only.</p><h3 id="Resequencer-StreamResequencing">Stream Resequencing</h3><p>The
next example shows how to use the stream-processing resequencer. Messages are
re-ordered based on their sequence numbers given by a <code>seqnum</code>
header using gap detection and timeouts on the level of individual
messages.</p><p><strong>Using the <a shape="rect"
href="fluent-builders.html">Fluent
Builders</a></strong><plain-text-body>{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/StreamResequencerTest.java}</plain-text-body>The
stream-processing resequencer can be further configured via the
<code>capacity()</code> and <code>timeout()</code>
methods.</p><plain-text-body>from("direct:start")
+ .resequence(header("seqnum")).stream().capacity(5000).timeout(4000L)
+ .to("mock:result")
+</plain-text-body><p>This sets the resequencer's capacity to 5000 and the
timeout to 4000 ms (by default, the capacity is 1000 and the timeout is 1000
ms). Alternatively, you can provide a configuration
object.</p><plain-text-body>from("direct:start")
+ .resequence(header("seqnum")).stream(new StreamResequencerConfig(5000,
4000L))
+ .to("mock:result")
+</plain-text-body><p>The stream-processing resequencer algorithm is based on
the detection of gaps in a message stream rather than on a fixed batch size.
Gap detection in combination with timeouts removes the constraint of having to
know the number of messages of a sequence (i.e. the batch size) in advance.
Messages must contain a unique sequence number for which a predecessor and a
successor is known. For example a message with the sequence number 3 has a
predecessor message with the sequence number 2 and a successor message with the
sequence number 4. The message sequence 2,3,5 has a gap because the successor
of 3 is missing. The resequencer therefore has to retain message 5 until
message 4 arrives (or a timeout occurs).</p><p>If the maximum time difference
between messages (with successor/predecessor relationship with respect to the
sequence number) in a message stream is known, then the resequencer's timeout
parameter should be set to this value. In this case it is guaranteed th
at all messages of a stream are delivered in correct order to the next
processor. The lower the timeout value is compared to the out-of-sequence time
difference the higher is the probability for out-of-sequence messages delivered
by this resequencer. Large timeout values should be supported by sufficiently
high capacity values. The capacity parameter is used to prevent the resequencer
from running out of memory.</p><p>By default, the stream resequencer expects
<code>long</code> sequence numbers but other sequence numbers types can be
supported as well by providing a custom
expression.<plain-text-body>{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/resequencer/MyFileNameExpression.java}</plain-text-body><plain-text-body>{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/resequencer/ResequencerFileNameTest.java}</plain-text-body>or
custom comparator via the <code>comparator()</code> method
</p><plain-text-body>ExpressionResultComparator<Exchange> comparator =
new MyComparator();
+from("direct:start")
+ .resequence(header("seqnum")).stream().comparator(comparator)
+ .to("mock:result");
+</plain-text-body><p>or via a <code>StreamResequencerConfig</code>
object.</p><plain-text-body>ExpressionResultComparator<Exchange>
comparator = new MyComparator();
StreamResequencerConfig config = new StreamResequencerConfig(100, 1000L,
comparator);
-from("direct:start")
- .resequence(header("seqnum")).stream(config)
- .to("mock:result");
-]]></script>
-</div></div><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML Extensions</a></strong></p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<script class="brush: xml; gutter: false; theme: Default"
type="syntaxhighlighter"><![CDATA[<camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
+from("direct:start")
+ .resequence(header("seqnum")).stream(config)
+ .to("mock:result");
+</plain-text-body><p><strong>Using the <a shape="rect"
href="spring-xml-extensions.html">Spring XML
Extensions</a></strong></p><parameter
ac:name="">xml</parameter><plain-text-body><camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
<route>
- <from uri="direct:start"/>
+ <from uri="direct:start"/>
<resequence>
<simple>in.header.seqnum</simple>
- <to uri="mock:result" />
- <stream-config capacity="5000" timeout="4000"/>
+ <to uri="mock:result" />
+ <stream-config capacity="5000" timeout="4000"/>
</resequence>
</route>
</camelContext>
-]]></script>
-</div></div><h3 id="Resequencer-FurtherExamples">Further Examples</h3><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/trunk/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java?view=markup">batch-processing
resequencer junit test case</a> and the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/StreamResequencerTest.java?view=markup">stream-processing
resequencer junit test case</a></p><p></p><h4
id="Resequencer-UsingThisPattern">Using This Pattern</h4>
-
-<p>If you would like to use this EIP Pattern then please read the <a
shape="rect" href="getting-started.html">Getting Started</a>, you may also find
the <a shape="rect" href="architecture.html">Architecture</a> useful
particularly the description of <a shape="rect"
href="endpoint.html">Endpoint</a> and <a shape="rect"
href="uris.html">URIs</a>. Then you could try out some of the <a shape="rect"
href="examples.html">Examples</a> first before trying this pattern
out.</p></div>
+</plain-text-body><h3 id="Resequencer-FurtherExamples">Further
Examples</h3><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/trunk/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java?view=markup">batch-processing
resequencer junit test case</a> and the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/StreamResequencerTest.java?view=markup">stream-processing
resequencer junit test case</a></p><p><parameter ac:name=""><a shape="rect"
href="using-this-pattern.html">Using This Pattern</a></parameter></p></div>
</td>
<td valign="top">
<div class="navigation">