Immediate destruction is the simplest type of lifecycle management. It allows us to request that a resource be destroyed immediately by invoking a destroy
operation in the instance service. Notice how, even though the factory service is responsible for creating the resources, destruction must be requested to each individual resource through the instance service.
To add immediate destruction to our service, we simply need to extend from the standard WSRF ImmediateResourceTermination
portType. This portType adds a destroy
operation to our portType that will instruct the current resource to terminate itself immediately.
<portType name="MathPortType"
wsdlpp:extends="wsrpw:GetResourceProperty
wsrlw:ImmediateResourceTermination"
wsrp:ResourceProperties="tns:MathResourceProperties">
<operation name="add">
<input message="tns:AddInputMessage"/>
<output message="tns:AddOutputMessage"/>
</operation>
<operation name="subtract">
<input message="tns:SubtractInputMessage"/>
<output message="tns:SubtractOutputMessage"/>
</operation>
</portType>
To be able to do this, we must remember to declare the WS-ResourceLifetime namespace, and import its WSDL file:
<definitions name="MathService"
targetNamespace="http://www.globus.org/namespaces/examples/core/MathService_instance_rl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://www.globus.org/namespaces/examples/core/MathService_instance_rl"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsrlw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/WSDLPreprocessor"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:import namespace= "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl" location="../../wsrf/lifetime/WS-ResourceLifetime.wsdl" />
This is part of file |
Next, we need to add the Globus-supplied DestroyProvider
operation provider to the instance service. This provider implements the destroy
operation mentioned above.
<?xml version="1.0" encoding="UTF-8"?>
<deployment name="defaultServerConfig"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Instance service -->
<service name="examples/core/rl/MathService" provider="Handler" use="literal" style="document">
<parameter name="className" value="org.globus.examples.services.core.rl.impl.MathService"/>
<wsdlFile>share/schema/examples/MathService_instance_rl/Math_service.wsdl</wsdlFile>
<parameter name="allowedMethods" value="*"/>
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
<parameter name="scope" value="Application"/>
<parameter name="providers" value="GetRPProvider DestroyProvider"/>
</service>
<!-- Factory service -->
<service name="examples/core/rl/MathFactoryService" provider="Handler" use="literal" style="document">
<parameter name="className" value="org.globus.examples.services.core.rl.impl.MathFactoryService"/>
<wsdlFile>share/schema/examples/FactoryService/Factory_service.wsdl</wsdlFile>
<parameter name="allowedMethods" value="*"/>
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
<parameter name="scope" value="Application"/>
<parameter name="instance" value="examples/core/rl/MathService"/>
</service>
</deployment>
This file is
|
Now, we can compile the service:
./globus-build-service.sh rl
And deploy it:
globus-deploy-gar $EXAMPLES_DIR/org_globus_examples_services_core_rl.gar
To try out resource destruction, we will use a client that is identical to the simple client seen in Chapter 5, Multiple resources. The only difference is that, at the end of the client we will add a call to the destroy
operation.
package org.globus.examples.clients.FactoryService_Math_rl; import org.apache.axis.message.addressing.Address; import org.apache.axis.message.addressing.EndpointReferenceType; import org.globus.examples.stubs.MathService_instance_rl.MathPortType; import org.globus.examples.stubs.MathService_instance_rl.service.MathServiceAddressingLocator; import org.globus.examples.stubs.Factory.service.FactoryServiceAddressingLocator; import org.globus.examples.stubs.Factory.FactoryPortType; import org.globus.examples.stubs.Factory.CreateResource; import org.globus.examples.stubs.Factory.CreateResourceResponse; import org.oasis.wsrf.lifetime.Destroy; /* This client creates a new MathService instance through a FactoryService. This client * expects one parameter: the factory URI. */ public class Client_immed { public static void main(String[] args) { FactoryServiceAddressingLocator factoryLocator = new FactoryServiceAddressingLocator(); MathServiceAddressingLocator instanceLocator = new MathServiceAddressingLocator(); try { String factoryURI = args[0]; EndpointReferenceType factoryEPR, instanceEPR; FactoryPortType mathFactory; MathPortType math; // Get factory portType factoryEPR = new EndpointReferenceType(); factoryEPR.setAddress(new Address(factoryURI)); mathFactory = factoryLocator.getFactoryPortTypePort(factoryEPR); // Create resource and get endpoint reference of WS-Resource. // This resource is our "instance". CreateResourceResponse createResponse = mathFactory .createResource(new CreateResource()); instanceEPR = createResponse.getEndpointReference(); // Get instance PortType math = instanceLocator.getMathPortTypePort(instanceEPR); System.out.println("Created instance."); // Perform an addition math.add(10); // Perform another addition math.add(5); // Perform a subtraction math.subtract(5); math.destroy(new Destroy()); System.out.println("Destroyed instance."); } catch (Exception e) { e.printStackTrace(); } } }
This file is
|
Compile the client:
javac \ -classpath ./build/stubs/classes/:$CLASSPATH \ org/globus/examples/clients/FactoryService_Math_rl/Client_immed.java
And run it:
java \ -classpath ./build/stubs/classes/:$CLASSPATH \ org.globus.examples.clients.FactoryService_Math_rl.Client_immed \ http://127.0.0.1:8080/wsrf/services/examples/core/rl/MathFactoryService
If all goes well, you should see the following:
Created instance. Destroyed instance.
Well, that wasn't too exciting, was it? How do we really now that resource destruction is actually happening? Well, there's a simple way of testing it. Modify the last lines of the client so they will look like so:
math.destroy(new Destroy());
System.out.println("Destroyed instance.");
// Perform another addition
math.add(5);
As you can see, we are going to try to invoke an operation after destroying the resource that operation is supposed to use. As you can probably imagine, no good will come of this. If you recompile the client and run it again, you should again see the following:
Created instance. Destroyed instance.
And, then, a really nasty error message where you should be able to make out the following:
java.rmi.RemoteException: ; nested exception is: org.globus.wsrf.NoSuchResourceException
What has just happened is that the add
has been invoked as normal. However, the endpoint reference that is being passed in the call refers to a resource that no longer exists. So, when add
tries to retrieve the resource, a NoSuchResourceException
is thrown.