camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Recipient List
Date Fri, 04 Dec 2009 16:35:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Recipient+List">Recipient
List</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h3><a name="RecipientList-RecipientList"></a>Recipient List</h3>

<p>The <a href="http://www.enterpriseintegrationpatterns.com/RecipientList.html"
rel="nofollow">Recipient List</a> from the <a href="/confluence/display/CAMEL/Enterprise+Integration+Patterns"
title="Enterprise Integration Patterns">EIP patterns</a> allows you to route messages
to a number of dynamically specified recipients.</p>

<p><img src="http://www.enterpriseintegrationpatterns.com/img/RecipientList.gif"
align="absmiddle" border="0" /></p>

<p>The recipients will receive a copy of the <b>same</b> <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a> and Camel will execute them sequentially.</p>

<h4><a name="RecipientList-StaticRecipientList"></a>Static Recipient List</h4>

<p>The following example shows how to route a request from an input <b>queue:a</b>
endpoint to a static list of destinations</p>

<p><b>Using Annotations</b><br/>
You can use the <a href="/confluence/display/CAMEL/RecipientList+Annotation" title="RecipientList
Annotation">RecipientList Annotation</a> on a POJO to create a Dynamic Recipient
List. For more details see the <a href="/confluence/display/CAMEL/Bean+Integration" title="Bean
Integration">Bean Integration</a>.</p>

<p><b>Using the <a href="/confluence/display/CAMEL/Fluent+Builders" title="Fluent
Builders">Fluent Builders</a></b></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>).multicast().to(<span
class="code-quote">"seda:b"</span>, <span class="code-quote">"seda:c"</span>,
<span class="code-quote">"seda:d"</span>);
    }
};
</pre>
</div></div>

<p><b>Using the <a href="/confluence/display/CAMEL/Spring+XML+Extensions" title="Spring
XML Extensions">Spring XML Extensions</a></b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;camelContext errorHandlerRef=<span
class="code-quote">"errorHandler"</span> streamCache=<span class="code-quote">"false"</span>
id=<span class="code-quote">"camel"</span> xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"seda:a"</span>/&gt;</span>
        <span class="code-tag">&lt;multicast&gt;</span>
            <span class="code-tag">&lt;to uri=<span class="code-quote">"seda:b"</span>/&gt;</span>
            <span class="code-tag">&lt;to uri=<span class="code-quote">"seda:c"</span>/&gt;</span>
            <span class="code-tag">&lt;to uri=<span class="code-quote">"seda:d"</span>/&gt;</span>
        <span class="code-tag">&lt;/multicast&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<h4><a name="RecipientList-DynamicRecipientList"></a>Dynamic Recipient List</h4>

<p>Usually one of the main reasons for using the <a href="http://www.enterpriseintegrationpatterns.com/RecipientList.html"
rel="nofollow">Recipient List</a> pattern is that the list of recipients is dynamic
and calculated at runtime. The following example demonstrates how to create a dynamic recipient
list using an <a href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a>
(which in this case it extracts a named header value dynamically) to calculate the list of
endpoints which are either of type <a href="http://camel.apache.org/maven/camel-core/apidocs/org/apache/camel/Endpoint.html"
rel="nofollow">Endpoint</a> or are converted to a String and then resolved using
the endpoint <a href="/confluence/display/CAMEL/URIs" title="URIs">URIs</a>.</p>

<p><b>Using the <a href="/confluence/display/CAMEL/Fluent+Builders" title="Fluent
Builders">Fluent Builders</a></b></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>).recipientList(header(<span
class="code-quote">"foo"</span>));
    }
};
</pre>
</div></div>

<p>The above assumes that the header contains a list of endpoint URIs. The following
takes a single string header and tokenizes it</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:a"</span>).recipientList(
        header(<span class="code-quote">"recipientListHeader"</span>).tokenize(<span
class="code-quote">","</span>));
</pre>
</div></div>

