LibraryLink ToToggle FramesPrintFeedback

Chapter 5. Atom

The atom: component is used for polling atom feeds.

FUSE Mediation Router will default poll the feed every 60th seconds. Note: The component currently only supports polling (consuming) feeds.

atom://atomUri

Where atomUri is the URI to the atom feed to poll.

Property Default Description
splitEntries true If true 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 false then Camel will poll a fresh feed on every invocation.
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.
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.
feedHeader true Sets whether to add the Abdera Feed object as a header.
sortEntries false If splitEntries is true, this sets whether to sort those entries by updated date.
consumer.delay 60000 Delay in millis between each poll
consumer.initialDelay 1000 Millis before polling starts
consumer.userFixedDelay false true to use fixed delay between pools, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

FUSE Mediation Router will set the in body on the returned Exchange with the entries. Depending on the splitEntries flag FUSE Mediation Router will either return one Entry or a List<Entry>.

Option Value Behavior
splitEntries true Only a single entry from the currently being processed feed is set: exchange.in.body(Entry)
splitEntries false The entires list of entries from the feed is set: exchange.in.body(List<Entry>)

FUSE Mediation Router can set the Feed object on the in header (see feedHeader option to disable this):

FUSE Mediation Router atom uses these headers.

Header Description
org.apache.camel.component.atom.feed FUSE Mediation Router 1.x: When consuming the org.apache.abdera.model.Feed object is set to this header.
CamelAtomFeed FUSE Mediation Router 2.0: When consuming the org.apache.abdera.model.Feed object is set to this header.

In this sample we poll James Strahams blog.

from("atom://http://macstrac.blogspot.com/feeds/posts/default").to("seda:feeds");

In this sample we want to filter only good blogs we like to a seda queue. The sample also shows how to setup FUSE Mediation Router standalone, not running in any Container or using Spring.

// This is the CamelContext that is the heart of Camel
private CamelContext context;

// We use a simple Hashtable for our bean registry. For more advanced usage Spring is supported out-of-the-box
private Hashtable beans = new Hashtable();

// We iniitalize Camel
private void setupCamel() throws Exception {
    // First we register a blog service in our bean registry
    beans.put("blogService", new BlogService());

    // Then we create the camel context with our bean registry
    context = new DefaultCamelContext(new CamelInitialContextFactory().getInitialContext(beans));

    // Then we add all the routes we need using the route builder DSL syntax
    context.addRoutes(createRouteBuilder());

    // And finally we must start Camel to let the magic routing begins
    context.start();
}

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

            // From the feeds we filter each blot entry by using our blog service class
            from("seda:feeds").filter().method("blogService", "goodBlog").to("seda:goodBlogs");

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

/**
 * This is the actual junit test method that does the assertion that our routes is working
 * as expected
 */
public void testFiltering() throws Exception {
    // Get the mock endpoint
    MockEndpoint mock = context.getEndpoint("mock:result", MockEndpoint.class);

    // There should be two good blog entries from the feed
    mock.expectedMessageCount(2);

    // Asserts that the above expectations is true, will throw assertions exception if it failed
    // Camel will default wait max 20 seconds for the assertions to be true, if the conditions
    // is true sooner Camel will continue
    mock.assertIsSatisfied();
}

/**
 * Services for blogs
 */
public class BlogService {

    /**
     * Tests the blogs if its a good blog entry or not
     */
    public boolean isGoodBlog(Exchange exchange) {
        Entry entry = exchange.getIn().getBody(Entry.class);
        String title = entry.getTitle();

        // We like blogs about Camel
        boolean good = title.toLowerCase().contains("camel");
        return good;
    }

}