Service Oriented JBI: Invoking External Web Services from ServiceMix

Exclusive offer: get 50% off this eBook here
Service Oriented Java Business Integration

Service Oriented Java Business Integration — Save 50%

Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook

$29.99    $15.00
by Binildas A. Christudas | April 2010 | .NET BPEL Microsoft SOA Web Services

In this article by Binildas C. A., author of Service Oriented Java Business Integration, we will cover practical use of JBI Proxy—to proxy external web services in the JBI bus.

You can use XFire to create stub classes based on your WSDL exposed by your external web service. Now you can inject the stub into your JSR181 SU. The stub will be used by the proxy to generate the exchange with the HTTP provider (which should be referenced as the "service").

Using JBI proxy now, it is possible to invoke web services in the RPC style from within the JBI bus. For this we leverage the stub classes generated out from the web service WSDL using Axis.

Web Service Code Listing

We are interested in proxy setup to access a remote web service, hence we will not discuss the details of the web service deployment in this section. Instead, we will just browse through the important web service interfaces and the associated WSDL and then move on to binding the proxy.

The web service implements the IHelloWeb remote interface which in turn extends the IHello business interface. They are listed here as follows:

  • IHello.java: IHello is a simple BI, having a single business method hello.
  • public interface IHello
    {
    String hello(String param);
    }

  • IHelloWeb.java: In order to deploy a web service, we need an interface complying with the Java RMI semantics, and IHelloWeb will serve this purpose.
  • public interface IHelloWeb extends IHello, java.rmi.Remote {}

  • HelloWebService.wsdl: The main sections in the web service WSDL is shown as follows:
  • <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions targetNamespace="http://AxisEndToEnd.
    axis.apache.binildas.com" ...>
    <wsdl:types ... />
    <wsdl:message ... />
    <wsdl:portType name="IHelloWeb">
    </wsdl:portType>
    <wsdl:binding name="HelloWebServiceSoapBinding"
    type="impl:IHelloWeb">
    </wsdl:binding>
    <wsdl:service name="IHelloWebService">
    <wsdl:port binding="impl:HelloWebServiceSoapBinding"
    name="HelloWebService">
    <wsdlsoap:address
    location="http://localhost:8080/AxisEndToEnd/services/
    HelloWebService"/>
    </wsdl:port>
    </wsdl:service>
    </wsdl:definitions>

This is enough about the web service and we will move on to the next step.

Axis Generated Client Stubs

We use org.apache.axis.wsdl.WSDL2Java class in the wsdl2java task to generate client-side binding classes and stubs. The main classes are available in the folder ch13\JbiProxy\03_AccessExternalWebService\01_ws\gensrc and they are as follows:

  • HelloWebService.java
  • HelloWebServiceSoapBindingStub.java
  • IHelloWeb.java
  • IHelloWebService.java
  • IHelloWebServiceLocator.java

All the above artifacts are Axis generated client-side stubs, hence we will not look into the details of them here. Instead, let us look into the structural relationship between the various developer created and Axis generated artifacts shown in the following figure:

Service Oriented Java Business Integration

Referring to the above diagram, let us understand the relevant artifacts. Here our aim is to generate a JBI proxy for an externally bound web service. We are doing this using the following classes:

  • ITarget.java: This interface is synonymous to the BI IHello, having a single business method hello. We want to auto-route request-response through the JBI proxy. In order to facilitate this we have retained the method signature in the interfaces the same.

  • public interface ITarget
    {
    String hello(String input);
    }

  • TargetService.java: In TargetService, we auto-wire the web service stub. So, the helloWeb instance field in TargetService will hold a reference to the stub to the web service. When the hello method is invoked in TargetService, the call is delegated to the stub which will invoke the remote web service.
  • public class TargetService implements ITarget
    {
    private com.binildas.apache.axis.AxisEndToEnd.
    IHelloWeb helloWeb;
    public TargetService(){}
    public TargetService(com.binildas.apache.axis.
    AxisEndToEnd.IHelloWeb helloWeb)
    {
    this.helloWeb = helloWeb;
    }
    public String hello(String input)
    {
    System.out.println("TargetService.echo : String. this = " +
    this);
    try
    {
    return helloWeb.hello(input);
    }
    catch(Exception exception)
    {
    exception.printStackTrace();
    return exception.getMessage();
    }
    }
    }

  • IHelloProxy.java: We now need to wire the JBI proxy to the web services stub. IHelloProxy is an interface defined for this purpose and hence is having the same single business method, hello.

  • public interface IHelloProxy
    {
    public String hello(String input);
    }

  • IHelloProxyService.java: HelloProxyService is a wrapper or adapter for the JBI proxy. In other words, the helloProxy instance field in HelloProxyService will refer to the JBI proxy.
  • public class HelloProxyService implements IHelloProxy
    {
    private IHelloProxy helloProxy;
    public void setHelloProxy(IHelloProxy helloProxy)
    {
    this.helloProxy = helloProxy;
    }
    public String hello(String input)
    {
    System.out.println("HelloProxyService.hello. this = " + this);
    return helloProxy.hello(input);
    }
    }

