# Platform Development Studio - Developer’s Guide

# Communication Service Example

This section describes the example Communication Service in the Platform Development Studio:

- Overview

- High-level Flow for sendData (Flow A)
- High-level Flow for startNotification and stopNotification (Flow B)
- High-level flow for notifyDataReception (Flow C)

- Interfaces

- Web Service Interface Definition
- Network Interface Definition

- Directory Structure
- Classes
- Store configuration
- SLA Example

## Overview

The Communication service example demonstrates the following:

- Structure and execution workflow in a Communication Service.
- Parameter validation
- Hitless upgrade
- Retry
- Simple TCP/IP protocol-based simulator
- Testability with the PTE

The example is based on an end-to-end Communication Service, with a set of simple interfaces

- SendData, which defines the operation `sendData` used to send data to a given address.
- NotificationManager, which defines these operations:

- `startEventNotification`, which starts a subscription for network-triggered events.
- `stopEventNotification`, which ends the subscription for network-triggered events.

- Notification, which defines the operation:

- `notifyDataReception`, used to notify the application on a network-triggered event.

The SendData and NotificationManager interfaces are used by an application and implemented by the Communication Service.

The Notification interface is used by the Communication Service and implemented by an application.

The Communication Service to network node interface is a simple TCP/IP based interface that defines the two commands:

- `sendDataToNetwork`, that sends data to the network node.
- `receiveData`, that is used by the network node to send data to a receiver - in this case the network protocol plug-in.

Figure 5-1 illustrates the flow for these operations.

Figure 5-1 Overview of example Communication Service

The flow marked A* is for`sendData`, the flow marked B* is for `startNotification` and s`topNotification`, and the flow marked C* is for `notifyDataReception`.

The modules marked with 1 are automatically generated based on the WSDL files that define the application-facing interface and code generation templates provided by the Platform Development Studio. The modules marked with 2 are skeletons generated at build time.

### High-level Flow for sendData (Flow A)

1. A1: An application invokes the Web Service SendData, with the operation `sendData`.
2. A2: The request is passed on the EJB for the interface, which passes it on to the network protocol plug-in. The diagram is simplified, but at this stage the Plug-in Manager is invoked and makes a routing decision to route to the appropriate plug-in.
3. A3: The Plug-in Manager invokes the `sendData` method in the class SendDataPluginNorth. It will always invoke a class named PluginNorth, that has a prefix that is the same as the Java representation of the Web Service interface.
4. A4: The request is passed on to class SendDataPluginToNetworkAdapter that performs the protocol translation according to the network-interface.
5. A5: The request is passed to SendDataPluginSouth.
6. A6: The request is handed off to the network node.

### High-level Flow for startNotification and stopNotification (Flow B)

The initial steps (B1-B3) are similar to flow A*. Instead of translating the request to a command on the network node, NotificationManagerNorth uses the StoreHelper to either store a new or remove a previously registered subscription for notifications. The data stored, the NotificationData, is used in network-triggered requests to resolve which application started the notification and the destination to which to send it. In the example the notification is started on an address, so the address is stored together with information to which endpoint the application wants the notification to be sent.

### High-level flow for notifyDataReception (Flow C)

1. C1: The network protocol plug-in receives the network-triggered command `receiveData` on NetworkToNotificationPluginAdapter.
2. C2: SendDataPluginSouth can be used to add additional information to the request before passing in on.
3. C3: NetworkToNotificationPluginAdapter performs the protocol translation.
4. C4: StoreHelper is used to examine if the request matches any stored NotificationData. If so, the information in NotificationData is retrieved. This information includes which application instance that the request resolves to and on which endpoint this application wants to be notified about the network triggered event.
5. C5: NotificationCallbackFactory is used to get a hold of an active NotificationCallback EJB to pass on the request to.
6. C6: The request is passed on to the NotificationCallback EJB.
7. C7: The request is passed on to an application.

## Interfaces

The example Communication Service translates between an application-facing interface, defined in WSDL, see Web Service Interface Definition and a network interface, TCP/IP based, see Network Interface Definition.

### Web Service Interface Definition

#### Interface: SendData

This interface is a simple interface containing operations for sending data.

##### Operation: sendData

Send data to the network.

Input message: sendDataMessage

Part name | Part type | Optional | Description
--- | --- | --- | ---
data | xsd:string | N | The data to be sent to the target device
address | xsd:anyURI | N | Address of the target device. Example: tel:4154011234

Output message: sendDataResponse

Part name | Part type | Optional | Description
--- | --- | --- | ---
none |  |  |

#### Interface: NotificationManager

The Notification Manager Web Service is a simple interface containing operations for managing subscriptions to network triggered events.

##### Operation: startEventNotification

Start the subscription of event notification from the network.

Input message: startEventNotificationRequest

Part name | Part type | Optional | Description
--- | --- | --- | ---
correlator | xsd:string | N | Service unique identifier provided to set up this notification.
endPoint | xsd:string | N | Endpoint address. Endpoint of the application to receive notifications. Example: http://www.hostname.com/NotificationService/services/Notification
address | xsd:anyUR | N | Service activation number. Example: tel:4154567890

Output message: invokeMessageResponse

Part name | Part type | Optional | Description
--- | --- | --- | ---
none |  |  |

##### Operation: stopEventNotification

Stop the subscription of event notification from the network.

Input message: stopEventNotificationRequest

Part name | Part type | Optional | Description
--- | --- | --- | ---
correlator | xsd:string | N | Service unique identifier provided to set up this notification.

Output message: stopEventNotificationResponse

Part name | Part type | Optional | Description
--- | --- | --- | ---
none |  |  |

#### Interface: NotificationListener

The NotificationListener interface defines the methods that the Communication Service invokes on a Web Service that is implemented by an application.

