HOWTO
a. ResourceContext, ResourcHome
d. Add Service Instance to Twisted Container
Add
your WSDL entry under appropriate section in "pyGridWare/config.txt".
GLOBUS_WSDL section is relative to the environment variable GLOBUS_LOCATION. LOCAL_WSDL section is a relative or absolute file path.
GLOBUS_WSDL]
CounterService
= share/schema/core/samples/counter/counter_service.wsdl
[LOCAL_WSDL]
WidgetService = docs/widget.wsdl
Regenerate
all bindings and install.
WARNING -- The generator is a little buggy, many of the generated modules have been edited to work. Be careful what you uncomment!!!
%python
setup.py --regenerate install
Generates
three modules for each WSDL (eg. Òcounter_service.wsdlÓ)
pyGridWare/generated/stubs/Counter_services.py
pyGridWare/generated/services/Counter_services_server.py
pyGridWare/generated/types/Counter_services_types.py
Create a resource
import
pyGridWare.generated.stubs.Counter_services as COUNTER
locator
= COUNTER.CounterServiceLocator()
port
= locator.getCounterPortType(portAddress=url, **kw)
request
= COUNTER.CreateCounterRequest()
msg
= port.createCounter(request)
Counter Port using EPR
epr
= msg._EndpointReference
port
= locator.getCounterPortType(portAddress=url, \
endPointReference=epr, **kw)
msg
= port.add(100)
First, you need to establish a security
context. Second, you need to
specify a signature handler. Third
you need to specify the "node" or message to be signed.
from
pyGridWare.security.gss.Authenticate import GssAuthenticationHandler
auth
= GssAuthenticationHandler()
KeyName
= auth.authenticate(url)
from
pyGridWare.security.gss.GssSignatureHandler import \
GssSignatureHandler
locator
= COUNTER.CounterServiceLocator()
kw
= {}
kw['sig_handler']
= GssSignatureHandler()
kw['sig_handler'].setContextID(KeyName)
port
= locator.getCounterPortType(portAddress=url, **kw)
from
pyGridWare.security.Utility import MessageSigUtility
request
= COUNTER.CreateCounterRequest()
MessageSigUtility.Sign(request)
msg
= port.createCounter(request)
First you need to create a notification consumer,
and from it you can retrieve the notification context. Second, provide the
notificationConsumer's EPR in the Subscribe message, and also provide the
resource property QName we want to be notified about.
from
pyGridWare.notification.NotificationConsumer import \
NotificationConsumer
notificationConsumer
= NotificationConsumer()
notificationConsumer.start()
WARNING -- The topic expression expects to
receive a QName in text content.
This is a little screwy since we need to manually specify the prefix
mapping. Becareful not to use a
prefix that the underlying implementation might write over (eg. xmlns, xsi,
xsd, SOAP-ENC, SOAP-ENV, ns[0-9]*) since this prefix will be set in the SOAP
Envelope.
ctx
= notificationConsumer.getNotificationContext()
request
= COUNTER.SubscribeRequest()
request._ConsumerReference
= ctx.getConsumerReference()
request._TopicExpression
= TopicExpression()
request._TopicExpression._text
= "counter:Value"
request._UseNotify
= True
port.binding.nsdict['counter']
= "http://counter.com"
msg
= port.Subscribe(request)
First youÕll need to create a resource context, and resource home. The context will hold state and information specific to the resource. Secondly youÕll need to implement the service by sub-classing the generated server module.
WARNING -- Currently these classes are not
automatically generated.
eg. 'pyGridWare/generated/properties/Counter_properties.py'
class
CounterKey(int):
typecode = ZSI.TC.Iint(pname=("http://counter.com",'CounterKey'))
eg. 'pyGridWare/generated/resource/Counter_context.py'
from
pyGridWare.resource.ResourceHome import PersistentResourceHome
class
CounterHome(PersistentResourceHome):
def getResourceContext(self, ps, address):
key = AddressingUtils.getResourceID(ps, \
CounterKey.typecode)
return self.get(key)
eg. 'pyGridWare/generated/resource/Counter_context.py'
from
pyGridWare.resource.ResourceContext import ResourceContext
class
CounterContext(ResourceContext):
home = CounterHome()
def __init__(self):
ResourceContext.__init__(self)
self.properties = CounterProperties()
def setResourceID(self, resourceID):
ResourceContext.setResourceID(self, CounterKey(resourceID))
Eg. 'pyGridWare.services.CounterService'.
First subclass the generated server
interface, and overide each "wsa_" method and call the base class
method to set up the request instance (available as "self.request")
and initialize the response (return by base class "wsa_" call).
All the logic of each operation
will reside within the service's "wsa_" methods.
Types of Operations:
First need to create a context, set the URL of the
service, and register it to the resource home. Then need to retrieve the End Point Reference (EPR)
from the context instance, and set this in the response message that is
returned to the calling party.
Retrieve the resource context from the
ResourceHome, and use the ImmediateResourceTermination interface to destroy it.
Retrieve the resource context from the
ResourceHome, and use the ScheduledResourceTermination interface to destroy it.
Retrieve the resource context from the
ResourceHome, then grab the resource properties from the resource context. Use the request to retrieve the
property from the resource properties, and return it in the wildcard element.
Retrieve the resource context from the
ResourceHome, then grab the resource properties from the resource context. Then grab the "Value"
resource property. Add "self.request"
to "Value", then set the "Value" resource property with
their sum.
The sum will also be returned, but since the return
value is an immutable (int) we need to capture the typecode information by
subclassing the immutable type, and specify the typecode.
Subscribe to a resource property to receive notifications when that resource property's state changes. Retrieve the resource context from the ResourceHome, then get the SubscriptionManager singleton. Use the Subscription Manager to subscribe to the resource property using the request, it will return an EPR representing the subscription that must be returned in the response message.
Eg. "pyGridWare.generated.services.Counter_services_server.py"
Inherit from class
GssSecureResourceMixIn, and specify signature over response message.
from pyGridWare.services.CounterService import Counter
from pyGridWare.security.gss.GssService import GssSecureResourceMixIn
class SecureCounter(GssSecureResourceService, Counter):
def __init__(self, post='/wsrf/services/SecureCounterService', **kw):
GssSecureResourceService.__init__(self, post)
def wsa_add(self, ps, address):
esponse = Counter.wsa_add(self, ps, address)
# Specify Signature over response if security
specified.
MessageSigUtility.Sign(request)
return response
Basically you need to identify or create the resource node in the siteÕs resource tree where the service instance will reside, and also pass in the POST value when creating the service instance.
Run the twisted service container:
%./start-container.sh