Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS...

41
Understanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram ([email protected]) Grid Specialist Freelance Writer 05 Apr 2005 This tutorial introduces the Globus WS Java Core, an implementation of the WS-Resource Framework (WSRF). It explains how to use these classes to create a simple auction system. Section 1. Before you start What is this tutorial about? This tutorial is Part 4 in a four-part series about the WS-Resource Framework (WSRF). Part 1 and Part 2 detailed the WSRF specification, defining WS-Resources and the means for creating, setting, retrieving, and destroying them and their Resource Properties. Part 3 explained WS-Notification, in which a Web service could subscribe to receive notification of various events or topics. In this tutorial, we will explain how to use the Globus WS Java™ Core to build an application that creates an auction as a WS-Resource, and gets and sets resource properties. We'll also see notifications in action. We will cover the following: Setting up the WS Java core environment Building a WSRF application Creating a singleton-WS Resource Creating and referencing multiple WS-Resource instances Using the WS Java Core classes © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 41

Transcript of Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS...

Page 1: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Understanding WSRF, Part 4: Using the WS JavaCore classesSkill Level: Introductory

Babu Sundaram ([email protected])Grid SpecialistFreelance Writer

05 Apr 2005

This tutorial introduces the Globus WS Java Core, an implementation of theWS-Resource Framework (WSRF). It explains how to use these classes to create asimple auction system.

Section 1. Before you start

What is this tutorial about?

This tutorial is Part 4 in a four-part series about the WS-Resource Framework(WSRF). Part 1 and Part 2 detailed the WSRF specification, defining WS-Resourcesand the means for creating, setting, retrieving, and destroying them and theirResource Properties. Part 3 explained WS-Notification, in which a Web servicecould subscribe to receive notification of various events or topics.

In this tutorial, we will explain how to use the Globus WS Java™ Core to build anapplication that creates an auction as a WS-Resource, and gets and sets resourceproperties. We'll also see notifications in action.

We will cover the following:

• Setting up the WS Java core environment

• Building a WSRF application

• Creating a singleton-WS Resource

• Creating and referencing multiple WS-Resource instances

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 41

Page 2: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

• Working with Resource Properties

• Destroying WS-Resources

Who should take this tutorial?

This tutorial should be read by developers who are trying to use Web services withstateful resources. It will be particularly helpful for developers working on gridapplications targeted at Globus Toolkit 4.

This tutorial requires a familiarity with the general principles of WSRF. (All the WSRFinformation needed can be found in the other parts of this series (see Resources).The code uses the Java™ language, so being comfortable with Java programming isa must.

Prerequisites

This tutorial uses a component of the Globus Toolkit V4 (GT4), consisting of thebase WSRF classes. You can download the container classes.

This tutorial uses GT4 Beta, V3.9.5, of the WSRF classes, but the interface isunlikely to change between now and final release.

In order to follow along with the code, you will also need the Java 2 Standard EditionSoftware Development Kit (J2SESDK). You can download V1.5.

You may use any development environment you like to create your classes,including a simple text editor. The files are actually compiled during the buildingprocess. On the other hand, an IDE such as Rational Application Developer V6.0can make your life easier.

To build the examples, you will also need the Ant Java build tool.

Make sure Java and Ant are installed and tested before proceeding. We'll install andtest the Globus container in Getting ready: The server.

Section 2. Overview

What is WSRF?

If you've read the other parts of this tutorial, you're well aware of the principlesbehind the WS-Resource (WSRF), but just in case you haven't, let's take a momentto explain what it's all about.

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 2 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 3: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

WSRF is a way to use "stateful" resources in the stateless environment of Webservices. When you make a request to a Web service, the only information availableis the information that is part of the request. That's fine for transient operations, butdoesn't really lend itself to more complicated applications. WSRF is about changingthat environment into one in which you can create a persistent resource and manageit through a Web service. That combination is called a WS-Resource.

For example, we are going to create a simple auction service. Each auction has astatus message and tracks the highest bid placed on it. That means the auctionmust exist even when we're not directly interacting with it, which makes the auction"stateful."

We'll also create a Web service that interacts with the auction, enabling us to readthe status message and place bids.

The combination of the service is the WS-Resource. Each service can interact withmultiple resources, creating multiple WS-Resources. The values of aWS-Resource's Resource Properties define its state. In the course of this tutorial,you'll see how to view and manipulate these properties.

WS-Resources can be created and destroyed, and we'll look at that as well.

What is the WS Java Core?

WSRF is a great idea, but implementing it can be almost ludicrously complicated.What's more, WSRF was developed as a way of simplifying state managementwithin the Globus grid environment, so a standard implementation was a must.

The WS Java Core is a Java implementation of WSRF, intended to be part of V4 ofthe Globus Toolkit. To use it, we need a "container," or Web server, that hosts ourWeb services. The Java classes come packaged with a container, as well as variousscripts that can be used to interact with the WS-Resources.

What is JNDI?

The Java Naming and Directory Interface (JNDI) provides a way to look up variousobjects, much like looking up a phone number in the phone book. Objects can beadded to the directory and associated with a key. When an object is needed, simplyreference it via the key.

The directory itself can be virtually anything, from a database to an LDAP directoryto the file system, as long as the appropriate "provider" class exists.

Consider this simple example, adapted from The JNDI Tutorial:

import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import java.util.Hashtable;

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 41

Page 4: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

import java.io.File;

public class JNDIDemo {

public static void main (String[] args){

// Check that user has supplied name of file to lookupif (args.length != 1) {

System.err.println("usage: java Lookup <filename>");

System.exit(-1);}

String name = args[0];

Hashtable env = new Hashtable();env.put(Context.INITIAL_CONTEXT_FACTORY,

"com.sun.jndi.fscontext.RefFSContextFactory");

try {// Create the initial contextContext ctx = new InitialContext(env);

// Look up an objectObject obj = ctx.lookup(name);

File theFile = (File)obj;System.out.println("The file, "+name+

", has a size of "+theFile.length()+".");

} catch (NamingException e) {System.err.println("Problem looking up " +

name + ": " + e);}

}}

Concentrating on the try-catch block, where the action is, we're creating acontext in which items are looked up. Once we have that context, we can look up theObject based on its name or the key with which it was added to the context. In thiscase, we're looking for a file, so we can retrieve it and display information about it.Running the application looks something like this:

>>> java -classpath .:./lib/fscontext.jar:./lib/providerutil.jar JNDIDemo/home/globus/jnditest/Lookup.java

The file, /home/globus/jnditest/Lookup.java, has a size of 2581.

