Since we're on a major migration process of this website, some component documents here are out of sync right now. In the meantime you may want to look at the asciidoc in the repository:

Routing/Mediation service

The routing/mediation between services/bundles will be created using Camel Spring DSL language. We will describe its creation/genesis step by step.

First, create the file camel-context.xml in the directory src/main/resources/META-INF/spring and add the lines :

Compare to a simple camel project, the spring beans tag has been enriched with new namespaces :

Now, that the schema/namespaces are declared, we can start to add additional stuffs like import resources, beans reference, ... that our routing engine will use.

Step 1 : Webservice infrastructure : CXF

We will use the CXF framework to deploy the reportincident webservice and run it into the OSGI platform.

To work with it, resources (= spring beans) declared in CXF project must be imported using the statement import resource.

These imports will be used by spring at the bundle startup to instantiate the beans defined in these files. These beans are responsible in fact to deploy the architecture of the CXF bus top of the OSGI server and to provide a servlet that we will use to communicate with webservices engine of CXF.

Remark : for the purpose of this tutorial, we have packaged this configuration into the camel-spring file but it could be defined in a separate xml file with by example the component bean that Camel will use to communicate with CXF bus. This allows you to separate routing from parameters to be provided to configure endpoints.

The camel CXF endpoint is configurated like this :

Remarks :
(1) - the address corresponds to the URI address of the web services,
(2) - the serviceClass is the name of the class used work with the webservices and deployed in the bundle reportincident.webservice
(3) - xmlns:s is the namespace of the reportincident webservice (see reportincident.webservice)

Step 2 : Queuing engine

No matter if the incidents come from a webservice or a files but before to process and save them in the database, we will put
our messages in a queue. The queue manager used here is ActiveMQ.
Like CXF, we will use spring xml file to deploy ActiveMq into the server and configure it. This will be done in two steps

a) ActiveMQ

Like CXF, ActiveMq can be installed in the infrastructure using a spring.xml configuration file. So, create the file activemq-broker.xml in the directory src/main/resources/META-INF/spring and add the following lines.

At the bundle startup, Spring will instantiate the beans declared and in consequence start the queuing engine. We haven't changed the content of the file corresponding to what is proposed in the ServiceMix distribution but you can use here the same technique described for the Datasource and add properties that you configure through by example a org.apache.activemq.config.etc file.

The activeMq broker can also be integrated differently because the ServiceMix4 distribution (and not ServiceMix Kernel) proposes it in standard with additional commands that you can use from the console to :

Available commands in activemq:
browse Display selected messages in a specified destination
bstat Displays useful broker statistics
create-broker Creates a broker instance.
destroy-broker Destroys a broker instance.
list Lists all available brokers in the specified JMX context
purge Delete selected destination's messages that matches the message selector
query Display selected broker component's attributes and statistics

The pom.xml file must be modified to add properties required by Spring blueprint. So add the following lines :

Remarks :
(1) - Include-Resource will allow to add to the jar generated the spring files of the directory src/main/resources/META-INF/spring
(2) - The Spring-Context tag allows to provide specific information used by Spring blueprint service to load the application context and how to load it. The asterisk means that all the spring xml files will be processed
(3) - The list of classes to be used is dependent of the queue engine use as implementation. This list must be reviewed when switching from ActiveMq to IBM WebSphere MQ, Tibco, ...

b) Camel ActiveMq component

To makes Camel independent of the JMS queue engine deployed in the OSGI server, we will implement a proxy using blueprint service between Camel component and the queuing engine used (Apache ActiveMq, IBM Websphere MQ, Oracle Advance Queue, TIBCO, ...)

First, create a spring DSL file osgi-queuingservice.xml in the directory {{src/main/resources/META-INF-spring}}directory containing the following information :

(1) Spring will instantiate the ActiveMqComponent to work with the ActiveMq server. If you would like to use another JMS component, then switch this class to org.apache.camel.component.jms.JmsComponent

(2) Our camel component will be exposed on the OSGI registry as an org.apache.camel.Component and has a reference to the ActiveMQComponent, JMSComponent

Next adapt the POM.xml file like this to instruct the felix plugin how to generate the MANIFEST.MF file

Remark that we import here the org.apache.activemq.camel.component class and not the ActiveMQComponent java class.

All the infrastructure is in place, so we can start to describe the beans that we will use

Step 3 : Beans references

5 beans will be used by our application :

  • BindyCsvDataFormat : to generate the model, marshall (= parse a CSV file in to incidents objects) or unmarshall (= create a CSV file from incidents objects)
  • IncidentSaver : proxy service who will extract from the body of the message the Incidents objects and call the reportinicident.Service bundle to save in the DB the incidents
  • WebService : service who will receive messages from WebServices, extract them from the body message and transform them into Incident objects
  • Feedback : simple class who will send a message back to the webservice