<h5><a name="RecipientList-Iteratablevalue"></a>Iteratable value</h5>
<p>The dynamic list of recipients that are defined in the header must be iteratable
such as:</p>
<ul class="alternate" type="square">
	<li><tt>java.util.Collection</tt></li>
	<li><tt>java.util.Iterator</tt></li>
	<li>arrays</li>
	<li><tt>org.w3c.dom.NodeList</tt></li>
	<li><b>Camel 1.5.1:</b> a single String with values separated with comma</li>
	<li>any other type will be regarded as a single value</li>
</ul>


<p><b>Using the <a href="/confluence/display/CAMEL/Spring+XML+Extensions" title="Spring
XML Extensions">Spring XML Extensions</a></b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;camelContext errorHandlerRef=<span
class="code-quote">"errorHandler"</span> streamCache=<span class="code-quote">"false"</span>
id=<span class="code-quote">"camel"</span> xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"seda:a"</span>/&gt;</span>
        <span class="code-tag">&lt;recipientList&gt;</span>
            <span class="code-tag">&lt;xpath&gt;</span>$foo<span class="code-tag">&lt;/xpath&gt;</span>
        <span class="code-tag">&lt;/recipientList&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<p>For further examples of this pattern in use you could look at one of the <a href="http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RecipientListTest.java?view=markup"
rel="nofollow">junit test case</a></p>

<h5><a name="RecipientList-UsingdelimiterinSpringXML"></a>Using delimiter
in Spring XML</h5>
<p><b>Available as of Camel 1.5.1</b><br/>
In Spring DSL you can set the <tt>delimiter</tt> attribute for setting a delimiter
to be used if the header value is a single String with multiple separated endpoints. By default
Camel uses comma as delimiter, but this option lets you specify a customer delimiter to use
instead.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;route&gt;</span>
  <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:a"</span>
/&gt;</span>
  <span class="code-tag"><span class="code-comment">&lt;!-- use comma as a
delimiter for String based values --&gt;</span></span>
  <span class="code-tag">&lt;recipientList delimiter=<span class="code-quote">","</span>&gt;</span>
    <span class="code-tag">&lt;header&gt;</span>myHeader<span class="code-tag">&lt;/header&gt;</span>
  <span class="code-tag">&lt;/recipientList&gt;</span>
<span class="code-tag">&lt;/route&gt;</span>
</pre>
</div></div>

<p>So if <b>myHeader</b> contains a String with the value <tt>"activemq:queue:foo,
activemq:topic:hello , log:bar"</tt> then Camel will split the String using the delimiter
given in the XML that was comma, resulting into 3 endpoints to send to. You can use spaces
between the endpoints as Camel will trim the value when it lookup the endpoint to send to.
</p>

<p>Note: In Java DSL you use the <tt>tokenizer</tt> to archive the same.
The route above in Java DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:a"</span>).recipientList(header(<span
class="code-quote">"myHeader"</span>).tokenize(<span class="code-quote">","</span>));
</pre>
</div></div>

<p>In <b>Camel 2.1</b> its a bit easier as you can pass in the delimiter
as 2nd parameter:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:a"</span>).recipientList(header(<span
class="code-quote">"myHeader"</span>), <span class="code-quote">"#"</span>);
</pre>
</div></div>

<h3><a name="RecipientList-Sendingtomultiplerecipientsinparallel"></a>Sending
to multiple recipients in parallel</h3>
<p><b>Available as of Camel 2.2</b></p>

<p>The <a href="/confluence/display/CAMEL/Recipient+List" title="Recipient List">Recipient
List</a> now supports <tt>parallelProcessing</tt> that for example <a
href="/confluence/display/CAMEL/Splitter" title="Splitter">Splitter</a> also supports.
You can use it to use a thread pool to have concurrent tasks sending the <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a> to multiple recipients concurrently.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:a"</span>).recipientList(header(<span
class="code-quote">"myHeader"</span>)).parallelProcessing();
</pre>
</div></div>

