Monday, April 16, 2012

Apache Camel first steps I

Many articles and tutorials exist over the web showing the usage of Apache Camel. The Camel site itself it's a great (of course) source of information and how-tos. Read the first chapter of "Camel in action" (available here) is useful as well. It is a very good way to understand the different aspects that Camel offers, it's definitely worth the price.

When I started working with it I had some difficulties in understanding how to get the best out of it such as the great advantage of using beans to implement the business logic of an app. Once I understood that precious feature I created a workshop to show it to my fellow coworkers.

This post will show a basic route that is going to be extended in the next few posts in order to cover more advanced and interesting features such as the Properties component and the usage of the Bean component. Let's start!

What we are going to see:
  • create a Camel Java DSL project using maven the archetype
  • implement moving files using a route
  • test the route at runtime
Prerequisite:
  • install Eclipse (I am currently using Helios)
  • have m2eclipse plugin installed in Eclipse
Open Eclipse and create a new maven project


Set the base dir of the project then select the maven archetype as show below:


In the next screen define group and artifact id:


Ok now you are set and ready to implement your Camel application. In your project view you should have something similar to:


As you can see I am actually using camel-2.6.0 version. Feel free to use the latest one (2.9.1) since we are going to use features that are compatible with the new version.

Now let's implement the route. It will get an xml file from a directory, check one of its element value  and move the file in some directory based on that value:

        from("file:src/data?noop=true").

            choice().
                when(xpath("/person/city = 'London'")).to("file:target/messages/uk").
                otherwise().to("file:target/messages/others");

The choice..when..otherwise methods work as an if..then..else statement so the code is pretty self explanatory. This is one of the nice features of Camel after all! 

This is the rest of the class code:

/**
 * A Camel Router
 */
public class MyRouteBuilder extends RouteBuilder {

    /**
     * A main() so we can easily run these routing rules in our IDE
     */
    public static void main(String... args) throws Exception {
        Main.main(args);
    }

    /**
     * Let's configure the Camel routing rules using Java code...
     */
    public void configure() {

        getContext().setTracing(true);
       
        // here is a sample which processes the input files
        // (leaving them in place - see the 'noop' flag)
        // then performs content based routing on the message
        // using XPath
        from("file:target/test-classes/data?noop=true").
            choice().
                when(xpath("/person/city = 'London'")).to("file:target/messages/uk").
                otherwise().to("file:target/messages/others");

    }
}

The main method allows to run the route in a runtime environment directly within  Eclipse.
While setting the tracing mode will show what is happening at run time in the Camel environment log. Let's start the route:



This is the output that you should see in the console window:



The environment started and dropping the xml files from the src/data to src/foo will trigger the execution of the route. Note that src/foo will be created by Camel as soon as the framework properly starts. The following is the snapshot of the console after the execution:



Look in target/messages/others and target/messages/uk you have the two xml files moved in one of the two directories based on their content.

Let's create a test of our route. The code shown below tests one of the two endpoints in particular the file moved in target/messages/uk. The most interesting thing is the usage of the @EndpointInject annotation that allows to send content to an endpoint. It is actually an extremely power way of using Camel and in the next post I will show how to take advantage of this technique when implementing routes and business logic.

/**
*
*/
public class MyRouteBuilderTest extends CamelSpringTestSupport {


Logger log = Logger.getLogger(MyRouteBuilderTest.class);

@EndpointInject
ProducerTemplate producer;

@Test
public void testUkFile() {
File inFile = new File("target/test-classes/data/message1.xml");

try {
producer.sendBody("file:target/test-classes/data?noop=true", inFile);
Thread.sleep(1000);
File output = new File("target/messages/uk/" + inFile.getName());
assertTrue(output.exists());
} catch (Exception e) { log.fatal(e);
assertNull(e);

}
}

/*
* (non-Javadoc)
*
* @see
* org.apache.camel.test.CamelSpringTestSupport#createApplicationContext()
*/
@Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext(
"classpath:META-INF/spring/camel-context.xml");
}
}

No comments:

Post a Comment