HOWTO


 

 

  1. Generate client stubs, server stubs, and types from a WSDL file.
  2. Example Client Script
    1. Basic Counter Example
    2. Add Message Level Security
    3. Add Notification Consumer

      3.  Create A Service

a.    ResourceContext, ResourcHome

b.    Create Service Module

c.     Secure Service

d.    Add Service Instance to Twisted Container

 

 


I.      Generate client stubs, server stubs, and types

 

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

 

 

 


II.    Client Script

A.   Basic Example (eg. "bin/CounterClient.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)

 

B.   Add Security (eg. "bin/SecureCounterClient.py"):

 

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.

 

1.    Secure Conversation:  Establish a Security Context

 

from pyGridWare.security.gss.Authenticate import GssAuthenticationHandler

auth = GssAuthenticationHandler()

KeyName = auth.authenticate(url)

 

2.    Security Handler and set Security Context ID.

 

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)

3.    Specify Message to be Signed:

 

from pyGridWare.security.Utility import MessageSigUtility

request = COUNTER.CreateCounterRequest()

MessageSigUtility.Sign(request)

 

4.    Send out request

 

msg = port.createCounter(request)

 

 

C.  Add Notification (eg. Òbin/NotificationCounterClient.pyÓ)

 

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.

 

1.    Create a Notification Consumer:

 

from pyGridWare.notification.NotificationConsumer import \

    NotificationConsumer

notificationConsumer = NotificationConsumer()

notificationConsumer.start()

 

2.    Use Stub to Subscribe:

 

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)

 

 

 


 

 

III.   Create a Service

 

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.

A.   ResourceContext, ResourceHome and ResourceID:

 

WARNING -- Currently these classes are not automatically generated.

 

1.    ResourceID: self-describing data

 

 eg. 'pyGridWare/generated/properties/Counter_properties.py'

 

class CounterKey(int):

    typecode = ZSI.TC.Iint(pname=("http://counter.com",'CounterKey'))

2.    ResourceHome:

 

 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)

 

3.    ResourceContext:

 

 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))

 

 

B.   Create a new service module

 

 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:

1.    Factory Pattern:  Create a resource  'wsa_createCounter'

 

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.

 

2.    Lifetime:  Destroy a resource 'wsa_Destroy'

 

Retrieve the resource context from the ResourceHome, and use the ImmediateResourceTermination interface to destroy it.

 

3.    Lifetime: Set terminationTime 'wsa_SetTerminationTime'

 

Retrieve the resource context from the ResourceHome, and use the ScheduledResourceTermination interface to destroy it.

 

4.    Properties:  Retrieve a resource property value 'wsa_GetResourceProperty'

 

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.

5.    Counter Add:  add an integer to the counter.

 

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.

 

6.    Subscribe: Subscribe to a resource property 'wsa_Subscribe'

 

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.

 

 

C.  Secure Service

 

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

 

 

D.  Add Service Instance to "bin/server-config.tac"

 

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