Modifying, Compiling, and Deploying a Simple Grid Service
Version 0.41 (12 September 04)
Written by Jeffrey C. House with modifications by Mark Holliday
Modified for CSCE 490/590
Cluster and Grid Computing, University of Arkansas
by Amy Apon
Overview
The objective of this assignment is for you to learn how to develop a simple Grid Service using the Globus Toolkit 3.2. This assignment will take you through the steps necessary to compile and deploy a prewritten grid service. Towards the end of the assignment, you will be required to modify the code that is given to you to help broaden your experience with developing grid services.
Introduction to Grid Services
Grid Services are an extension of web services. Like a web service a key feature of a grid service is that there is a process running the service on some machine and there can be one or more processes running clients on some machines that can request that the service process provide the service. The machines running the client processes and the service process need not be the same machine; in other words, the grid service can be a distributed system. In fact the possible configuration can be more complicated in that there can be more than one process that is an instantiation of the service.
The above description means that a grid service, as does a web service, provides a client-server form of interaction. One way that a grid service and a web service differ is that a grid service can be either stateful or stateless, In contrast, a web service can only be stateless. That a grid service is stateful means that the grid service can remember previous information from the last client-server interaction. When a grid service is stateless, the grid service does not retain state about an interaction with a client and thus the grid service is not aware of what happened during previous interactions with the same client (or any other client)
Grid services can also have one-to-one or one-to-many interactions with clients. The one-to-one approach to grid services means that an individual client will have their own instance of a grid service, and more than likely, that grid service will be destroyed after the interaction with the client is complete. The one-to-many approach to grid services means that there is only one instance of the grid service and the information that service has is available to any number of clients.
Grid services also use a factory approach for creating new instances of a service. Each grid service has an associated factory for the creation and management of the instances of that grid service.
Assignment Specifics
We will:
·Download a file to your home account on talon.csce.uark.edu. The file that you need to get is http://csce.uark.edu/~aapon/courses/gridcomputing/homework/gridsrv.tar
·In the first shell logon to talon and cd to your GridServices directory and run the NameChangeScript script (only run the script once)
· Define the grid service using java
· Define the Grid Service Interface using GWSDL and Specify Namespace Mappings
· Write the Deployment Descriptor
· Build the Math Service
· Deploy the Math Service
· Compile the Client
· Use the netstat –t –all command to see what TCP ports are in use
· Start a container using a TCP port that is free
· In a second shell logon to talon and cd to your GridServices directory
· Run Your Client
· Add Multiplication to Your Math Service
· Ending the Session
Step 1: Getting Started
You should logon to talon.csce.uark.edu. When you logon you will initially be in your home directory which is /home/yourusername. Throughout this handout you should view the string yourusername as referring to your username on talon.
Now that you are logged on, use the wget command to get the tar file above:
[yourusername@talon yourusername]$ wget \ http://csce.uark.edu/~aapon/courses/gridcomputing/homework/gridsrv.tar
The Linux command interpreter (shell) executes what is entered on one line at the command prompt. That one line usually (and always in this assignment) has just one command. The problem is that sometimes that one command is longer than the width of the console screen or of the width of a document page. There are two solutions that the command interpreter supports. One solution is that since a line is defined as all the characters until a newline character, the shell can handle a command that is so long that it wraps around on the console to the next line as long as the user does not enter a newline character. The second solution is that the shell views a backslash character, “\”, as escaping the next character. Thus, a backslash character immediately before a newline character is not considered to be the start of a new line by the shell.
In this handout whenever a command is long it will be shown on multiple lines but with a backslash character at the end of each line except the last line. It is important when entering a command in this manner that the newline character (generated by pressing the ENTER key) be immediately after the backslash character.
You can display the contents of your home directory using the ls (LiSt) command.
[yourusername@talon yourusername]$ ls
WebServices gridsrv.tar
Next, use the tar command to create a directory named GridServices with several subdirectories and files in it:
[yourusername@talon yourusername]$ tar xvf gridsrv.tar
This directory and its contents are created so that you could work on this assignment. You can see the contents of that directory by using the cd command and then the ls command.:
[yourusername@talon yourusername]$ cd GridServices
[yourusername@talon GridServices]$ ls
assignments build.xml nameChangeScriptUndo tmp
build.properties lib namespace2package.mappings
build.sh nameChangeScript schema
This is a fairly simple framework that is given to you so that when you write grid services, compilation and deployment will be much easier.
When you create a grid service, you must deploy them into a globus container to make the grid service available. Since all students will deploy their services into the same container it is necessary to have unique names for every service that is deployed. Sam Daoud has created a script that takes your username into account and modifies every occurrence of assignments, whether it is a folder name or contents of a java source file. The script replaces assignments with yourusernameAssignments, where yourusername is the username you used to logon to talon. You should run the script only once and you should do so from your GridServices directory as follows:
[yourusername@talon GridServices]$ ./nameChangeScript
When the script runs a number of messages will be displayed stating each change the script attempted to make and whether the change succeeded.
An obvious question is “What happens if you have already run the nameChangeScript and you run it again?” No damage will occur. When the script runs the second time the last few of the messages that will be displayed will say that the change failed. This is because the directory named assignments has already been changed to the name yourusernameAssignments. However, you can continue with the rest of the steps of the assignment.
Step 2: Defining the grid service with java.
The Grid Service for this assignment is a simple Math Service that can perform basic arithmetic for a client, such as addition and subtraction, and send the result back to the client. The Math Service itself is stateful, meaning that the result of any previous arithmetic operation is remembered by the service, and the previous result is used in forthcoming calculations. The first step in developing the Math Service is writing the java code for the service. Assuming that you are in your GridServices directory, /home/yourusername/GridServices, the java code for the service is located at
yourusernameAssignments/services/MathService/impl/MathImpl.java
Here are the contents of MathImpl.java:
package yourusernameAssignments.services.MathService.impl;
import org.globus.ogsa.impl.ogsi.GridServiceImpl;
import yourusernameAssignments.stubs.MathService.MathPortType;
import java.rmi.RemoteException;
public class MathImpl extends GridServiceImpl implements MathPortType
{
private int value = 0;
public MathImpl()
{
super("Simple MathService");
}
public void add(int a) throws RemoteException
{
value = value + a;
}
public void subtract(int a) throws RemoteException
{
value = value - a;
}
public int getValue() throws RemoteException
{
return value;
}
}
As you can see MathImpl inherits from GridServiceImpl and implements MathPortType. GridServiceImpl is a class provided by the Globus Toolkit 3.2 and all Grid Services must extend that class. The MathPortType is created for you when you build the service and is a stub which defines the operations that are exposed to clients. The three methods add, subtract and getValue, are the operations exposed to the clients. Each of these methods must throw a RemoteException because the services use Java Remote Method Invocation (RMI) behind the scenes.
Step 3: Define the Grid Service Interface using GWSDL and Specify Namespace Mappings
The second step in developing a Grid Service is defining the interface for the service. The interface is defined using Grid Web Services Description Language (GWSDL) which specifies what operations are exposed through the Grid Service to client(s). Assuming that you are in your GridServices directory, /home/yourusername/GridServices, the GWSDL for this is in
schema/yourusernameAssignments/MathService/Math.gwsdl
and the contents are as follows:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="MathService"
targetNamespace="http://www.globus.org/namespaces/yourusernameAssignments/MathService"
xmlns:tns="http://www.globus.org/namespaces/yourusernameAssignments/MathService"
xmlns:ogsi="http://www.gridforum.org/namespaces/2003/03/OGSI"
xmlns:gwsdl="http://www.gridforum.org/namespaces/2003/03/gridWSDLExtensions"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<import location="../../ogsi/ogsi.gwsdl"
namespace="http://www.gridforum.org/namespaces/2003/03/OGSI"/>
<types>
<xsd:schema targetNamespace="http://www.globus.org/namespaces/yourusernameAssignments/MathService"
attributeFormDefault="qualified"
elementFormDefault="qualified"
xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:element name="add">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="addResponse">
<xsd:complexType/>
</xsd:element>
<xsd:element name="subtract">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="subtractResponse">
<xsd:complexType/>
</xsd:element>
<xsd:element name="getValue">
<xsd:complexType/>
</xsd:element>
<xsd:element name="getValueResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="AddInputMessage">
<part name="parameters" element="tns:add"/>
</message>
<message name="AddOutputMessage">
<part name="parameters" element="tns:addResponse"/>
</message>
<message name="SubtractInputMessage">
<part name="parameters" element="tns:subtract"/>
</message>
<message name="SubtractOutputMessage">
<part name="parameters" element="tns:subtractResponse"/>
</message>
<message name="GetValueInputMessage">
<part name="parameters" element="tns:getValue"/>
</message>
<message name="GetValueOutputMessage">
<part name="parameters" element="tns:getValueResponse"/>
</message>
<gwsdl:portType name="MathPortType" extends="ogsi:GridService">
<operation name="add">
<input message="tns:AddInputMessage"/>
<output message="tns:AddOutputMessage"/>
<fault name="Fault" message="ogsi:FaultMessage"/>
</operation>
<operation name="subtract">
<input message="tns:SubtractInputMessage"/>
<output message="tns:SubtractOutputMessage"/>
<fault name="Fault" message="ogsi:FaultMessage"/>
</operation>
<operation name="getValue">
<input message="tns:GetValueInputMessage"/>
<output message="tns:GetValueOutputMessage"/>
<fault name="Fault" message="ogsi:FaultMessage"/>
</operation>
</gwsdl:portType>
</definitions>
In the above GWSDL, you can see in bold that you specify the name of the GWSDL file and the target namespace. The target namespace specifies that all operations defined in the file will be part of that namespace. Also highlighted in bold are all the necessary XML tags needed to specify the add method.
The line
<gwsdl:portType name="MathPortType" extends="ogsi:GridService">
names the PortType for this service and specifies that it extends ogsi:GridService, which all Grid Services must do.
It is also necessary to specify how the GWSDL namespaces match up with the java packages for use with the build script. When you create additional services you just add their mappings to this file. Assuming that you are in your home directory, /home/yourusername/GridServices, the file for this is named
namespace2package.mappings
and the partial content of that file is:
http\://www.globus.org/namespaces/yourusernameAssignments/MathService=yourusernameAssignments.stubs.MathService
http\://www.globus.org/namespaces/yourusernameAssignments/MathService/bindings=yourusernameAssignments.stubs.MathService.bindings
http\://www.globus.org/namespaces/yourusernameAssignments/MathService/service=yourusernameAssignments.stubs.MathService.service.
.
Step 4: Writing the Deployment Descriptor
The deployment descriptor defines how the Grid Service will be deployed. Assuming that you are in your directory, /home/yourusername/GridServices, the Deployment descriptor for the Math Service is located at
yourusernameAssignments/services/MathService/server-deploy.wsdd
Here are the contents of the file server-deploy.wsdd:
<?xml version="1.0"?>
<deployment name="defaultServerConfig" xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="yourusernameAssignments/MathService" provider="Handler" style="wrapped">
<parameter name="name" value="MathService"/>
<paqrameter name="baseClassName" value="yourusernameAssignments.services.MathService.impl.MathImpl"/>
<parameter name="className" value="yourusernameAssignments.stubs.MathService.MathPortType"/>
<parameter name="schemaPath" value="schema/yourusernameAssignments/MathService/Math_service.wsdl"/>
<!-- Start common parameters -->
<parameter name="allowedMethods" value="*"/>
<parameter name="persistent" value="true"/>
<parameter name="handlerClass" value="org.globus.ogsa.handlers.RPCURIProvider"/>
</service>
<service name="yourusernameAssignments/MathFactoryService" provider="Handler" style="wrapped">
<parameter name="name" value="MathService Factory"/>
<parameter name="instance-name" value="MathService Instance"/>
<parameter name="instance-schemaPath" value="schema/yourusernameAssignments/MathService/Math_service.wsdl"/>
<parameter name="instance-baseClassName" value="yourusernameAssignments.services.MathService.impl.MathImpl"/>
<parameter name="instance-className" value="yourusernameAssignments.stubs.MathService.MathPortType"/>
<!-- Start common parameters -->
<parameter name="allowedMethods" value="*"/>
<parameter name="persistent" value="true"/>
<parameter name="className" value="org.gridforum.ogsi.Factory"/>
<parameter name="baseClassName" value="org.globus.ogsa.impl.ogsi.GridServiceImpl"/>
<parameter name="schemaPath" value="schema/ogsi/ogsi_factory_service.wsdl"/>
<parameter name="handlerClass" value="org.globus.ogsa.handlers.RPCURIProvider"/>
<parameter name="factoryCallback" value="org.globus.ogsa.impl.ogsi.DynamicFactoryCallbackImpl"/>
<parameter name="operationProviders" value="org.globus.ogsa.impl.ogsi.FactoryProvider"/>
</service>
</deployment>
In the deployment descriptor, I have highlighted two sections in bold because they are the most important and specific to the Math Service. The first section of bold text describes the Math Service. The service name is the location of where the service will be placed in the Globus container. The baseClassName specifies where in the namespace the actual java implementation of the service is located. Similarly, className specifies where the PortType is found and schemaPath specifies where the GWSDL description of the service interface is found. The second section of bold text describes the Math Service Factory in a similar way to the Math Service. Remember that services use a factory approach for creating services.
Step 5: Building the Math Service
From your GridServices directory, you can build your Math Service by using the build script. The build script takes two arguments. The first is the path to your service and the second is the path to the GWSDL file for that service. To run the build script, perform the following:
[yourusername@talon GridServices]$ ./build.sh \ yourusernameAssignments/services/MathService \ schema/yourusernameAssignments/MathService/Math.gwsdl
The backslash character is because the command is on more than one line. Each backslash character must immediately precede a newline character. The output should look similar to the following:
rm: cannot lstat ‘build’ : No such file or directory
Buildfile: build.xml
echoPackageInfo:
[echo] package: yourusernameAssignments.services.MathService
[echo] interface.name: Math
[echo] package.dir: yourusernameAssignments/services/MathService
[echo] schema.dir: /home/user/GridServices/schema/yourusernameAssignments/MathService [echo] service.name: MathService
[echo] gar.filename: yourusernameAssignments_services_MathService
createBuildTree:
[mkdir] Created dir: /home/user/GridServices/build/classes
[mkdir] Created dir: /home/user/GridServices/build/bin
[mkdir] Created dir: /home/user/GridServices/build/lib
[mkdir] Created dir: /home/user/GridServices/build/schema
[mkdir] Created dir: /home/user/GridServices/build/stubs
copySchemaFiles:
[copy] Copying 228 files to /home/user/GridServices/build/schema
configDirAvailable:
copyConfigFiles:
mappingFileAvailable:
mergeMapping:
Overriding previous definition of reference to classpath
mappingAvailable:
mergePackageMapping:
[echo] merging namespace2package.mappings
[copy] Copying 1 file to /home/user/GridServices/build/schema
setenv:
checkSchemaUptodate:
generateWSDLfromGWSDL:
[copy] Copying 1 file to /home/user/GridServices/build/schema/yourusernameAssignments/MathService
Overriding previous definition of reference to classpath
WSDLUptodate:
GWSDL2WSDL:
[echo] Generating wsdl for Math.gwsdl
Overriding previous definition of reference to classpath
BindingUptodate:
generateBinding:
[echo] Generating schema for Math
generateStubs:
Overriding previous definition of reference to classpath
generateStubs:
[echo] Generating stubs from /home/user/GridServices/build/schema/yourusernameAssignments/MathService/Math_service.wsdl
compileStubs:
[javac] Compiling 30 source files to /home/user/GridServices/build/classes
jarStubs:
[jar] Building jar: /home/user/GridServices/build/lib/yourusernameAssignments_MathService-stub.jar
compileService:
[javac] Compiling 1 source file to /home/user/GridServices/build/classes
jarService:
[jar] Building jar: /home/user/GridServices/build/lib/yourusernameAssignments.services.MathService.jar
gar:
makeGar:
testJars:
copyJars:
[copy] Copying 2 files to /home/user/GridServices/tmp/gar
testSchema:
copySchema:
[copy] Copying 5 files to /home/user/GridServices/tmp/gar/schema/yourusernameAssignments/MathService
testEtc:
copyEtc:
testShare:
copyShare:
testDocs:
copyDocs:
testBin:
copyBin:
setGarID:
testPostDeployAvailable:
copyPostDeploy:
[copy] Copying 1 file to /home/user/GridServices/tmp/gar
[copy] Warning: Could not find file /home/user/GridServices/deploy-client.wsdd to copy.
[jar] Building jar: /home/user/GridServices/build/lib/yourusernameAssignments_services_MathService.gar
[delete] Deleting directory /home/user/GridServices/tmp/gar
all:
BUILD SUCCESSFUL
Total time: 26 seconds
During the build process, a new directory is created in your GridServices directory that is named build. All of your stubs and class files that were generated will be in that directory and its subdirectories. More importantly, a GAR file is created called
build/lib/yourusernameAssignments_services_MathService.gar
The GAR file is the package that contains every file that is needed to successfully deploy your Math Service into the Globus container. The files contained in the GAR file are the java class files, GWSDL, compiled stubs, and the deployment descriptor.
Step 6: Deploying the Math Service
To deploy the Math Service you will use a tool called ANT (Another Neat Tool). ANT (http://ant.apache.org) is a build tool somewhat like the make program. However make-like tools are shell-based while the configuration files for ANT are XML (eXtensible Manipulation Language)-based. ANT deployment of the Math Service can be done two simple steps, and requires you to be in the Globus Toolkit 3.2 directory. That directory is specified by the GLOBUS_LOCATION environment variable. You can see its value by using the printenv (for print environment) command.
[yourusername@talon GridServices]$ printenv GLOBUS_LOCATION
/usr/local/globus
[yourusername@talon GridServices]$
Use cd to change to that directory and then use ANT to deploy the Math Service.
[yourusername@talon GridServices]$ cd $GLOBUS_LOCATION
In our environment it is important to make sure that the $GLOBUS_LOCATION/server-config.wsdd file can be written by every user on the system. We do this by making sure the file is in the globus group, that every user is in the globus group, and that the file remains group writable after the deploy step. To make sure that you are in the globus group, use the newgrp command:
[yourusername@talon globus]$ newgrp globus
Next, deploy the Math Service:
[yourusername@talon globus]$ ant deploy \
-Dgar.name=/home/yourusername/GridServices/build/lib/usernameAssignments_services_MathService.gar
The backslash character is because the command is on more than one line. Each backslash character must immediately precede a newline character. The above sequence of commands is shown in a smaller font for a reason. It is essential that there be no spaces anywhere in the string starting with the hyphen, “-“. This includes that there can not be a space immediately after the hyphen and there can not be spaces around the equal sign, “=”. If the command is shown in a larger font, the word processing software inserts spaces in that string.
Make sure that you substitute your username in for yourusername in the above command. If the deployment is successful, you will see output similar to the following:
Buildfile: build.xml
deploy:
deployGar:
setGarID:
deployGarFiles:
[unjar] Expanding: /home/yourusername/GridServices/build/lib/username/Assignments_services_MathService.gar into /usr/local/globus/tmp/gar
[copy] Copying 5 files to /usr/local/globus/schema
[chmod] Skipping fileset for directory /usr/local/globus/bin. It is empty.
[copy] Copying 2 files to /usr/local/globus/lib
testServerDeployAvailable:
deployServer:
[echo] deploying server config...
testClientDeployAvailable:
deployClient:
generateUndeploy:
setGarID:
testPostDeployAvailable:
setAbsoluteGlobusLocation:
postDeploy:
[delete] Deleting directory /usr/local/globus/tmp/gar
BUILD SUCCESSFUL
Total time: 11 seconds
The service has now been deployed. Any container that is started on this machine by any user will list your service as one of the deployed (and thus, available) services.
Finally, be sure that the server-config.wsdd file is left so that others can deploy services after you:
[aapon@talon globus]$ ls -l server-config.wsdd
-rw-rw-r-- 1 aapon globus 59102 Oct 10 17:19 server-config.wsdd
If the file permissions do not allow group write, then you need to change them:
[aapon@talon globus]$ chmod g+w server-config.wsdd
Step 7: Compiling the Client
At the end of the previous step you were in directory GLOBUS_LOCATION. Use the cd command to make /home/yourusername/GridServices your current directory. Assuming that you are in your directory /home/yourusername/GridServices, the client code for this service can be found at
usernameAssignments/clients/MathService/Client.java
Here are the contents of the Java Client:
package usernameAssignments.clients.MathService;
import usernameAssignments.stubs.MathService.service.MathServiceGridLocator;
import usernameAssignments.stubs.MathService.MathPortType;
import java.net.URL;
public class Client
{
public static void main(String[] args)
{
try
{
// Get command-line arguments
URL GSH = new java.net.URL(args[0]);
int a = Integer.parseInt(args[1]);
// Get a reference to the MathService instance
MathServiceGridLocator mathServiceLocator = new MathServiceGridLocator();
MathPortType math = mathServiceLocator.getMathServicePort(GSH);
// Call remote method 'add'
math.add(a);
System.out.println("Added " + a);
// Get current value through remote method 'getValue'
int value = math.getValue();
System.out.println("Current value: " + value);
}
catch(Exception e)
{
System.out.println("ERROR!");
e.printStackTrace();
}
}
}
When the client is run from the command line you pass it two arguments. The first argument is the GSH (Grid Service Handle), and the second argument is the integer to add. The GSH is a URL that specifies where the service resides. The location of the service is relative to the namespace the Math Service was deployed to. In the first bold line in the client code we are creating a new MathServiceGridLocator. In the second bold statement, the MathServiceGridLocator is used to get the MathPortType by calling the method getMathServicePort passing as an argument the GSH. These classes are generated for you when you run the build script. You do not have to write them yourself; all you ever have to do is write the service and client code.
If you are not currently in your GridServices directory, /home/yourusername/GridServices, use cd to go to that directory. To compile the java client code from your GridServices directory do the following:
[yourusername@talon GridServices]$ javac -classpath \
./build/classes/:$CLASSPATH \
yourusernameAssignments/clients/MathService/Client.java
The backslash characters are because the command is on more than one line. Each backslash character must immediately precede a newline character.
Step 8: Finding Which TCP Ports are in use
First you need to determine whether talon can support running another container. A container process requires a substantial amount of main memory. At most a few containers can be run on the same machine without thrashing occurring. For example, on a machine with 512 megabytes of main memory we recommend certainly no more than four containers running and preferably less. Thus, if several users are using the same machine to complete this assignment they should coordinate to prevent overcommitment of main memory. Use the uptime command to see what the current load average is on talon. In the example below the load average is 0.00.
[yourusername@talon GridServices]$ uptime
17:39:41 up 2 days, 5:30, 3 users, load average: 0.00, 0.00, 0.00
[yourusername@talon GridServices]$
If the load average is above two or three you should not start a container. The commands vmstat and ps aux can be used to monitor in more detail the memory usage of a container process.
In the next step you will want to start a container process running. A container process listens on a TCP port when it is running. If you do not specify what port it will listen on then it will choose port 8080 by default. Often another process is using port 8080. Since only one process can be listening on a port at a time, you need to determine which ports are free before you start the container. The netstat (NETwork STATistics) command can be used to find this information.
[yourusername@talon yourusername]$ netstat –t –all
The –t flag and the –all flag causes the netstat command to show all the TCP ports that are currently in use.
Step 9: Start the Container for your Grid Service
Now that the client code is compiled you can start the Globus container. The Globus container contains all services that have been deployed. To start the container, you must be in the Globus Toolkit directory. This directory is specified by the GLOBUS_LOCATION environment variable and on talon is /usr/local/globus. To start the container, do the following:
[yourusername@talon GridServices]$ cd $GLOBUS_LOCATION
[yourusername@talon globus]$ globus-start-container -p yourportnumber
The string yourportnumber is a placeholder for the port you determined is free from using the netstat command in the previous step. If the container command exits stating that the address is already in use, you can try using a different port number in the range from 8081 to 65535.
Starting a container often takes a minute or so. In addition, sometimes starting the container temporarily fails. In particular, it is not unusual for an error message from the UHERestartHandler to appear stating “ping failed for a uhe so restarting it”. This error message may appear several times before the container finally successfully starts.
Now that the container is running, you will see your MathService listed as one of the services available. Two of the lines should look similar to the following. The IP address 130.184.163.48 is the address of talon which is the machine on which the container is running.
http://130.184.163.48:yourportnumber/ogsa/services/Assignments/username/MathService
http://130.184.163.48:yourportnumber/ogsa/services/Assignments/username/MathFactoryService
Note that there are quite a number of services listed. Any service that has been deployed on this machine by any user will appear in this list. A service will remain deployed until it is explicitly undeployed. How to undeploy a service is described in a later step in this assignment.
Step 10: Run the Client
To start the client, you need to open another terminal connection to talon. This is because the container will not return to the command prompt once it starts running. Once you logon a second time to talon in this second shell use cd to move to your GridServices directory.
To start the client from your GridServices directory, do the following which passes the GSH of the service and the integer 5 as the arguments. Note that the in the middle of the GSH is the string yourportnumber. This is a placeholder that you will replace with the port number on which your container is listening. As always the string yourusername must be replaced by your username on talon.
[yourusername@talon GridServices]$ java -classpath \
./build/classes/:$CLASSPATH \
yourusernameAssignments.clients.MathService.Client \
http://130.184.163.48:yourportnumber/ogsa/services/yourusernameAssignments/MathService 5
The backslash characters are because the command is on more than one line. Each backslash character must immediately precede a newline character. The last line is wrapping around since it is too long but is a single string. The IP address 130.184.163.48 is being used since your container is running on talon and that is talon’s IP address. If the client runs fine you will get this output:
Added 5
Current value:
Step 11: Practice Exercise (for your own benefit only): Add Multiplication to Your Math Service
Congratulations, you have successfully compiled, deployed, and tested your first Grid Service. However, you are not finished yet. You need to modify the Math Service to support multiplication. Assuming that you are in your GridServices directory, /home/yourusername/GridServices, the file that you will need to edit is at the relative path:
yourusernameAssignments/services/MathService/impl/MathImpl.java
In that file insert a multiply method.
Also you will need to edit the GWSDL file at (assuming you are in /home/yourusername/GridServices)
schema/yourusernameAssignments/MathService/Math.gwsdl
so that the multiply method is exposed to clients.
Also edit yourusernameAssignments/clients/MathService/Client.java (assuming you are in /home/yourusername/GridServices) and use the add, subtract, and multiply methods in any way you want, but all methods have to be used and results of each calculation should be displayed on the screen using the getValue method and System.out.println.
Once those files are edited, you can follow the steps in Appendix B for building and deploying the Math Service and compiling the Client code.
Step 12: Ending the Session
You have now completed creating and deploying a service, creating a client, and using that client to access that service. What do you need to do if you are finished. Your client program has finished running. However, you have started a globus container process. You have also deployed a service that is available within that container. Even if you logoff of talon the service remains deployed.
[yourusername@talon globus]$ globus-stop-container soft http://talon.csce.uark.edu:yourportnumber/ogsa/services/core/management/OgsiManagementService
[yourusername@talon yourusername]$ cd $GLOBUS_LOCATION
[yourusername@talon globus]$ ant undeploy \
-Dgar.id=yourusernameAssignments_services_MathService
The backslash character is because the command is on more than one line. Each backslash character must immediately precede a newline character. It is essential that there be no spaces anywhere in the string starting with the hyphen, “-“. This includes that there can not be a space immediately after the hyphen and there can not be spaces around the equal sign, “=”. The directory $GLOBUS_LOCATION/undeploy has a list of services that have been undeployed.
Acknowledgements
This assignment is derived from
“Classroom Exercises for Grid Services” by A. Apon, J. Mache, Y. Yara,
and K.
Landrus, Proc. 5th Int. Conference on Linux Clusters: The HPC
Revolution, May
2004.
Appendix A: Additional Resources
In addition to this assignment text, there are many good resources on the internet to help ease the pain of writing Grid Services for the Globus Toolkit 3.2.
The Globus Alliance:
http://www.globus.org/
The Globus Toolkit 3 Programmer's Tutorial:
http://www.casa-sotomayor.net/gt3-tutorial/
The Apache Web Services Project
Apache AXIS
Apache ANT:
http://ant.apache.org/
In addition to the resources on the internet there are also good learning resources found in your GridServices directory on talon. Besides the Math Service, there are also two prewritten services provided as examples. One is a simple Hello World Service and the other is a Pi Service, which can calculate Pi to the number of decimal places you provide.
Appendix B: Quick Commands
Build/Compile the Service
[yourusername@talon GridServices]$ ./build.sh \
yourusernameAssignments/services/MathService \
schema/yourusernameAssignments/MathService/Math.gwsdl
Deploy the Service
[yourusername@talon GridServices]$ cd $GLOBUS_LOCATION
[yourusername@talon globus]$ ant deploy \
-Dgar.name=/home/username/GridServices/build/lib/yourusernameAssignments_services_MathService.gar
Start the Globus Container
Determine a free TCP port number in the range of 8081 to 65535 using the netstat –t –all command. Call the port number you have chosen yourportnumber in the command below.
[yourusername@talon globus]$ globus-start-container -p yourportnumber
Compile the Java Client Code
[yourusername@talon globus]$ cd /home/yourusername/GridServices
[yourusername@talon GridServices]$ javac -classpath \
./build/classes/:$CLASSPATH \
yourusernameAssignments/clients/MathService/Client.java
Execute the client code
[yourusername@talon GridServices]$ java -classpath \
./build/classes/:$CLASSPATH \
yourusernameAssignments.clients.MathService.Client \
http://130.184.163.48:yourportnumber/ogsa/services/yourusernameAssignments/MathService 5
Stop the Globus Container
[yourusername@talon globus]$ globus-stop-container soft http://130.184.163.48:yourportnumber/ogsa/services/core/management/OgsiManagementService
In the command above recall that the yourportnumber must be replaced by the port number on which you have the container listening.