<p>And in Spring XML its an attribute on the recipient list tag.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   &lt;route&gt;
       &lt;from uri=<span class="code-quote">"direct:a"</span>/&gt;
       &lt;recipientList parallelProcessing=<span class="code-quote">"<span class="code-keyword">true</span>"</span>&gt;
           &lt;header&gt;myHeader&lt;/header&gt;
       &lt;/recipientList&gt;
   &lt;/route&gt;
</pre>
</div></div>

<h3><a name="RecipientList-Stopcontinuingincaseonerecipientfailed"></a>Stop
continuing in case one recipient failed</h3>
<p><b>Available as of Camel 2.2</b></p>

<p>The <a href="/confluence/display/CAMEL/Recipient+List" title="Recipient List">Recipient
List</a> now supports <tt>stopOnException</tt> that for example <a href="/confluence/display/CAMEL/Splitter"
title="Splitter">Splitter</a> also supports. You can use it to stop sending to any
further recipients in case any recipient failed. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:a"</span>).recipientList(header(<span
class="code-quote">"myHeader"</span>)).stopOnException();
</pre>
</div></div>

<p>And in Spring XML its an attribute on the recipient list tag.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   &lt;route&gt;
       &lt;from uri=<span class="code-quote">"direct:a"</span>/&gt;
       &lt;recipientList stopOnException=<span class="code-quote">"<span class="code-keyword">true</span>"</span>&gt;
           &lt;header&gt;myHeader&lt;/header&gt;
       &lt;/recipientList&gt;
   &lt;/route&gt;
</pre>
</div></div>

<p><b>Note:</b> You can combine <tt>parallelProcessing</tt>
and <tt>stopOnException</tt> and have them both <tt>true</tt>.</p>

<h3><a name="RecipientList-Usingcustom%7B%7BAggregationStrategy%7D%7D"></a>Using
custom <tt>AggregationStrategy</tt></h3>
<p><b>Available as of Camel 2.2</b></p>

<p>You can now use you own <tt>AggregationStrategy</tt> with the <a href="/confluence/display/CAMEL/Recipient+List"
title="Recipient List">Recipient List</a>. However its not that often you need that.
What its good for is that in case you are using <a href="/confluence/display/CAMEL/Request+Reply"
title="Request Reply">Request Reply</a> messaging then the replies from the recipient
can be aggregated. By default Camel uses <tt>UseLatestAggregationStrategy</tt>
which just keeps that last received reply. What if you must remember all the bodies that all
the recipients send back, then you can use your own custom aggregator that keeps those. Its
the same principle as with the <a href="/confluence/display/CAMEL/Aggregator" title="Aggregator">Aggregator</a>
EIP so check it out for details.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:a"</span>).recipientList(header(<span
class="code-quote">"myHeader"</span>)).aggregationStrategy(<span class="code-keyword">new</span>
MyOwnAggregationStrategy());
</pre>
</div></div>


<p>And in Spring XML its an attribute on the recipient list tag.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   &lt;route&gt;
       &lt;from uri=<span class="code-quote">"direct:a"</span>/&gt;
       &lt;recipientList strategyRef=<span class="code-quote">"myStrategy"</span>&gt;
           &lt;header&gt;myHeader&lt;/header&gt;
       &lt;/recipientList&gt;
   &lt;/route&gt;

   &lt;bean id=<span class="code-quote">"myStrategy"</span> class=<span
class="code-quote">"com.mycompany.MyOwnAggregationStrategy"</span>/&gt;
</pre>
</div></div>

<h3><a name="RecipientList-Usingcustomthreadpool"></a>Using custom thread
pool</h3>
<p><b>Available as of Camel 2.2</b></p>

<p>This is only needed when you use <tt>parallelProcessing</tt>. By default
Camel uses a thread pool with 10 threads. Notice this is subject to change when we overhaul
thread pool management and configuration later (hopefully in Camel 2.2).</p>

<p>You configure this just as you would with the custom aggregation strategy.</p>



<h4><a name="RecipientList-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>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Recipient+List">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=49325&revisedVersion=26&originalVersion=25">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Recipient+List?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message