Platform Development Studio - Developer’s Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Container Services

This chapter provides a high-level description of Oracle Communications Services Gatekeeper container services. It also provides an overview of other parts of the API available for the use of extension developers:

JavaDoc for the container API is available in the $PDS_Home/doc/javadoc directory of the Platform Development studio installation and on the Oracle Communications Services Gatekeeper site at http://www.oracle.com/technology/documentation/bea.html.

 


Container service APIs

The Oracle Communications Services Gatekeeper container service APIs provide the basic infrastructure by which a Communication Service and the container services of Oracle Communications Services Gatekeeper can communicate.

All APIs for inter-working with the container services are found in com.bea.wlcp.wlng.api.*.

In order for a network protocol plug-in of a Communication Service to interact with Oracle Communications Services Gatekeeper it must be deployable in the context of Oracle Communications Services Gatekeeper. Once it is deployable, it can have access to certain utility functions.

.

Table 7-1 Summary of the container services APIs
Package
Summary
com.bea.wlcp.wlng.api.account
Represents an application instance and the related accounts and groups and the states of the accounts.
com.bea.wlcp.wlng.api.corba
Factory to retrieve an ORB.
com.bea.wlcp.wlng.api.edr.*
Annotations, interfaces and classes used when annotating EDRs. Descriptor classes for alarms, EDRs, and CDRs.
Helper classes for EDR listeners.
com.bea.wlcp.wlng.api.event_channel
Classes to publish and listen to events over cluster-wide event channels.
com.bea.wlcp.wlng.api.interceptor
Interfaces and classes for service interceptors.
com.bea.wlcp.wlng.api.management.*
MBean helper classes.
com.bea.wlcp.wlng.api.plugin.*
Plug-in related classes and interfaces.
See Plug-in.
com.bea.wlcp.wlng.api.servicecorrelation
Interface to implement if extending the existing service correlation mechanism.
com.bea.wlcp.wlng.api.statistics
Annotation for statistics.
com.bea.wlcp.wlng.api.storage
Interfaces and classes for the Storage Service.
com.bea.wlcp.wlng.api.timers
Factory for using commonj.timers API.
com.bea.wlcp.wlng.api.util
Classes and interfaces for commonly used functions, for example ID generator, InstanceFactory, and clustering.
com.bea.wlcp.wlng.api.work
Factory for using commonj.work API.

 


Class: InstanceFactory

The Instance Factory is the mechanism used in Oracle Communications Services Gatekeeper to retrieve instances of a given interface, class, or abstract class. You retrieve an instance of the Instance Factory using the public static method getInstance(). The factory itself has a single method:

getImplementation(Class theClass) - Retrieves a class that implements a given interface or extends a given class

The implementation to be used is located and used based on the following rules:

  1. First, check the jar file’s instancemap, a standard java.util.Properties file. Every jar file can have its own instancemap. The instancemap provides a list that maps a given interface, class, or abstract class to the preferred implementation of that functionality. See Listing 7-1 for an example.
  2. Note: The interface name used in the instancemap must be unique across all plug-ins for a given Service Enabler. It is not possible to use the same interface in two instancemap files belonging to two different plug-ins and still map them to two different implementations.
  3. If a mapping is provided and the target class has a public constructor or static singleton method, instantiate it.
  4. If there is no explicit mapping, or if there is no public constructor or static singleton method for a mapped class, instantiate an object named according to the following pattern: theClass.getClass().getName() +”Impl” if this exists and has a public constructor or static singleton method.
  5. Listing 7-1 Example instancemap file
    com.bea.wlcp.wlng.MyInterface=com.bea.wlcp.wlng.MyImplementation
    com.bea.wlcp.wlng.MyOtherInterface=com.bea.wlcp.wlng.MyOtherImplementation

For details see Javadoc for Package com.bea.wlcp.wlng.api.util Class InstanceFactory.

 


Class: ClusterHelper

com.bea.wlcp.wlng.api.util.cluster.ClusterHelper

Helper class for getting the JNDI Context for the network and access tier.

For details see Javadoc for Package com.bea.wlcp.wlng.api.util.cluster Interface ClusterHelper.

 


Service: EventChannel Service