(The command should be all on one line. It's broken here only for spacerequirements.)

So why is this important to WSRF? Because JNDI is used to let the system knowwhere to look for specific classes that are part of an application.

What we're going to accomplish

We are going to create a simple auction application. We'll start by creating a singleresource so you can see how all the necessary files -- and there are many -- fittogether.

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 4 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 5: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Next, we'll create multiple instances of the WS-Resource auction and look at how toadd bids to an individual auction by manipulating its resource properties.

Finally, we'll look at destroying these resources, directly and indirectly.

Along the way, we'll learn about creating not only the actual WS-Resources but alsothe clients that access them, and the script and configuration files that keep it alltogether.

Section 3. Putting together a WSRF service

Getting ready: The server

We're going to create a simple WSRF-based system, but before we can do that, weneed to take care of several prerequisites. Follow these steps to set up your system.First, get the container running:

1. Download the Globus WS Java Core.

2. Uncompress the .tar file into a directory, such as/home/globus/ws-core-3.9.5. That directory will be yourGLOBUS_LOCATION.

3. In a terminal window, set the value of GLOBUS_LOCATION. For example,the following may be used:

>> GLOBUS_LOCATION=/home/globus/ws-core-3.9.5>> export GLOBUS_LOCATION=$GLOBUS_LOCATION

4. Add $GLOBUS_LOCATION/bin to your path, as in:>> PATH=$GLOBUS_LOCATION/bin:$PATH>> export PATH=$PATH

5. Start the container by typing:globus-start-container -nosec

This command starts the container with no security. (We're not dealingwith security issues in this tutorial.)

A list of installed services can now be seen, and the window should not returncontrol. To stop the container, enter <ctrl>-C in this window.

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 41

Page 6: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Now let's get the development window ready.

Getting ready: The development window

Normally, when building a Java application, the code is written, compiled, thentested. The process we're going to use works a little bit differently.

Instead of compiling the code directly, we're going to write it and place it in theproper directories, then we're going to use the Ant build tool to compile and deploythe application. That means we must do the following to get ready:

1. Choose a location for the development files, such as/home/globus/auction. We'll refer to it as AUCTION_HOME.

2. Create the following directories in AUCTION_HOME:<AUCTION_HOME>/etc<AUCTION_HOME>/schema<AUCTION_HOME>/schema/tutorial<AUCTION_HOME>/src

3. Make sure a Java SDK is installed and tested.

4. Set JAVA_HOME, as in:

>>> JAVA_HOME=/home/globus/jdk1.5.0_01>>> export JAVA_HOME=$JAVA_HOME

5. Make sure the Ant package is installed and tested.

6. Set ANT_HOME, as in:

>>> ANT_HOME=/home/globus/apache-ant-1.6.2>>> export ANT_HOME=$ANT_HOME

7. Set GLOBUS_HOME, as in:

>>> GLOBUS_LOCATION=/home/globus/ws-core-3.9.5>>> export GLOBUS_LOCATION=$GLOBUS_LOCATION

8. Make sure JAVA_HOME/bin, ANT_HOME/bin and GLOBUS_HOME/binare on the path, as in:

>>> PATH=$GLOBUS_LOCATION/bin:$JAVA_HOME/bin:$ANT_HOME/bin:$PATH>>> export PATH=$PATH

This sequence should set all of the appropriate variables. If you experience errors

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 6 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 7: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

suggesting CLASSPATH problems, execute the following script:

$GLOBUS_LOCATION/etc/globus-devel-env.sh

In the rest of this section, we'll look at the files needed to add to the directories we'vecreated.

How the structure works

Before we look at the actual files, it helps to understand how the process works. AWSRF application consists of a number of interconnected resources and Webservices, and it helps to understand how they fit together.

We're going to deal with the following files:

• Auction.java -- This is the resource. This class actually manages allthe actions we're going to take with regard to the auction, such as settingproperty values.

• AuctionHome.java -- This is the ResourceHome. This class isresponsible for creating multiple instances of the resource and for helpinglocate a specific instance, as requested.

• AuctionService.java -- This is the service that will interact with theresource. This class contains methods such as Bid(), which then call theresource class to actually do the work.

• auction_port_type.wsdl -- This is the WSDL file that defines whatthe service can do. It also defines the resource properties document forthe resource.

• deploy-jndi-config.xml -- This file links the service, the resource,and the ResourceHome so the server knows where to look when itreceives a request.

• deploy-server.wsdd -- This file explains how to link the service withthe actual class that implements it. It also provides a way to integratestandard capabilities into our application, which we'll see later, in .

• deploy-client.wsdd -- We're not actually using this file, and it'spractically empty, but we need it anyway.

• NStoPkg.properties -- This one is actually empty, but it needs to bepresent. This file specifies how to derive the package names from thenamespaces if they need to be different from what can be derived fromthe service's WSDL file.

• post-deploy.xml -- This file provides instructions for miscellaneousinstructions to be carried out after Ant finishes the deployment, such ascreating shell scripts to represent the client classes.

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 41

Page 8: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

• build.xml -- This is, in many ways, the grand-daddy of them all,containing the instructions that guide the entire build process.

Many of these files are standard files that come with WSRF. We'll only concentrateon the changes needed to make to these files to customize them for an application.

Create the WSDL file

This is, at its core, a Web services application, so it makes sense that we shouldstart with the WSDL file. Much of this file should look familiar from Part 1 of thisseries. Create the following file and save it asAUCTION_HOME/schema/tutorial/auction_port_type.wsdl:

<definitions name="Auction"targetNamespace="http://tutorial.globus.org/auction"xmlns:tns="http://tutorial.globus.org/auction"xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ResourceProperties-1.2-draft-01.xsd"xmlns:wsrlw="http://docs.oasis-open.org/wsrf/2004/06/ws

rf-WS-ResourceLifetime-1.2-draft-01.wsdl"xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/W

SDLPreprocessor"xmlns:gtwsdl1="http://docs.oasis-open.org/wsrf/2004/06/w

srf-WS-ServiceGroup-1.2-draft-01.wsdl"xmlns:wsa=

"http://schemas.xmlsoap.org/ws/2004/03/addressing"xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/ws

n-WS-BaseNotification-1.2-draft-01.wsdl"xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/ws

rf-WS-ResourceProperties-1.2-draft-01.wsdl"xmlns="http://schemas.xmlsoap.org/wsdl/">

<importnamespace="http://docs.oasis-open.org/wsrf/2004/06/ws

rf-WS-BaseFaults-1.2-draft-01.wsdl"location="../wsrf/faults/WS-BaseFaults.wsdl"/>

<importnamespace="http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ResourceLifetime-1.2-draft-01.wsdl"location="../wsrf/lifetime/WS-ResourceLifetime.wsdl"/>

<importnamespace="http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ResourceProperties-1.2-draft-01.wsdl"location=

"../wsrf/properties/WS-ResourceProperties.wsdl"/><import

namespace="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"

location="../wsrf/notification/WS-BaseN.wsdl"/><import

namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.wsdl"

location="../wsrf/servicegroup/WS-ServiceGroup.wsdl"/>

<importnamespace="http://docs.oasis-open.org/wsn/2004/06/wsn-W

S-BaseNotification-1.2-draft-01.wsdl"location="../wsrf/notification/WS-BaseN.wsdl" />

<types><schema

targetNamespace="http://tutorial.globus.org/auction"

xmlns:tns="http://tutorial.globus.org/auction"xmlns="http://www.w3.org/2001/XMLSchema"xmlns:xsd="http://www.w3.org/2001/XMLSchema">

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 8 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 9: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<importnamespace="http://schemas.xmlsoap.org/ws/2004/03/addressing"schemaLocation=

"../ws/addressing/WS-Addressing.xsd"/>

<importnamespace="http://docs.oasis-open.org/wsrf/2004/06/w

srf-WS-ServiceGroup-1.2-draft-01.xsd"schemaLocation=

"../wsrf/servicegroup/WS-ServiceGroup.xsd"/>

<element name="StatusMessage"type="xsd:string"/>

<element name="CurrentBid" type="xsd:string"/>

<element name="AuctionResourceProperties"><complexType><sequence>

<element ref="tns:StatusMessage"/><element ref="tns:CurrentBid"/>

</sequence></complexType>

</element>

</schema></types>

<portType name="AuctionPortType"wsrp:ResourceProperties="AuctionResourceProperties">

<operation name="GetResourceProperty"><input name="GetResourcePropertyRequest"

message="wsrpw:GetResourcePropertyRequest"wsa:Action="http://docs.oasis-open.org/wsrf/20

04/06/wsrf-WS-ResourceProperties/GetResourceProperty"/><output name="GetResourcePropertyResponse"

message="wsrpw:GetResourcePropertyResponse"wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/w

srf-WS-ResourcePropertiesGetResourcePropertyResponse"/><fault name="InvalidResourcePropertyQNameFault"

message="wsrpw:InvalidResourcePropertyQNameFault"/>

<fault name="ResourceUnknownFault"message="wsrpw:ResourceUnknownFault"/>

</operation>

</portType></definitions>

This creates a basic WS-Resource with a resource properties document calledAuctionResourceProperties and the basic operation required of aWS-Resource: GetResourceProperty. We haven't added any extra operationsyet.

Create the service

The actual service doesn't do anything specific yet, except provide a way to accessthe capabilities built in to a WS-Resource by virtue of the providers we'll add to it in amoment, so create the following empty service class and save it asAUCTION_HOME/src/org/globus/tutorial/auction/AuctionService.java:

package org.globus.tutorial.auction;

import java.rmi.RemoteException;

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 41

Page 10: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

import org.globus.wsrf.ResourceContext;

public class AuctionService{

}

Create the resource

Now create the actual resource class and save it asAUCTION_HOME/src/org/globus/tutorial/auction/Auction.java:

package org.globus.tutorial.auction;

import org.globus.wsrf.Resource;import org.globus.wsrf.ResourceIdentifier;import org.globus.wsrf.ResourceProperty;import org.globus.wsrf.ResourcePropertySet;import org.globus.wsrf.ResourceProperties;import org.globus.wsrf.impl.SimpleResourcePropertySet;import org.globus.wsrf.impl.SimpleResourceProperty;

public class Auction implements Resource, ResourceProperties, ResourceIdentifier

{// this is the initial message that all auctions//will start withfinal static String INITIAL_STATUS =

"Welcome to the Auction Service (No Bids yet!)";

/** the identifier of this auction*/private Object id;

/** Stores the ResourceProperties of this auction*/private ResourcePropertySet propSet;

/** The message displayed on the auction. */private ResourceProperty StatusMessage;

/** initializes the Auction. */public void initialize() throws Exception {

// choose an IDthis.id = new Integer(hashCode());

// create the resource property setthis.propSet = new SimpleResourcePropertySet(

AuctionConstants.RP_SET);

// create resource propertythis.StatusMessage =

new SimpleResourceProperty(AuctionConstants.MESSAGE_RP);

this.propSet.add(this.StatusMessage);this.StatusMessage.add(INITIAL_STATUS+": "+

id.toString());

}

public ResourcePropertySet getResourcePropertySet(){

return propSet;}

public void setStatusMessage(String m){

this.StatusMessage.set(0, m);

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 10 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 11: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

}

public Object getID(){

return id;}

}

At the moment, this is very basic. We're simply initializing the value of theStatusMessage resource property with a message and the value of the class' uniquekey so we can see whether it changes when we call the service multiple times. (We'lllook more closely at this class in the next section. For now, just copy and paste.)

Before we move on to ResourceHome, we need to take care of the constantsreferenced in the class.

Create the constants

One of the goals of this project is to have code that is easily translatable. In otherwords, we should be able to simply replace a class or some other easilyinterchangeable part in order to change the language used by the application. Forsimplicity, we've cheated and hard-coded the initial StatusMessage in the class, butthe rest of the text has been separated out into a separate class. Create the classfile asAUCTION_HOME/src/org/globus/tutorial/auction/AuctionConstants.java:

package org.globus.tutorial.auction;

import javax.xml.namespace.QName;

public interface AuctionConstants{

static final String AUCTION_NS="http://tutorial.globus.org/auction";

static final QName RP_SET = new QName(AUCTION_NS,"AuctionResourceProperties");

static final QName MESSAGE_RP = new QName(AUCTION_NS,"StatusMessage");

static final QName BID_RP = new QName(AUCTION_NS,"CurrentBid");

}

Another advantage of pulling these names into a separate class is the ease ofmaintainability; to change the namespace, we can simply change it here and bedone with it.

Create the ResourceHome

To start with, we're creating a singleton class, which makes the ResourceHome's jobeasy. All it needs to do is create a single instance of the Auction object. Create theclass and save it asAUCTION_HOME/src/org/globus/tutorial/auction/AuctionHome.java:

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 41

Page 12: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

package org.globus.tutorial.auction;

import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;

import org.globus.wsrf.Resource;import org.globus.wsrf.impl.SingletonResourceHome;

public class AuctionHome extends SingletonResourceHome{

static final Log logger =LogFactory.getLog(AuctionHome.class);

public Resource findSingleton() {logger.info("Creating a single Auction.");try {

Auction myAuction = new Auction();myAuction.initialize();return myAuction;

} catch(Exception e) {logger.error(

"Exception when creating the Auction: "+e);return null;

}}

}

The logging information gets output to the container window by default.

Create a simple client

At this point, we've created all of the classes for the WS-Resource, but we'll need away to see it in action. Create this simple client class and save it asAUCTION_HOME/src/org/globus/tutorial/auction/client/ShowStatus.java:

** This file or a portion of this file is licensed under* the terms of the* Globus Toolkit Public License, found at* http://www.globus.org/toolkit/download/license.html.* This notice must appear in redistributions of this file,* with or without modification.*/package org.globus.tutorial.auction.client;

import org.oasis.wsrf.properties.WSResourcePropertiesServiceAddressingLocator;import org.oasis.wsrf.properties.GetResourceProperty;import

org.oasis.wsrf.properties.GetResourcePropertyResponse;import org.apache.commons.cli.ParseException;import org.apache.commons.cli.CommandLine;

import org.globus.tutorial.auction.AuctionConstants;import org.globus.wsrf.client.BaseClient;import org.globus.wsrf.utils.AnyHelper;import org.globus.wsrf.utils.FaultHelper;

import javax.xml.rpc.Stub;

public class ShowStatus extends BaseClient {

final staticWSResourcePropertiesServiceAddressingLocator locator =

new WSResourcePropertiesServiceAddressingLocator();

public static void main(String[] args) {

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 12 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 13: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

ShowStatus client = new ShowStatus();

// first, parse the commandlinetry {CommandLine line = client.parse(args);

} catch(ParseException e) {System.err.println("Parsing failed: " +

e.getMessage());System.exit(1);

} catch (Exception e) {System.err.println("Error: " + e.getMessage());System.exit(1);

}

// now query for the resource propertytry {

GetResourceProperty port =locator.getGetResourcePropertyPort(

client.getEPR());client.setOptions((Stub)port);

GetResourcePropertyResponse response =port.getResourceProperty(

AuctionConstants.MESSAGE_RP);

System.out.println(AnyHelper.toSingleString(response));

} catch(Exception e) {if (client.isDebugMode()) {

FaultHelper.printStackTrace(e);} else {

System.err.println("Error: " +FaultHelper.getMessage(e));

}}

}

}

