Tuesday, August 27, 2013

Taste of Apache Camel: Part III - More on using Beans

Let us continue with the topic about beans from previous post. I mentioned that beans can process and convert data to different types.

Example 3:

Make a file movies.txt that looks like this (movie name:actors separated with comma):

Now we'll try to read the file and put it in simple POJO.

For route to read a file, there is file component. So let's make a new route in configure() method in our route builder class.

In this route we're using file component to read a file movie.txt from some folder and with property noop=true the file will not be removed but just read. The body that component file produces will be of type java.io.File.
When invoking our bean ExampleBean there is a new method giveMeMovies that accepts body from route. In our bean we must therefore create this method.

In this method implementation I use @Body annotation. It is not necessary but I use it for easier code reading.
The method just reads file line by line and creates list of Movie objects. This list is then returned to route and becomes new body with different type. In the route there is processor to show how to get body and data from it.

Example 4:

Method giveMeMovies in ExampleGean returns a list of objects. That's why this method can be used with splitter. Splitter splits a message into a number of pieces and process them independently. This time we will not change ExampleBean since we have everything we need to show how splitter works. We just need to make a new route in configure() method in our route builder class.

This route has exactly same functionality as one in Example 3 but is few lines shorter. Be careful to close splitter with .end() or you could have problems when route does something after splitter.

My posts on Apache Camel:
 - Part I - Property Placeholder
 - Part II - Using Beans
 - Part III - More on using Beans
 - Part IV - Solr
 - Part V - Marshalling and Unmarshalling

Friday, August 23, 2013

Taste of Apache Camel: Part II - Using Beans

In my previous post I showed how to use Property Placeholder. Next we'll look into using Beans. They can be used in few ways mentioned on Apache Camel page.
Lets make a new Maven project and pom.xml should look something like this:
This time blueprint.xml will not be necessary, unless you want to run it in container like Karaf or Fuse.
To demonstare how beans work, lets create one.
The bean is very simple. It has only one method that prints out content of route body. This method also has annotation @Handler to indicate that this method should be used for Bean Binding. This has an advantage as you need not specify a method name in the Camel route, and therefore do not run into problems after renaming the method in an IDE that can't find all its references.

Example 1:


The route is simple, too.
The component timer fires and generate message exchanges. Here route is fired every 10 seconds with initial delay of 10 seconds. Parameter repeatCount specifies a maximum limit of number of fires, where zero or negative means fire forever. Timer component is part of camel-core, but for more advanced features camel-quartz could be used.
Body for the route is here set to some hardcoded string, and our bean will get it as parameter to the method. Bean is invoked as endpoint with .bean(). This is enough. Camel knows which method to use, because it is annotated with @Handler annotation.

Example 2:


Lets make another method in out ExampleBean bean. This time method is not annotated, because only one per bean is allowed. This method has two parameters and returns another string.
Now let make another route in configure() method in our route builder class. Here we specified which method from our bean route must use. In double quotes method name must be specified and what the values of parameters will be. If you would like to know how Bean Binding works in more details, go here. When route is started, it should be accessible on url http://localhost:2208/beanexample2/{name}/{surname} and it should return an answer that answerMe method in ExampleBean put together.
Here we see that bean changed body value of out route just by returning some value. The same way the body can be converted to some other type as I will demonstrate in one of my future posts.

My posts on APache Camel:
 - Part I - Property Placeholder
 - Part II - Using Beans
 - Part III - More on using Beans
 - Part IV - Solr
 - Part V - Marshalling and Unmarshalling

Tuesday, August 20, 2013

Taste of Apache Camel: Part I - Property Placeholder

I started learning Apache Camel about a year ago. All routes are running in Red Hat JBoss FUSE, but about that some other time.
All routes are written in Java DSL and Blueprint with help of Maven.
I will show how to use Property Placeholder in blueprint.xml to set some properties which will be used in route. The route will be simple. The route will listen on some URL on port, that is set in blueprint.xml and returns some answer.
First we must set pom.xml:
Next step is blueprint.xml. It must be in folder resources/OSGI-INF/blueprint. Here are two properties. First one is port on which this service will be accessible. Second one is answer of this service. What are all other things I will try to explain when looking at FUSE Fabric.
Finally the source code. Every class that has route defined as Java DSL, must extend org.apache.camel.builder.RouteBuilder. And that class must implement configure() method. To run this route in shell, main method must create org.apache.camel.main.Main object. When route is started, it should be accessible on url http://localhost:2013/ppexample/{yout text}.
If this works, you should notice that port is set to what was value in main method and not in blueprint.xml. If you omit setters in main method, values from blueprint.xml will be used.

My posts on APache Camel:
 - Part I - Property Placeholder
 - Part II - Using Beans
 - Part III - More on using Beans
 - Part IV - Solr
 - Part V - Marshalling and Unmarshalling