##### Operation: notifyDataReception

Method used for receiving a notification.

Input message: notifyDataReceptionRequest

Part name | Part type | Optional | Description
--- | --- | --- | ---
correlator | xsd:string | N | Service unique identifier provided to set up this notification.
originatingAddress | xsd:anyURI | N | Address of the device where the data originated. Example: tel:4153083412
data | xsd:string |  | Data sent by the originating device.

Output message: notifyDataReceptionResponse

Part name | Part type | Optional | Description
--- | --- | --- | ---
none |  |  |

### Network Interface Definition

#### sendDataToNetwork

Send data from the Communication Service to the network node.

Argument | Type | Description
--- | --- | ---
fromAddress | String | The address from which the request is sent.
toAddress | String | The address to which the request shall be sent.
data | String | The data to send.

#### receiveData

Send data from the network node to the Communication Service.

Argument | Type | Description
--- | --- | ---
fromAddress | String | The address from which the request is sent.
toAddress | String | The address to which the request shall be sent.
data | String | The data to send.

## Directory Structure

Below is a description of the directory structure for the example Communication Service.

    communication_service

    +- build.properties

    +- common.xml

    +- build.xml

    +- example

    | +- common

    | | +- build.xml

    | | +- dist

    | | | +- request_factory_skel

    | | | +- tmp

    | | | +- example.war

    | | | +- example_callback.jar

    | | | +- example_callback_client.jar

    | | | +- example_service.jar

    | | | +- resources

    | | | | +- enabler

    | | | | + facade

    | | | +- src

    | | | | +- com/<package name>Plugin

    | | | | | +- ExceptionType.java

    | | | | | +- NotificationManagerPluginFactory.java

    | | | | | +- SendDataPluginFactory.java

    | | | | | +- handlerconfig.xml

    | | | | | +- weblogic.xml

    | | +- wsdl

    | +- dist

    | | +- com.acompany.plugin.example.netex.store_4.1.jar

    | | +- example_enabler.ear

    | | +- example_facade.ear

    | +- plugins

    | | +- nextex

    | | | +- build.xml

    | | | +- dist

    | | | | +- example_netex_plugin.jar

    | | | | +- com.acompany.plugin.example.nextex.store_4.1.0.0.jar

    | | | +- build

    | | | +- config

    | | | | +- edr

    | | | | | +- alarm.xml

    | | | | | +- cdr.xml

    | | | | | +- edr.xml

    | | | | | +- alarm.xml

    | | | | +- instance_factory

    | | | | | +- instancemap

    | | | +- dist

    | | | | +- com.acompany.plugin.example.netex.store_4.1.jar

    | | | | +- example_netex_plugin.jar

    | | | +- src/com/acompany/plugin/example/netex/

    | | | |           +- context

    | | | |           +- management

    | | | |           +- notification

    | | | |           +- notificationmanager

    | | | |           +- senddata

    | | | |           +- store

    | | | +- storage

    | | | | +- wlng-cachestore-config-extensions.xml

### Directories for WSDL

Below is a list of WSDL files that define the application-facing interface and the Java representation of these in the plug-in.

#### Application-initiated traffic

##### $PDS_HOME/example/communication_service/example/common/wsdl/service

    example_common_faults.wsdl

    example_common_types.xsd

    example_data_send_interface.wsdl

    example_data_send_service.wsdl

    example_notification_manager_interface.wsdl

    example_notification_manager_service.wsdl

#### Network-triggered traffic

##### $PDS_HOME/example/communication_service/example/common/wsdl/callback

    example_notification_interface.wsdl

    example_notification_service.wsdl

### Directories for Java Source

Below is a list of Java source directories for the Communication Service Common and the Plug-in.

#### Communication Service Common

##### $PDS_HOME/example/communication_service/example/common/src

    com.acompany.example.plugin.ExceptionType

    com.acompany.example.plugin.NotificationManagerPluginFactory

    com.acompany.example.plugin.SendDataPluginFactory

#### Plug-in

##### $PDS_HOME/example/communication_service/example/plugins/netex/src

    com.acompany.plugin.example.netex.context.ContextTranslatorImpl

    com.acompany.plugin.example.netex.management.ConfigurationStoreHandler

    com.acompany.plugin.example.netex.management.ExampleMBean

    com.acompany.plugin.example.netex.management.ExampleMBeanImpl

    com.acompany.plugin.example.netex.management.Management

    com.acompany.plugin.example.netex.notification.north.NotificationHandlerNorth

    com.acompany.plugin.example.netex.notification.south.NetworkToNotificationPluginAdapter

    com.acompany.plugin.example.netex.notification.south.NetworkToNotificationPluginAdapterImpl

    com.acompany.plugin.example.netex.notificationmanager.north.NotificationManagerPluginNorth

    com.acompany.plugin.example.netex.senddata.north.SendDataPluginNorth

    com.acompany.plugin.example.netex.senddata.south.SendDataPluginSouth

    com.acompany.plugin.example.netex.senddata.south.SendDataPluginToNetworkAdapter

    com.acompany.plugin.example.netex.senddata.south.SendDataPluginToNetworkAdapterImpl

    com.acompany.plugin.example.netex.store.FilterImpl

    com.acompany.plugin.example.netex.store.NotificationData

    com.acompany.plugin.example.netex.store.StoreHelper

    com.acompany.plugin.example.netex.ExamplePluginInstance

    com.acompany.plugin.example.netex.ExamplePluginService

### Directories for resources

Only the Communication Service common components have associated resources. The resources are XML files that serve as deployment descriptors for the network tier EAR and the access tier EAR.

##### $PDS_HOME/example/communication_service/example/common/resources/at/META-INF