We'll look at this code in much more detail later, but for now, understand that itsimply requests the value of the StatusMessage resource property for the currentAuction object, then it displays it in the client window.

Alter the build file

Now we can start putting things together. Let's start with the build file. Create this fileand save it as AUCTION_HOME/build.xml:

<?xml version="1.0" encoding="UTF-8"?><project basedir="." default="all"

name="globus_tutorial_auction"><description>

WSRF Tutorial</description>

<!--Give user a chance to override without editing thisfile (and without typing -D each time it compiles it)-->

<property environment="env"/>

<property file="build.properties"/><property file="${user.home}/build.properties"/>

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 41

Page 14: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<!-- Edit this line to set the location of GlobusInstallation -->

<propertylocation="/home/globus/ws-core-3.9.5"name="env.GLOBUS_LOCATION"/>

<property location="${env.GLOBUS_LOCATION}"name="deploy.dir"/>

<property name="base.name"value="tutorial_auction"/>

<property name="package.name"value="globus_${base.name}"/>

<property name="jar.name"value="${package.name}.jar"/>

<property name="gar.name"value="${package.name}.gar"/>

<property location="build" name="build.dir"/><property location="build/classes"

name="build.dest"/><property location="build/lib"

name="build.lib.dir"/><property location="build/stubs"

name="stubs.dir"/><property location="build/stubs/src"

name="stubs.src"/><property location="build/stubs/classes"

name="stubs.dest"/><property name="stubs.jar.name"

value="${package.name}_stubs.jar"/><property location="${deploy.dir}/share/globus_wsrf_

common/build-packages.xml"name="build.packages"/><property location="${deploy.dir}/share/globus_wsrf_tools/build-stubs.xml"name="build.stubs"/><property name="java.debug" value="on"/>

<property name="test-reports.dir"value="test-reports"/>

<property name="junit.haltonfailure"value="true"/>

<property location="${deploy.dir}/share/schema"name="schema.src"/>

<property location="${build.dir}/schema"name="schema.dest"/>

<property name="garjars.id" value="garjars"/><fileset dir="${build.lib.dir}" id="garjars"/>

<property name="garschema.id" value="garschema"/><fileset dir="${schema.dest}" id="garschema"

includes="tutorial/*"/>

<property name="garetc.id" value="garetc"/><fileset dir="etc" id="garetc"/>

<target name="init"><mkdir dir="${build.dir}"/><mkdir dir="${build.dest}"/><mkdir dir="${build.lib.dir}"/>

<mkdir dir="${stubs.dir}"/><mkdir dir="${stubs.src}"/><mkdir dir="${stubs.dest}"/>

<mkdir dir="${schema.dest}"/>

<copy toDir="${schema.dest}"><fileset dir="${schema.src}"

casesensitive="yes"><include name="wsrf/**/*"/><include name="ws/**/*"/>

</fileset></copy>

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 14 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 15: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<copy toDir="${schema.dest}"><fileset dir="schema/"

casesensitive="yes"><include name="tutorial/*"/>

</fileset></copy>

<available file="${stubs.dest}/org.globus.wsrf.mds.aggregator"

property="stubs.present" type="dir"/></target>

<target name="bindings" depends="init"><ant antfile="${build.stubs}"

target="generateBinding"><property name="source.binding.dir"

value="${schema.dest}/tutorial"/><property name="target.binding.dir"

value="${schema.dest}/tutorial"/><property name="binding.root"

value="Auction"/><property name="porttype.wsdl"

value="auction_port_type.wsdl"/></ant>

</target>

<target name="stubs" unless="stubs.present"depends="bindings">

<ant antfile="${build.stubs}"target="generateStubs">

<property location="${schema.dest}/tutorial"

name="source.stubs.dir"/><property name="wsdl.file"