This service is used to broadcast events to other Oracle Communications Services Gatekeeper server instances and to register listeners for events originating in other Oracle Communications Services Gatekeeper server instances.

Interface: EventChannel

Use this interface to broadcast events to other instances of Oracle Communications Services Gatekeeper, and to register listeners for events originating in them. It is used, for example, in propagating changes of cached data. It is retrieved using the com.bea.wlcp.wlng.api.event_channel.EventChannelFactory.

An event has a name and a value, where the name is an identifier for the event and the value is any object implementing java.io Serializable.

The following methods are available:

Interface: EventChannelListener

This interface is used to receive events published using EventChannel.

The following method is available:

 


Service: Statistics service

Standard statistics are generated automatically when a plug-in implements PluginNorth and PluginNorthCallBack interfaces. In addition to this, custom statistics can be generated explicitly.

To explicitly generate statistics, annotate the method where you wish to generate statistics.

The syntax of the annotation is:

@Statistics(id=<My_Statistics_Type>)

@ExceptionStatistics(id=<My_Statistics_Type>)

The annotations are defined in:

om.bea.wlcp.wlng.api.statistics.Statistics 
com.bea.wlcp.wlng.api.statistics.ExceptionStatistics

The @Statistics annotation generates a statistics event when the method returns, while the @ExceptionStatistics annotation generates a statistics event if an exception is thrown.

The statistics type must be registered. Use the addStatisticType operation in the Management Console. For more information, see “Managing and Configuring Statistics and Transaction Licenses” in the System Administration Guide.

For extensions, the statistics ID shall be in the range 1000 to 2250.

 


Plug-in

The com.bea.wlcp.wlng.api.plugin.* packages contain a range of interfaces and classes for use by the extension developer.

See Communication Service Description.

 


Management

Base classes and annotations for giving the Oracle Communications Services Gatekeeper Management Console or other JMX tools management access to Communication Services. See Making Communication Services Manageable for more information. Also see the JavaDoc for the packages: com.bea.wlcp.wlng.api.management.*

 


EDR

See Annotations, EDRs, Alarms, and CDRs.. Also see the JavaDoc for the packages com.bea.wlcp.wlng.api.edr.*

 


SLA Enforcement

SLA enforcement operates on methods identified by the Java representation of the interface, and the operation on the application-facing interface for the Communication Service or the service type of the Communication Service.

The content of the tag <scs> defined in the <serviceContract> tag in the SLA is the plug-in type for the plug-in.

An operation on the application-facing interface is represented in the rules according to the following scheme: <service name> and <operation name>.

Parameters in the operation are represented in the rules according to the following scheme:

arg<n>.<parameter name>

where <n> in arg<n> depends on the WSDL that defines the application-facing interface; normally this is arg0.

If the parameter in <parameter name > is

SLA enforcement can also be done for a certain service type. The service type is defined when generating the Communication Service or network protocol plug-in using the Eclipse Wizard. SLA enforcement for service types relates to quotas and request rates and are defined under the element <serviceTypeContract>.

For enforcement of custom SLAs, see Custom Service Level Agreements.

 


Service Correlation

It is often the case that service providers would like to be able to bundle what are to Oracle Communications Services Gatekeeper separate services into a single unit for charging purposes. An end user could send an SMS to the provider requesting the location of the coffee shop closest to her current location. The application would receive the network-initiated SMS (one service), do a user location lookup on the customer (one service), and then send the customer an MMS with a map showing the requested information (one service). So three Oracle Communications Services Gatekeeper services need to be grouped into a single service charging unit. To do this, Oracle Communications Services Gatekeeper provides the framework for a Service Correlation service that uses a Service Correlation ID (SCID) to combine/correlate all the services.

The SCID itself is provided either by the application or by an external mechanism that the Communication Service must provide (see Interface: ExternalInvocation). Oracle Communications Services Gatekeeper does not check whether or not it is unique. The SCID is stored in the OLS Work Context, so that it can be accessed by both the Access Tier and the Network Tier. The Service Correlation class registers itself as a RequestContextListener. When application-initiated request traffic enters the plug-in, the Service Correlation service takes the SCID from the Work Context and places it in the RequestContext object, where it will be available to the EDR service. When network-initiated request traffic is leaving the plug-in, the Service Correlation service takes the SCID from the RequestContext object and places it in the Work Context, where it can be retrieved by the SOAP Handler and passed along to the application.

