camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > NotifyBuilder
Date Thu, 18 Feb 2010 07:57: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/NotifyBuilder">NotifyBuilder</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">
         <h2><a name="NotifyBuilder-NotifyBuilder"></a>NotifyBuilder</h2>
<p><b>Available as of Camel 2.2</b></p>

<p>The <tt>NotifyBuilder</tt> is a builder from the <tt>org.apache.camel.builder</tt>
package which allows you to build expressions and then test or wait for that condition to
occur. The expressions is based around notifications about <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a> being routed. So what does that mean? It means that
you can build an expressions which can tell you when Camel is finished with routing 5 messages
etc.</p>

<p>You may want to use this when testing a route which you cannot or will not use <a
href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a>s. </p>

<p>Suppose we have a very simple route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  from(<span class="code-quote">"jms:queue:quotes"</span>)
     .to(<span class="code-quote">"bean:quotes"</span>);
</pre>
</div></div>

<p>Now you want to test this route without using mocks or the likes. Imagine the route
being more complex and a production ready route.<br/>
We want to test that it could process a message send to that queue. By using the <a href="/confluence/display/CAMEL/NotifyBuilder"
title="NotifyBuilder">NotifyBuilder</a> we can build an expression which <em>expresses
when that condition occurred</em>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"> 
  NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder().whenDone(1).create();

  <span class="code-comment">// now use some API to send a message etc. Maybe you cannot
use Camel's ProducerTemplate
</span>  <span class="code-comment">// now we want to wait until the message has
been routed and completed
</span>
  <span class="code-object">boolean</span> done = notify.matches(10, TimeUnit.SECONDS);
  assertTrue(<span class="code-quote">"Should be done"</span>, done);

  <span class="code-comment">// now maybe use some API to see that the message did as
expected</span>
</pre>
</div></div>

<p>This is a very basic example with a simple builder expression. What we said that
we want it to match when any Exchange is done. The builder have many more methods to set more
complex expressions, which even can be stacked using <b>and, or, not</b> operations.</p>

<h3><a name="NotifyBuilder-Methods"></a>Methods</h3>