value="Auction_service.wsdl"/><property location="${stubs.src}"

name="target.stubs.dir"/></ant>

</target>

<target depends="stubs" name="compileStubs"><delete dir="${stubs.src}/org/apache"/><javac debug="${java.debug}"destdir="${stubs.dest}" srcdir="${stubs.src}">

<include name="**/*.java"/><classpath>

<fileset dir="${deploy.dir}/lib"><include name="*.jar"/>

</fileset></classpath>

</javac></target>

<target depends="compileStubs" name="compile"><javac debug="${java.debug}"

destdir="${build.dest}" srcdir="src"><include name="**/*.java"/><classpath>

<pathelement location="${stubs.dest}"/><fileset dir="${deploy.dir}/lib">

<include name="*.jar"/></fileset>

</classpath></javac>

</target>

<target depends="compileStubs" name="jarStubs"><jar basedir="${stubs.dest}" destfile=

"${build.lib.dir}/${stubs.jar.name}"/></target>

<target depends="compile" name="jar">

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 41

Page 16: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<jar basedir="${build.dest}"destfile="${build.lib.dir}/${jar.name}"/>

</target>

<target depends="jar, jarStubs" name="dist"><ant antfile="${build.packages}"

target="makeGar"><property name="gar.name"

value="${build.lib.dir}/${gar.name}"/><reference refid="${garjars.id}"/><reference refid="${garschema.id}"/><reference refid="${garetc.id}"/>

</ant></target>

<target name="clean"><delete dir="tmp"/><delete dir="${build.dir}"/><delete file="${gar.name}"/><delete dir="${test-reports.dir}"/>

</target>

<target depends="dist" name="deploy"><ant antfile="${build.packages}"

target="deployGar"><property name="gar.name"

value="${build.lib.dir}/${gar.name}"/><property name="gar.id"

value="${package.name}"/><!-- <property name="noSchema"

value="true"/> --></ant>

</target>

<target name="undeploy"><ant antfile="${build.packages}"

target="undeployGar"><property name="gar.id"

value="${package.name}"/></ant>

</target>

<target depends="deploy" name="all"/>

<target depends="compile" name="test"><mkdir dir="${test-reports.dir}"/><junit fork="yes"

haltonfailure="${junit.haltonfailure}"printsummary="yes"timeout="600000">

<classpath><pathelement location="${build.dest}"/><pathelement location="${deploy.dir}"/><pathelement location=

"${deploy.dir}/etc/wsrf-bundles.properties"/><fileset dir="${deploy.dir}/lib">

<include name="*.jar"/></fileset>

</classpath><formatter type="xml"/><batchtest todir="${test-reports.dir}">

<fileset dir="${build.dest}"><include name="**/*Test.class"/>

</fileset></batchtest>

</junit></target>

</project>

This is a standard Globus build file, but some areas we may want to later customizehave been bolded.

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 16 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 17: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Alter the server deployment file

The standard server deployment file needs to be customized to match the names ofthe classes we're using. Create the file and save it asAUCTION_HOME/deploy-server.wsdd:

<deployment name="defaultServerConfig"xmlns="http://xml.apache.org/axis/wsdd/"xmlns:aggr="http://mds.globus.org/aggregator/types"xmlns:java=

"http://xml.apache.org/axis/wsdd/providers/java"xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<service name="AuctionService"provider="Handler"use="literal" style="document">

<parameter name="providers"value="GetRPProvider"/>

<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>

<parameter name="scope" value="Application"/><parameter name="allowedMethods" value="*"/><parameter name="activateOnStartup"

value="true"/><parameter name="className" value=

"org.globus.tutorial.auction.AuctionService"/><wsdlFile>share/schema/tutorial/Auction_service.wsdl

</wsdlFile>

</service>

</deployment>

Alter the JNDI file

The JNDI file links the service with the appropriate ResourceHome. Create the JNDIconfiguration file and save it as AUCTION_HOME/deploy-jndi-config.xml:

<jndiConfigxmlns="http://wsrf.globus.org/jndi/config">

<service name="AuctionService">

<resourcename="home"type=

"org.globus.tutorial.auction.AuctionHome"><resourceParams>

<parameter><name>factory</name><value>

org.globus.wsrf.jndi.BeanFactory</value>

</parameter></resourceParams>

</resource>

</service></jndiConfig>

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 41

Page 18: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Alter the post-deployment file

Now we need to tell Ant to create a shell script for the client so we don't have to typethe fully qualified class name every time we want to execute it. Create the followingfile and save it as AUCTION_HOME/etc/post-deploy.xml:

<!-- ===================================================================

Build Instructions:

This file is automatically called at the end of the deploymentof the corresponding component's gar (see build-packages.xml).

==================================================================== --><project default="all" basedir=".">

<property environment="env"/>

<property file="build.properties"/><property file="${user.home}/build.properties"/>

<property name="env.GLOBUS_LOCATION" value="."/><property name="deploy.dir"

location="${env.GLOBUS_LOCATION}"/><property name="abs.deploy.dir"

location="${deploy.dir}"/><property name="build.launcher"

location="${abs.deploy.dir}/share/globus_wsrf_common/build-launcher.xml"/>

<target name="setup">

<ant antfile="${build.launcher}"target="generateLauncher"><property name="launcher-name"

value="show-status"/><property name="class.name" value=

"org.globus.tutorial.auction.client.ShowStatus"/></ant>

</target>

</project>

This file tells Ant to create a script called show-status in the GLOBUS_HOME/bindirectory. Calling that script is the same as calling the client class directly.

The stragglers

We have two more files to create. First, createAUCTION_HOME/deploy-client.wsdd:

<?xml version="1.0" encoding="UTF-8"?><deployment name="defaultServerConfig"

xmlns="http://xml.apache.org/axis/wsdd/"xmlns:aggr="http://mds.globus.org/aggregator/types"xmlns:java=

"http://xml.apache.org/axis/wsdd/providers/java"xmlns:xsd="http://www.w3.org/2001/XMLSchema">

</deployment>

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 18 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 19: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Then create an empty file and save it as AUCTION_HOME/NStoPkg.properties.

Deploy the service

Now we're ready to test the service. Remember that window where we setANT_HOME and JAVA_HOME? Navigate to the AUCTION_HOME directory and type:

ant deploy

If all goes well, a BUILD SUCCESSFUL message will be displayed. If not, look at theoutput to find the problem and correct it, then run the Ant script again.

Once we've deployed the service, we need to start or restart the container. In thecontainer window, enter <ctrl>-C, if necessary, and once again type:

globus-start-container -nosec

Now we're ready to run the client.

Test the service

To test the service, we need to run the ShowStatus class. We don't have to worryabout package names or any of that, however, because the build process created ashell script that calls the class. At the command line in the deployment window, type:

show-status -s http://localhost:8080/wsrf/services/AuctionService

The following response should appear:

<ns1:StatusMessage xmlns:ns1="http://tutorial.globus.org/auction">

Welcome to the Auction Service (No Bids yet!): 27844531</ns1:StatusMessage>

Running show-status multiple times shows that we're dealing with a single object.The value of the id we're outputting doesn't change.

Now we have a working application, so we can change it to show some of the moreuseful ways of dealing with WS-Resources.

Section 4. Creating and using multiple resources

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 41

Page 20: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

The difference between one and many

Now that we have a working application, we can start actually dealing with thefeatures of a WS-Resource.

The first capability to look at is the ability to have multiple instances of the sameresource type. For example, we can create multiple auctions. But when we do that,things get a little more complicated. For one thing, rather than simply referring to theservice by its URL, we need to refer to the WS-Resource by its endpoint reference.An endpoint reference, part of the WS-Addressing specification, includes informationabout the URL for the service, as well as other identifying information. Consider thisendpoint reference, generated by the finished application:

<AuctionEndpoint xsi:type="ns1:EndpointReferenceType"xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"xmlns:ns1= "http://schemas.xmlsoap.org/ws/2004/03/addressing"><ns1:Address xsi:type="ns1:AttributedURI">

http://127.0.0.1:8080/wsrf/services/AuctionService</ns1:Address><ns1:ReferenceProperties

xsi:type="ns1:ReferencePropertiesType"><ns1:BidKey xmlns:ns1="http://auction.com">

5283320</ns1:BidKey>

</ns1:ReferenceProperties><ns1:ReferenceParameters

xsi:type="ns1:ReferenceParametersType"/></AuctionEndpoint>

It contains all the necessary information for locating a specific WS-Resourceinstance. Now let's go ahead and create those specific instances.

Let AuctionHome handle multiple instances