Interface: ExternalInvocation

Because Service Correlator IDs may need to be stored across several invocations and a RequestContext object exists only for the lifetime of a single request, a Communication Service needs to create a way of storing and retrieving the SCIDs. This is done by implementing the ExternalInvocation interface. This interface has two methods: one stores the Service Correlation ID and one retrieves it. The implementor is free to modify the ID once it has been stored, or to use the Invocation object to create IDs in the first place.

When the Service Correlation service takes the SCID (should there be one) out of the Work Context of an application-initiated request, it automatically attempts to store it in an object of this type before putting the SCID in the RequestContext.

When a network-initiated request is leaving the plug-in, the Service Correlation service automatically attempts to retrieve an SCID from an object of this type, using the SCID (should there be one) it finds in the RequestContext object before it sets the Work Context. In this way, if the ExternalInvocation object has modified the SCID in any way, it is this modified version that is put in the Work Context and thus sent on to the application. The ExternalInvocation implementation class should have an empty public constructor or a static method that returns itself.

Class: ExternalInvocatorFactory

This class is used by the Service Correlation service to locate and instantiate the correct ExternalInvocation object. It does this by using an instancemap. The instancemap entry should look like this:

com.bea.wlcp.wlng.api.servicecorrelation.ExternalInvocation=myPackageStructure.myImplClass

where myImplClass is the ExternalInvocation implementation.

Class: ServiceCorrelation

This class manages the transport and storage of the Service Correlation ID across multiple service invocations.

Implementing the ExternalInvocation Interface

There are four basic steps in creating a custom service correlation:

  1. Create a jar file that includes your code. For example:
  2. Listing 7-2 Sample Custom Service Correlation
    package myPackageStructure;
    import com.bea.wlcp.wlng.api.servicecorrelation.ExternalInvocation;
    import com.bea.wlcp.wlng.api.servicecorrelation.ExternalInvocationException;
    public class MyImplClass implements ExternalInvocation {
     public MyImplClass() {
     }
     public String pushServiceCorrelationID(String scID, String serviceName, String methodName, String spID, String appID, String appInstGrp) throws ExternalInvocationException {
      // your code here
      return scID;
     }
     public String getServiceCorrelationID(String scID, String serviceName, String methodName, String spID, String appID, String appInstGrp) throws ExternalInvocationException {
      // your code here
      return scID;
     }
    }
  3. Create the instancemap. See Class: ExternalInvocatorFactory.
  4. Put the instancemap file in the JAR. This makes your custom service correlation available to the service interceptor InvokeServiceCorrelation.
  5. Put the JAR file in $DOMAIN_Home/lib.

 


Parameter Tunneling

Parameter tunneling is a feature that allows an application to send additional parameters to Oracle Communications Services Gatekeeper and lets a plug-in use these parameters. This feature makes it possible for an application to tunnel parameters that are not defined in the interface that the application is using and can be seen as an extension to the application-facing interface.

The application sends the tunneled parameters in the SOAP header of a Web Services request.

The tunneled parameter can be retrieved in a plug-in by the key. The parameter is fetched from the RequestContext, using the method getXParam(String key). If a value for the key cannot be found, null is returned.

Listing 7-3 Get the value of the tunneled parameter ‘aParameterName’.
RequestContext.getCurrent().getXParam("aParameterName");

If the same parameter is defined in the <contextAttribute> SLA tag, it should override the parameter tunneled from the application. This behavior, however, is defined per plug-in.

 


Storage Services

The storage services provided in Oracle Communications Services Gatekeeper are of two types, described below:

ConfigurationStore

The Oracle Communications Services Gatekeeper container exposes a ConfigurationStore Java API that Communication Services can use to store simple configuration parameters instead of using JDBC and caching algorithms in each module.

Note: This utility is intended for configuration parameters only, not traffic data

All data stored in a ConfigurationStore are stored in a database table and cached in memory.

Below are the characteristics of a ConfigurationStore:

Interfaces

