JBoss ESB Webservice Consumer

Important note: JBoss ESB is an archived project and its latest release dates back to Mar 2013. The replacement technology for it is JBoss Fuse which is an open source enterprise integration platform and service bus. You can find here a quickstart tutorial about JBoss Fuse.

JBoss Enterprise Service Bus (ESB) provides since the release 4.2GA the ability to construct SOAP requests and consume SOAP responses without having to generate proxy code. This functionality can be used to invoke external Webservice Endpoints from within the ESB.

In order to interact with webservices JBoss ESB provides two out of the box Actions:

SOAP Client: This SOAP Client Action allows consumption of externally hosted Webservice endpoints.
SOAPProcessor: The SOAPProcessor action allows you to expose JBossWS Endpoints through endpoints (listeners) running on the ESB (“SOAP onto the bus”).

In this article we'll discuss about the SOAP client. Let's start with a simple WebService: (the code of this article can be found in the esb samples directory named webservice_consumer1)

@WebService(name = "HelloWorld", targetNamespace = "http://webservice_consumer1/helloworld")
public class HelloWorldWS
{
   @WebMethod
   public String sayHello(@WebParam(name = "toWhom")
   String toWhom)
   {

      String greeting = "Hello World Greeting for '" + toWhom + "' on " + new java.util.Date();

      return greeting;

   }

Just a simple JAX-WS Web Service with one exposed webmethod "sayHello". In Order to invoke this Web Service from JBoss ESB you need to provide 3 actions:

Step 1) Building the SOAP message with Request Action

 

The first action needed to consume a web service is the Request Action: this Action is in charge to convert the message into a webservice request map. 

Here's the RequestAction:

<action name="request-mapper"
    class="org.jboss.soa.esb.samples.quickstart.webservice_consumer1.MyRequestAction">
</action>

This is the implemented class MyRequestAction:

package org.jboss.soa.esb.samples.quickstart.webservice_consumer1;

import org.jboss.soa.esb.actions.AbstractActionLifecycle;
import org.jboss.soa.esb.actions.ActionUtils;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.message.Body;
import org.jboss.soa.esb.message.Message;
import java.util.HashMap;

public class MyRequestActionMyRequestAction extends AbstractActionLifecycle
{
   protected ConfigTree _config;

   public MyRequestAction(ConfigTree config)
   {
      _config = config;
   }

   public Message noOperation(Message message)
   {
      return message;
   }

 
   public Message process(Message message) throws Exception
   {
      logHeader();
      String msgBody = (String) message.getBody().get();
      HashMap requestMap = new HashMap();

      // add paramaters to the web service request map
      requestMap.put("sayHello.toWhom", msgBody);


      message.getBody().add(requestMap);
      System.out.println("Request map is: " + requestMap.toString());

      logFooter();
      return message;
   }

   public void exceptionHandler(Message message, Throwable exception)
   {
      logHeader();
      System.out.println("!ERROR!");
      System.out.println(exception.getMessage());
      System.out.println("For Message: ");
      System.out.println(message.getBody().get());
      logFooter();
   }

   // This makes it easier to read on the console
   private void logHeader()
   {
      System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
   }

   private void logFooter()
   {
      System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
   }

}            


take a loot at this:

requestMap.put("sayHello.toWhom", msgBody);

This is where the Web Service Request Map is built. In order to inject the HashMap into the Web Service the ESB uses a framework called OGNL.

 

What is OGNL ? OGNL stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects.

 

In our sample the key of the HashMap is the OGNL expression identifying the SOAP parameter to be populated with the key's value.     

In which part of the body is added the HashMap ? you have two choices

  • In the Default Body Location

         To add the map instance in the default body location simply use:

         Message.getBody().add(Map)

  • In one named body location

         To add the map instance in a certain body location you have to specify the body location parameter :
        Message.getBody().add(String,Map)
 

Step 2) Sending the SOAP message with SOAP Client Action

 

The second action in the pipeline is the SOAPClient Action which routes that message to the Web service. In order to use the SOAPClient action you need only to set a couple of properties:

  • the wsdl url
  • the SOAPAction (which is the @WebMethod exposed in the WebService)
<action name="soapui-client-action"
   class="org.jboss.soa.esb.actions.soap.SOAPClient">
    <property name="wsdl"
     value="http://127.0.0.1:8080/Quickstart_webservice_consumer1/HelloWorldWS?wsdl" />
    <property name="SOAPAction" value="sayHello"/>
    <property name="responseAsOgnlMap" value="true" />
</action>

There's an optional parameter responseAsOgnlMap which simply instructs the ESB to have the SOAP reponse data extracted into an OGNL keyed map and attached to the ESB Message.

Step 3) Retrieve the SOAP message with the Response Action


The last action in the pipeline is the Response Action:

<action name="response-mapper"
    class="org.jboss.soa.esb.samples.quickstart.webservice_consumer1.MyResponseAction">                
</action>

This is not different from the RequestAction. The callback method "process" captures and output the webservice response.

import org.jboss.soa.esb.actions.AbstractActionLifecycle;
import org.jboss.soa.esb.actions.ActionUtils;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.message.Body;
import org.jboss.soa.esb.message.Message;
import java.util.Map;

public class MyResponseAction extends AbstractActionLifecycle
{
   protected ConfigTree _config;

   public MyResponseAction(ConfigTree config)
   {
      _config = config;
   }

   public Message noOperation(Message message)
   {
      return message;
   }

   /*
    * Retrieve and output the webservice response.
    */
   public Message process(Message message) throws Exception
   {

      logHeader();

      // The "responseLocation" property was set in jboss-esb.xml to
      // "helloworld-response"
      Map responseMsg = (Map) message.getBody().get(Body.DEFAULT_LOCATION);
      System.out.println(message.toString());
      System.out.println("Response Map is: " + responseMsg);

      logFooter();
      return message;
   }

   public void exceptionHandler(Message message, Throwable exception)
   {
      logHeader();
      System.out.println("!ERROR!");
      System.out.println(exception.getMessage());
      System.out.println("For Message: ");
      System.out.println(message.getBody().get());
      logFooter();
   }

   // This makes it easier to read on the console
   private void logHeader()
   {
      System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
   }

   private void logFooter()
   {
      System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
   }

}

In this article we've explored how JBoss ESB supports SOAP unaware endpoints making invocations on SOAP endpoints. This is only half of the new Webservices functionality being added for 4.2GA. Next article will discuss about how to expose Webservice endpoints for non-Webservice based services (SOAP "onto the bus").

Follow us on Twitter