In order to change the application to handle multiple instances, we don't actuallyhave to touch the resource at all. Instead, this job is handled by the ResourceHome.Make the following changes to the AuctionHome.java file:

package org.globus.tutorial.auction;

import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;

import org.globus.wsrf.ResourceKey;import org.globus.wsrf.impl.ResourceHomeImpl;import org.globus.wsrf.impl.SimpleResourceKey;

/** This class implements a resource home that can contain many Auctions*/

public class AuctionHome extends ResourceHomeImpl{

static final Log logger = LogFactory.getLog(AuctionHome.class);

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 20 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 21: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

/** This method creates a new AuctionResource */public ResourceKey create() {

logger.info("Creating a new Auction...");try {Auction myAuction = (Auction)createNewInstance();

myAuction.initialize();ResourceKey key = new SimpleResourceKey(

keyTypeName, myAuction.getID());this.add(key,myAuction);return key;

} catch(Exception e) {logger.error(

"Exception when creating Auction: "+e);return null;

}}

}

Now, rather than maintaining a single instance, the class creates multiple instancesas necessary and keeps track of them via a ResourceKey.

To make that work, we need to let JNDI know about the ResourceKey.

Add the ResourceKey to JNDI

In order for JNDI to be able to find the new WS-Resource instances, it needs toknow about the ResourceKeys we're using to track them. Make the followingchanges to the deploy-jndi-config.xml file:

<jndiConfigxmlns="http://wsrf.globus.org/jndi/config">

<service name="AuctionService">

<resourcename="home"type=

"org.globus.tutorial.auction.AuctionHome"><resourceParams>

<parameter><name>factory</name><value>

org.globus.wsrf.jndi.BeanFactory</value>

</parameter><parameter>

<name>resourceClass</name><value>

org.globus.tutorial.auction.Auction</value>

</parameter><parameter>

<name>resourceKeyName

</name><value>

{http://auction.com}BidKey</value>

</parameter><parameter>

<name>resourceKeyType

</name><value>

java.lang.Integer</value>

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 41

Page 22: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

</parameter></resourceParams>

</resource>

</service></jndiConfig>

These values are related to the resource properties for the class.

Add Create support to the WSDL

In order to be able to use the Web service to create an instance, we need to add thatcapability to the auction_port_type.wsdl file:

<definitions name="Auction"targetNamespace="http://tutorial.globus.org/auction"xmlns:tns="http://tutorial.globus.org/auction"xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ResourceProperties-1.2-draft-01.xsd"xmlns:wsrlw="http://docs.oasis-open.org/wsrf/2004/06/ws

rf-WS-ResourceLifetime-1.2-draft-01.wsdl"xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/W

SDLPreprocessor"xmlns:gtwsdl1="http://docs.oasis-open.org/wsrf/2004/06/w

srf-WS-ServiceGroup-1.2-draft-01.wsdl"xmlns:wsa=

"http://schemas.xmlsoap.org/ws/2004/03/addressing"xmlns:wsntw= "http://docs.oasis-open.org/wsn/2004/06/ws

n-WS-BaseNotification-1.2-draft-01.wsdl"xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/ws

rf-WS-ResourceProperties-1.2-draft-01.wsdl"xmlns="http://schemas.xmlsoap.org/wsdl/">

<importnamespace= "http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-BaseFaults-1.2-draft-01.wsdl"location="../wsrf/faults/WS-BaseFaults.wsdl"/>

<importnamespace= "http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ResourceLifetime-1.2-draft-01.wsdl"location=

"../wsrf/lifetime/WS-ResourceLifetime.wsdl"/><import

namespace= "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

location="../wsrf/properties/WS-ResourceProperties.wsdl"/>

<importnamespace="http://docs.oasis-open.org/wsn/2004/06/wsn-W

S-BaseNotification-1.2-draft-01.wsdl"location="../wsrf/notification/WS-BaseN.wsdl"/>

<importnamespace= "http://docs.oasis-open.org/wsrf/2004/06/wsr

f-WS-ServiceGroup-1.2-draft-01.wsdl"location=

"../wsrf/servicegroup/WS-ServiceGroup.wsdl"/>

<importnamespace="http://docs.oasis-open.org/wsn/2004/06/wsn-W

S-BaseNotification-1.2-draft-01.wsdl"location="../wsrf/notification/WS-BaseN.wsdl" />

<types><schema

targetNamespace="http://tutorial.globus.org/auction"

xmlns:tns="http://tutorial.globus.org/auction"xmlns="http://www.w3.org/2001/XMLSchema"xmlns:xsd="http://www.w3.org/2001/XMLSchema">

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 22 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 23: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<importnamespace="http://schemas.xmlsoap.org/ws/2004/03/addressing"schemaLocation=

"../ws/addressing/WS-Addressing.xsd"/>

<importnamespace="http://docs.oasis-open.org/wsrf/2004/0

6/wsrf-WS-ServiceGroup-1.2-draft-01.xsd"schemaLocation=

"../wsrf/servicegroup/WS-ServiceGroup.xsd"/>

<element name="StatusMessage"type="xsd:string"/>

<element name="CurrentBid" type="xsd:string"/>

<element name="AuctionResourceProperties"><complexType><sequence>

<element ref="tns:StatusMessage"/><element ref="tns:CurrentBid"/>

</sequence></complexType>

</element>

<element name="Create"><complexType/>

</element>

<element name="CreateResponse"type="wsa:EndpointReferenceType" />

</schema></types>

<message name="CreateRequest"><part name="CreateRequest"

element="tns:Create" /></message>

<message name="CreateResponse"><part name="CreateResponse"

element="tns:CreateResponse" /></message>

<portType name="AuctionPortType"wsrp:ResourceProperties="AuctionResourceProperties">

<operation name="GetResourceProperty"><input name="GetResourcePropertyRequest"

message="wsrpw:GetResourcePropertyRequest"wsa:Action="http://docs.oasis-open.org/wsrf/20

04/06/wsrf-WS-ResourceProperties/GetResourceProperty"/><output name="GetResourcePropertyResponse"

message="wsrpw:GetResourcePropertyResponse"wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties/GetResourcePropertyResponse"/>

<fault name="InvalidResourcePropertyQNameFault"message="wsrpw:InvalidResourcePropertyQNameFault"/><fault name="ResourceUnknownFault"

message="wsrpw:ResourceUnknownFault"/></operation>

<operation name="Create"><input name="CreateRequest"

message="tns:CreateRequest" /><output name="CreateResponse"

message="tns:CreateResponse" /></operation>

</portType></definitions>

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 23 of 41

Page 24: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

These are the same additions we made in Part 1 of this series.

Now we have to add the operation to the service itself.

Add create support to the service

It's not enough to simply add the operation to the WSDL file. If we want the serviceto create a new instance, we have to add that to the actual service:

package org.globus.tutorial.auction;

import java.rmi.RemoteException;import org.globus.wsrf.ResourceContext;

importorg.apache.axis.message.addressing.EndpointReferenceType;

import org.globus.wsrf.ResourceKey;import org.globus.wsrf.utils.AddressingUtils;

public class AuctionService{

public EndpointReferenceType create(Create c)throws RemoteException

{ResourceContext ctx =

ResourceContext.getResourceContext();AuctionHome home =

(AuctionHome)ctx.getResourceHome();

ResourceKey key = home.create();

// form an EPR that points to the sticky noteEndpointReferenceType epr;try {

epr = AddressingUtils.createEndpointReference(ctx, key);

} catch(Exception e) {throw new RemoteException(

"Could not form an EPR to new auction: "+e);}

return epr;}

}

Let's take a look at what's actually going on here. First we get the JNDI context forthe resource, and from there, a reference to the appropriate ResourceHome:AuctionHome. From there, we can actually create the new resource and return itsendpoint reference.

Creating a new auction

To make all of this happen, we'll again need a client script. Create a new class as inAUCTION_HOME/src/org/globus/tutorial/auction/client/CreateAuction.java:

/** This file or a portion of this file is licensed under the terms of the* Globus Toolkit Public License, found at

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 24 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 25: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

* http://www.globus.org/toolkit/download/license.html.* This notice must appear in redistributions of this file,* with or without modification.*/package org.globus.tutorial.auction.client;

import org.globus.tutorial.auction.service.AuctionServiceAddressingLocator;

import org.apache.axis.message.addressing.EndpointReferenceType;

import org.apache.commons.cli.ParseException;import org.apache.commons.cli.CommandLine;

