Home SOA & ESB JBoss ESB Webservice Producer
11 | 03 | 2010
JBoss 5 AS Book
"JBoss AS 5 development" reviews
Please share your feedback/review with other readers!
Banner
Dashboard
Advertise with Us
Banner
RSS Feed
Login
Sign here for the NewsLetter.



Poll
What book could be in your wish list next XMas ?
 
JBoss admin resources
Banner
JBoss howto

How can you solve deployment errors caused by large war/jar/ear files ?

jboss recipe of the day ...
Read More

How do you configure your .war to be deployed after your EJB ?

jboss recipe of the day ...
Read More

How do I configure a Queue/Topic to work in a cluster?

JBoss recipe of the day ...
Read More
JBoss ESB Webservice Producer
Written by Mark S.   

The SOAPProcessor action, formerly known as "JBossWSAdapter", allows you to expose JBossWS 2.x and higher Webservice Endpoints through listeners running on the ESB (“SOAP onto the bus”).
 

 

A classic JBossESB usecase is one where the ESB is used to expose a Webservice interface for an existing Java based Service that doesn't already expose a Webservice interface. This means that these Services are invocable over any transport channel supported by the ESB (http, ftp, jms etc).
In order to achieve this, ESB defines a "wrapper webservice" that maps calls to the target Service.
 

Let's see in practice how to use the SOAPProcessor action. If you have downloaded the ESB service bus
move to the folder "samples\quickstarts\webservice_producer". There you can see one example of a WebService Producer.
 

Let's take a look at the jboss-esb.xml configuration file

 

<jbossesb
        xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
        parameterReloadSecs="5">

    <providers>
        <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">
            <jms-bus busid="quickstartGwChannel">
                <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_webservice_producer_gw"/>
            </jms-bus>
            <jms-bus busid="quickstartEsbChannel">
                <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_webservice_producer_esb"/>
            </jms-bus>
        </jms-provider>

        <jbr-provider name="JBR-Http" protocol="http" host="localhost">
            <jbr-bus busid="Http-1" port="8765" />
        </jbr-provider>

        <jbr-provider name="JBR-Socket" protocol="socket" host="localhost">
            <jbr-bus busid="Socket-1" port="8888" />
        </jbr-provider>

    </providers>

    <services>

        <service category="MyServiceCategory" name="MyWSProducerService" description="WS Frontend speaks natively to the ESB">

            <listeners>
                <jms-listener name="JMS-Gateway" busidref="quickstartGwChannel" is-gateway="true"/>
                <jbr-listener name="Http-Gateway" busidref="Http-1" is-gateway="true"/>
                <jbr-listener name="Socket-Gateway" busidref="Socket-1" is-gateway="true"/>

                <jms-listener name="JMS-ESBListener" busidref="quickstartEsbChannel"/>
            </listeners>
            <actions>
                <action name="print-before" class="org.jboss.soa.esb.actions.SystemPrintln">
                    <property name="message"
                              value="[Quickstart_webservice_producer] BEFORE invoking jbossws endpoint"/>
                </action>
                <action name="JBossWSAdapter" class="org.jboss.soa.esb.actions.soap.SOAPProcessor">
                    <property name="jbossws-endpoint" value="GoodbyeWorldWS"/>
                </action>
                <action name="print-after" class="org.jboss.soa.esb.actions.SystemPrintln">
                    <property name="message"
                              value="[Quickstart_webservice_producer] AFTER invoking jbossws endpoint"/>
                </action>
		<action name="testStore" class="org.jboss.soa.esb.actions.TestMessageStore"/>	
            </actions>
        </service>

    </services>

</jbossesb>


The first thing to notice is that JBoss ESB uses JBoss remoting interfaces as provider for http and socket transport. We'll explain later a bit more about jBoss remoting. In order to receive http/socket requests it's necessary to install a listener for this interfaces. This is achieved with the  <jbr-listener>
JBoss ESB

Picture 1: JBoss ESB exposing WebServices over http,socket,jms protocols

Said that, the action needed to invoke the webservice is very straightforward.  The action requires only one mandatory property value, which is the "jbossws-endpoint" property.  This property names the JBossWS endpoint that the SOAPProcessor is exposing (invoking).

 

 <action name="JBossWSAdapter" class="org.jboss.soa.esb.actions.soap.SOAPProcessor">
      <property name="jbossws-endpoint" value="GoodbyeWorldWS"/>
 </action>

 

Notice : There's one optional property "rewrite-endpoint-url" which is not used in this sample. This property is there to support load balancing on HTTP endpoints, in which case the Webservice endpoint container will have been configured to set the HTTP(S) endpoint address in the WSDL to that of the Load Balancer. 




 


The Web Service endpoint is deployed in the .esb archive as web application. It's made up of only one class and exposed 3 WebMethods:
 