Contains deployment descriptors for the access tier EAR file. These must be present in the META-INF directory of the EAR. See Oracle WebLogic Server Developing Applications with WebLogic Server at http://download.oracle.com/docs/cd/E12840_01/wls/docs103/programming for a description of the enterprise application deployment descriptor elements.

    application.xml

    weblogic-application.xml

The code generation creates these files, and the build script takes care of the packaging.

##### $PDS_HOME/example/communication_service/example/common/resources/nt/META-INF

Contains deployment descriptors for the network tier EAR file. These must be present in the META-INF directory of the EAR. See Oracle WebLogic Server Developing Applications with WebLogic Server at http://download.oracle.com/docs/cd/E12840_01/wls/docs103/programming for a description of the enterprise application deployment descriptor elements.

    application.xml

    weblogic-application.xml

    weblogic-extension.xml

The code generation creates these files, and the build script takes care of the packaging.

### Directories for Configuration of Plug-in

##### $PDS_HOME/example/communication_service/example/plugins/netex/config/edr

Sample entries to add in the EDR, CDR, and Alarm filters.

    alarm.xml

    cdr.xml

    edr.xml

These serves as examples. Add the contents of these to the EDR configuration file. Use the EDR Configuration Pane as described in Managing and Configuring EDRs, CDRs and Alarms in the System Administrator’s Guide.

##### $PDS_HOME/example/communication_service/example/plugins/netex/instance_factory

Sample instance map for mapping of classes, interfaces, and abstract classes.

When using com.bea.wlcp.wlng.api.util.InstanceFactory to retrieve instances for a given interface, class, or abstract class, this mapping is referenced. The mapping can be overridden. See JavaDoc for InstanceFactory for details.

    instancemap

##### $PDS_HOME/example/communication_service/example/plugins/netex/storage

Sample store configuration file. Defines how the Storage service is used by the plug-in, store type, table names, query definitions, and get and set methods. See StoreHelper, FilterImpl, and NotificationData.

    wlng-cachestore-config-extensions.xml

### Directories for Build and Configuration of Builds

##### $PDS_HOME/example/communication_service/

    build.properties

Defines the installation directory for Oracle Communications Services Gatekeeper and for the Platform Development Studio.

    common.xml

Defines properties, class paths, task definitions, and macros for the build.

    build.xml

Main build file to build the Communication Service. This build file also contains targets for packaging deployable artifacts into the access and network tier.

##### $PDS_HOME/example/communication_service/example/common

    build.xml

Build file for the common parts of the Communication Service.

##### $PDS_HOME/example/communication_service/example/plugins/netex

    build.xml

Build file for the plug-in.

### Directories for Classes, JAR, and EAR Files

##### $PDS_HOME/example/communication_service/example/dist

Deployment artefacts for the Communication Service.

    example_facade.ear

The part of the Communication Service that is deployed in the access tier.

    example_enabler.ear

The part of the Communications Service that is deployed in the network tier.

##### $PDS_HOME/example/communication_service/example/common/dist

JAR and WAR files for the common parts of the Communication Service.

    example_callback_client.jar

    example_callback.jar

    example_service.jar

    example.war

##### $PDS_HOME/example/communication_service/example/common/dist/request_factory_skel

Auto generated source for skeleton classes extending com.bea.wlcp.wlng.api.plugin.RequestFactory.

One class is generated per Service WSDL, that is per interface that defines application-initiated operations.

The classes are named <PreFix>PluginFactory, where <PreFix> is picked up from the WSDL binding in the WSDL file.

In the subdirectory that corresponds to the package name, the following classes are generated:

    NotificationManagerPluginFactory.java

    SendDataPluginFactory.java

These are generated as skeletons, but in the example they are adapted to the specific use cases.

##### $PDS_HOME/example/communication_service/example/plugins/netex/dist

Contains individual JAR files comprises the plug-in.

    com.acompany.plugin.example.netex.store_4.1.jar

Includes the schema file for the store used by the plug-in, packaged together with the classes for which instances are stored. This file must be put in `$DOMAIN_HOME/config/store_schema` on each server in the network tier. The server needs to be restarted if any changes have been done to the store schema or the classes referred to in the store schema.

    example_netex_plugin.jar

The JAR for the plug-in.

##### $PDS_HOME/example/communication_service/example/plugins/netex/dist/mbean_generationdir

Output directory for the MBean that has been processed by the javadoc2annotation ant task.

## Classes

Below is a description of the classes and the methods defined in these classes:

- Communication Service Common

- ExceptionType
- NotificationManagerPluginFactory
- SendDataPluginFactory

- Plug-in Layer

- ContextTranslatorImpl
- ExamplePluginService
- ConfigurationStoreHandler
- ExampleMBean
- ExampleMBeanImpl
- Management
- NotificationHandlerNorth
- NetworkToNotificationPluginAdapter
- NetworkToNotificationPluginAdapterImpl
- NotificationManagerPluginNorth
- SendDataPluginNorth
- SendDataPluginSouth
- SendDataPluginToNetworkAdapter
- SendDataPluginToNetworkAdapterImpl
- FilterImpl
- NotificationData
- StoreHelper

### Communication Service Common

#### ExceptionType

Class.

Enumeration for exception types:

Defines:

- SERVICE_ERROR
- POLICY_ERROR

#### NotificationManagerPluginFactory

Class.

Extends RequestFactory.

Helper class that is used by the service EJB for two purposes:

- Creating routing information requested by the Plug-in Manager when routing the method call to a plug-in.
- Converting Exceptions, thrown either by the Plug-in Manager or by the plug-in, to Exceptions that are supported by the application-facing interface.

Note: | This class needs to remain in this package and the class name must not be changed.

##### public void validateRequest(Method method, Object... args)

Validates the request to make sure that mandatory parameters are present. Operates on a Java representation of the Web Service call.

