A notification service

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.

Defining the service interface

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>
[Note]

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
[Note]

These lines can be found in $TUTORIAL_DIR/namespace2package.mappings

Service Implementation

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();
}
[Note]

The complete implementation can be found in $TUTORIAL_DIR/org/globus/progtutorial/services/core/notifications/impl/MathImpl.java

Deployment Descriptor

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>
[Note]

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.

Compile and deploy

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
[Note]

Remember, you have to run this from your GT3 installation directory, with a user with write permissions on that directory.