The bean wiring discussed in this section is done using Spring and is shown in the next section.

Service Oriented Java Business Integration Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook
Published: March 2008
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

XBean-based JBI Proxy Binding

Using XBean, we will now configure the JBI proxy to be deployed onto the standard servicemix-jsr181 JBI component.

The xbean.xml is as shown in the following code:

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:jsr181="http://servicemix.apache.org/jsr181/1.0"
xmlns:http="http://servicemix.apache.org/http/1.0"
xmlns:test="http://test">
<classpath>
<location>.</location>
</classpath>
<jsr181:endpoint annotations="none"
service="test:echoService"
serviceInterface="test.IHelloProxy">
<jsr181:pojo>
<bean class="test.HelloProxyService">
<property name="helloProxy">
<jsr181:proxy service="test:TargetService"
context="#context"
type="test.IHelloProxy" />
</property>
</bean>
</jsr181:pojo>
</jsr181:endpoint>
<jsr181:endpoint annotations="none"
service="test:TargetService"
serviceInterface="test.ITarget">
<jsr181:pojo>
<bean class="test.TargetService" >
<constructor-arg type="com.binildas.apache.axis.
AxisEndToEnd.IHelloWeb">
<ref bean="stub"/>
</constructor-arg>
</bean>
</jsr181:pojo>
</jsr181:endpoint>
<bean id="stub"
class="com.binildas.apache.axis.AxisEndToEnd.
HelloWebServiceSoapBindingStub">
<constructor-arg type="java.net.URL" index="0">
<ref bean="url"/>
</constructor-arg>
<constructor-arg type="javax.xml.rpc.Service" index="1">
<ref bean="serviceLocator"/>
</constructor-arg>
</bean>
<bean id="url" class="java.net.URL">
<constructor-arg>
<value>http://localhost:8080/AxisEndToEnd/
services/HelloWebService</value>
</constructor-arg>
</bean>
<bean id="serviceLocator"
class="com.binildas.apache.axis.AxisEndToEnd.
IHelloWebServiceLocator">
</bean>
</beans>

We now have enough configurations to invoke the external web service. Is there anything fishy in the configuration above? You can go through that once again and let me wait till the end of our discussion to explain what I am hiding from you at this point.

Deployment Configuration

For deployment, we will package again all the relevant artifacts for the JSR proxy binding into a standard SA. We will also have an HTTP bound SA so that we can use a simple HTTP client to test the setup. As the configurations are exactly the same as what we used in the previous example, they are not repeated here. But we need to mention one thing here. The JBI proxy uses web service stub classes to invoke the external service and hence depends on the Axis libraries. We resolve this dependency by compiling the stub classes and including them also in the SA. We also copy all relevant Axis API jars to the ServiceMix optional library path. The ant target for that is given here:

<target name="copy-dependency" depends="init">
<javac srcdir="../01_ws/gensrc" destdir="${build.dir}">
<classpath refid="javac.classpath" />
<include name="**/*ServiceLocator.java"/>
</javac>
<copy todir="${servicemix.home}/lib/optional" overwrite="true">
<fileset dir="${axis.home}/lib" includes="*.jar" />
</copy>
</target>

Deploying and Running the Sample

To build the entire codebase and deploy the sample, change directory to ch13\JbiProxy\03_AccessExternalWebService which contains a top-level build.xml file. Execute ant as shown here:


cd ch13\JbiProxy\03_AccessExternalWebService
ant

