ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Constructing Web Services with the Globus Toolkit Version 4

by Birali Hakizumwami
10/19/2005

This article introduces a new way of building enterprise software by leveraging grid computing concepts implemented by the Globus Toolkit version 4 (GT4). GT4 is an open source implementation of the Open Grid Services Infrastructure (OGSI). The implementation is intended to serve as a proof of concept for OGSI, and to be used as a reference for other implementations. This article addresses only the GT4 Java core services, which provide a run-time environment capable of hosting grid services written in Java. The run-time environment mediates between the application and the underlying network, and transport protocol engines.

Grid Definition

A grid is a collection of distributed computing resources available over a local or wide area network that appear to an end user or application as one large virtual computing system. Grid computing is an approach to distributed computing that spans not only locations but also organizations, machine architectures, and software boundaries to provide increased power, collaboration, and information access to everyone connected to a grid. Distributed resources, such as cycles, storage, and information, can be accessed from and provided to any location in the grid. The vision is to create virtual dynamic organizations through secure, coordinated resource sharing among individuals, institutions, and resources.

Globus Toolkit Version 4

In this article, we will only focus on the GT4 Java core services (Figure 1). These services offer a run-time environment capable of hosting grid services. The run-time environment mediates between the user-defined application services and the GT4 core services, underlying network, and transport protocol engines. GT4 Core also provides development support, including programming models for exposing and accessing grid service implementations such as GRAM (Grid Resource Allocation Management). One of the compelling reasons to use GT4 is that it builds upon existing web services standards and technologies like SOAP and WSDL. All of the grid service interfaces are exposed in WSDL format. GT4 provides software libraries that support security, discovery, resource management, invocation, communication, exception handling, data management, etc.

GT4 Java Architecture
Figure 1. GT4 Java architecture

Figure 1 show the major architectural components of the server side of GT4. This is just a subset of the functionality that GT4 provides and that we use for this article. The GT4 architecture consists of a grid container to manage all of the deployed web services throughout their lifecycles. The GT4 grid container uses Apache AXIS as its web services engine to handle all of the SOAP message processing, JAX-RPC handler processing, and web services configuration.

Java Web Services in a Nutshell

Related Reading

Java Web Services in a Nutshell
By Kim Topley

Loan Payment Processing Example

We provide this example to show how using the Globus Toolkit can solve the integration challenges of heterogeneous systems within the enterprise. Some applications may be mainframe legacy applications and some may use modern technologies such as J2EE. Even when using up-to-date technologies, sharing information between different applications within the same enterprise can present a tremendous challenge. Figure 2 shows an example of an interaction between loan payment processing and the accounting departments within a mortgage organization. The accounting department uses the loan payment processing service to account for the loan.

Loan Processing Grid Architecture
Figure 2. Loan processing grid architecture (click for full-size image)

To create and deploy a grid service, we need to:

We use the top-down approach (Figure 3) to create the grid service. This approach starts by providing a WSDL file that contains the abstract definition of the service including the types, messages and portTypes. Starting with a document/literal WSDL and then generating the Java artifacts from that leads to the most interoperability.

Top-down approach
Figure 3. Top-down approach

We use some of the tools that come with the GT4 toolkit to generate the binding and stubs. The next step with this approach is to provide the implementation of the interfaces.

Loan Payment Processing Service Interface Definition

The port types for the Loan Payment Processing example are defined the a file loan.wsdl. It describes three operations (createLoan, processLoanPayment, and getLoan) that the loan payment processing service will provide. First, let's describe the requests/responses:

<types>

  <xsd:element name="createLoan">
    <xsd:complexType>
      <xsd:sequence>
          <xsd:element name="loanNumber" type="xsd:int"/>
        <xsd:element name="amountUPB" type="xsd:double"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="createLoanResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="returnValue" type="xsd:int"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="processLoanPayment">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="loanNumber" type="xsd:int"/>
        <xsd:element name="amount" type="xsd:double"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="processLoanPaymentResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="returnValue" type="xsd:int"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="getLoan">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="loanNumber" type="xsd:int"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="getLoanResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="returnValue" type="tns:LoanType"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

</types>

We define the loan data type in a file, loan.xsd. We use the import <xsd:import schemaLocation="loan.xsd"/> directive to import this file into loan.wsdl and use it as a return type for the getLoan operation.

<complexType name="LoanType">
    <sequence>
        <element name="loanNumber" type="int"/>
        <element name="UPB" type="double"/>
        <element name="status" type="string"/>
        <element name="createDate" type="string"/>
    </sequence>
</complexType>

Next we define all of the messages. A Message element consists of one or more part sections. Each part element corresponds to a parameter. Each part has a type attribute. Messages can be either Requests (input messages) or Responses (output messages).

<message name="CreateLoanInputMessage">
  <part name="parameters" element="tns:createLoan"/>
</message>
<message name="CreateLoanOutputMessage">
  <part name="parameters" element="tns:createLoanResponse"/>
</message>

<message name="ProcessLoanPaymentInputMessage">
  <part name="parameters" element="tns:processLoanPayment"/>
</message>
<message name="ProcessLoanPaymentOutputMessage">
  <part name="parameters"
    element="tns:processLoanPaymentResponse"/>
</message>

<message name="GetLoanInputMessage">
  <part name="parameters" element="tns:getLoan"/>
</message>
<message name="GetLoanOutputMessage">
  <part name="parameters" element="tns:getLoanResponse"/>
</message>

Finally, we define all of the port types. A port type defines one or more operations using the operation element. Each unique operation element defines an operation and the input/output messages associated with the operation. The operation elements within a port type define the syntax for calling all methods in the port type.

