In this tutorial we will learn how to provide a Web service facade using a Came blueprint project which proxies request to a legacy web service.
This is the second tutorial about Camel and Web services – here you can read the first part: Proxy Web services request with Camel where we have covered this scenario:

The scenario we will discuss in this tutorial is the same, just we will turn the project in a blueprint project and deploy it on JBoss Fuse 6.Here is the blueprint for our project:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<cxf:bus><!-- interceptor per request/response del ws/rest -->
<cxf:features>
<cxf:logging limit="1024"/>
</cxf:features>
</cxf:bus>
<bean id="beanAdapter" class="com.sample.source.ws.BeanAdapter"/>
<!-- WEB SERVICE FACADE -->
<camelcxf:cxfEndpoint id="input-cxf" address="http://localhost:9080/example-input-cxf/"
serviceClass="com.sample.source.ws.FuseExampleCXF"/>
<!-- TARGET WEB SERVICE -->
<camelcxf:cxfEndpoint id="SimpleWebSevice"
address="http://localhost:8080/webserviceslegacy/LegacyWebServiceImpl"
wsdlURL="http://localhost:8080/webserviceslegacy/LegacyWebServiceImpl?wsdl"
serviceClass="com.sample.target.ws.LegacyWebService" />
<camelContext id="example-cxf" xmlns="http://camel.apache.org/schema/blueprint">
<route id="input-cxf">
<from uri="cxf:bean:input-cxf"/>
<transform>
<simple>
${in.body[0]}
</simple>
</transform>
<log message="Message input: ${in.body}"/>
<transform>
<method bean="beanAdapter" method="transform" />
</transform>
<removeHeaders pattern="*"/>
<to uri="cxf:bean:SimpleWebSevice" />
</route>
</camelContext>
</blueprint>
So, the first Web service (input-cxf) is just a Contract exposed through the Camel route. It just contains an interface definition or a WSDL. In our case, it is composed of a Web interface:
package com.sample.source.ws;
import com.sample.source.bean.Wrapper;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface FuseExampleCXF {
@WebMethod
int count(Wrapper wrapper);
}
This Web service has the count method which receives as input a Wrapper Object. The use case is providing a compatibility facade to Web service clients that use this interface and adapt the parameter using a Bean Transformation. The class which is in charge to perform the transformation is the com.sample.source.ws.BeanAdapter class which follows here:
package com.sample.source.ws;
import com.sample.target.bean.Struct;
import com.sample.source.bean.Wrapper;
import org.apache.camel.Exchange;
public class BeanAdapter {
public Struct transform(Wrapper input) {
Struct struct = new Struct();
struct.setX(input.getA());
struct.setY(input.getB());
return struct;
}
}
This class will be in charge to transform the Wrapper class from the incoming Web service into the Struct class which is expected by the target Web service:
package com.sample.target.ws;
import com.sample.target.bean.Struct;
import javax.jws.*;
@WebService
public interface LegacyWebService {
@WebMethod
public int callStruct(@WebParam( name = "total")Struct s);
}
The Web service is deployed on an external middleware, such as JBoss EAP with the following implementation:
package com.sample.target.ws;
import com.sample.target.bean.Struct;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@WebService
public class LegacyWebServiceImpl implements LegacyWebService {
@WebMethod
public int callStruct(@WebParam( name = "struct")Struct s) {
System.out.println("Invoked Web service with "+s.getX() + " and "+s.getY());
return s.getX() + s.getY();
}
}
In order to build the OSGI bundle you can use the following pom.xml :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>it.fuse.demo</groupId>
<artifactId>fuse-demo</artifactId>
<packaging>bundle</packaging>
<name>Fuse :: Demo</name>
<version>0.0.3-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<camel.version>2.15.1.redhat-620133</camel.version>
<fabric8.version>1.2.0.redhat-133</fabric8.version>
<karaf.enterprise.version>2.4.0.redhat-620133</karaf.enterprise.version>
<jboss.fuse.bom.version>6.2.0.redhat-133</jboss.fuse.bom.version>
<maven.bundle.plugin.version>2.5.3</maven.bundle.plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.fuse.bom</groupId>
<artifactId>jboss-fuse-parent</artifactId>
<version>${jboss.fuse.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-blueprint</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicemix.specs</groupId>
<artifactId>org.apache.servicemix.specs.jaxws-api-2.2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>fuse-public-repository</id>
<name>FuseSource Community Release Repository</name>
<url>https://repo.fusesource.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
</repository>
</repositories>
</project>
Now from the Karaf command line, install at first the features required to provision the bundle:
JBossFuse:karaf@root> features:install cxf JBossFuse:karaf@root> features:install camel-jaxb JBossFuse:karaf@root> features:install camel-blueprint JBossFuse:karaf@root> features:install camel-cxf
Next, install the bundle on JBoss Fuse with:
JBossFuse:karaf@root> osgi:install -s mvn:org.apache.camel/fuse-demo/0.0.3-SNAPSHOT
That’s all. Verify with any Web service client that the Web service available on http://localhost:9080/example-input-cxf/ correctly responds and the route camel forwards the call to the target Web service.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.source.sample.com/">
<soapenv:Header/>
<soapenv:Body>
<ws:count>
<!--Optional:-->
<arg0>
<a>1</a>
<b>2</b>
</arg0>
</ws:count>
</soapenv:Body>
</soapenv:Envelope>
You should expect as return a response with the sum of the two parameters of the Wrapper object:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:countResponse xmlns:ns2="http://ws.source.sample.com/">
<return>3</return>
</ns2:countResponse>
</soap:Body>
</soap:Envelope>