##### public RequestInfo createRequestInfo(Class<? extends Plugin> type, Method method, Object... args)

Used by the service EJB to extract routing data from the method call. The routing data is then given to the Plug-in Manager. This method returns the routing data in a RequestInfo object.

Returns a:

- AddressRequestInfo if the request contains an actual address that can be routed to a specific plug-in.
- CorrelatorRequestInfo if the request contains an correlator that relates to an operation that relates to states (to start or to stop something). Most often it is the starting and stopping of notifications that use a correlator.

##### public Throwable convertEx(Method method, Throwable e)

Called by the service EJB in order to convert Exceptions thrown by the Plug-in Manager and the Plug-in to Exceptions defined by the called method.

##### private Throwable convertEx(Method method, PluginException e)

Converts a PluginException to an Exception that can be thrown by the method called by the application.

### Plug-in Layer

#### ContextTranslatorImpl

Class.

Implements interface com.bea.wlcp.wlng.api.plugin.context.ContextTranslator.

Responsible for setting any non-simple parameter into the RequestContext.

##### public void translate(Object param, ContextInfo info)

Puts the member variables of a complex data type into the ContextInfo.

Checks the interface type.

Gets the simple data types provided in the parameter param.

Puts each of the parameters into the ContextInfo object.

These parameters are provided in each subsequent EDR that is emitted in the request.

#### ExamplePluginService

Package: com.acompany.plugin.example.netex

Implements ManagedPluginService.

Initial point for the network protocol plug-in.

Defines the life-cycle for a plug-in service.

Also holds the data that is specific for the plug-in instance.

This class manages the life-cycle for the plug-in service, including implementing the necessary interfaces that make the plug-in deployable in Oracle Communications Services Gatekeeper. It is also responsible for registering the north interfaces with the Plug-in Manager. At startup time it uses the InstanceFactory to create one instance of each plug-in service and at activation time it registers these with the Plug-in Manager. The InstanceFactory uses an instancemap to find out which class it should instantiate for each plug-in interface implementation. The instance map is found under the resource directory. It also has

##### public boolean isRunning()

Checks to see if the plug-in service is in running state.

##### public String[] getSupportedSchemes()

Returns a list of address schemes the plug-in supports.

##### public void init(String id, PluginPool pool)

Initializes the plug-in service with its ID and a reference to its plug-in pool.

##### public void doStarted()

When entering state Started, the plug-in instantiates a TimerManager.

##### public void doStopped()

No action.

##### public void doActivated()

No action.

##### public void doDeactivated()

No action.

##### public void handleSuspending(CompletionBarrier barrier)

The plug-in service does not handle graceful shutdown: it propagates the request to public void handleForceSuspending().

##### public void handleForceSuspending()

When the plug-in is being forcefully suspended, the plug-in service iterates through all plug-in instances and calls public void handleSuspending() on each.

##### public boolean isActive()

While there is a connection to the network node and the plug-in is in state ACTIVE/RUNNING this method must return true, in all other cases false. This method is invoked by the Plug-in Manager during route selection.

##### public ServiceType getServiceType()

Returns the type of the service. Used by the Plug-in Manager to route requests to a plug-in instance that can manage the type of request. The ServiceType is auto-generated based on the WSDL that defines the application-facing interfaces.

##### public String getNetworkProtocol()

Returns a descriptive name of the network protocol being used.

##### createInstance(String)

Creates a new plug-in instance.

#### ExamplePluginInstance

Package: com.acompany.plugin.example.netex.

Implements ManagedPluginInstance

Defines the life-cycle for a plug-in instance/

This class manages the life-cycle for the plug-in instance including implementing the necessary interfaces that make the plug-in an instance in Oracle Communications Services Gatekeeper.

It is also responsible for instantiating classes that implement the traffic interfaces and for initializing stores to use and MBeans.

##### public String getId()

Returns the plug-in instance ID.

##### public void activate()

- Instantiates the classes implementing the PluginNorth interface:

- SendDataPluginNorth
- NotificationManagerPluginNorth
- NotificationHandlerNorth

- Instantiates the class implementing the PluginSouth interface:

- SendDataPluginSouth

- Instantiates the classes that implements the southbound and northbound adapter instances:

- NetworkToNotificationPluginAdapterImpl
- SendDataPluginToNetworkAdapterImpl

- Creates the network proxy:
- Registers the PluginNorth interfaces into the Plug-in Manager.
- Registers the PluginSouth interfaces into the Plug-in Manager.
- Registers the NetworkToNotificationPluginAdapter into the network proxy to be notified when a request arrives from the network node.
- Sets NotificationHandlerNorth to NetworkToNotificationPluginAdapter in order to forward request to the application.
- Sets the network proxy into the SendDataPluginToNetworkAdapter in order to send request to the network.
- Sets SendDataPluginToNetworkAdapter into SendDataPluginNorth.
- Instantiates ConfigurationStoreHandler.
- Instantiates Management and registers the plug-in into it.

##### private void rethrowServiceDeploymentException(Exception e)

Re-throws a ServiceDeploymentException if any other exception is encountered. The exception is wrapped in a ServiceDeploymentException.

##### public ConfigurationStoreHandler getConfigurationStore()

Returns a handle to the ConfigurationStore used by the plug-in instance. The ConfigurationStore was initiated in public void activate().

##### public NetworkProxy getNetworkProxy()

Returns handle to the NetworkProxy. The NetworkProxy was initiated in public void activate().

##### public void connect()

Connects to the network using NetworkProxy.

##### ConnectTimerTask

Inner class of ExamplePluginService.

Extends java.util.TimerTask.

It has one method, run(), that tries to connect to the network node, if not connected. This class is instantiated and scheduled as a java.util.Timer in public void handleResuming().

#### ConfigurationStoreHandler

