Orchestrate JAX-WS Web services with JBoss Fuse

In this tutorial we will learn how to install a Camel blueprint project on JBoss Fuse and orchestrate a CXF Web service which is published on WildFly application server.

The starting point for this tutorial is a simple HelloWorld Web service. Here is the implementation class:

@WebService(endpointInterface = "demows.HelloWorld",
            targetNamespace = "http://hello.world.ns/",
            name = "HelloWorld",
            serviceName = "HelloWorldService",
            portName = "HelloWorldPort")
@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
public class HelloWorldImpl implements HelloWorld {

    public String sayHi(String text) {
    	System.out.println(text);
        return "Hello " + text;
    }
    
    public String greetings(Person person) {
    	System.out.println(person);
        return "Greetings " + person.getName() + " " + person.getSurname();
    }
}

The implementation class is deployed on WildFly application server and the WSDL is available at: http://localhost:8080/demows/HelloWorldService?wsd

Creating the BluePrint project

Now we will create a Camel blue print project. If you are running in JBoss Developer studio, choose New Fuse Project and select the camel-archetype-blueprint:

jboss fuse jax-ws web service tutorial

Now let’s code the blueprint.xml file. The first attempt will be invoking the sayHi method which received as input a String. This will be pretty easy as we just need:

  • A CXF Endpoint declaration
  • Setting the Body with the value of the String
  • Something to trigger the execution of the route, such as a one-shot Timer

Here is the blueprint.xml which does it:

<?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:cxf="http://camel.apache.org/schema/blueprint/cxf"
	xmlns:camel="http://camel.apache.org/schema/spring"
	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/spring http://camel.apache.org/schema/spring/camel-spring.xsd
             http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd
             http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
 

	<cxf:cxfEndpoint id="SimpleWebSevice"
		address="http://localhost:8080/demows/HelloWorldService" wsdlURL="http://localhost:8080/demows/HelloWorldService?wsdl"
		serviceClass="demows.HelloWorldImpl" />

	<camelContext trace="true" id="cbr-example-context"
		xmlns="http://camel.apache.org/schema/blueprint" xmlns:order="http://fusesource.com/examples/order/v7">
		<route id="wsClient">
			<from uri="timer:foo?repeatCount=1" />
			<setBody>
				<simple>Helloworld</simple>
			</setBody>
		 
			<log message="${body}" />
			<to uri="cxf:bean:SimpleWebSevice?defaultOperationName=sayHi" />
			<to uri="mock:result" />
		</route>
	</camelContext>

</blueprint>

You can publish directly the project from JBoss Developer Studio by adding a Fuse Server. If you don’t have JBoss Developer Studio, from the shell build the project at first:

mvn clean install

then from the Karaf console execute:

JBossFuse:karaf@root> osgi:install -s mvn:com.mycompany/jaxws-fuse-demo/1.0.0-SNAPSHOT

The project should be deployed. Check on the Karaf console that the osgi has been installed:

JBossFuse:karaf@root> osgi:list

You should find something like this at the end of the list:

[ 271] [Active ] [Created ] [ ] [ 60] A Camel CXF Blueprint Route (1.0.0.SNAPSHOT)

On the WildFly application server console you should expect to find a log of the Web service call:

jboss fuse tutorial blueprint jaxws

Passing Objects from the Camel Route

And now with the more complex example: we will pass a Person object to the Camel route. For this purpose we will add a simple PersonFactory class that will grab the body and construct a Person from it. To keep it pretty simple I’ve used a StringTokenizer:

package demows;

import java.util.StringTokenizer;

public class PersonFactory {

    public Person createPerson(String body){
    	StringTokenizer st = new StringTokenizer(body,":");
    	
    	System.out.println("Going to create Person "+body);
        Person person = new Person();
        person.setName(st.nextToken());
        person.setSurname(st.nextToken());
    	return person;
    }
    
    public PersonFactory() { }
}

Now we need to vary a little bit our blueprint so that the PersonFactory class is defined and used to generate a Person object:

<?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:cxf="http://camel.apache.org/schema/blueprint/cxf"
	xmlns:camel="http://camel.apache.org/schema/spring"
	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/spring http://camel.apache.org/schema/spring/camel-spring.xsd
             http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd
             http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">

	<cxf:cxfEndpoint id="SimpleWebSevice"
		address="http://localhost:8080/demows/HelloWorldService" wsdlURL="http://localhost:8080/demows/HelloWorldService?wsdl"
		serviceClass="demows.HelloWorldImpl" />

	<bean id="personFactory" class="demows.PersonFactory" />

	<camelContext trace="true" id="cbr-example-context"
		xmlns="http://camel.apache.org/schema/blueprint" xmlns:order="http://fusesource.com/examples/order/v7">
		<route id="wsClient">
			<from uri="timer:foo?repeatCount=1" />
			<setBody>
				<simple>john:doe</simple>
			</setBody>
			<bean ref="personFactory" method="createPerson" />
			<log message="${body}" />
			<to uri="cxf:bean:SimpleWebSevice?defaultOperationName=greetings" />
			<to uri="mock:result" />
		</route>
	</camelContext>


</blueprint>

Now redeploy the project from JBoss developer studio. If you are using just the shell uninstall the previous bundle

JBossFuse:karaf@root> osgi:uninstall [bundleid]

Then re-install it:

JBossFuse:karaf@root> osgi:install -s mvn:com.mycompany/jaxws-fuse-demo/1.0.0-SNAPSHOT

Now check from the hawtio console to see your Camel route in action (http://localhost:8181):

jax-ws jboss fuse tutorial web service example

As you can see, all the route steps have been correctly executed. You should find as well a log on the application server console informing you that the Web service has been invoked. Have fun with JBoss Fuse and Web services!