So, adapt the camel-context.xml file :

Remarks :

(1) - The name of the package containing the class of the model must be provided as parameter
(2) - We inject into our proxy service using OSGI service reference, the interface IncidentService
(3) - We need also an OSGI service reference to the queue engine using the interface org.apache.camel.Component

We will quickly review the three classes that we will created for our project in the directory org.apache.camel.example.reportincident.internal :

a) IncidentSaver

Remarks :
(1) - We instantiate List and Map classes that we will use to extract objects of our incident model
(2) - Using the method exchange.getIn().getBody(), we extract the objects from the message and put them in a List
(3) - We get the Header field ('Origin') to check the origin of the messages (file). This info will be persisted in the DB
(4) - The object incident is retrieved from the Map model. In our case, the key is unique because we have only created one model class
(5) - The incident is saved in the database by calling the OSGI service IncidentService.saveIncident
(6) - The field setIncidentService is used by Spring to inject dependency with OSGI service

b) WebService

Remarks :
(1) - The message coming from the WebService and copied in the InputReportIncident class is retrieved from the body using the method exchange.getIn().getBody()
(2) - We create using the model a class Incident where we will put webservice's InputReportIncident
(3) - We get the Header field ('Origin') to check the origin of the messages (webservice). This info will be persisted in the DB
(4) - The model incident is added to the Map and List objects required by Camel Bindy
(5) - The model is added to the body object of the message that we send it OUT
(6) - Thbe header parameter is also propagated for the next endpoint

c) Feedback

Remarks :
(1) - An OutputReportIncident object is created because it will be used to send the message back to the webservice
(2) - The field/property setCode is setted with the value ("OK")
(3) - The method setOk() will be called by Camel routing

Step 4 : Routing

Now that evverything is in place, we can create the three routes that we need to implement the architecture that we have presented in the introduction of this tutorial

From File(s) to queue

This first route will be used by Apache Camel to read files deposited in the directory. Here is the explanation of the route

Remarks :
(1) - camel:camelContext tag is used to instantiate the camelcontext at the launch of the bundle. The trace parameter is defined as true so the tracing will be available on the console
(2) - The from uri="file" informs Camel that a file component must be started and it will listen for incoming files deposited in the directory d:/temp/data/reportincident. When the file is processed (end of the Camel route), then it is moved to the directory d:/temp/backup/ where the file is renamed (.bak extension is added). During the process of the file and till the route is not finished, the file will be locked
(3) - A header is added to the message with the property origin setted to file
(4) - To parse the content of the CSV file into a collection of incident objects, we use the action unmarshall where the reference provided corresponds to the bean BindyCsvDataFormat instantiated by Spring
(5) - The result of the parsing process is copied as a message in the queue:in

From Webservices to queue

The second route will read incoming web services call, extract the XML messages from the web services, transform it into an InputReportIncident, send the object to a bean who will convert it into an Incident object and put the result in the queue:in.

Remarks :
(1) - The CXF component will be used by Camel to receive incoming web services calls
(2) - A header is added to the message with the property origin setted to webservice
(3) - The content of the SOAP envelop is extract and the XML messages is mapped to the InputReportIncident class
(4) - A message contaning the header, InputReportIncident object is send the bean "Webservice" where the object will be transformed into an Incident object
(5) - The message is placed into a queue which is a inOnly so no OUT message will be send back to the bean webservice
(6) - A transform process is added to send back to the web services the reply. Using camel:method, we can define which method of the class to use

From queue to DB

The last route will read messages of the queue and send them to the bean IncidentSaver to save the incidents in the database

Add instructions to generate MANIFEST.MF file

Now that the reportincident.routing project is ready, we will modify the pom.xml file to add required instructions to generate the jar and MANIFEST.MF file of the bundle :

Remarks :
(1) - Classes required by Camel, CXF muste be imported.
(2) - Our internal classes are declared as private to avoid that they become available for another bundles of the OSGI server


In this section of the tutorial, we have discussed how to design the routing between endpoints/components of our application using Camel Spring DSL language. We have also investigated how to setup the infrastructure required to work with ActiveMq, any other queuing engine and CXF. In the next chapter, we will see how to create the web application, package the solution and deploy it on ServiceMix.


© 2004-2015 The Apache Software Foundation.
Apache Camel, Camel, Apache, the Apache feather logo, and the Apache Camel project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
Graphic Design By Hiram