<p>These methods is for building the expression:</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> from(endpointUri) </td>
<td class='confluenceTd'> Matches only when <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a>s are incoming from that particular endpoint. The endpointUri
can be a pattern, which is the same pattern matching used by <a href="/confluence/display/CAMEL/Intercept"
title="Intercept">Intercept</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> filter(predicate) </td>
<td class='confluenceTd'> Filters out unwanted <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a>s (only messages passing (true) the predicate is used).
</td>
</tr>
<tr>
<td class='confluenceTd'> whenReceived(number) </td>
<td class='confluenceTd'> Matches when X number or more messages has been received.
</td>
</tr>
<tr>
<td class='confluenceTd'> whenDone(number) </td>
<td class='confluenceTd'> Matches when X number or more messages is done. </td>
</tr>
<tr>
<td class='confluenceTd'> whenComplete(number) </td>
<td class='confluenceTd'> Matches when X number or more messages is complete. </td>
</tr>
<tr>
<td class='confluenceTd'> whenFailed(number) </td>
<td class='confluenceTd'> Matches when X number or more messages is failed. </td>
</tr>
<tr>
<td class='confluenceTd'> whenExactlyDone(number) </td>
<td class='confluenceTd'> Matches when exactly X number of messages is done. </td>
</tr>
<tr>
<td class='confluenceTd'> whenExactlyComplete(number) </td>
<td class='confluenceTd'> Matches when exactly X number of messages is complete. </td>
</tr>
<tr>
<td class='confluenceTd'> whenExactlyFailed(number) </td>
<td class='confluenceTd'> Matches when exactly X number of messages is failed. </td>
</tr>
<tr>
<td class='confluenceTd'> whenBodiesReceived(bodies) </td>
<td class='confluenceTd'> Matches when the message bodies has been received in the same
order. This method is non strict which means that it will disregard any additional received
messages. </td>
</tr>
<tr>
<td class='confluenceTd'> whenExactBodiesReceived(bodies) </td>
<td class='confluenceTd'> Matches when the message bodies has been received in the same
order. This method is strict which means the exact number of message bodies is expected. </td>
</tr>
<tr>
<td class='confluenceTd'> whenBodiesDone(bodies) </td>
<td class='confluenceTd'> Matches when the message bodies are done in the same order.
This method is non strict which means that it will disregard any additional done messages.
</td>
</tr>
<tr>
<td class='confluenceTd'> whenExactBodiesDone(bodies) </td>
<td class='confluenceTd'> Matches when the message bodies are done in the same order.
This method is strict which means the exact number of message bodies is expected. </td>
</tr>
<tr>
<td class='confluenceTd'> whenAnyReceivedMatches(predicate) </td>
<td class='confluenceTd'> Matches if any one of the received messages matched the <a
href="/confluence/display/CAMEL/Predicate" title="Predicate">Predicate</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> whenAllReceivedMatches(predicate) </td>
<td class='confluenceTd'> Matches only when all of the received messages matched the
<a href="/confluence/display/CAMEL/Predicate" title="Predicate">Predicate</a>.
</td>
</tr>
<tr>
<td class='confluenceTd'> whenAnyDoneMatches(predicate) </td>
<td class='confluenceTd'> Matches if any one of the done messages matched the <a
href="/confluence/display/CAMEL/Predicate" title="Predicate">Predicate</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> whenAllDoneMatches(predicate) </td>
<td class='confluenceTd'> Matches only when all of the done messages matched the <a
href="/confluence/display/CAMEL/Predicate" title="Predicate">Predicate</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> whenReceivedSatisfied(mock) </td>
<td class='confluenceTd'> Matches if the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> is satisfied for received messages. Is used for fine grained
matching by setting the expectations on the <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a>
which already have a great library for doing so. </td>
</tr>
<tr>
<td class='confluenceTd'> whenReceivedNotSatisfied(mock) </td>
<td class='confluenceTd'> Matches if the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> is <b>not</b> satisfied for received messages.
Is used for fine grained matching by setting the expectations on the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> which already have a great library for doing so. </td>
</tr>
<tr>
<td class='confluenceTd'> whenDoneSatisfied(mock) </td>
<td class='confluenceTd'> Matches if the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> is satisfied for messages done. Is used for fine grained matching
by setting the expectations on the <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a>
which already have a great library for doing so. </td>
</tr>
<tr>
<td class='confluenceTd'> whenDoneNotSatisfied(mock) </td>
<td class='confluenceTd'> Matches if the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> is <b>not</b> satisfied for messages done. Is used
for fine grained matching by setting the expectations on the <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a> which already have a great library for doing so. </td>
</tr>
<tr>
<td class='confluenceTd'> and </td>
<td class='confluenceTd'> Appends an additional expressions using the <b>and</b>
operator. </td>
</tr>
<tr>
<td class='confluenceTd'> or </td>
<td class='confluenceTd'> Appends an additional expressions using the <b>or</b>
operator. </td>
</tr>
<tr>
<td class='confluenceTd'> not </td>
<td class='confluenceTd'> Appends an additional expressions using the <b>not</b>
operator. </td>
</tr>
</tbody></table>

<p>And these methods is for using the builder after creating the expression:</p>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> create() </td>
<td class='confluenceTd'> Creates the builder expression. After you have <b>created</b>
it you can use the <tt>matches</tt> methods. </td>
</tr>
<tr>
<td class='confluenceTd'> matches() </td>
<td class='confluenceTd'> Does the builder match currently. This operation returns immediately.
This method is to be used <b>after</b> you have created the expression. </td>
</tr>
<tr>
<td class='confluenceTd'> matches(timeout, TimeUnit) </td>
<td class='confluenceTd'> Wait until the builder matches or timeout. This method is
to be used <b>after</b> you have created the expression. </td>
</tr>
<tr>
<td class='confluenceTd'> reset() </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> Resets the notifier. </td>
</tr>
</tbody></table>