The Java interface APIs are found in the package com.bea.wlcp.wlng.api.storage.

The entry point to configuration stores is through the com.bea.wlcp.wlng.api.storage.configuration.ConfigurationStoreFactory using the following method:

public abstract ConfigurationStore getStore(String moduleName, String name, int storeType) throws ConfigurationException;

The ConfigurationStore service exposes an interface with the following features:

Listing 7-4 is an example of using the Configuration Store.

Listing 7-4 Example of a ConfigurationStoreHelper
package com.acompany.plugin.example.netex.management;
import com.bea.wlcp.wlng.api.storage.configuration.*;
/**
 * Class used for handling the configuration store.
 *
 * @author Copyright (c) 2007 by BEA Systems, Inc. All Rights Reserved.
 */
public class ConfigurationStoreHandler {
/**
   * Constants used for the values stored in the store.
   */
  public static final String KEY_NETWORK_HOST = "KEY_NETWORK_HOST";
  public static final String KEY_NETWORK_PORT = "KEY_NETWORK_PORT";
/**
   * Constant to access either the local store. Note that these are
   * just names for the store.
   */
  private static final String LOCAL_STORE = "local";
/**
   * Local configuration store instance.
   */
  private ConfigurationStore localConfigStore;
/**
   * Constructor.
   *
   * @param pluginId The plugin id
   * @throws ConfigurationException An exception thrown if the initialization failed
   */
  public ConfigurationStoreHandler(String pluginId)
    throws ConfigurationException {
    ConfigurationStoreFactory factory = ConfigurationStoreFactory.getInstance();
    localConfigStore = factory.getStore(pluginId, LOCAL_STORE,
            ConfigurationStore.STORE_TYPE_LOCAL);
    // To obtain a shared configuration store, use ConfigurationStore.STORE_TYPE_SHARED
    localConfigStore.initialize(KEY_NETWORK_HOST, "localhost");
    localConfigStore.initialize(KEY_NETWORK_PORT, 5001);
  }
  /**
   * Sets an integer value in the local store.
   *
   * @param key The key associated with the value.
   * @param value The value to store.
   * @throws ConfigurationException An exception thrown if the operation failed
   */
  public void setLocalInteger(String key, Integer value)
    throws ConfigurationException {
    localConfigStore.setInteger(key, value);
  }
/**
   * Gets an integer value from the local store.
   *
   * @param key The key associated with the value.
   * @return The value associated with the key.
   * @throws InvalidTypeException thrown if type is invalid.
   * @throws NotInitializedException thrown if key value has not been
   * initialized.
   */
  public Integer getLocalInteger(String key)
    throws InvalidTypeException, NotInitializedException {
    return localConfigStore.getInteger(key);
  }
/**
   * Sets a string value in the local store.
   *
   * @param key The key associated with the value.
   * @param value The value to store.
   * @throws ConfigurationException An exception thrown if the operation failed
   */
  public void setLocalString(String key, String value)
    throws ConfigurationException {
    localConfigStore.setString(key, value);
  }
/**
   * Gets a string value from the local store.
   *
   * @param key The key associated with the value.
   * @return The value associated with the key.
   * @throws InvalidTypeException thrown if type is invalid.
   * @throws NotInitializedException thrown if key value has not been
   * initialized.
   */
  public String getLocalString(String key)
    throws InvalidTypeException, NotInitializedException {
    return localConfigStore.getString(key);
  }
}

StorageService

The Storage Service is used for storing data that is not configuration-related, but related to the traffic flow through a Communication Service, in a cluster-wide store.

It provides mechanisms for:

A Communication Service extension uses the StorageService through an API. The API functionality is implemented by a storage provider. Oracle Communications Services Gatekeeper uses a write-through invalidating storage provider. Invalidating stores are backed by a database table. Other storage providers, supporting additional features, can be integrated but are not supported out-of-the box.

Extensions can use the com.bea.wlcp.wlng.api.storage.Store interface. This interface extends a java.util.Map interface and adds the following methods:

