In this example we'll take the code from the Service Data chapter and add notifications to it. We'll see that, once we have service data defined in the service, adding notifications is very simple.
Adding support for notifications does affect the interface, since we need our service to expose some notification-related methods to the outer world (for example, we need to provide a subscribe method so that clients can subscribe themselves to SDEs). However, we don't need to define any operations ourselves. We just need to extend from a standard portType called NotificationSource which includes all these notification-related operations. If we take the GWSDL from the previous example, we just have to add the following:
<gwsdl:portType name="MathPortType" extends="ogsi:GridService ogsi:NotificationSource">
<!-- <operation>s -->
<!-- <serviceData> -->
</gwsdl:portType>
The complete GWSDL file is located in $TUTORIAL_DIR/schema/progtutorial/MathService_sd_notif/Math.gwsdl |
The only other change is that this new GWSDL file has a new target namespace:
<definitions name="MathService" targetNamespace="http://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif"
xmlns:tns="http://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif"
xmlns:data="http://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif/MathSDE"
xmlns:ogsi="http://www.gridforum.org/namespaces/2003/03/OGSI"
xmlns:gwsdl="http://www.gridforum.org/namespaces/2003/03/gridWSDLExtensions"
xmlns:sd="http://www.gridforum.org/namespaces/2003/03/serviceData"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
Since we have a new interface (and, therefore, a new namespace) we need to add the following namespace-to-package mappings to our mappings file:
http\://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif= org.globus.progtutorial.stubs.MathService_sd_notif http\://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif/bindings= org.globus.progtutorial.stubs.MathService_sd_notif.bindings http\://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif/service= org.globus.progtutorial.stubs.MathService_sd_notif.service http\://www.globus.org/namespaces/2004/02/progtutorial/MathService_sd_notif/MathSDE= org.globus.progtutorial.stubs.MathService_sd_notif.servicedata
These lines can be found in $TUTORIAL_DIR/namespace2package.mappings |
The service implementation is practically identical to the previous example's implementation. The only difference is that now we'll tell the MathData SDE to notify all its subscribers each time the add or subtract method is invoked:
public void add(int a) throws RemoteException
{
mathDataValue.setLastOp("Addition");
incrementOps();
mathDataValue.setValue(mathDataValue.getValue() + a);
mathDataSDE.notifyChange();
}
The complete implementation can be found in $TUTORIAL_DIR/org/globus/progtutorial/services/core/notifications/impl/MathImpl.java |
The deployment descriptor is also very similar to the one used in the previous example, with one important change:
<?xml version="1.0"?>
<deployment name="defaultServerConfig" xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="progtutorial/core/notifications/MathService" provider="Handler" style="wrapped">
<parameter name="name" value="MathService (with Notifications)"/>
<parameter name="className" value="org.globus.progtutorial.stubs.MathService_sd_notif.MathPortType"/>
<parameter name="baseClassName"
value="org.globus.progtutorial.services.core.notifications.impl.MathImpl/>
<parameter name="schemaPath" value="schema/progtutorial/MathService_sd_notif/Math_service.wsdl"/>
<parameter name="operationProviders"
value="org.globus.ogsa.impl.ogsi.NotificationSourceProvider"/>
<!-- Start common parameters -->
<parameter name="allowedMethods" value="*"/>
<parameter name="persistent" value="true"/>
<parameter name="handlerClass" value="org.globus.ogsa.handlers.RPCURIProvider"/>
</service>
</deployment>
This file is $TUTORIAL_DIR/org/globus/progtutorial/core/notifications/server-config.wsdd |
When defining the service interface we extended from the NotificationSource portType because we needed some operations that notification sources must provide. But, where do we get the implementation of those operations? Well, this is a good example of how 'implementation by inheritance' (extending from GridServiceImpl) and 'implementation by delegation' (using operation providers) are not mutually exclusive in GT3. We have most of the implementation of our service in the MathImpl class (which extends from GridServiceImpl), and complete the implementation by 'plugging in' an operation provider (NotificationSourceProvider, included with GT3) that provides all the notification source functionality.
Let's build the service:
./tutorial_build.sh \ org/globus/progtutorial/services/core/notifications \ schema/progtutorial/MathService_sd_notif/Math.gwsdl
Now, deploy the GAR file and start the service container:
ant deploy \ -Dgar.name=$TUTORIAL_DIR/build/lib/org_globus_progtutorial_services_core_notifications.gar globus-start-container
Remember, you have to run this from your GT3 installation directory, with a user with write permissions on that directory. |