@WebService(name = "GoodbyeWorldWS", targetNamespace="http://webservice_producer/goodbyeworld")
public class GoodbyeWorldWS {

    @WebMethod
    public String sayGoodbye(@WebParam(name="message") String message) {

        Message esbMessage = SOAPProcessor.getMessage();
        if(esbMessage != null) {
            System.out.println("**** SOAPRequest perhaps mediated by ESB:\n" + esbMessage.getBody().get());
        }
        System.out.println("Web Service Parameter - message=" + message);
        return "... Ah Goodbye then!!!! - " + message;
    }

    @WebMethod
    public String sayAdios(String message) {
        Message esbMessage = SOAPProcessor.getMessage();
        if(esbMessage != null) {
            System.out.println("**** SOAPRequest perhaps mediated by ESB:\n" + esbMessage.getBody().get());
        }
        System.out.println("Web Service Parameter - message=" + message);
        return "... Adios Amigo!!!! - " + message;
    }
    
    @WebMethod
    @Oneway
    public void sayGoodbyeWithoutResponse(@WebParam(name="message") String message) {

        Message esbMessage = SOAPProcessor.getMessage();
        if(esbMessage != null) {
            System.out.println("**** SOAPRequest perhaps mediated by ESB:\n" + esbMessage.getBody().get());
        }
        System.out.println("Web Service Parameter - message=" + message);
    }


ok time to deploy your .esb archive.

$ ant deploy

 

11:40:56,546 INFO  [TomcatDeployer] deploy, ctxPath=/Quickstart_webservice_producer, warUrl=.../tmp/deploy/tmp51717Quickstart_webservice_producer.esb-contents/Quickstart_webservice_producer-exp.war/

11:40:58,515 INFO  [WSDLFilePublisher] WSDL published to: file:/D:/jbossesb-server-4.4.GA/server/default/data/wsdl/Quickstart_webservice_producer.esb/Quickstart
_webservice_producer.war/GoodbyeWorldWSService51718.wsdl


 

If everything was successful .esb archive is now available and the wsdl archive was generated.

Ok now the webservice is deployed but how the client interface knows which protocol can be used to interact with the WebServices ? this problem is solved by the ESB exposing a contract for the webservice.

This application lists URLs that can be used by your Webservice Client (e.g. soapUI) for accessing a Service's WSDL, enabling WSDL based invocation of the Service through an ESB Endpoint.

The SOAPProcessor Action publishes contract information by being annotated with the org.jboss.internal.soa.esb.publish.Publish annotation as follows :

 

@Publish(WebserviceContractPublisher.class)
public class SOAPProcessor extends AbstractActionPipelineProcessor {
...
}


If you want to inspect the Contract for the Webservice take a look at the Contract console at
http://localhost:8080/contract/


jboss esb web services

 Picture 2: JBoss ESB Contracts console showing the available protocols for WebService endpoints


Connecting to your webservice


Last piece of the puzzle is the client which connects to the WebService. We'll skip the JMS sendMethod (which is a plain JMS client ) rather it's interesting to note how to connect to your remote listener:

 

 private void sendMessageToJBRListener(String protocol, int port, String message) throws Throwable {
        String locatorURI = protocol + "://localhost:" + port;
        InvokerLocator locator = new InvokerLocator(locatorURI);
        System.out.println("Calling JBoss Remoting Listener using locator URI: " + locatorURI);

        Client remotingClient = null;
        try {
            remotingClient = new Client(locator);
            remotingClient.connect();

            // Deliver the message to the listener...
            Object response = remotingClient.invoke(message);
            System.out.println("JBR Class: " + response.getClass().getName());
            System.out.println("Response from JBoss Remoting Listener '" + locatorURI + "' was '" + response + "'.");
        } finally {
            if(remotingClient != null) {
                remotingClient.disconnect();
            }
        }
    }


This method used JBoss remoting framework : What is it about ? JBoss remoting is a core framework that provides remote services like remoting JMX MBeans, remoting EJBs, and so on.  It supports an invocation model much more versatile then RMI or old-styled web services. There is no need to generate and compile a client-side agent for each service. As a result, JBoss Remoting provides the basis for more complex and heavyweight remoting frameworks.
 

JBoss Remoting defines the org.jboss.remoting.InvokerLocator class : this is the object that identifies the location of our service, as well as describing what transport protocol to use.

As you can see from the method sendMessageToJBRListener, the code is independent from the protocol: you simply feed the protocol : so for example if you use http, you'll use the JBR protocol "http://localhost:8765" , while for socket you'll use JBR protocol "socket://localhost:8888"
 

This is all you need in order to create a client that can be used to locate and connect to a remote service.


JBoss.org Search
Custom Search
Comments
Search
Only registered users can write comments!

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."