vendredi 11 novembre 2011

Riding the Camel : the beginning


Camel is an Apache project : it's a wonderful toolbox to write applications dealing with integration problems.

Integration problems ? Not me !


What does Camel really mean by claiming itself an integration framework ?
Well, it means that you can use Camel as a ground to support common use cases in information system (IS) integration :
  • take datas from one place (file, FTP, HTTP, JMS, ...) to another (memory, file, FTP, HTTP,JMS, ...) to another with or without transformations
  • manage asynchronous exchange from one point to another in your IS
  • open routes inside your IS to establish bridges between isolated zones
  • expose webserivce in a standard way : REST, JAX-WS
  • communicate with other ISs
  • ...

Integration problems ? Me too !


Camel can be used inside your application (batch, webapp, ...) for various needs not marked as "integration problems":
  • reading CSV file to object
  • support asynchronous processing : a massive business request for printing datas, ...
  • executing system commands
  • search in a LDAP repository
  • ...

A quick ride with Camel


Camel implements Enterprise Integration Patterns. EIPs are a bible of pragmatic solutions to common integration problems : how to transport and route messages in IS.
It sounds like ESB stuff, quite foggy and complicated but Camel deals with all this in a pragmatic, lightweight and smart way.
First of all Camel does not claim itself an ESB.
Yes, you can find some core ESB features in Camel, that's not the point !
Most vehicles share same basic components but is a Ferrari a Hummer ?
So now, here is a simple use case :
A web application must display earthquakes that have occured world wide in the last seven days.
Datasource is provided by US Gov and is updated continously : a minute based update will suffice.

The datasource is here.
So, how can Camel help me ?
Well, Camel is provided with lots of components dealing with lots of protocols and proposing few useful concepts.
Here is the core "integration" code :
from("quartz://dataTimer?cron=0+*+*+*+*+?").to("direct:datas");
from("direct:datas")
        .to("http4://earthquake.usgs.gov/earthquakes/catalogs/eqs7day-M1.txt")
        .unmarshal().csv().process(new Processor(){
                public void process(Exchange exchange) throws Exception {
                        Message message = exchange.getIn();
                        List<List<String>> datas = (List<List<String>>) message.getBody();
                        // Skip header
                        datas = datas.subList(1, datas.size()-1);
                        // Process my data
                        for(List<String> row:datas){
                                // Process Row
                                String datetime = row.get(3);
                                String region = row.get(9);
                                String magnitude = row.get(6);
                                // Do something smart
                        }
                }
});
This sample code shows you Camel core concepts.

Core concepts


Camel is a routing and a mediation engine: routing is about to transport informations from one place to another.
It means that Camel uses the Route concept to interact with its environment.
Route concept defines a way to process informations from Endpoint toEndpoint, it has a start and an end, like a real world route.
Informations are encapsulated into Exchange : in and out informations are stored in Message objects inside an Exchange.
Camel Endpoint is an implementation of Message Endpoint Pattern. SomeEndpoint receive Exchange from outside the Route to which they belong, some produce exchanges into the Route by themselves, some make both.
Endpoints in Camel are represented by their URI : an Endpoint URI tells about the endpoint nature and configuration.
And Endpoint is created by a Component: a Camel component is an Endpoint factory.
When Camel tries to solve an Endpoint URI, it picks up the Component associated to the URI protocol part and asks the Component for creation of the Endpoint.
For instance : quartz://dataTimer?cron=0+*+*+*+*+?
Tells Camel to find a Component knowing how to deal with "quartz" protocol. When the Component is found, Camel asks it to create the Endpoint with the URI. If it succeeds Endpoint is added to the current Route.
The sample code shows us basic use of RouteBuilder. RouteBuilder is a very convenient tool to build routes. It's a Java DSL who tries to hide complexity by providing an API close to fluent language.
from("quartz://dataTimer?cron=0+*+*+*+*+?").to("direct:datas");
This line creates a new RouteDefinition object (using the URI), and then invokes "to" method on RouteDefinition object.
The first URI tells us that the Quartz Component is involved.
The last URI shows the Direct Component usage.
This line creates a route based on Quartz and Direct components.
The quartz endpoint will produce an exchange every minute and send it to the next endpoint which will send the exchange to the "datas" endpoint in a synchronous way.
As you can guess this first route is about to trigger the polling of datas through the second route, every minute.
Now:
from("direct:datas")
        .to("http4://earthquake.usgs.gov/earthquakes/catalogs/eqs7day-M1.txt")
        .unmarshal().csv().process(new Processor(){
                public void process(Exchange exchange) throws Exception {
                        ...
                }
});
This line creates a route with the first endpoint as "direct:datas".
The "to" method creates an endpoind based on HTTP4 component and returns aProcessorDefinition[7] object.
When activated by an incoming exchange, this endpoint will issue an HTTP request to get the datas and send an exchange including datas to the next endpoint. The default format is byte array.
Here there is no endpoint after polling datas.
The unmarshal method invoked on a ProcessorDefinition object adds aDataFormat to this processor definition and tells Camel to use this data format to process the "in" value of current exchange.
Then the "csv" method says it is csv dataformat. It uses Camel CSV Dataformat.
It goes like this :
Create route -> Create endpoint datas as a synchronous endpoint -> Get earthquake.usgs.gov/earthquakes/catalogs/eqs7day-M1.txt -> Process datas as CSV -> Invoke custom processor
This article is not provided with complete source code because i want you to understand basic Camel concepts.
Here is a diagram of some Camel core concepts :



The next article will show many ways to integrate Camel in your (mavenized) app.





Contrat Creative Commons

the jee architect cookbook by Olivier SCHMITT est mis à disposition selon les termes de la licence Creative Commons Paternité - Pas d'Utilisation Commerciale - Pas de Modification 3.0 Unported.

Aucun commentaire:

Enregistrer un commentaire