camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Atom
Date Tue, 24 Aug 2010 08:50:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<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="https://cwiki.apache.org/confluence/display/CAMEL/Atom">Atom</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (2)</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" > <br>Maven users will need to
add the following dependency to their {{pom.xml}} for this component: <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">{code<span
class="diff-added-chars"style="background-color: #dfd;">:xml</span>}</span>
<br></td></tr>
            <tr><td class="diff-unchanged" >&lt;dependency&gt; <br>
   &lt;groupId&gt;org.apache.camel&lt;/groupId&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| {{filter}} | {{true}} |  Is only
used by the split entries to filter the entries to return. Camel will default use the {{UpdateDateFilter}}
that only return new entries from the feed. So the client consuming from the feed never receives
the same entry more than once. The filter will return the entries ordered by the newest last.
| <br>| {{lastUpdate}} | {{null}} | Is only used by the filter, as the starting timestamp
for selection never entries (uses the {{entry.updated}} timestamp). Syntax format is: {{yyyy-MM-ddTHH:MM:ss}}.
Example: {{2007-12-24T17:45:59}}. |  <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">|
{{throttleEntries}} | {{true}} | *Camel 2.5:* Sets whether all entries identified in a single
feed poll should be delivered immediately. If {{true}}, only one entry is processed per {{consumer.delay}}.
Only applicable when {{splitEntries}} is set to {{true}}. | <br></td></tr>
            <tr><td class="diff-unchanged" >| {{feedHeader}} | {{true}} | Sets
whether to add the Abdera Feed object as a header. | <br>| {{sortEntries}} | {{false}}
| If {{splitEntries}} is {{true}}, this sets whether to sort those entries by updated date.
| <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Atom-AtomComponent"></a>Atom Component</h2>

<p>The <b>atom:</b> component is used for polling atom feeds.</p>

<p>Camel will default poll the feed every 60th seconds.<br/>
<b>Note:</b> The component currently only supports polling (consuming) feeds.</p>

<p>Maven users will need to add the following dependency to their <tt>pom.xml</tt>
for this component:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
    <span class="code-tag">&lt;groupId&gt;</span>org.apache.camel<span
class="code-tag">&lt;/groupId&gt;</span>
    <span class="code-tag">&lt;artifactId&gt;</span>camel-atom<span
class="code-tag">&lt;/artifactId&gt;</span>
    <span class="code-tag">&lt;version&gt;</span>x.x.x<span class="code-tag">&lt;/version&gt;</span>
    <span class="code-tag"><span class="code-comment">&lt;!-- use the same
version as your Camel core version --&gt;</span></span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h3><a name="Atom-URIformat"></a>URI format</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
atom:<span class="code-comment">//atomUri[?options]</span>
</pre>
</div></div>

<p>Where <b>atomUri</b> is the URI to the atom feed to poll. </p>

<h3><a name="Atom-Options"></a>Options</h3>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Property </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>splitEntries</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> If <tt>true</tt> Camel will poll the feed and
for the subsequent polls return each entry poll by poll. If the feed contains 7 entries then
Camel will return the first entry on the first poll, the 2nd entry on the next poll, until
no more entries where as Camel will do a new update on the feed. If <tt>false</tt>
then Camel will poll a fresh feed on every invocation. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>filter</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'>  Is only used by the split entries to filter the entries to
return. Camel will default use the <tt>UpdateDateFilter</tt> that only return
new entries from the feed. So the client consuming from the feed never receives the same entry
more than once. The filter will return the entries ordered by the newest last. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>lastUpdate</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> Is only used by the filter, as the starting timestamp for
selection never entries (uses the <tt>entry.updated</tt> timestamp). Syntax format
is: <tt>yyyy-MM-ddTHH:MM:ss</tt>. Example: <tt>2007-12-24T17:45:59</tt>.
</td>
</tr>
<tr>
<td class='confluenceTd'> <tt>throttleEntries</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> <b>Camel 2.5:</b> Sets whether all entries identified
in a single feed poll should be delivered immediately. If <tt>true</tt>, only
one entry is processed per <tt>consumer.delay</tt>. Only applicable when <tt>splitEntries</tt>
is set to <tt>true</tt>. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>feedHeader</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> Sets whether to add the Abdera Feed object as a header. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>sortEntries</tt> </td>
<td class='confluenceTd'> <tt>false</tt> </td>
<td class='confluenceTd'> If <tt>splitEntries</tt> is <tt>true</tt>,
this sets whether to sort those entries by updated date. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.delay</tt> </td>
<td class='confluenceTd'> <tt>60000</tt> </td>
<td class='confluenceTd'> Delay in millis between each poll. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.initialDelay</tt> </td>
<td class='confluenceTd'> <tt>1000</tt> </td>
<td class='confluenceTd'> Millis before polling starts. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.userFixedDelay</tt> </td>
<td class='confluenceTd'> <tt>false</tt> </td>
<td class='confluenceTd'> If <tt>true</tt>, use fixed delay between pools,
otherwise fixed rate is used. See <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html"
class="external-link" rel="nofollow">ScheduledExecutorService</a> in JDK for details.
</td>
</tr>
</tbody></table>
</div>