<portType name="LoanPortType">
  <operation name="createLoan">
    <input message="tns:CreateLoanInputMessage"/>
    <output message="tns:CreateLoanOutputMessage"/>
    <fault name="Fault" message="ogsi:FaultMessage"/>
  </operation>
  <operation name="processLoanPayment">
    <input message="tns:ProcessLoanPaymentInputMessage"/>
    <output message="tns:ProcessLoanPaymentOutputMessage"/>
    <fault name="Fault" message="ogsi:FaultMessage"/>
  </operation>
  <operation name="getLoan">
    <input message="tns:GetLoanInputMessage"/>
    <output message="tns:GetLoanOutputMessage"/>
    <fault name="Fault" message="ogsi:FaultMessage"/>
  </operation>
</portType>

Service Implementation

In the previous step, the LoanPortType endpoint interface was generated. All remotely available operations must be public and throw java.rmi.RemoteException, as defined in the PortType interface. In this section, we provide a class, LoanServiceImpl, that implements the LoanPortType interface. The implementation uses stub classes that were generated from the loan.wsdl file from the previous section.

public class LoanServiceImpl implements LoanPortType

The LoanServiceImpl class implement the methods defined in the LoanPortType interface. The createLoan method takes a loanNumber as a parameter in the constructor of the generated CreateLoan object.

public CreateLoanResponse createLoan(CreateLoan cl)
throws java.rmi.RemoteException

public ProcessLoanPaymentResponse processLoanPayment(ProcessLoanPayment plp)
throws java.rmi.RemoteException

public GetLoanResponse getLoan(GetLoan gl) throws java.rmi.RemoteException

Please refer to the full source code in the Resources section for the details of the methods' implementations.

Build and Deployment of the Loan Payment Processing Web Service

To build a deployable GT4 archive file, we follow the steps described below. The build.xml Ant build file provided with this article contains the tasks to perform these steps. The Ant tasks in build.xml call the following GT4 Ant tasks that can be found in the build files that come with the GT4 distribution:

%GLOBUS_LOCATION%/share/globus_wsrf_common/build-packages.xml
%GLOBUS_LOCATION%/share/globus_wsrf_tools/build-stubs.xml
%GLOBUS_LOCATION%/share/schema

Building the GT4 Deployable GAR File

To build our deployable grid archive file (GAR), loan.gar, we follow the following steps (these steps correspond to the Ant tasks in build.xml):

Please refer to the full build.xml in the source code for the complete list of Ant build tasks for the above steps. The GT4 deployment descriptor deploy-server.wsdd for our web service will look like this:

<service name="loan/impl/LoanService" provider="Handler"
use="literal" style="document">
    <parameter name="className" value="loan.impl.LoanServiceImpl"/>
    <wsdlFile>share/schema/loan/Loan_service.wsdl</wsdlFile>
    <parameter name="allowedMethods" value="*"/>
    <parameter name="handlerClass"
    value="org.globus.axis.providers.RPCProvider"/>
    <parameter name="scope" value="Application"/>
    <parameter name="providers" value="GetRPProvider"/>
    <parameter name="loadOnStartup" value="true"/>
</service>

Let's describe some parameters found in the deploy-server.wsdd file:

Deploying the GAR File

The GAR file loan.gar contains all of the files and information the web server needs to deploy the web service. We use the GT4 deployment tool:

%GLOBUS_LOCATION%/bin/globus-deploy-gar $PROJECT_HOME/loan.gar

to copy the archive files (loan.wsdl, compiled stubs, compiled implementation, loan.wsdd) into the appropriate server location directory tree of the GT4 container.

Testing the Loan Payment Processing Example

Client Implementation

Figure 1 described how the loan origination subsystem and the loan accounting subsystem can act as clients to the loan payment processing web services. Now that we have build and deploy our web service in the GT4 grid container, we need to test the services with a client program. Test cases simulate a loan creation event, a loan monthly payment activity event, and a loan pay-off event. The client expects the service URI as one of its arguments from the command line. The client program is compiled separately. Following are a description of the main steps to implement the client to call our web services:

Please see the full code listing in the attached source code for the client. Before compiling the client, make sure you run the following script that comes with the GT4 distribution:

%GLOBUS_LOCATION%/etc/globus-devel-env.bat

The globus-devel-env.bat script takes care of putting all of the Globus libraries into the CLASSPATH, because the client is being compiled as a standalone application. Also, make sure that the CLASSPATH used to compile the client contains the directory where all of the compiled stub classes are placed, so our client can access generated stub classes such as LoanServiceAddressingLocator.

Starting the Grid Container

Use the following GT4 command to start the grid container:

%GLOBUS_LOCATION%/bin/globus-start-container -nosec

The -nosec option disable the security configuration to simplify testing. If the container is started successfully, you'll see a list with the URIs of all the deployed services. If our LoanService is correctly deployed, the following line appears in the list of deployed services (assuming a default GT4 installation):

[13]: http://localhost:8080/wsrf/services/loan/impl/LoanService

Testing the Loan Payment Processing Web Services

To test the service using the client, we consider the following scenarios: creating a loan, making payments, and paying off the loan.

Conclusion

This article described how the GT4 grid infrastructure can be leveraged to create application grid services based on existing web services standards. Although GT4 has been primarily used to solve large scientific computational problems, it can be used as a way to implement a service-oriented architecture within an enterprise. This article shows through a simple example how to create and deploy a grid service using the GT4 Core Java Services. It does not cover the more advanced concepts on how to use other grid services, such as the Grid Resource Allocation and Management (GRAM), Reliable File Transfer (RFT), notification, or security.

Resources

Birali Hakizumwami is currently working as an application architect.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.