<p>We will most likely add additional methods in the future, so check out the <tt>NotifyBuilder</tt>
for latest and greatest methods.</p>

<h3><a name="NotifyBuilder-DifferencebetweenDoneandCompleted"></a>Difference
between Done and Completed</h3>
<p>The difference between <b>done</b> and <b>completed</b> is
that done can also include failed messages, where as completed is only successful processed
messages.</p>

<h3><a name="NotifyBuilder-Examples"></a>Examples</h3>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"direct:foo"</span>).whenDone(5)
                .create();
</pre>
</div></div>
<p>Here we want to match when the <tt>direct:foo</tt> endpoint have done
5 messages. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"direct:foo"</span>).filter(body().contains(<span
class="code-quote">"test"</span>)).whenDone(5)
                .create();
</pre>
</div></div>
<p>Here we want to match when the <tt>direct:foo</tt> endpoint have done
5 messages which contains the word 'test' in the body.<br/>
The filter accepts a <a href="/confluence/display/CAMEL/Predicate" title="Predicate">Predicate</a>
so you can use <a href="/confluence/display/CAMEL/XPath" title="XPath">XPath</a>,
<a href="/confluence/display/CAMEL/Bean" title="Bean">Bean</a>, <a href="/confluence/display/CAMEL/Simple"
title="Simple">Simple</a> and whatnot. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"jms:*"</span>).whenDone(1)
                .create();
</pre>
</div></div>
<p>Here we just say that at least one message should be done received from any JMS endpoint
(notice the wildcard matching).</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"direct:foo"</span>).whenDone(5)
                .and().from(<span class="code-quote">"direct:bar"</span>).whenDone(7)
                .create();
</pre>
</div></div>
<p>Here both 5 foo messages and 7 bar messages must be done. Notice the use of the <b>and</b>
operator.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"direct:foo"</span>).whenBodiesReceived(<span
class="code-quote">"Hello World"</span>, <span class="code-quote">"Bye World"</span>)
                .create();
</pre>
</div></div>
<p>Here we expect to receive two messages with <tt>Hello World</tt> and
<tt>Bye World</tt>.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .whenAnyReceivedMatches(body().contains(<span class="code-quote">"Camel"</span>))
                .create();
</pre>
</div></div>
<p>Here we want to match when we have received a message which contains Camel in the
body.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        <span class="code-comment">// lets use a mock to set the expressions as it got
many great assertions <span class="code-keyword">for</span> that
</span>        <span class="code-comment">// notice we use mock:<span class="code-keyword">assert</span>
which does NOT exist in the route, its just a pseudo name
</span>        MockEndpoint mock = getMockEndpoint(<span class="code-quote">"mock:<span
class="code-keyword">assert</span>"</span>);
        mock.expectedBodiesReceivedInAnyOrder(<span class="code-quote">"Hello World"</span>,
<span class="code-quote">"Bye World"</span>, <span class="code-quote">"Hi
World"</span>);

        NotifyBuilder notify = <span class="code-keyword">new</span> NotifyBuilder(context)
                .from(<span class="code-quote">"direct:foo"</span>).whenReceivedSatisfied(mock)
                .create();
</pre>
</div></div>
<p>Now it bring powers to the table. We combine a mock with the builder. We use the
mock to set fine grained expectations such as we should receive 3 messages in any order. Then
using the builder we can tell that those messages should be received from the <tt>direct:foo</tt>
endpoint.</p>

<p>You can combine multiple expressions as much as you like. However we suggest to use
the mock for fine grained expectations that you may already know how to use.</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/NotifyBuilder">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=11469138&revisedVersion=7&originalVersion=6">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/NotifyBuilder?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message