Handles storage of configuration data using the StorageService.

A set of default settings are defined as static final variables. These are used to populate the ConfigurationStore with default values the first time the plug-in is deployed.

Takes the plug-in ID as a parameter. The plug-in ID is the key in the ConfigurationStore.

Uses ConfigurationStoreFactory to get a handle to the ConfigurationStoreService and gets the local ConfigurationStore that handles configuration data for the plug-in instance.

The plug-in only deals with configuration data that is unique for the instance in a specific server, so the store is fetched as outlined in Listing 5-1.

Listing 5-1 Get a server-specific (local) ConfigurationStore

    ConfigurationStoreFactory factory = ConfigurationStoreFactory.getInstance();

    localConfigStore = factory.getStore(pluginId, LOCAL_STORE, ConfigurationStore.STORE_TYPE_LOCAL);

If the plug-in uses a ConfigurationStore that is shared between the plug-in instances in the cluster, it must fetch that one as well, as outlined in Listing 5-2

Listing 5-2 Get a cluster-wide (shared) ConfigurationStore

    ConfigurationStoreFactory factory = ConfigurationStoreFactory.getInstance();

    sharedConfigStore = factory.getStore(pluginId, SHARED_STORE, ConfigurationStore.ConfigurationStore.STORE_TYPE_SHARED);

After the ConfigurationStore is fetched, it is initialized with default values for the available configuration settings. These default values can be changed later on, using the MBeans, see ExampleMBean.

##### public void setLocalInteger(String key, Integer value),

##### public Integer getLocalInteger(String key),

##### public void setLocalString(String key, String value), and

##### public String getLocalString(String key)

The methods above are used to set and get data to and from the ConfigurationStore. One set/get pair must be implemented per data type in the ConfigurationStore. It is only necessary to implement set/get methods for the data types actually used by the plug-in.

In the set methods, the parameter name/key is provided as the first parameter and the actual value is provided in the second parameter.

In the get methods, the parameter name/key is provided as the parameter and the actual value is returned.

#### ExampleMBean

Interface.

Management interface for the example simulator.

It defines the following methods:

- public void setNetworkPort(int port) throws ManagementException;
- public int getNetworkPort() throws ManagementException;
- public void connect() throws ManagementException;
- public void disconnect() throws ManagementException;
- public boolean connected();

Implemented by ExampleMBeanImpl.

All MBean methods should throw com.bea.wlcp.wlng.api.management.ManagementException or a subclass thereof if the management operation fails.

#### Management

Class.

Handles registration of the ExampleMBean in the MBean Server.

#### NotificationHandlerNorth

##### NotificationHandlerNorth()

Constructor.

Empty.

##### public void deliver(String data, String destinationAddress, String originatingAddress)

Delivers data originating from the network node to the application.

NetworkToNotificationPluginAdapterImpl calls this method upon a network triggered request.

The actual delivery is not done directly to the application. Instead it is done via the service callback client EJB which forwards the request to the service callback EJB. Both of these are generated during the build process.

First, the NotificationData associated with the destination address is fetched.

NotificationCallback, which is a generated class, is fetched using private NotificationCallback getNotificationCallback().

NotifyDataReception, a generated class that is a Java representation of the operation defined in the callback WDSL is instantiated.

The correlator associated with the NotificationData is set on NotifyDataReception.

The data (payload) in the network triggered request is set on NotifyDataReception.

The originating address in the network-triggered request is converted to a URI and set on NotifyDataReception.

The endpoint associated with NotificationData is fetched.

A remote call is done to the method notifyDataReception on the Callback EJB in the access tier. The endpoint and NotifyDataReception are supplied as parameters.

##### private NotificationCallback getNotificationCallback()

Helper method to get the object representing the Callback EJB.

If the object is already retrieved it is returned, otherwise the NotificationCallbackFactory is used to get a new object. This is the preferred pattern.

Using the CallBackFactory ensures high-availability between the network tier and the access tier for network triggered requests.

The Callback is generated during the build process when the access tier is generated. Three files are generated per callback WSDL. The names are based on the interface name defined in the WSDL. The interface in the WSDL is Notification, so:

- the factory is named NotificationCallbackFactory.
- the implementation class is named NotificationCallbackImpl
- an interface is named is named NotificationCallback.

The classes are completely based on the WSDL file for the callback interface. The factory is used to retrieve the implementation class that implements the interface.

##### private NotificationData getNotificationData(String destinationAddress)

Helper method to fetch the NotificationData from the StoreHelper. The NotificationData is retrieved based on the key destination address.

#### NetworkToNotificationPluginAdapter

Interface

extends PluginSouth, NetworkCallback

Defines the interface between NetworkToNotificationPluginAdapter and the network node.

##### public void setNotificationHandler(NotificationHandlerNorth notificationHandlerNorth)

Sets the NotificationHandler.

#### NetworkToNotificationPluginAdapterImpl

Class.

Implements NetworkToNotificationPluginAdapter.

##### public void setNotificationHandler(NotificationHandlerNorth notificationHandlerNorth)

Sets NotificationHandlerNorth in the class.

##### public String resolveAppInstanceGroupdId(ContextMapperInfo info)

From interface com.bea.wlcp.wlng.api.plugin.PluginSouth

Gives the plug-in an opportunity to add additional values to the RequestContext before the network-triggered requests is passed on to public void receiveData(@ContextKey(EdrConst ants.FIELD_ORIGINATING_ADDRESS) String fromAddress, @ContextKey(EdrConstants.FIELD_DESTINATION_ADDRESS) @MapperInfo(C) String toAddress, String data).

This method is called only once per network-triggered request. It is invoked after r`esolveAppInstanceGroupId(ContextMapperInfo)`, when the RequestContext for the current request has been rebuilt.