<p>You can append query options to the URI in the following format, <tt>?option=value&amp;option=value&amp;...</tt></p>

<h3><a name="Atom-Exchangedataformat"></a>Exchange data format</h3>

<p>Camel will set the In body on the returned <tt>Exchange</tt> with the
entries. Depending on the <tt>splitEntries</tt> flag Camel will either return
one <tt>Entry</tt> or a <tt>List&lt;Entry&gt;</tt>.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Value </th>
<th class='confluenceTh'> Behavior </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>splitEntries</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'>  Only a single entry from the currently being processed feed
is set: <tt>exchange.in.body(Entry)</tt> </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>splitEntries</tt> </td>
<td class='confluenceTd'> <tt>false</tt> </td>
<td class='confluenceTd'> The entire list of entries from the feed is set: <tt>exchange.in.body(List&lt;Entry&gt;)</tt>
</td>
</tr>
</tbody></table>
</div>


<p>Camel can set the <tt>Feed</tt> object on the In header (see <tt>feedHeader</tt>
option to disable this):</p>

<h3><a name="Atom-MessageHeaders"></a>Message Headers</h3>
<p>Camel atom uses these headers.</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Header </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.camel.component.atom.feed</tt>
</td>
<td class='confluenceTd'> Camel 1.x: When consuming the <tt>org.apache.abdera.model.Feed</tt>
object is set to this header. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>CamelAtomFeed</tt> </td>
<td class='confluenceTd'> Camel 2.0: When consuming the <tt>org.apache.abdera.model.Feed</tt>
object is set to this header. </td>
</tr>
</tbody></table>
</div>


<h3><a name="Atom-Samples"></a>Samples</h3>
<p>In this sample we poll James Strachan's blog.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"atom:<span class="code-comment">//http://macstrac.blogspot.com/feeds/posts/<span
class="code-keyword">default</span>"</span>).to(<span class="code-quote">"seda:feeds"</span>);</span>
</pre>
</div></div>

<p>In this sample we want to filter only good blogs we like to a SEDA queue. The sample
also shows how to setup Camel standalone, not running in any Container or using Spring.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// This is the CamelContext that is the heart of Camel
</span><span class="code-keyword">private</span> CamelContext context;

@Override
<span class="code-keyword">protected</span> CamelContext createCamelContext()
<span class="code-keyword">throws</span> Exception {
    <span class="code-comment">// We initialize Camel
</span>
    SimpleRegistry registry = <span class="code-keyword">new</span> SimpleRegistry();
    <span class="code-comment">// First we register a blog service in our bean registry
</span>    registry.put(<span class="code-quote">"blogService"</span>, <span
class="code-keyword">new</span> BlogService());

    <span class="code-comment">// Then we create the camel context with our bean registry
</span>    context = <span class="code-keyword">new</span> DefaultCamelContext(registry);

    <span class="code-comment">// Then we add all the routes we need using the route
builder DSL syntax
</span>    context.addRoutes(createRouteBuilder());

    <span class="code-comment">// And <span class="code-keyword">finally</span>
we must start Camel to let the magic routing begins
</span>    context.start();

    <span class="code-keyword">return</span> context;
}

/**
 * This is the route builder where we create our routes in the advanced Camel DSL syntax
 */