import org.globus.tutorial.auction.Create;import org.globus.tutorial.auction.AuctionPortType;import org.globus.wsrf.client.BaseClient;import org.globus.wsrf.encoding.ObjectSerializer;import org.globus.wsrf.encoding.SerializationException;import org.globus.wsrf.utils.FaultHelper;import java.io.FileWriter;import java.io.IOException;import java.util.Random;import javax.xml.namespace.QName;import javax.xml.rpc.Stub;

public class CreateAuction extends BaseClient {

final static AuctionServiceAddressingLocator locator =new AuctionServiceAddressingLocator();

final static CreateAuction client =new CreateAuction();

public static void main(String[] args) {

// first, parse the commandlinetry {

CommandLine line = client.parse(args);} catch(ParseException e) {

System.err.println("Parsing failed: " +e.getMessage());

System.exit(1);} catch (Exception e) {

System.err.println("Error: " + e.getMessage());System.exit(1);

}

try {

AuctionPortType port =locator.getAuctionPortTypePort(

client.getEPR());client.setOptions((Stub)port);

EndpointReferenceType epr = port.create(new Create());

System.out.println("New Auction Created...");

// now write the EPR to a file for later usewriteEPR(epr);

} catch(Exception e) {if (client.isDebugMode()) {

FaultHelper.printStackTrace(e);} else {

System.err.println("Error: " +FaultHelper.getMessage(e));

}}

}

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 25 of 41

Page 26: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

static final QName NAME =new QName("", "AuctionEndpoint");

// we use this random number generator to generate//EPR filenamesstatic final Random rnd = new Random();

public static void writeEPR(EndpointReferenceType epr)throws IOException, SerializationException

{

// invent a filenameString filename = "bid-"+rnd.nextInt()+".epr";

FileWriter fw = null;

try {fw = new FileWriter(filename);

// write the EPR into the fileObjectSerializer.serialize(fw, epr, NAME);

fw.write('\n');} finally {

if (fw != null) {try { fw.close(); } catch (Exception e) {}

}}

System.out.println("EPR written to file: "+filename);

}}

Let's take this one step at a time. First off, when creating this class in an IDE, theremay be trouble compiling it because some of the referenced classes won't exist untilthey're generated by the build process.

Having said that, note that the class extends BaseClient, which has some handyfeatures, such as the ability to parse the command-line arguments and determinethe server or endpoint we're trying to reach.

From there, we're getting a reference to the Web service and using it to create a newinstance of the Auction class. Once we have it, we write the endpoint reference outto a file and output the name of the file so we can reference it.

Before moving on, add this class to the post-deploy.xml file, just as we addedShowStatus. Call it create-auction.

Using a specific WS-Resource

In the build window, type:

ant undeployant deploy

Restart the container.

Now run the create-auction script:

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 26 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 27: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

create-auction -s http://localhost:8080/wsrf/services/AuctionService

We should get a response such as:

New Auction Created...EPR written to file: bid--1904700805.epr

Now to run show-status, we need to call it with the endpoint reference, as in:

show-status -e bid--1904700805.epr

That should give us a result such as:

<ns1:StatusMessagexmlns:ns1="http://tutorial.globus.org/auction">

Welcome to the Auction Service (No Bids yet!): 27844531</ns1:StatusMessage>

Notice that we didn't have to change the ShowStatus class to handle endpoints;that's taken care of by the system.

Section 5. A closer look: Resource properties

Define the currentBid property

Working with WS-Resources depends on being able to access and manipulate theresource properties. In this section, we will view and set the CurrentBid resourceproperty.

The first step is to add the Bid operation to the WSDL file:

...<element name="StatusMessage"

type="xsd:string"/><element name="CurrentBid" type="xsd:string" />

<element name="AuctionResourceProperties"><complexType><sequence>

<element ref="tns:StatusMessage"/><element ref="tns:CurrentBid" />

</sequence></complexType>

</element>

<element name="Bid" type="xsd:string" /><element name="BidResponse">

<complexType/></element>

<element name="Create">

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 27 of 41

Page 28: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

<complexType/></element><element name="CreateResponse"

type="wsa:EndpointReferenceType" />

</schema></types>

<message name="CreateRequest"><part name="CreateRequest"

element="tns:Create" /></message>

<message name="CreateResponse"><part name="CreateResponse"

element="tns:CreateResponse" /></message>

<message name="BidRequest"><part name="BidRequest"

element="tns:Bid" /></message>

<message name="BidResponse"><part name="BidResponse"

element="tns:BidResponse" /></message>

<portType name="AuctionPortType"wsrp:ResourceProperties="AuctionResourceProperties">

...<operation name="Create">

<input name="CreateRequest"message="tns:CreateRequest" />

<output name="CreateResponse"message="tns:CreateResponse" />

</operation>

<operation name="Bid"><input name="BidRequest"

message="tns:BidRequest" />

<output name="BidResponse"message="tns:BidResponse" />

</operation>

</portType></definitions>

First, create the Bid and BidResponse elements, then use them to create theBidRequest and BidResponse messages. Finally, use the messages to createthe Bid operation.

Now we need to add this capability to the service.

Add bidding to the service

Again, just adding the operation to the WSDL file doesn't tell the service how to do it,so add the Bid() method to the AuctionService class:

...EndpointReferenceType epr;try {

epr = AddressingUtils.createEndpointReference(ctx, key);

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 28 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 29: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

} catch(Exception e) {throw new RemoteException(

"Could not form an EPR to new auction: "+e);}

return epr;}

public BidResponse Bid(String bid)throws RemoteException

{// get appropriate resourceAuction resource = (Auction)ResourceContext.getResourceContext().getResource();

// set the text on itresource.setCurrentBid(bid);

return new BidResponse();}

}

This method requests the appropriate Auction WS-Resource based on theendpoint reference submitted with the request. Once JNDI locates the resource, wecan simply set the appropriate value for the resource property.

Now we need to enable that capability for the actual resource.

.

Manage the currentBid property

In order to work with the CurrentBid resource property, we need to initialize it andprovide access to it:

...public class Auction implements Resource, ResourceProperties, ResourceIdentifier

{final static String INITIAL_STATUS =

"Welcome to the Auction Service (No Bids yet!)";final static String INITIAL_BID = "0";

/** the identifier of this auction*/private Object id;

....private ResourceProperty StatusMessage;private ResourceProperty CurrentBid;

public void initialize() throws Exception {

// choose an IDthis.id = new Integer(hashCode());

// create the resource property setthis.propSet = new SimpleResourcePropertySet(

AuctionConstants.RP_SET);

// create resource propertiesthis.StatusMessage = new SimpleResourceProperty(

AuctionConstants.MESSAGE_RP);this.CurrentBid = new SimpleResourceProperty(

AuctionConstants.BID_RP);

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 29 of 41

Page 30: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

this.propSet.add(this.StatusMessage);this.StatusMessage.add(INITIAL_STATUS);

this.propSet.add(this.CurrentBid);this.CurrentBid.add(INITIAL_BID);

}

public ResourcePropertySet getResourcePropertySet(){

return propSet;}

public void setStatusMessage(String m){

this.StatusMessage.set(0, m);

}

public void setCurrentBid(String bid){

this.CurrentBid.set(0, bid);}

public Object getID(){

return id;}

}

First, we set the initial value for CurrentBid in the initialize() method bycreating a new SimpleResourceProperty and adding the Object thatrepresents the appropriate value. From there, we simply provide a method that setsthe private CurrentBid variable.

Now we're ready to create a client that places a bid on the auction.

Get the currentBid property

The first step in adding a bid to the auction is to retrieve the existing CurrentBidvalue. Create a new class and save it asAuction_Home/src/org/globus/tutorial/auction/client/OfferBid.Java:

/** This file or a portion of this file is licensed under the terms of the* Globus Toolkit Public License, found at* http://www.globus.org/toolkit/download/license.html.* This notice must appear in redistributions of this file,* with or without modification.*/package org.globus.tutorial.auction.client;

import org.oasis.wsrf.properties.WSResourcePropertiesServiceAddressingLocator;import org.oasis.wsrf.properties.GetResourceProperty;import

org.oasis.wsrf.properties.GetResourcePropertyResponse;import org.globus.tutorial.auction.service.AuctionServiceAddressingLocator;import org.apache.commons.cli.ParseException;import org.apache.commons.cli.CommandLine;import org.globus.tutorial.auction.AuctionPortType;

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 30 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 31: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

import org.globus.tutorial.auction.AuctionConstants;import org.globus.wsrf.client.BaseClient;import org.globus.wsrf.utils.AnyHelper;import org.globus.wsrf.utils.FaultHelper;import javax.xml.namespace.QName;import javax.xml.rpc.Stub;import java.util.List;