The default implementation is supposed to be empty.

RequestContext contains the fully rebuilt RequestContext.

ContextMapperInfo contains the annotated parameters in public void receiveData(@ContextKey(EdrConst ants.FIELD_ORIGINATING_ADDRESS) String fromAddress, @ContextKey(EdrConstants.FIELD_DESTINATION_ADDRESS) @MapperInfo(C) String toAddress, String data).

##### public void receiveData(@ContextKey(EdrConst ants.FIELD_ORIGINATING_ADDRESS) String fromAddress, @ContextKey(EdrConstants.FIELD_DESTINATION_ADDRESS) @MapperInfo(C) String toAddress, String data)

From NetworkCallback.

The network node invokes this method when a network-triggered events occurs.

The parameter:

- fromAddress is the address representing the originator of the request
- toAddress is the address representing the destination of the request.
- data contains the payload of the request.

The method is annotated with @Edr, so the method is woven with annotation EDR.

fromAddress and toAddress are annotated with @ContextKey, which means that they will be put it the current RequestContext under the key specified by the string in the argument of the annotation. As illustrated in Listing 5-3, they are put in the RequestContext under the keys EdrConstants.FIELD_ORIGINATING_ADDRESS and EdrConstants.FIELD_DESTINATION_ADDRESS, respectively. These keys ensure that the values will be available in all subsequent EDRs emitted during this request.

toAddress is also annotated with @MapperInfo, which means that the value should be registered in ContextMapperInfo under the key specified by the string in the argument of the annotation. In Listing 5-3, the key is C.