This will build the web service, generate required web service client stubs, and also package all the necessary service assemblies. First, we need to deploy the web service. For that, transfer the web service war file placed in ch13\JbiProxy\03_AccessExternalWebService\01_ws\dist folder into the webapps folder of your favorite web container and restart the container. You can double check whether your web service deployment works by executing a client kept in the web service folder itself. For that, execute the ant run target as follows:

ch13\JbiProxy\03_AccessExternalWebService\01_ws
ant run

Now, bring up the ServiceMix container by executing the servicemix.xml file contained in the same folder.

ch13\JbiProxy\03_AccessExternalWebService
%SERVICEMIX_HOME%/bin/servicemix servicemix.xml

The Client.html provided again in the same folder can be used to send messages to test the deployed service.

Proxy and WSDL Generation

I have asked you to go through the JBI proxy XBean configuration once more in a previous section. Do you think we have actually made the web service a proxy? If we need to truly proxy the web service, then the XBean configuration should be something like the following code:


<jsr181:endpoint annotations="none"
service="test:TargetService"
serviceInterface="com.binildas.apache.axis.
AxisEndToEnd.IHelloWeb">
<jsr181:pojo>
<bean class="com.binildas.apache.axis.AxisEndToEnd.
HelloWebServiceSoapBindingStub" >
<constructor-arg type="java.net.URL" index="0">
<ref bean="url"/>
</constructor-arg>
<constructor-arg type="javax.xml.rpc.Service" index="1">
<ref bean="serviceLocator"/>
</constructor-arg>
</bean>
</jsr181:pojo>
</jsr181:endpoint>

The above configuration is right and that is what we need to proxy the web service. However the issue here is that the class HelloWebServiceSoapBindingStub, which if you look at the source code you can see, is dependent on many apache axis RPC API classes. For proper JBI proxying, the JBI container should be able to generate WSDL out of the exposed API but it may not make sense to generate WSDL out of these RPC-dependent classes. In fact the WSDL generator fails and throws an error. Hence instead what we have done in the previous example is that we have a proxy wrapper TargetService to which we inject the HelloWebServiceSoapBindingStub instance using the Spring injection mechanism. Then we delegate any calls from the TargetService instance to the stub instances, and that does the magic.

Summary

You have seen how an external web service can be bound to the JBI bus and then exposed as proxies within the bus itself so that other components within the bus can route messages through these proxies.


If you have read this article you may be interested to view :

Service Oriented Java Business Integration Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook
Published: March 2008
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Binildas A. Christudas

Binildas C. A. provides Technical Architecture consultancy for IT solutions. He has over 13 years of IT experience, mostly in Microsoft and Sun technologies. Distributed Computing and Service Oriented Integration are his main stream skills, with extensive hands-on experience in Java and C#.NET programming. Binil holds a BTech. degree in Mechanical Engineering from College of Engineering, Trivandrum (www.cet.ac.in) and an MBA in Systems Management, from Institute of Management, Kerala (www.imk.ac.in). A well-known and a highly sought-after thought leader, Binil has designed and built many highly scalable middle-tier and integration solutions for several top-notch clients including Fortune 500 companies. He has been previously employed by multiple IT consulting firms including IBS Software Services (www.ibsplc.com) and Tata Consultancy Services (www.tcs.com) and currently works for Infosys Technologies (www.infosys.com) as a Principal Architect where he heads the J2EE Architects group servicing Communications Service Provider clients.

Binil is a Sun Certified Programmer (SCJP), Developer (SCJD), Business Component Developer (SCBCD) and Enterprise Architect (SCEA), Microsoft Certified Professional (MCP) and Open Group (TOGAF8) Certified Enterprise Architecture Practitioner. He is also a Licensed Zapthink Architect (LZA) in SOA. Besides Technical Architecture Binil also practices Enterprise Architecture.

When not in software, Binil spends time with wife Sowmya & daughter Ann in ‘God's Own Country’, Kerala (www. en.wikipedia.org/wiki/Kerala). Binil does long distance running and is a national medalist in Power Lifting. You may contact Binil at biniljava@yahoo.co.in or binil_christudas@infosys.com.

Books From Packt


Oracle SOA Suite 11g R1 Developer's Guide
Oracle SOA Suite 11g R1 Developer's Guide

RESTful Java Web Services
RESTful Java Web Services

SOA Patterns with BizTalk Server 2009
SOA Patterns with BizTalk Server 2009

Amazon SimpleDB Developer Guide
Amazon SimpleDB Developer Guide

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide
Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control
BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control

Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software