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!