Listing 5-3 Annotation of network-triggered method

    ...

    @Edr

    public void receiveData(

       @ContextKey(EdrConstants.FIELD_ORIGINATING_ADDRESS)

       String fromAddress,

       @ContextKey(EdrConstants.FIELD_DESTINATION_ADDRESS)

       @MapperInfo(C)

       String toAddress,

      String data) {

    ...

#### NotificationManagerPluginNorth

Class.

Implements NotificationManagerPlugin.

##### public StartEventNotificationResponse startEventNotification(@ContextTranslate(ContextTranslatorImpl.class) StartEventNotification parameters)

Starts a subscription for notifications on network-triggered requests.

The method is a Java representation of the application-facing operation startEventNotification, defined in the WSDL that was used as input for the code generation.

As illustrated in Listing 5-4, the method is annotated with @EDR, and the parameter is put in the RequestContext using the annotation @ContextTranslate, since the parameter is a complex data type that requires traversal in order to resolve the simple data types. When using this annotation, the class is provided as an ID.

Listing 5-4 Annotations for startEventNotification

    ...

    @Edr

    public StartEventNotificationResponse startEventNotification(

    @ContextTranslate(ContextTranslatorImpl.class) StartEventNotification parameters)

    throws ServiceException {

    ...

In the operation, these parameters are included:

    <xsd:element name="correlator" type="xsd:string"/>

    <xsd:element name="endPoint" type="xsd:string"/>

    <xsd:element name="address" type="xsd:anyURI"/>

The values of correlator and endPoint are put in NotificationData.

The application instance ID for the originator of the request, the application that uses the Web Services interface, is resolved from the RequestContextManager and put in NotificationData.

Using StoreHelper, NotificationData is put in the StorageService.

##### public StopEventNotificationResponse stopEventNotification(@ContextTranslate(ContextTranslatorImpl.class) StopEventNotification parameters)stopEventNotification(StopEventNotification)

Ends a previously started subscription for notifications on network-triggered requests.

The method is a Java representation of the application-facing operation `stoptEventNotification`, defined in the WSDL that was used as input for the code generation.

The method is annotated in a similar manner to public StartEventNotificationResponse startEventNotification(@ContextTranslate(ContextTranslatorImpl.class) StartEventNotification parameters).

Using StoreHelper, NotificationData corresponding to the correlator provided in the requests is removed from the StorageService.

#### SendDataPluginNorth

Class.

Implements SendDataPlugin.

##### public void setPluginToNetworkAdapter(SendDataPluginToNetworkAdapter adapter)

Sets SendDataPluginToNetworkAdapter to be used for application-initiated requests.

##### public SendDataResponse sendData(@ContextTranslate(ContextTranslatorImpl.class) SendData parameters)

Sends data to the network

The method is a Java representation of the application-facing operation `sendData`, defined in the WSDL that was used as input for the code generation.

The method is annotated in a similar manner to public StartEventNotificationResponse startEventNotification(@ContextTranslate(ContextTranslatorImpl.class) StartEventNotification parameters).

Passes on the request to SendDataPluginToNetworkAdapter.

If there is a need to retry the request, this method re-throws a PluginRetryException, so the request can be retried by the service interceptors.

#### SendDataPluginSouth

Class.

implements PluginSouth.

##### public SendDataPluginSouth()

Constructor.

Empty.

##### public void send(NetworkProxy proxy, String address, String data)

Sends data to the network node.

Passes on the request to sendDataToNetwork using the NetworkProxy.

The method is annotated with @Edr.

##### public String resolveAppInstanceGroupdId(ContextMapperInfo info)

Empty implementation that returns null. This method has meaning, and is used, only in network-triggered requests.

The application instance ID is already known in the RequestContext, since the class only handles application-initiated requests.

##### public void prepareRequestContext(RequestContext ctx, ContextMapperInfo info))

From interface com.bea.wlcp.wlng.api.plugin.PluginSouth

Gives the plug-in an opportunity to add additional values to the RequestContext before the application-initiated requests is passed on to public void send(NetworkProxy proxy, String address, String data).

Empty in this example. Normally all data about the request should be known at this point, so no additional data needs to be set.

#### SendDataPluginToNetworkAdapter

Interface.

Defines the interface between the plug-in and the network node for application-initiated requests.

#### SendDataPluginToNetworkAdapterImpl

Class.

##### public SendDataPluginToNetworkAdapterImpl()

Constructor.

Instantiates SendDataPluginSouth.

##### public void setNetworkProxy(NetworkProxy networkProxy)

Sets the NetworkProxy object. This is a remote object in the network node.

##### public void send(String address, String data)

Hands off the request to the network node using SendDataPluginSouth.

#### FilterImpl

Class.

Implements interface com.bea.wlcp.wlng.api.storage.filter.Filter.

This is the query filter used for the named store NotificationData.

Evaluates whether an entry in the named store NotificationData matches the filter. The filter is defined in XML, see Store configuration.

##### public boolean matches(Object value)

Must be invoked after public void setParameters(Serializable ... parameters).

Returns true if the value provided in Object matches parameters[0], as set in public void setParameters(Serializable ... parameters).

##### public void setParameters(Serializable ... parameters)

Sets the query parameters for the filter.

The parameters are ordered as provided to the StoreQuery and it is the responsibility of the implementation to handle them in this order.

#### NotificationData

Class.

Implements Serializable

The data structure representing a notification. The notification is registered and de-registered by applications using the application-facing Web Services interfaces and represents a subscription for network-triggered events. The NotificationData is used for:

- Matching a network-triggered event with a subscription started by an application. The match is usually based on the destination address in the requests from the network.
- Resolving information on which application instance created the subscription, and the endpoint on which the application expects to be notified of the event.

NotificationData is stored using the storage service, normally using the invalidating cache storage provider for cluster-wide access and high performance.

Each of the attributes to be stored must have a corresponding set method and get method.

The class must be serializable.

##### public NotificationData()

Constructor.

Empty.

#### StoreHelper

Class.

Singleton.

Helper class for storing NotificationData using the StorageService.

##### public static StoreHelper getInstance()

Returns the single instance of StoreHelper.

##### public void addNotificationData(URI address, NotificationData notificationData)

Stores the NotificationData using the Storage Service.

The named store is retrieved using private Store<String, NotificationData> getStore().

The NotificationData is put into the named store. The address is the key and the object is the value.

The named store is released. This should always be done in a finally{...} block.

##### public void removeNotificationData(String correlator)

Removes NotificationData using the StorageService.

The named store is retrieved using private Store<String, NotificationData> getStore().

A Set of matching entries are returned using private Set<Map.Entry<String, NotificationData>> getEntries(String correlator, Store<String, NotificationData> store).

If there are matching entries, all are removed using private void removeEntries(Set<Map.Entry<String, NotificationData>> set, Store<String, NotificationData> store).

The named store is released. This should always be done in a finally{...} block.

##### public NotificationData getNotificationData(String destinationAddress)

Gets NotificationData using the StorageService

The named store is retrieved using private Store<String, NotificationData> getStore().

The NotificationData that is keyed on destinationAddress is fetched from the store.

The named store is released. This should always be done in a finally{...} block.

##### private Store<String, NotificationData> getStore()

Gets a named stored from com.bea.wlcp.wlng.api.storage.StoreFactory.

##### private Set<Map.Entry<String, NotificationData>> getEntries(String correlator, Store<String, NotificationData> store)

Gets a java.util.Set of entries of NotificationData from a named store using the StorageService. The query being used is a named query, com.bea.wlcp.wlng.plugin.example.netex.Query, defined in wlng-cachestore-config-extensions.xml.

##### private void removeEntries(Set<Map.Entry<String, NotificationData>> set, Store<String, NotificationData> store)

Removes a java.util.Set of entries of NotificationData using the StorageService. The NotificationData is removed from a named store.

#### ExamplePluginInstance

Class.

Implements com.bea.wlcp.wlng.api.plugin.ManagedPluginInstance.

Defines the life-cycle for a plug-in instance.

Also holds the data that is specific to the plug-in instance.

##### public ExamplePluginInstance(String id, ExamplePluginService parent)

Constructor.

The id is the plug-in instance ID, and the parent is the Plug-in service the of which the plug-in is an instance.

##### public String getId()

The plug-in instance returns the ID that it was instantiated with.

##### public void activate()

Called when the plug-in instance is activated, so the plug-in:

- Instantiates the traffic interfaces.
- Registers the traffic interfaces with the Plug-in Manager.
- Register callbacks between the interfaces.
- Initiates the Store.
- Instantiates and registers the MBean interface.

If the plug-in service is in state ACTIVE (RUNNING), public void handleResuming() is called.

##### public void handleResuming()

Connects to the network node.

If the connection fails, a timer is triggered to retry the connection setup.

##### public void deactivate()

Called when the plug-in instance is deactivated.

If the plug-in service is in state ACTIVE (RUNNING), public void handleSuspending() is called.

The call-back is unregistered from the network node.

The MBean is unregistered.

##### public void handleSuspending()

If existing, the timer associated with connection setup is cancelled.

The plug-in disconnects from the network node.

##### public List<PluginInterfaceHolder> getNorthInterfaces()/ public List<PluginInterfaceHolder> getSouthInterfaces()

Returns a list of the interfaces.

##### public boolean isConnected()

Returns true if there is a connection to the network node, that is if the plug-in instance is ready to accept traffic.

##### public int customMatch(RequestInfo requestInfo)

Checks the operation that is about to be invoked on the plug-in instance by introspection of the RequestInfo associated with request.

If the operation is StopEventNotification and the correlator provided is cached using the Storage service, the request must be sent to all instances of the plug-in, since the request depends on an earlier request (startNotification). MATCH_REQUIRED is returned.

If the operation is any other than StopEventNotification, the request is unrelated to any previous operation and any plug-in instance can be used. MATCH_OPTIONAL is returned.

##### private void rethrowDeploymentException(Exception e)

Re-throws a DeploymentException given another exception. The exception is wrapped in a DeploymentException.

##### public ConfigurationStoreHandler getConfigurationStore()

Gets the ConfigurationStoreHandler.

#### ExamplePluginService

Class.

Implements com.bea.wlcp.wlng.api.plugin.ManagedPluginService.

Defines the life-cycle for a plug-in service.

Also holds the data that is specific for the plug-in instance.

##### public ExamplePluginService()

Constructor.

Empty.

##### public TimerManager getTimerManager()

Gets a handle to the TimerManager.

##### public boolean isRunning()

Checks if the plug-in service is in RUNNING state.

##### public String[] getSupportedSchemes()

Returns an array of supported address schemes.

##### public void init(String id, PluginPool pool)

Initializes the plug-in service with the ID and a reference to the plug-in pool.

The PluginPool holds all plug-in instances.

##### public void doStarted()

Instantiates a TimerManager to be used.

##### public void doStopped()/public void doActivated()/public void doDeactivated()

Empty implementation. Nothing to do here.

##### public void handleResuming()

Iterates over all plug-in instances using the PluginInstancePool and calls public void handleResuming() on ExamplePluginInstance

##### public void handleSuspending(CompletionBarrier barrier)

The nature of the example network protocol is that is does not have connections to maintain. Because it is possible to treat this event as in public void handleForceSuspending () the request is passed on to that method.

##### public void handleForceSuspending ()

When the plug-in service is being forcefully suspended, the plug-in instances are disconnected from the network node immediately, without waiting for any in-flight requests to complete.

This is done by iterating over the PluginInstancePool and calling public void handleSuspending() on ExamplePluginInstance

##### public ServiceType getServiceType()

Returns the service type, com.acompany.example.servicetype.ExampleServiceType.type. The type is automatically generated when the service EJB is generated.

##### public String getNetworkProtocol()

Returns the network protocol. A string used for informational purposes.

##### public ManagedPluginInstance createInstance(String pluginInstanceId)

Creates a new instance of the plug-in service. The ID for the new plug-in is supplied together with the object that created the instance (this).

## Store configuration

The store configuration file `wlng-cachestore-config-extensions.xml` defines:

- Which data to store
- The get and set methods to retrieve and store the data
- The database table structure use to store the data
- Queries to perform on the store

Listing 5-5 shows the store configuration file for the example Communication Service.

The configuration file defines:

- The store type ID: since the store type ID is prefixed with wlng.db.wt (wlng.db.wt.es_example), the store is a write-through cache.
- The table to be used: es_example
- The identifier for the store is a combination of the type of the key column (java.lang.String) and the type of the value column (com.acompany.plugin.example.netex.store.NotificationData). These are used when the store is retrieved from the StoreFactory, see private Store<String, NotificationData> getStore()
- The key column: address
- The value columns for the key:

- correlator
- endpoint
- appinstance

- The get and set methods for the value columns.
- The query to use when doing lookups in the store.

The configuration file, together with any non-complex data types must be packaged into a .jar and put in the directory `$DOMAIN_HOME/config/store_schema` so it can be accessed by the storage service.

Listing 5-5 Store configuration for the example Communication Service

    <?xml version="1.0" encoding="UTF-8"?>

    <store-config xmlns="http://www.bea.com/ns/wlng/30"

                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                  xsi:schemaLocation="http://www.bea.com/ns/wlng/30 wlng-cachestore-config.xsd">

      <db_table name="es_example">

        <key_column name="address" data_type="VARCHAR(100)"/>

        <value_column name="correlator" data_type="VARCHAR(100)">

          <methods>

            <get_method name="getCorrelator"/>

            <set_method name="setCorrelator"/>

          </methods>

        </value_column>

        <value_column name="endpoint" data_type="VARCHAR(255)">

          <methods>

            <get_method name="getEndPoint"/>

            <set_method name="setEndPoint"/>

          </methods>

        </value_column>

        <value_column name="appinstance" data_type="VARCHAR(100)">

          <methods>

            <get_method name="getApplicationInstance"/>

            <set_method name="setApplicationInstance"/>

          </methods>

        </value_column>

      </db_table>

      <store type_id="wlng.db.wt.es_example" db_table_name="es_example">

        <identifier>

          <classes key-class="java.lang.String" value-class="com.acompany.plugin.example.netex.store.NotificationData"/>

        </identifier>

        <index>

          <get_method name="address"/>

        </index>

      </store>

      <query name="com.bea.wlcp.wlng.plugin.example.netex.Query">

        <sql><![CDATA[SELECT * FROM es_example WHERE correlator LIKE ?]]></sql>

      </query>

    </store-config>

## SLA Example

Below is an example SLA for the example Communication Service. There are examples of service provider group and application group SLAs in:

    $PDS_HOME\pte\resource\sla

Listing 5-6 Example SLA for the example Communication Service

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

    <Sla xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" applicationGroupID="default_app_group" xsi:noNamespaceSchemaLocation="app_sla_file.xsd">

        <serviceContract>

            <startDate>2008-04-17</startDate>

            <endDate>2099-04-17</endDate>

            <scs>com.acompany.example.plugin.SendDataPlugin</scs>

            <contract/>

        </serviceContract>

        <serviceContract>

            <startDate>2008-04-17</startDate>

            <endDate>2099-04-17</endDate>

            <scs>com.acompany.example.plugin.NotificationManagerPlugin</scs>

            <contract/>

        </serviceContract>

        <serviceContract>

            <startDate>2008-04-17</startDate>

            <endDate>2099-04-17</endDate>

            <scs>com.acompany.example.callback.NotificationCallback</scs>

            <contract/>

        </serviceContract>

    </Sla>