public class OfferBid extends BaseClient {

final staticWSResourcePropertiesServiceAddressingLocator locator1= new WSResourcePropertiesServiceAddressingLocator();

final static AuctionServiceAddressingLocator locator =new AuctionServiceAddressingLocator();

public static void main(String[] args) {OfferBid client = new OfferBid();

String newBid = "";

// first, parse the commandlinetry {

CommandLine line = client.parse(args);List options = line.getArgList();if (options.size() < 1) {

System.err.println("Setting Bid requires an Integer argument");System.exit(1);

}newBid = (String)options.get(0);

} catch(ParseException e) {System.err.println("Parsing failed: " +

e.getMessage());System.exit(1);

} catch (Exception e) {System.err.println("Error: " + e.getMessage());System.exit(1);

}

try {

GetResourceProperty port =locator1.getGetResourcePropertyPort(

client.getEPR());client.setOptions((Stub)port);

GetResourcePropertyResponse response =port.getResourceProperty(AuctionConstants.BID_RP);

String existingBid =AnyHelper.toSingleString(response);

existingBid =existingBid.substring(existingBid.indexOf(">")+1);

existingBid =existingBid.substring(0,existingBid.indexOf("<"));

System.out.println("Current Bid = " +existingBid);

} catch(Exception e) {if (client.isDebugMode()) {

FaultHelper.printStackTrace(e);} else {

System.err.println("Error with writing bid: " + FaultHelper.getMessage(e));

}}

}}

As in our other clients, we're first parsing the command line, so the system canlocate the appropriate WS-Resource based on the endpoint reference. Once we

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 31 of 41

Page 32: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

have a reference to that service, we can execute the GetResourcePropertyoperation and turn the response into a String.

As we saw in Test the service, the response consists of an element and not just thevalue, so here we're extracting the actual value. (We know this is a simple element,so we can use this somewhat unorthodox method of parsing the string looking forthe > and < characters.) From there, we output it to the command line.

Set the currentBid property

To actually set the value we will need to call the Bid operation for the appropriateresource:

...public class OfferBid extends BaseClient {

final staticWSResourcePropertiesServiceAddressingLocator locator1= new WSResourcePropertiesServiceAddressingLocator();

final static AuctionServiceAddressingLocator locator =new AuctionServiceAddressingLocator();

public static void main(String[] args) {...

try {

GetResourceProperty port =locator1.getGetResourcePropertyPort(

client.getEPR());client.setOptions((Stub)port);

GetResourcePropertyResponse response =port.getResourceProperty(

AuctionConstants.BID_RP);

String existingBid =AnyHelper.toSingleString(response);

existingBid = existingBid.substring(existingBid.indexOf(">")+1);

existingBid = existingBid.substring(0,existingBid.indexOf("<"));

System.out.println("Current Bid = " +existingBid);

System.out.println("Your Bid = " + newBid);

AuctionPortType port1 =locator.getAuctionPortTypePort(

client.getEPR());client.setOptions((Stub)port1);

if (existingBid.equals("0")) {port1.bid(newBid);

} else if (Integer.parseInt(existingBid) <Integer.parseInt(newBid) ){

port1.bid(newBid);} else {

System.out.println("Higher Bid exists. Write bid failed!");

System.exit(1);}

System.out.println("Bid Accepted.");

} catch(Exception e) {if (client.isDebugMode()) {

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 32 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 33: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

FaultHelper.printStackTrace(e);} else {

System.err.println("Error with writing bid: " +

FaultHelper.getMessage(e));}

}}

}

Although it's not obvious at the moment, the service that executes theGetResourceProperty request and the service that executes the Bid request arenot the same service. The former comes from a provider we added to thedeploy-server.wsdd file, as we'll see in Add destruction support to the resource. Fornow, notice that we're using two locators to locate the different ports.

Calling the bid() method actually executes the Bid operation inAuctionService. This method, in turn, calls the appropriate setter within theAuction class.

Now we need to create the script for the new client.

Add the new client

As before, to use this new client, we'll want to add it to the post-deploy.xml file:

...<target name="setup">

<ant antfile="${build.launcher}"target="generateLauncher"><property name="launcher-name"

value="show-status"/><property name="class.name"

value="org.globus.tutorial.auction.client.ShowStatus"/></ant>

<ant antfile="${build.launcher}"target="generateLauncher"><property name="launcher-name"

value="create-auction"/><property name="class.name" value=

"org.globus.tutorial.auction.client.CreateAuction"/></ant>

<ant antfile="${build.launcher}"target="generateLauncher"><property name="launcher-name"

value="offer-bid"/><property name="class.name" value=

"org.globus.tutorial.auction.client.OfferBid"/></ant>

</target>

</project>

You can use this process for adding any number of client classes. Now we are readyto run the client.

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 33 of 41

Page 34: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Bid on an auction

Now we're ready to actually bid on an auction.

Undeploy the existing application using ant undeploy and redeploy it using antdeploy, then restart the container.

Start by creating a new auction resource:

create-auction -s http://localhost:8080/wsrf/services/AuctionService

The new auction is now visible, along with the name of the file that contains itsendpoint reference, as in:

New Auction Created...EPR written to file: bid--1769679151.epr

Now run the offer-bid script, referencing that endpoint reference and providing abid value:

offer-bid -e bid--1769679151.epr 42

A response showing the current and new bids now exists, as in:

Current Bid = 0Your Bid = 42Bid Accepted.

We can experiment with different bid values, noticing that the value is persistent:

$ offer-bid -e bid--1769679151.epr 42Current Bid = 42Your Bid = 42Higher Bid exists. Write bid failed!$ offer-bid -e bid--1769679151.epr 43Current Bid = 42Your Bid = 43Bid Accepted.

We can also experiment by creating multiple auctions and sending them individualbids.

Section 6. WS-ResourceLifetime

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 34 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 35: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Add destruction support to the WSDL

Now we've created and manipulated WS-Resources, so we should look atdestroying them, as specified in the WS-ResourceLifetime specification. In thissection, we'll look at immediate and scheduled destruction of resources.

Let's start by destroying a resource. The first step is to add support for the Destroyoperation to the WSDL file:

...<portType name="AuctionPortType"

wsrp:ResourceProperties="AuctionResourceProperties">

...<operation name="Bid"><input name="BidRequest"

message="tns:BidRequest" />

<output name="BidResponse"message="tns:BidResponse" />

</operation>

<operation name="Destroy"><input message="wsrlw:DestroyRequest"

wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime/Destroy"/>

<output message="wsrlw:DestroyResponse"wsa:Action="http://docs.oasis-open.org/w

srf/2004/06/wsrf-WS-ResourceLifetime/DestroyResponse"/><fault

message="wsrlw:ResourceNotDestroyedFault"name="ResourceNotDestroyedFault"/>

<fault message="wsrlw:ResourceUnknownFault"name="ResourceUnknownFault"/>

</operation></portType>

</definitions>

The next step, however, is not to add this method to the service.

Add destruction support to the resource

Because the destruction of a WS-Resource is a standard operation likeGetResourceProperty, the tool kit includes a way to add support for it withouthaving to implement it directly.

Part of the deploy-server.wsdd file is a parameter called providers, which hasas its value the list of standard providers that should be added to the service:

...<service name="AuctionService" provider="Handler"

use="literal" style="document">

<parameter name="providers"value="GetRPProvider DestroyProvider

SetTerminationTimeProvider"/><parameter name="handlerClass"value="org.globus.axis.providers.RPCProvider"/>

<parameter name="scope" value="Application"/>...

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 35 of 41

Page 36: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

In this case, we're adding the DestroyProvider, which covers the immediatedestruction we're attempting now, and the SetTerminationTimeProvider, whichwe'll be attempting in a moment.

Destroying the WS-Resource directly

We have two choices for destroying an auction resource. The first is to create aclient application:

/** This file or a portion of this file is licensed under the terms of the* Globus Toolkit Public License, found at* http://www.globus.org/toolkit/download/license.html.* This notice must appear in redistributions of this file,* with or without modification.*/package org.globus.tutorial.auction.client;

import org.oasis.wsrf.lifetime.WSResourceLifetimeServiceAddressingLocator;import org.oasis.wsrf.lifetime.ImmediateResourceTermination;import org.apache.commons.cli.ParseException;

import org.globus.wsrf.client.BaseClient;import org.globus.wsrf.utils.FaultHelper;import javax.xml.rpc.Stub;

