camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject [CONF] Apache Camel > Idempotent Consumer
Date Wed, 09 Feb 2011 23:02:00 GMT
    <base href="">
            <link rel="stylesheet" href="/confluence/s/2036/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="">Idempotent
    <h4>Page <b>edited</b> by             <a href="">Christian
                         <h4>Changes (1)</h4>
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >On completion Camel will remove the
message id from the repository if the Exchange failed, otherwise it stays there. <br>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Camel
provides the following Idempotent Consumer implementations: <br>- MemoryIdempotentRepository
<br>- FileIdempotentRepository <br>- JdbcMessageIdRepository <br>- JpaMessageIdRepository
<br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. Options <br>The Idempotent
Consumer has the following options: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h3><a name="IdempotentConsumer-IdempotentConsumer"></a>Idempotent

<p>The <a href=""
class="external-link" rel="nofollow">Idempotent Consumer</a> from the <a href="/confluence/display/CAMEL/Enterprise+Integration+Patterns"
title="Enterprise Integration Patterns">EIP patterns</a> is used to filter out duplicate
messages. </p>

<p>This pattern is implemented using the <a href=""
class="external-link" rel="nofollow">IdempotentConsumer</a> class. This uses an <a
href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a> to
calculate a unique message ID string for a given message exchange; this ID can then be looked
up in the <a href=""
class="external-link" rel="nofollow">IdempotentRepository</a> to see if it has been
seen before; if it has the message is consumed; if its not then the message is processed and
the ID is added to the repository.</p>

<p>The Idempotent Consumer essentially acts like a <a href="/confluence/display/CAMEL/Message+Filter"
title="Message Filter">Message Filter</a> to filter out duplicates.</p>

<p>Camel will add the message id eagerly to the repository to detect duplication also
for Exchanges currently in progress.<br/>
On completion Camel will remove the message id from the repository if the Exchange failed,
otherwise it stays there.</p>

<p>Camel provides the following Idempotent Consumer implementations:</p>
<ul class="alternate" type="square">

<h3><a name="IdempotentConsumer-Options"></a>Options</h3>
<p>The Idempotent Consumer has the following options:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
<td class='confluenceTd'> eager </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> <b>Camel 2.0:</b> Eager controls whether Camel
adds the message to the repository before or after the exchange has been processed. If enabled
before then Camel will be able to detect duplicate messages even when messages are currently
in progress. By disabling Camel will only detect duplicates when a message has successfully
been processed. </td>
<td class='confluenceTd'> messageIdRepositoryRef </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> A reference to a <tt>IdempotentRepository</tt>
to lookup in the registry. This option is mandatory when using XML DSL. </td>

<h3><a name="IdempotentConsumer-UsingtheFluentBuilders"></a><b>Using
the <a href="/confluence/display/CAMEL/Fluent+Builders" title="Fluent Builders">Fluent

<p>The following example will use the header <b>myMessageId</b> to filter
out duplicates</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">RouteBuilder builder = <span class="code-keyword">new</span>
RouteBuilder() {
    <span class="code-keyword">public</span> void configure() {
        errorHandler(deadLetterChannel(<span class="code-quote">"mock:error"</span>));

        from(<span class="code-quote">"seda:a"</span>)
            .idempotentConsumer(header(<span class="code-quote">"myMessageId"</span>),
            .to(<span class="code-quote">"seda:b"</span>);

<p>The above <a href=""
class="external-link" rel="nofollow">example</a> will use an in-memory based <a
class="external-link" rel="nofollow">MessageIdRepository</a> which can easily run
out of memory and doesn't work in a clustered environment. So you might prefer to use the
JPA based implementation which uses  a database to store the message IDs which have been processed</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>).idempotentConsumer(
        header(<span class="code-quote">"messageId"</span>),
        jpaMessageIdRepository(lookup(JpaTemplate.class), PROCESSOR_NAME)
).to(<span class="code-quote">"mock:result"</span>);

<p>In the above <a href=""
class="external-link" rel="nofollow">example</a> we are using the header <b>messageId</b>
to filter out duplicates and using the collection <b>myProcessorName</b> to indicate
the Message ID Repository to use. This name is important as you could process the same message
by many different processors; so each may require its own logical Message ID Repository.</p>

<p>For further examples of this pattern in use you could look at the <a href=""
class="external-link" rel="nofollow">junit test case</a></p>

<h3><a name="IdempotentConsumer-SpringXMLexample"></a>Spring XML example</h3>

<p>The following example will use the header <b>myMessageId</b> to filter
out duplicates</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
repository for the idempotent consumer --&gt;</span></span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"myRepo"</span>
class=<span class="code-quote">"org.apache.camel.processor.idempotent.MemoryIdempotentRepository"</span>/&gt;</span>

<span class="code-tag">&lt;camelContext xmlns=<span class="code-quote">""</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
        <span class="code-tag">&lt;idempotentConsumer messageIdRepositoryRef=<span
            <span class="code-tag"><span class="code-comment">&lt;!-- use
the messageId header as key for identifying duplicate messages --&gt;</span></span>
            <span class="code-tag">&lt;header&gt;</span>messageId<span
            <span class="code-tag"><span class="code-comment">&lt;!-- if not
a duplicate send it to this mock endpoint --&gt;</span></span>
            <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:result"</span>/&gt;</span>
        <span class="code-tag">&lt;/idempotentConsumer&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>

<h4><a name="IdempotentConsumer-UsingThisPattern"></a>Using This Pattern</h4>

<p>If you would like to use this EIP Pattern then please read the <a href="/confluence/display/CAMEL/Getting+Started"
title="Getting Started">Getting Started</a>, you may also find the <a href="/confluence/display/CAMEL/Architecture"
title="Architecture">Architecture</a> useful particularly the description of <a
href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a> and <a
href="/confluence/display/CAMEL/URIs" title="URIs">URIs</a>. Then you could try out
some of the <a href="/confluence/display/CAMEL/Examples" title="Examples">Examples</a>
first before trying this pattern out.</p>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href=""
class="grey">Change Notification Preferences</a>
        <a href="">View
        <a href="">View
        <a href=";showCommentArea=true#addcomment">Add

View raw message