Using Apache CFX and Apache Camel in ESB
- 8 minutes read - 1609 wordsIn the previous article, we learned about ESB and deployed our first OSGi bundle on FuseESB.
In this article, we will learn how to build Apache CXF and Apache Camel component and deploy them on FuseESB.
Lets understand what are these components :
Apache Camel ™
Powerful open source integration framework based on known Enterprise Integration Patterns with powerful Bean Integration.
Camel lets you create the Enterprise Integration Patterns to implement routing and mediation rules in either a Java based Domain Specific Language (or Fluent API), via Spring or Blueprint based Xml Configuration files or via the Scala DSL. This means you get smart completion of routing rules in your IDE whether in your Java, Scala or XML editor.
Apache CFX
Apache CXF is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.
OSGI Apache CXF packaging and deployment
Create the CXF OSGi Bundle
-
Create the Maven project using
servicemix-cxf-code-first-osgi-bundle
archetype. Run Following command.mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-cxf-code-first-osgi-bundle -DarchetypeVersion=2011.02.1-fuse-00-08 -DgroupId=com.tk.example.cxf -DartifactId=cxf-example -Dversion=1.0
It will generate the maven project as folder “
cxf-example
” in the directory where you run the above command.Note : Make sure you have added fusesource repository to the maven, refer to http://fusesource.com/docs/esb/4.3.1/esb_deploy_osgi/Build-GenerateMaven.html#Build-GenerateMaven-AddRepos
-
Import the “
cxf-example
” in eclipse as maven project- Select File > Import > Existing Maven Projects
- Browse the folder “cxf-example” as Root Directory
- Finish
-
Brief discussion about the main files:
Person.java
- This is the main web service interface. Interface is written under@WebService
to make it JAX-WS webservice.package com.tk.example.cxf; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; @WebService @XmlSeeAlso({com.nagarro.example.cxf.types.ObjectFactory.class}) public interface Person { @RequestWrapper(localName = "GetPerson", className = "com.nagarro.example.cxf.types.GetPerson") @ResponseWrapper(localName = "GetPersonResponse", className = "com.tk.example.cxf.types.GetPersonResponse") @WebMethod(operationName = "GetPerson") public void getPerson( @WebParam(mode = WebParam.Mode.INOUT, name = "personId") javax.xml.ws.Holder<java.lang.String> personId, @WebParam(mode = WebParam.Mode.OUT, name = "ssn") javax.xml.ws.Holder<java.lang.String> ssn, @WebParam(mode = WebParam.Mode.OUT, name = "name") javax.xml.ws.Holder<java.lang.String> name ) throws UnknownPersonFault; }
PersonImpl.java
– This is the implementation class of the Person interface.beans.xml
– Spring bean class define the service end point.<jaxws:endpoint id="HTTPEndpoint" implementor="com.tk.example.cxf.PersonImpl" address="/PersonServiceCF"/>
pom.xml
- The maven build file to build as jar file.Client.java
to test the web service. -
Run maven “clean install” on the attached project.
mvn clean install
OR Right click on pom.xml and select Run As > Maven clean and then again Run As > Maven install.
It will generate cxf-example-1.0.jar in target folder.
-
You have created the OSGi bundle successfully. Now deploy these in next steps.
Deploy the CXF OSGi Bundle in FuseESB
-
Run following command on FuseESB console to install the bundle
osgi:install -s file:<PROJECT_DIR>/target/cxf-example-1.0.jar
osgi:install -s file:D:\cxf-camel-osgi\cxf-example\target\cxf-example-1.0.jar
or Just drop the cxf-example-1.0.jar in deploy folder.
-
Now access the WSDL on following URL
http://<hostname>:<port>/cxf/<WSName>?wsdl
-
Run Client.java after correcting the url and port.
Invoking getPerson... getPerson._getPerson_personId=Guillaume getPerson._getPerson_ssn=000-000-0000 getPerson._getPerson_name=Guillaume
Let’s try to build our own helloworld service.
HelloWorldWS.java
package com.tk.example.hellowrold;
import javax.jws.WebService;
/**
* HelloWorld Web Service.
* @author kuldeep
*/
@WebService
public interface HelloWorldWS {
/**
* Method to say Hi
* @param text
* @return Hello text :)
*/
String sayHi(String text);
}
- HelloWorldWSImpl.java
package com.tk.example.hellowrold;
import javax.jws.WebService;
/**
* HelloWorld Web Service implementation
* @author kuldeep
*/
@WebService(endpointInterface = "com.tk.example.hellowrold.HelloWorldWS")
public class HelloWorldWSImpl implements HelloWorldWS {
public String sayHi(String text){
System.out.println("Inside say Hi");
return "Hello " + text + ":)";
}
}
- Define service end point in beans.xml
<jaxws:endpoint id="helloworld"
implementor="com.tk.example.hellowrold.HelloWorldWSImpl"
address="/HelloWorld"/>
- Build the project again and deploy it to FuseESB
- Open URL http://localhost:8181/cxf/HelloWorld?wsdl to see the wsdl
- Let create a test class to consume the HelloWorld web service
package com.tk.example.hellowrold.test;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.nagarro.tk.hellowrold.HelloWorldWS;
public class WSTest {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(HelloWorldWS.class);
factory.setAddress("http://localhost:8181/cxf/HelloWorld");
HelloWorldWS client = (HelloWorldWS)factory.create();
String response = client.sayHi("User");
System.out.println(response);
}
}
- Run this class.
It should print on console
Hello User:)
OSGI Apache Camel packaging and deployment
Create the Camel OSGi Bundle
-
Create the Maven project using
servicemix-camel-osgi-bundle
archetype. Run Following command.mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-camel-osgi-bundle -DarchetypeVersion=2011.02.1-fuse-00-08 -DgroupId=com.tk.example.camel -DartifactId=camel-example -Dversion=1.0
It will generate the maven project as folder “
camel-example
” in the directory where you run the above command.Note : Make sure you have added fusesource repository to the maven, refer to http://fusesource.com/docs/esb/4.3.1/esb_deploy_osgi/Build-GenerateMaven.html#Build-GenerateMaven-AddRepos
-
Import the “camel-example” in eclipse as maven project as described in last section and It should create following structure.
-
Brief discussion about the main files:
MyTransform.java
- This class will act as log generator, Its will log the message “»>set body : package com.tk.example.camel; import java.util.Date; import java.util.logging.Logger; public class MyTransform { private static final transient Logger LOGGER = Logger.getLogger(MyTransform.class.getName()); private boolean verbose = true; private String prefix = "MyTransform"; public Object transform(Object body) { String answer = prefix + " set body: " + new Date(); if (verbose) { System.out.println(">>>> " + answer); } LOGGER.info(">>>> " + answer); return answer; } public boolean isVerbose() { return verbose; } public void setVerbose(boolean verbose) { this.verbose = verbose; } public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } }
camel-context.xml
– This file is a spring configuration file, it define the camel routing.<?xml version="1.0" encoding="UTF-8"?> <!-- Generated by Apache ServiceMix Archetype --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://camel.apache.org/schema/osgi" xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" xmlns:ctx="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://camel.apache.org/schema/osgi http://camel.apache.org/schema/osgi/camel-osgi.xsd http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <osgi:camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="timer://myTimer?fixedRate=true&period=2000"/> <bean ref="myTransform" method="transform"/> <to uri="log:ExampleRouter"/> </route> </osgi:camelContext> <bean id="myTransform" class="com.tk.example.camel.MyTransform"> <property name="prefix" value="${prefix}"/> </bean> <osgix:cm-properties id="preProps" persistent-id="com.tk.example.camel"> <prop key="prefix">MyTransform</prop> </osgix:cm-properties> <ctx:property-placeholder properties-ref="preProps" /> </beans>
This creates route between component “
timer
” and “log
”. EndPoint URI are defined as follows:scheme:contextPath[?queryOptions]
Where “scheme
” identifies the protocol/component and the “contextPath
” is the details that will be interpreted by provided protocol/component and the “queryOptions
” are the parameters. List of components can be found at http://fusesource.com/docs/esb/4.4.1/camel_component_ref/Intro-ComponentsList.htmlSo in above example the producer timer generates a message from the
myTransform.transform()
and propagate it to logger.pom.xml
- The maven build file to build as jar file. -
Run maven “clean install” on the attached project.
mvn clean install
OR Right click on pom.xml and select Run As > Maven clean and then again Run As > Maven install.
It will generate “camel-example-1.0.jar” in “target” folder.
-
You have created the Camel OSGi bundle successfully. Now deploy these in next steps.
Deploy the Camel OSGi Bundle in FuseESB
This example uses the camel-core feature (Ref to http://fusesource.com/docs/esb/4.4.1/camel_component_ref/Intro-ComponentsList.html ) for timer and log component. Verify that camel-core is installed on FuseESB.
-
Run following command on Fuse ESB console.
$ features:list | grep camel-core [installed] [2.8.0-fuse-01-13] camel-core camel-2.8.0-fuse-01-13
It should list a row on console with status installed something like above.
If it does not then install the camel-core by running following command
$ features:install camel-core
-
Run following command on FuseESB console to install the bundle
osgi:install -s file:<PROJECT_DIR>/target/camel-example-1.0.jar
For example
osgi:install -s file:D:/cxf-camel-osgi/camel-example/target/camel-example-1.0.jar
or Just drop the cxf-example-1.0.jar in deploy folder.
-
It will start printing logs on console as well as in log file
>>>> MyTransform set body: Thu Jan 19 14:02:28 IST 2012 >>>> MyTransform set body: Thu Jan 19 14:02:30 IST 2012 >>>> MyTransform set body: Thu Jan 19 14:02:32 IST 2012 >>>> MyTransform set body: Thu Jan 19 14:02:34 IST 2012 >>>> MyTransform set body: Thu Jan 19 14:02:36 IST 2012
You can locale log for “ExampleRouter” category in log file.
Exercise 1 – Write message to files.
- Let’s try to add another route in above example which will direct the log to a file.
<route> <from uri="timer://myTimer?fixedRate=true&period=2000"/> <bean ref="myTransform" method="transform"/> <to uri="file:C:/timerLog"/> </route>
- Build and install the bundle.
- It will write each message to a file in the given directory path.
Exercise 2 – Inbox/Outbox
Lets write a route which picks files from one folder and put them to other folder.
-
Add following route
<route> <from uri="file:C:/inbox"/> <to uri="file:C:/outbox"/> </route>
-
Build and install the bundle Now try to put any file in input box folder, c:/inbox, it will be immediately moved to c:/outbox folder.
Exercise 3 – Filter
Filter the files based on extension and put them in respective folders.
-
Add following route
<route> <from uri="file:C:/inbox"/> <choice> <when> <simple>${file:name.ext} == 'png' or ${file:name.ext} == 'bmp' or ${file:name.ext} == 'gif'</simple> <to uri="file:C:/outbox/images"/> </when> <when> <simple>${file:name.ext} == 'txt'</simple> <to uri="file:C:/outbox/text"/> </when> <when> <simple>${file:name.ext} == 'doc' or ${file:name.ext} == 'docx'</simple> <to uri="file:C:/outbox/office"/> </when> <otherwise> <to uri="file:C:/outbox/other"/> </otherwise> </choice>
-
Build and install the bundle
-
Now try to put any file in input box folder, c:/inbox, it will be immediately moved to respective folders.
OSGI Apache Camel and CXF packaging and deployment
Integrate Camel and CXF
-
User the same eclipse project of example POC - OSGI Apache CXF packaging and deployment
-
Copy the project “cxf-example” and Paste as “
camel-cxf-example
” -
Add camel dependency in
pom.xml
<properties> <camel.version>2.8.0-fuse-00-08</camel.version> </properties> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency>
-
Edit
beans.xml
- Use following schema definition<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring-2.1.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http://camel.apache.org/schema/cxf http://activemq.apache.org/camel/schema/cxf/camel-cxf.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
Define the service end point as camel-cxf end point instead of jax-ws as follows Change from
<jaxws:endpoint id="helloworld" implementor="com.tk.example.hellowrold.HelloWorldWSImpl" address="/HelloWorld"/>
to
<cxf:cxfEndpoint id="helloworld" address="/HelloWorld" serviceClass="com.tk.example.hellowrold.HelloWorldWS" />
-
Lets define camel route which will direct every web service call to a file.
<camel:camelContext xmlns="http://camel.apache.org/schema/spring"> <camel:route> <camel:from uri="cxf:bean:helloworld?synchronous=true" /> <camel:to uri="file:C:/outbox/messages"/> </camel:route> </camel:camelContext>
-
Run maven build and deploy the Jar in FuseESB ( I assume, you have learned the deployment by now, so not mentioning steps again)
-
It will write whatever message you sent to hello world service to the file and return the same
This completes the article. You have learned basics for CXF and Camel and working them together. Try more complex examples
#ESB #java #Apache Service Mix #Apache CFX #FuseESB #XML #Apache Camel #enterprise #integration #technology