public class CancelAuction extends BaseClient {

public static void main(String[] args) {CancelAuction client = new CancelAuction();try {

client.parse(args);} catch (ParseException e) {

System.err.println("Error: " + e.getMessage());System.exit(1);

} catch (Exception e) {System.err.println("Error: " + e.getMessage());System.exit(1);

}

WSResourceLifetimeServiceAddressingLocator locator =new WSResourceLifetimeServiceAddressingLocator();

try {ImmediateResourceTermination port =

locator.getImmediateResourceTerminationPort(client.getEPR());

client.setOptions((Stub)port);port.destroy(

new org.oasis.wsrf.lifetime.Destroy());} catch (Exception e) {

if (client.isDebugMode()) {FaultHelper.printStackTrace(e);

} else {System.err.println("Error: " +

FaultHelper.getMessage(e));}

}}

}

In this case, we're using theWSResourceLifetimeServiceAddressingLocator and itsgetImmediateResourceTerminationPort to get the actual service port thatrepresents the DestroyProvider. From there, we can simply call the destroy

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 36 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 37: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

method.

Once this class is added to the post-deploy.xml file, we can redeploy theapplication, restart the container, and create and destroy a resource just as we usedthe other scripts.

But that's not our only option.

Using the utilities

When it comes to standard operations, such as destroying resources, andmanipulating or querying resource properties, it's not necessary to add the code to aclient application. The WSRF container actually comes with scripts for all of theseactions. for example, we could have destroyed the resource using thewsrf-destroy script, as in:

$ create-auction -s http://localhost:8080/wsrf/services/AuctionServiceNew Auction Created...EPR written to file: bid-352967109.epr$ show-status -e bid-352967109.epr<ns1:StatusMessage xmlns:ns1="http://tutorial.globus.org/auction">Welcome to

the Auction Service (No Bids yet!): 22445676</ns1:StatusMessage>$ offer-bid -e bid-352967109.epr 1129Current Bid = 0Your Bid = 1129Bid Accepted.$ wsrf-destroy -e bid-352967109.eprDestroy operation was successful$ show-status -e bid-352967109.eprError: org.oasis.wsrf.properties.ResourceUnknownFaultType

After destroying a resource, trying to access it produces aResourceUnknownFaultType.

Expiring an auction: The WSDL file

The process of adding support for the scheduled destruction of a WS-Resource issimilar to that of destroying a resource immediately, but includes an extra step.

First, add the SetTerminationTime operation to the WSDL file:

...<portType name="AuctionPortType"

wsrp:ResourceProperties="AuctionResourceProperties">

...<operation name="Destroy">

<input message="wsrlw:DestroyRequest"wsa:Action="http://docs.oasis-open.org/w

srf/2004/06/wsrf-WS-ResourceLifetime/Destroy"/><output message="wsrlw:DestroyResponse"

wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime/DestroyResponse"/>

<faultmessage="wsrlw:ResourceNotDestroyedFault"

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 37 of 41

Page 38: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

name="ResourceNotDestroyedFault"/><fault message="wsrlw:ResourceUnknownFault"

name="ResourceUnknownFault"/></operation>

<operation name="SetTerminationTime"><input message="wsrlw:SetTerminationTimeRequest"

wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime/SetTerminationTime"/>

<output message="wsrlw:SetTerminationTimeResponse"

wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime/SetTerminationTimeResponse"/>

<fault message="wsrlw:UnableToSetTerminationTimeFault"

name="UnableToSetTerminationTimeFault"/><fault message="wsrlw:ResourceUnknownFault"

name="ResourceUnknownFault"/><fault message=

"wsrlw:TerminationTimeChangeRejectedFault"name="TerminationTimeChangeRejectedFault"/>

</operation>

</portType></definitions>

Now we need to add support to the actual resource.

Expiring an auction

We added support for the SetTerminationTimeProvider provider in Adddestruction support to the resource, but unlike in the case of immediate destruction,we're not finished. To schedule the destruction of a resource, we need to be able toset its TerminationTime:

...import org.globus.wsrf.ResourceLifetime;import java.util.Calendar;

public class Auction implements Resource,ResourceProperties, ResourceIdentifier,ResourceLifetime {

...private ResourceProperty StatusMessage;private ResourceProperty CurrentBid;private Calendar terminationTime;

/** initializes the Auction. */public void initialize() throws Exception {

...}

...public void setTerminationTime(Calendar time) {

this.terminationTime = time;}

public Calendar getTerminationTime() {return this.terminationTime;

}

public Calendar getCurrentTime() {return Calendar.getInstance();

}}

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 38 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 39: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

We don't have to set an initial TerminationTime value in the initialize()method -- although we can -- but the WS-ResourceLifetime specification requires usto provide a way to get and set the TerminationTime, and to get theCurrentTime as seen by the resource.

With these methods in place, we can schedule the destruction of the resource,through a client application or through the wsrf-set-termination-time script,which takes as parameters the endpoint reference and the number of seconds untilthe desired destruction.

Section 7. Summary

This tutorial provided an introduction to working with the WSRF implementationprovided by The Globus Alliance as part of Globus Toolkit V4. It explained thevarious pieces of the puzzle and how they all fit together, and demonstrates thecreation of a complete WSRF application.

It covered the following aspects of working with WSRF classes:

• Setting up the system

• The various configuration files

• Creating single and multiple resources

• Working with resource properties

• Destroying a resource

This is, of course, just a small portion of what we can do with these classes. Be sureto read the first three parts of this series to understand what WSRF can do, thenenvision even further implementations.

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 39 of 41

Page 40: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

Resources

Learn

• This tutorial is Part 4 in a series on WSRF. Be sure to read UnderstandingWSRF, Part 1: Using WS-ResourceProperties; Part 2: Working withWS-Resources: WS-ResourceLifetime, WS-ServiceGroup and WS-BaseFaults;and Part 3: Publish-subscribe with WS-Notification.

• The main location for WSRF documentation is at The Globus Alliance Web site,but the latest specifications can be found at OASIS.

• Check out The WS-Resource Framework at Globus.org.

• Learn more about Web Services Resource Properties 1.2 at OASIS.org.

• WS-ResourceLifetime (WSRF-RL)

• WS-ServiceGroup (WSRF-SG)

• WS-Base Faults (WSRF-BF)

• The actual recommdendations for SOAP and WSDL are maintained by theWorld Wide Web Consortium, and IBM is one of the companies that proposedWS-Addressing.

• Read "Merging grids and Web services" for more information.

• Be sure to read "Using WSDL in SOAP applications."

• "Deploying Web services with WSDL: Part 1" offers an introduction to Webservices.

• Read "Discover SOAP encoding's impact on Web service performance" toimprove performance by changing your encoding style.

• "The hidden impact of WS-Addressing on SOAP" looks at the current state ofthe "Web services revolution."

• You can find more information on the developerWorks SOA and Web serviceszone.

• The XML and XPath V1.0, XPath V2.0, and XML Schema recommendations aremaintained by the World Wide Web Consortium.

• Read "A survey of XML standards."

• developerWorks offers tutorials titled "Introduction to XML" and "Get started withXPath."

• You can also find more resources in the developerWorks XML zone.

• To listen to interesting interviews and discussions for software developers,check out check out developerWorks podcasts.

• Stay current with developerWorks' Technical events and webcasts.

developerWorks® ibm.com/developerWorks

Using the WS Java Core classesPage 40 of 41 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 41: Understanding WSRF, Part 4: Using the WS Java Core classesUnderstanding WSRF, Part 4: Using the WS Java Core classes Skill Level: Introductory Babu Sundaram (babu@cs.uh.edu) Grid Specialist

• Check out upcoming conferences, trade shows, webcasts, and other Eventsaround the world that are of interest to IBM open source developers.

Get products and technologies

• Download IBM product evaluation versions, and get your hands on applicationdevelopment tools and middleware products from DB2®, Lotus®, Rational®,Tivoli®, and WebSphere®.

• Innovate your next development project with IBM trial software, available fordownload or on DVD.

Discuss

• Participate in developerWorks blogs and get involved in the developerWorkscommunity.

About the author

Babu SundaramBabu Sundaram has been actively involved with grid computing research since theearly days of Globus Toolkit. He was part of the Globus implementation team duringhis internship at Argonne National Labs. He holds a bachelor's degree in mechanicalengineering and master's degree in computer science. He is pursuing hisdoctoral-level research in computer science at the University of Houston. He haspublished many papers in various conferences and grid-related workshops, and alsoco-authored sections of a few books about grid computing. He loves teaching and, attimes, works as lecturer teaching courses on Web services and aspects of gridcomputing. He welcomes feedback and can be reached at [email protected].

ibm.com/developerWorks developerWorks®

Using the WS Java Core classes© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 41 of 41