<span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
<span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            <span class="code-comment">// We pool the atom feeds from the source <span
class="code-keyword">for</span> further processing in the seda queue
</span>            <span class="code-comment">// we set the delay to 1 second
<span class="code-keyword">for</span> each pool as <span class="code-keyword">this</span>
is a unit test also and we can
</span>            <span class="code-comment">// not wait the <span class="code-keyword">default</span>
poll interval of 60 seconds.
</span>            <span class="code-comment">// Using splitEntries=<span class="code-keyword">true</span>
will during polling only fetch one Atom Entry at any given time.
</span>            <span class="code-comment">// As the feed.atom file contains
7 entries, using <span class="code-keyword">this</span> will require 7 polls to
fetch the entire
</span>            <span class="code-comment">// content. When Camel have reach
the end of entries it will refresh the atom feed from URI source
</span>            <span class="code-comment">// and restart - but as Camel by
<span class="code-keyword">default</span> uses the UpdatedDateFilter it will only
deliver <span class="code-keyword">new</span>
</span>            <span class="code-comment">// blog entries to <span class="code-quote">"seda:feeds"</span>.
So only when James Straham updates his blog with a <span class="code-keyword">new</span>
entry
</span>            <span class="code-comment">// Camel will create an exchange
<span class="code-keyword">for</span> the seda:feeds.
</span>            from(<span class="code-quote">"atom:file:src/test/data/feed.atom?splitEntries=<span
class="code-keyword">true</span>&amp;consumer.delay=1000"</span>).to(<span
class="code-quote">"seda:feeds"</span>);

            <span class="code-comment">// From the feeds we filter each blot entry by
using our blog service class
</span>            from(<span class="code-quote">"seda:feeds"</span>).filter().method(<span
class="code-quote">"blogService"</span>, <span class="code-quote">"isGoodBlog"</span>).to(<span
class="code-quote">"seda:goodBlogs"</span>);

            <span class="code-comment">// And the good blogs is moved to a mock queue
as <span class="code-keyword">this</span> sample is also used <span class="code-keyword">for</span>
unit testing
</span>            <span class="code-comment">// <span class="code-keyword">this</span>
is one of the strengths in Camel that you can also use the mock endpoint <span class="code-keyword">for</span>
your
</span>            <span class="code-comment">// unit tests
</span>            from(<span class="code-quote">"seda:goodBlogs"</span>).to(<span
class="code-quote">"mock:result"</span>);
        }
    };
}

/**
 * This is the actual junit test method that does the assertion that our routes is working
 * as expected
 */
@Test
<span class="code-keyword">public</span> void testFiltering() <span class="code-keyword">throws</span>
Exception {
    <span class="code-comment">// Get the mock endpoint
</span>    MockEndpoint mock = context.getEndpoint(<span class="code-quote">"mock:result"</span>,
MockEndpoint.class);

    <span class="code-comment">// There should be two good blog entries from the feed
</span>    mock.expectedMinimumMessageCount(2);

    <span class="code-comment">// Asserts that the above expectations is <span class="code-keyword">true</span>,
will <span class="code-keyword">throw</span> assertions exception <span class="code-keyword">if</span>
it failed
</span>    <span class="code-comment">// Camel will <span class="code-keyword">default</span>
wait max 20 seconds <span class="code-keyword">for</span> the assertions to be
<span class="code-keyword">true</span>, <span class="code-keyword">if</span>
the conditions
</span>    <span class="code-comment">// is <span class="code-keyword">true</span>
sooner Camel will <span class="code-keyword">continue</span>
</span>    mock.assertIsSatisfied();
}

/**
 * Services <span class="code-keyword">for</span> blogs
 */
<span class="code-keyword">public</span> class BlogService {

    /**
     * Tests the blogs <span class="code-keyword">if</span> its a good blog entry
or not
     */
    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
isGoodBlog(Exchange exchange) {
        Entry entry = exchange.getIn().getBody(Entry.class);
        <span class="code-object">String</span> title = entry.getTitle();

        <span class="code-comment">// We like blogs about Camel
</span>        <span class="code-object">boolean</span> good = title.toLowerCase().contains(<span
class="code-quote">"camel"</span>);
        <span class="code-keyword">return</span> good;
    }

}

</pre>
</div></div>

<h3><a name="Atom-SeeAlso"></a>See Also</h3>
<ul>
	<li><a href="/confluence/display/CAMEL/Configuring+Camel" title="Configuring Camel">Configuring
Camel</a></li>
	<li><a href="/confluence/display/CAMEL/Component" title="Component">Component</a></li>
	<li><a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a></li>
	<li><a href="/confluence/display/CAMEL/Getting+Started" title="Getting Started">Getting
Started</a></li>
</ul>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Atom">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=85869&revisedVersion=13&originalVersion=12">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Atom?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message