In this chapter we will see the two lifecycle management solutions offered by the WS-ResourceLifetime specification. Since lifecycle management mainly makes sense when we have several resources, the examples will focus on explaining what modifications are necessary to the example seen in (the factory/instance example).
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.
![]() | The WSDL presented in the last section of this chapter describes a service with WS-ResourceLifetime properties. You can skip most of this section and just generate and install the math service bindings. In this section I present a high level explanation of how to add immediate destruction to the math service. |
To add immediate destruction to our service, we need to add the standard WSRF ImmediateResourceTermination portType to our service through compositional inheritance. This portType adds a Destroy operation to our portType that will instruct the current resource to terminate itself immediately. In sum, we need to copy the WSRF ImmediateResourceTermination portType Destroy operation to the MathPortType and add a Destroy binding operation to MathBinding.
![]() | After making these changes to the MathService WSDL (or just grab the WSDL at the end of this chapter), save it as "/tmp/MathLTService.wsdl" and use the WSDL to create a new site. Then grab the "MathService.rpy" from the last chapter. The WS-ResourceLifetime operations are implemented for us. This RPY script will work with one modification to an import statement since the directory structure of our generated code is a little different. I'll accomplish this using sed. |
% mkdir /tmp/MathLTSite % cd /tmp/MathLTSite % mv /tmp/MathLTService.wsdl . % wsdl2web.py --script=client.py --rpy=MathService.rpy MathLTService.wsdl ... ... % grep MathLTService services/MathService.rpy from generated.MathLTService.services.MathLTService.MathService import MathServiceWSRF % cat /tmp/MathRPSite/services/MathService.rpy | sed s/MathRPService/MathLTService/g > services/MathService.rpy
![]() | This class has been generated for you. The WSRF operations specified in the WSDL definition are implemented in this layer. |
class MathServiceWSRF(MathService): def GetResourceContext(ps, address): """get a resource context""" return ManagerHome.getInstance().getResourceContext(ps, address) GetResourceContext = staticmethod(GetResourceContext) ... ... def wsa_Destroy(self, ps, address, **kw):#http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl DestroyRequest request,response = MathService.wsa_Destroy(self, ps, address)
ctx = MathServiceWSRF.GetResourceContext(ps, address)
ImmediateResourceTermination.Destroy(ctx)
return request,response
![]()
![]() | 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): locator = CLIENT.MathServiceLocator()port = locator.getMathPortType(**kw)
msg = port.createResource(CLIENT.CreateInputMessage())
iport = locator.getMathPortType(endPointReference=msg.EndpointReference, **kw)
iport.add(CLIENT.AddInputMessage(100))
iport.Destroy(CLIENT.DestroyRequest())
try: iport.subtract(CLIENT.SubtractInputMessage(99))
except ZSI.fault.Fault, ex: pass reactor.stop() print "EXCEPTION: ", ex.__class__
print '\tcode -- ', ex.code print '\tstring -- ', ex.string print '\targs -- ', ex.args print '\tdetail -- ', ex.detail print '\tactor -- ', ex.actor print '\theaderdetail -- ', ex.headerdetail print print "ZSI Fault:\n", ex.detail[0] print if __name__ == '__main__': op = GetBasicOptParser() (options, args) = op.parse_args() SetUp(options) kw = GetPortKWArgs(options) reactor.callWhenRunning(main, **kw) reactor.run()
![]() | Make sure to start the server first... |
% ./client.py -u http://127.0.0.1:9080/wsrf/services/MathService -d 0 EXCEPTION: ZSI.fault.Fault code -- (u'http://schemas.xmlsoap.org/soap/envelope/', u'Server') string -- Processing Failure args -- ((u'http://schemas.xmlsoap.org/soap/envelope/', u'Server'), u'Processing Failure', None, [>ZSI.fault.ZSIFaultDetail o140ecb0<], None) detail -- [>ZSI.fault.ZSIFaultDetail o140ecb0<] actor -- None headerdetail -- None ZSI Fault: pyGridWare.wsrf.faults.PropertiesFaults:ResourceUnknownFault <pyGridWare.wsrf.faults.PropertiesFaults.pyGridWare.wsrf.faults.PropertiesFaults.ResourceUnknownFault instance 16388a0 <ns2:ResourceUnknownFault xmlns:ns1="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-BaseFaults-1.2-draft-01.xsd" xmlns:ns2="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"><ns1:Timestamp xmlns:ns3="http://www.w3.org/2001/XMLSchema" xmlns:ns4="http://www.w3.org/2001/XMLSchema-instance" ns4:type="ns3:dateTime">2006-04-14T21:27:52Z</ns1:Timestamp></ns2:ResourceUnknownFault>> [trace: /Users/boverhof/Desktop/Workspace/Python/zsi/ZSI/twisted/WSresource.py:341:render_POST /Users/boverhof/Desktop/Workspace/Python/zsi/ZSI/twisted/WSresource.py:254:processRequest /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/pyGridWare-1.2.0rc3-py2.4.egg/pyGridWare/utility/web/resource.py:77:processRequest /private/tmp/MathLTSite/services/MathService.rpy:19:wsa_subtract /private/tmp/MathLTSite/generated/MathLTService/services/MathLTService/MathService.py:19:GetResourceContext /private/tmp/MathLTSite/generated/MathLTService/resource/MathLTService/MathService.py:24:getResourceContext /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/pyGridWare-1.2.0rc3-py2.4.egg/pyGridWare/resource/ResourceHome.py:52:get]
When subtract is invoked, the endpoint reference that is in the call to GetResourceContext refers to a resource that no longer exists, thus a ResourceUnknownFault is thrown and returned in a SOAP fault exception (ZSI.fault.Fault) to the client.