Department of Computing
Introductory Grid Computing Tutorial Notes #3
Objectives:
This tutorial aims to teach:
- Service Data in Grid Services
References:
For all the tutorial notes, you are expected to know the basics in Unix and Java. Please refer to the following tutorials for more information:
- Unix Tutorial for Beginners:
- Java Tutorials and Code Camps:
- The Globus Toolkit 3 Programmer’s Tutorial:
You can download the tutorials from the course web page, which is:
You can download the tutorial files from:
Instead of writing the commands manually, you can refer to the online version of the tutorials. Please do not forget to change the host ip and port name accordingly in the commands, when it is necessary.
The implementations and the explanations were taken from The Globus Toolkit 3 programmer’s tutorial, which was written by Borjo Sotomayor.
Section I: Service Data in Grid Services
Service Data is a structured collection of information that is associated to a Grid Service. This information must be easy to query, so Grid services can be classified and indexed according to their characteristics. Service data is much less technical than WSDL and is easier to classify and index.
The client can choose thanks to the Service Data associated to each MathService. If the client needs the most powerful service, without any consideration to how much it will cost, then it will probably choose the mainframe. If the decisive factor is cost, then Server A will probably be the best choice. However, if the client wants to do some sort of statistic analysis, then Server C is the best bet. Of course, this is an over-simplification: usually the client won’t implement some complicated algorithm to query Service Data and choose a service. It will probably delegate that task on an index service, which will make the decision based on multiple criteria: speed, cost, availability, etc. The criteria are usually specific to each particular problem; in the ‘US city temperature’ example, the criteria might be ‘number of cities available’, ‘availability of temperature, humidity, pressure, etc.’, ‘frequency of updates’, etc.
Summing up, Service Data is an essential part of service discovery.
We will define one Service Data Element (SDE):
- Undeploy your previous project: (Directory: $HOME/gt3)
ant undeploy -Dgar.id=mathtutorial
Remove the schema files.
rm –r $HOME/gt3/schema/mathtutorial.core.factory
- Create a new directory called “servicedata” under $HOME/gt3/samples/.
cd $HOME/gt3/samples
mkdir servicedata
- Create the following directory structure (Directory: $HOME/gt3/samples/servicedata)
mkdir mathtutorial
cd mathtutorial
mkdir core
cd core
mkdir factory
cd factory
mkdir client
mkdir impl
mkdir schema
- Set the TUTORIAL_DIR environment variable to $HOME/gt3/samples/servicedata
setenv TUTORIAL_DIR $HOME/gt3/samples/servicedata
- Copy “MathImpl.java” to $TUTORIAL_DIR/mathtutorial/code/factory/impl.
- Copy Math.gwsdl to $TUTORIAL_DIR/mathtutorial/core/factory/schema.
- Copy MathSDE.xsd to $TUTORIAL_DIR/mathtutorial/code/factory/schema.
- Copy Math.wsdd to $TUTORIAL_DIR/mathtutorial/code/factory.
- Copy namespace2package.mappings to $TUTORIAL_DIR.
- Copy Client.java to $TUTORIAL_DIR/mathtutorial/core/factory/client.
- Deploy your service (Directory = $TUTORIAL_DIR)
ant -Dgwsdl.interface=true -Dpackage=mathtutorial.core.factory -Dinterface.name=Math -Dpackage.dir=mathtutorial/core/factory/ -Dgwsdl.interface=Math.gwsdl -Dsde.schema.file=MathSDE.xsd
You should change the WSDL file name in build/classes/
- Then, deploy your service into Globus container (Directory = $HOME/gt3).
ant deploy -Dgar.name=$TUTORIAL_DIR/build/lib/mathtutorial.core.factory.Math.gar
- Run your globus container and check whether your service is displayed.
globus-start-container –p $MYPORT
- Open another terminal. Then, compile and run your client (Directory = $TUTORIAL_DIR).
javac -classpath ./build/classes/:$CLASSPATH mathtutorial/core/factory/client/Client.java
- Create an instance from your service.
ogsi-create-service math1
- Run your client.
java -classpath ./build/classes/:$CLASSPATH mathtutorial/core/factory/client/Client ogsa/services/mathtutorial/core/factory/MathFactoryService/math1 5
If everything goes successful, you will see the following information:
·Logging is working
·Date: Sun Feb 06 20:45:36 GMT 2005
·Version: Apache-XML-Security-J 1.0.4
Value: 5
Previous operation: Addition
# of operations: 1
EXERCISE:
Add a service data element, called “subtractnum”, which will display the total number of called “subtract” operations.
CODES:
MathImpl.java
package mathtutorial.core.factory.impl;
import org.globus.ogsa.ServiceData;
import org.globus.ogsa.impl.ogsi.GridServiceImpl;
import org.globus.ogsa.GridContext;
import org.globus.ogsa.GridServiceException;
import mathtutorial.core.factory.Math.MathPortType;
import mathtutorial.core.factory.MathDataType;
import mathtutorial.core.factory.Math.*;
import mathtutorial.core.factory.bindings.*;
import mathtutorial.core.factory.service.*;
import java.rmi.RemoteException;
public class MathImpl extends GridServiceImpl implements MathPortType
{
private ServiceData mathDataSDE;
private MathDataType mathDataValue;
public MathImpl()
{
super(“Simple MathService with Service Data”);
}
public void postCreate(GridContext context) throws GridServiceException
{
// Call base class’s postCreate
super.postCreate(context);
// Create Service Data Element
mathDataSDE = this.getServiceDataSet().create(“MathData”);
// Create a MathDataType instance and set intial values mathDataValue = new MathDataType();
mathDataValue.setLastOp(“NONE”);
mathDataValue.setNumOps(0);
mathDataValue.setValue(0);
// Set the value of the SDE to the MathDataType instance
mathDataSDE.setValue(mathDataValue);
// Add SDE to Service Data Set
this.getServiceDataSet().add(mathDataSDE);
}
// This method updates the MathData SDE increasing the
// number of operations by one
private void incrementOps()
{
int numOps = mathDataValue.getNumOps();
mathDataValue.setNumOps(numOps + 1);
}
public void add(int a) throws RemoteException
{
mathDataValue.setLastOp(“Addition”);
incrementOps();
mathDataValue.setValue(mathDataValue.getValue() + a);
}
public void subtract(int a) throws RemoteException
{
mathDataValue.setLastOp(“Subtraction”);
incrementOps();
mathDataValue.setValue(mathDataValue.getValue() - a);
}
}
Math.gwsdl
<?xml version=”1.0” encoding=”UTF-8”?>
<definitions name=”MathService”
targetNamespace=”
xmlns:tns=”
xmlns:data=”
xmlns:ogsi=”
xmlns:gwsdl=”
xmlns:sd=”
xmlns:xsd=”
xmlns=”
<import location=”../../ogsi/ogsi.gwsdl”
namespace=”
<import location=”MathSDE.xsd”
namespace=”
<types>
<xsd:schema targetNamespace=”
attributeFormDefault=”qualified”
elementFormDefault=”qualified”
xmlns=”
<!--======-->
<!-- Addition -->
<!--======-->
<xsd:element name=”add” type=”tns:add”>
<xsd:complexType name=”add”>
<xsd:sequence>
<xsd:element name=”a” type=”xsd:int”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name=”addResponse” type=”tns:addResponse”>
<xsd:complexType name=”addResponse”/>
</xsd:element>
<!--======-->
<!-- Subtraction -->
<!--======-->
<xsd:element name=”subtract” type=”tns:subtract”>
<xsd:complexType name=”subtract”>
<xsd:sequence>
<xsd:element name=”a” type=”xsd:int”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name=”subtractResponse” type=”tns:subtractResponse”>
<xsd:complexType name=”subtractResponse”/>
</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>
<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>
<sd:serviceData name=”MathData”
type=”data:MathDataType”
minOccurs=”1”
maxOccurs=”1”
mutability=”mutable”
modifiable=”false”
nillable=”false”>
</sd:serviceData>
</gwsdl:portType>
</definitions>
MathSDE.xsd
<?xml version=”1.0” encoding=”UTF-8”?>
<wsdl:definitions name=”MathData”
targetNamespace=”
xmlns:tns=”
xmlns:wsdl=”
<wsdl:types>
<schema targetNamespace=”
attributeFormDefault=”qualified”
elementFormDefault=”qualified”
xmlns=”
<complexType name=”MathDataType”>
<sequence>
<element name=”value” type=”int”/>
<element name=”lastOp” type=”string”/>
<element name=”numOps” type=”int”/>
</sequence>
</complexType>
</schema>
</wsdl:types>
</wsdl:definitions>
Math.wsdd
<?xml version=”1.0”?>
<deployment name=”defaultServerConfig” xmlns=”
xmlns:java=”
<service name=”mathtutorial/core/factory/MathFactoryService” provider=”Handler” style=”wrapped”>
<parameter name=”name” value=”MathService Factory”/>
<parameter name=”instance-name” value=”MathService Instance”/>
<parameter name=”instance-schemaPath” value=”schema/mathtutorial.core.factory/Math/MathService.wsdl”/>
<parameter name=”instance-baseClassName” value=”mathtutorial.core.factory.impl.MathImpl”/>
<!-- 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.PersistentGridServiceImpl”/>
<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>
build.properties
ogsa.root=/user/csckmst/css1tt/gt3
interface.name=Math
package.dir=./mathtutorial/core/factory
package=mathtutorial.core.factory
namespace2mappings.mappings
http\://
http\://
http\://
http\://
http\://
Client.java
package mathtutorial.core.factory.client;
import org.gridforum.ogsi.ExtensibilityType; import org.gridforum.ogsi.ServiceDataValuesType;
import org.globus.ogsa.utils.AnyHelper;
import org.globus.ogsa.utils.QueryHelper;
import mathtutorial.core.factory.service.MathServiceGridLocator;
import mathtutorial.core.factory.Math.MathPortType;
import mathtutorial.core.factory.MathDataType;
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 Math PortType
MathServiceGridLocator mathServiceLocator = new MathServiceGridLocator();
MathPortType math = mathServiceLocator.getMathServicePort(GSH);
// Get Service Data Element “MathData”
ExtensibilityType extensibility = math.findServiceData(QueryHelper.getNamesQuery(“MathData”));
ServiceDataValuesType serviceData = AnyHelper.getAsServiceDataValues(extensibility);
MathDataType mathData = (MathDataType) AnyHelper.getAsSingleObject(serviceData, MathDataType.class);
// Write service data
System.out.println(“Value: “ + mathData.getValue());
System.out.println(“Previous operation: “ + mathData.getLastOp());
System.out.println(“# of operations: “ + mathData.getNumOps());
// Call remote method
math.add(a);
}catch(Exception e)
{
System.out.println(“ERROR!”);
e.printStackTrace();
}
}
}