The storage service uses configuration files that define the configuration for stores and the relationship between the cluster-wide store and the database table that backs the store. In each configuration file it is possible to define named queries towards the store. There is one configuration file per plug-in. Each configuration store configuration file shall, together its XSD and any complex data types stored, be created and packaged in a JAR file, in the directory $DOMAIN_HOME/config/store_schema. The configuration file must be named wlng-cachestore-config-extensions.xml and it must be present in the root of the JAR.

For details about the store configuration file, see the corresponding xsd: com.bea.wlcp.wlng.storage_4.1.0.0.jar/wlng-cachestore-config.xsd in $OCSG_HOME/modules.

A Store is retrieved from com.bea.wlcp.wlng.api.storage.StoreFactory, either by the name of the store or by the class names of the key/value names. How to retrieve the Store depends on how the store is configured.

The store interface needs to be released when it is no longer needed. The programming model is to retrieve the Store from the StoreFactory when the Store is used, and to release it once it has finished, using try { .. } finally { store.release(); }

Listing 7-5 Example: retrieve a store identified by key/value classes, operate on it, and release it.
Store<String, NotificationData> store = StoreFactory.getInstance().getStore(String.class, NotificationData.class);
try {
   notificationData = store.put(address.toString(), notificationData);
} finally {
   store.release();
}

If it is a named store, it can also be retrieved by name as illustrated below.

Listing 7-6 Retrieving a store by name
Store<Serializable,Serializable> store = StoreFactory.getInstance().getStore("A", this.getClass().getClassLoader());

Store configuration file

The configuration file wlng-cachestore-config-extensions.xml defines attributes of the store and relations between the store, the cache for the store, and the mapping to a database table. This part is used by extension developers.

In addition, the configuration file can contain a section with mapping information between a store, the provider it uses, and the factory for the storage provider. This section should not be used by extension developers.

The XSD for the configuration file is located in com.bea.wlcp.wlng.storage_4.1.0.0.jar/wlng-cachestore-config.xsd in $OCSG_HOME/modules.

There is one configuration file per plug-in. The file must be embedded in a JAR that contains the file itself and any complex data types used. The JAR must be stored in $DOMAIN_HOME/config/store_schema.

Below is an example of a store configuration file for extensions.

Listing 7-7 Example of a store configuration file for extensions
<store-config>
  <db_table name="example_store_notification">
    <key_column name="address" data_type="VARCHAR(255)"/>
    <!-- bucket_column using default BLOB type -->
    <bucket_column name="notification_data_value"/>
    <value_column name="correlator" data_type="VARCHAR(255)">
      <methods>
        <get_method name="getCorrelator"/>
        <set_method name="setCorrelator"/>
      </methods>
    </value_column>
  </db_table>
  <store type_id="wlng.db.wt.example_store_notification"
         db_table_name="example_store_notification">
    <identifier>
      <classes key-class="java.lang.String"
               value-class="com.acompany.plugin.example.netex.notification.NotificationData"/>
    </identifier>
    <index>
      <get_method name="getCorrelator"/>
    </index>
  </store>
  <query name="com.bea.wlcp.wlng.plugin.example.netex.Query">
    <sql>
      <![CDATA[
    SELECT * FROM example_store_notification WHERE correlator = ?
   ]]>
    </sql>
    <filter-class>com.acompany.plugin.example.netex.store.FilterImpl</filter-class>
  </query>
</store-config>

A store is defined between the elements <store-config> and </store-config>

Each Store has three sections:

<store>

The store section defines the store itself. The attribute type_id defines the type of the store and a store type identifier. The ID must be mapped to a provider store mapping defined in wlng-cachestore-config.xml.

The name should always have the prefix wlng.db.wt. when using the storage provider in Oracle Communications Services Gatekeeper. The prefix which indicates that it is a write-through cache, that is, data put in the store is always written to database without any delay.

The attribute db_table_name identifies the database definition to use.

store contains the following elements:

<db_table>

The db_table section defines the database table used to persist data in store. The attribute name defines the table name to use. This name must be the same as the db_table_name specified in the store section. It contains the following elements:

...

