6.2. Scheduled destruction

Scheduled destruction is a more elaborate form of resource lifecycle management, as it allows us to specify exactly when we want the resource to be destroyed. The main application of scheduled destruction is to perform lease-based lifecycle management, where we initially set the destruction time of a resource some time in the future (for example, 5 minutes). This is called the lease. Our application must periodically renew the lease (setting the destruction time another 5 minutes in the future), or the resource will eventually be destroyed. This will allow our application to purge resources that for some reason (network failure, programmer errors, etc.) have become unavailable (and therefore can't receive the lease renewal).

Using scheduled destruction requires adding more code that immediate destruction because the standard WSRF portType that provides scheduled destruction not only adds a new operation (SetTerminationTime) but also two new resource properties: TerminationTime and CurrentTime. TerminationTime specifies when the resource is set to be destroyed, and the value of CurrentTime must always be the time in the machine that hosts the resource. This means that, not only will we have to modify the WSDL file, we will also have to make sure those two new resource properties are properly implemented in our resource class.

6.2.1. Overview: Directions to add scheduled destruction to our service

Note

The WSDL presented in the last section of this chapter describes a service with WS-ResourceLifetime properties. You can skip the next section, in which I present a high level explanation of how to add scheduled destruction to the math service.

We need to add the standard WSRF ScheduledResourceTermination portType to our service through compositional inheritance. This portType adds a SetTerminationTime operation to our portType that will instruct the current resource to terminate itself at the specified time. In sum, we need to add five things to our WSDL. First, copy the ScheduledResourceTermination portType SetTerminationTime operation to the MathPortType. Second, add a SetTerminationTime binding operation to MathBinding. Third, add a WSDL import for the WS-ResourceLifetime WSDL. Forth, add a XSD import for the WS-ResourceLifetime schema. Lastly, add the two global element declarations compromising the ScheduledResourceTerminationRP Resource Property to the MathResourceProperties element.

Note

After making these changes to the MathService WSDL (or just grab the WSDL at the end of this chapter), rebuild the mathservice bindings and install. Nothing else needs to be done.


python setup.py build -fgo mathservice
python setup.py install

6.2.2. Generated Stub Service: pyGridWare.generated.services.math.MathService

Note

This class has been generated for you.


class MathServiceWSRF(MathService):

    def GetResourceContext(ps, address):
        """get a resource context"""
        return ManagerHome.getInstance().getResourceContext(ps, address)
    GetResourceContext = staticmethod(GetResourceContext)

    ...
    ...

    def wsa_SetTerminationTime(self, ps, address, **kw): (1)
        #http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl SetTerminationTimeRequest
        request,response = MathService.wsa_SetTerminationTime(self, ps, address) (2)
        ctx = MathServiceWSRF.GetResourceContext(ps, address) (3)
        ScheduledResourceTermination.SetTerminationTime(ctx, request._RequestedTerminationTime) (4)
        response._NewTerminationTime = time.gmtime(ctx.getTerminationTime()) (5)
        response._CurrentTime = time.gmtime(time.time())
        return request,response (6)

(1)
Fully functional WSRF SetTerminationTime operation. Schedules a service instance, referenced by the EPR, for destruction.
(2)
Call lower-level service binding stub to set up the response and request python objects.
(3)
Retrieve the ResourceContext of the service instance.
(4)
Schedule the destruction of the service instance represented by the ResourceContext.
(5)
The response variable is an instance of the generated class SetTerminationTimeResponse representing the WSDL SetTerminationTimeResponse Message. The attributes representing the NewTerminationTime and CurrentTime need to be set before returning this "message" to the client.
(6)
Return python object representing the WS-ResourceLifetime Message SetTerminationTimeResponse

6.2.3. client_set_termination_time.py

We will test our service by creating a new resource, setting its termination 10 seconds in the future, and then checking every second to see if the resource is still 'alive'. When the resource is terminated, any call to the resource will produce an exception. Like the immediate destruction client, this client is similar to the simple client seen in . The following is the code that we will run after the resource has been created:

Note

Copy & Paste example..


#!/usr/bin/env python
############################################################################
# Automatically generated by wsdl2web.py
# See LBNLCopyright for copyright notice!
###########################################################################
from twisted.python import log
from twisted.internet import reactor

import ZSI
from pyGridWare.utility.scripts.client import GetBasicOptParser, GetPortKWArgs, SetUp
from generated.MathLTService.stubs import MathLTService as CLIENT


def main(**kw):
    import time
    locator = CLIENT.MathServiceLocator() (1)
    port = locator.getMathPortType(**kw) (2)

    msg = port.createResource(CLIENT.CreateInputMessage()) (3)
    print 'Created instance.'

    iport = locator.getMathPortType(endPointReference=msg.EndpointReference, **kw) (4)

    request = CLIENT.SetTerminationTimeRequest()
    startTime = time.time()
    termTime = startTime + 10
    request.RequestedTerminationTime = termTime (5)
    msg = iport.SetTerminationTime(request) (6)

    print 'Local Time'
    print 'Start Time                 ', time.strftime('%c', time.localtime(startTime))
    print 'Requested termination time ', time.strftime('%c', time.localtime(termTime))
    print
    print 'UTC Tuples'
    print 'RequestedTerminationTime ', time.gmtime(request.RequestedTerminationTime)
    print 'NewTerminationTime       ', msg.NewTerminationTime
    print 'CurrentTime              ', msg.CurrentTime
    print

    try:
        for i in range(1,20):
            iport.add(CLIENT.AddInputMessage(1)) (7)
            time.sleep(startTime + i - time.time())
            print 'Second %d' %i
    except ZSI.fault.Fault:(8)
        print 'resource has been destroyed: ', time.strftime('%c', time.localtime())
    else:
        print 'ERROR'

    reactor.stop()


if __name__ == '__main__':
    op = GetBasicOptParser()
    (options, args) = op.parse_args()
    SetUp(options)
    kw = GetPortKWArgs(options)
    reactor.callWhenRunning(main, **kw)
    reactor.run()


(1)
Here we obtain a reference to a MathPortType instance. Notice the factory's URI, where the service is located, and the WS-Addressing URI, which specifies the WS-Addressing version the client should use.
(2)
Once we have the MathPortType, we use it to invoke the createResource operation. This operation returns an endpoint reference, inside a CreateResourceResponse object. This endpoint reference includes both the instance service's URI and the new resource's identifier. In the next client we will take a peek inside the endpoint reference.
(3)
Call the createResource factory method, this returns a CreateOutputMessage instance.
(4)
The CreateOutputMessage contains an EPR, use it to obtain a new MathPortType which will now refer to the instance service.
(5)
(6)
We now use the iport to invoke SetTerminationTime, which schedules the destruction of the resource.
(7)
Invoke the add operation with iport until the the server returns a SOAP Fault containing a WSRP ResourceUnknownFault.
(8)
ZSI.fault.Fault, SOAP Fault Exception contains a ResourceUnknownFault, it has been destroyed.

6.2.4. Run the client:

Note

Make sure to start the server first...


% ./client_set_termination_time.py -u http://127.0.0.1:9080/wsrf/services/MathService -d 0 
Created instance.
Local Time
Start Time                  Fri Apr 14 14:49:44 2006
Requested termination time  Fri Apr 14 14:49:54 2006

UTC Tuples
RequestedTerminationTime  (2006, 4, 14, 21, 49, 54, 4, 104, 0)
NewTerminationTime        (2006, 4, 14, 21, 49, 54, 0, 0, 0)
CurrentTime               (2006, 4, 14, 21, 49, 43, 0, 0, 0)

Second 1
Second 2
Second 3
Second 4
Second 5
Second 6
Second 7
Second 8
Second 9
Second 10
Second 11
Second 12
'HTTP Error 500'
resource has been destroyed:  Fri Apr 14 14:49:56 2006