Listing 7-9 Example of multi key column configuration
...
<db_table name="combined_key_store">
  <multi_key_column name="sample_key_1" data_type="VARCHAR(30)">
    <methods>
      <get_method name="getSampleKey1"/>
      <set_method name="setSampleKey1"/>
    </methods>
  </multi_key_column>
  <multi_key_column name="sample_key_2" data_type="INT">
    <methods>
      <get_method name="getSampleKey2"/>
      <set_method name="setSampleKey2"/>
    </methods>
  </multi_key_column>
  <value_column name="sample_value" data_type="VARCHAR(30)">
    <methods>
      <get_method name="getSampleValue"/>
      <set_method name="setSampleValue"/>
    </methods>
  </value_column>
</db_table>

...

<query>

In addition to the standard java.util.Map interface, Stores have support for a StoreQuery interface. The behavior of these named queries are configured as part of the Storage Service configuration files.

The query section specifies a named query and a filter associated with the named query. The attribute name defines the name of the query. When using the storage service, the query is fetched using this name. The SQL query towards the database is defined in the element sql. The actual query is defined in the element <![CDATA[.....]]>.

The filter is a class that implements com.bea.wlcp.wlng.api.storage.filter.Filter, and the name of the class is defined in the element filter-class. The filter implements the method setParameters, and a matches(...) method.

The setParameters method maps the parameters to the filter class or a PreparedStatement setObject call ordered as the parameter array given. The filter class must implement the matches method in such a way that it will yield the same result as the SQL query specified.

Listing 7-10 Example of a named query
<query name="com.bea.wlcp.wlng.plugin.example.netex.Query">
    <sql>
      <![CDATA[
    SELECT * FROM example_store_notification WHERE correlator = ?
   ]]>
    </sql>
    <filter-class>com.acompany.plugin.example.netex.store.FilterImpl</filter-class>
  </query>
Listing 7-11 Example of using the named query using a filter
StoreQuery<String, NotificationData> storeQuery = store.getQuery("com.bea.wlcp.wlng.plugin.example.netex.Query");
storeQuery.setParameters(correlator);
set = storeQuery.entrySet();
Listing 7-12 Example of a filter implementation
public class FilterImpl implements Filter {
  /**
   * The query parameters.
   */
  private Serializable[] parameters;
  /**
   * Default constructor.
   */
  public FilterImpl() {
  }
  /**
   * Evaluate if a store entry matches the filter.
   *
   * @param value The store entry value to evaluate.
   */
  public boolean matches(Object value) {
     if (parameters == null || value == null || parameters.length == 0) {
       return false;
    }
    if (value instanceof NotificationData) {
      String compareValue = ((NotificationData) value).getCorrelator();
      if (compareValue != null) {
        return compareValue.equals(parameters[0]);
      }
      return compareValue == parameters[0];
    }
    return false;
  }
  /**
   * Set query parameters. The parameters will be ordered as provided to the
   * StoreQuery and it it the responsibility of the implementation to handle
   * them in this order.
   *
   * @param parameters The query parameters to use.
   */
  public void setParameters(Serializable ... parameters)
    throws StorageException {
    this.parameters = parameters;
  }
}

<provider-mapping>

The provider-mapping section contains definitions of which storage provider a given type-id is mapped to. This section shall not be used unless a custom storage provider is used.

In the type_id attribute for store_mapping type, the same ID shall be used as when the store was defined. A best match (longest matching entry) is performed. A wildcard (*) can be used at the end of type_id to match the prefix.

The <provider-name> entry references the type of store being used, see <providers>.

The type_id for the storage provider mapping in use is wlng.db.wt.*. which references the write-through provider.

There is another set of type_id attributes defined for store_mapping:

These store mapping types are present for internal and future use. All store mapping types (except for the internal wlng.db.log.*) are by default mapped to the keyword invalidating which represents the invalidating storage provider. This should not be changed unless a custom storage provider is used.

<providers>

The providers section contains mappings between the provider-name defined in the provider-mapping section and the factory class for the storage provider. This section should not be changed used unless a custom storage provider is used.

 


Shared libraries

It is possible for multiple plug-ins to share common libraries, for example a third party library or custom code that can be shared.

If there are such parts, these should preferably not be packaged into the plug-in jar but instead be copied into the APP-INF/lib directory of the Communication Service network tier EAR. All classes in this directory are available for all of the plug-ins in the EAR.


  Back to Top       Previous  Next