![]() ![]() ![]() ![]() ![]() ![]() |
This chapter provides a high-level description of Network 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 Network Gatekeeper site at http://www.oracle.com/technology/documentation/index.html.
The Network Gatekeeper container service APIs provide the basic infrastructure by which a Communication Service and the container services of Network 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 of a Communication Service to interact with Network Gatekeeper it must be deployable in the context of Network Gatekeeper. Once it is deployable, it can have access to certain utility functions.
See Service Interceptors.
|
|
See Plug-in.
|
|
See Service Correlation.
|
|
See Storage Services.
|
|
The Instance Factory is the mechanism used in Network 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:
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 6-1 for an example.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. |
theClass.getClass().getName() +”Impl”
if this exists and has a public constructor or static singleton method. 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.
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.
This service is used to broadcast events to other Network Gatekeeper server instances and to register listeners for events originating in other Network Gatekeeper server instances.
Use this interface to broadcast events to other instances of Network 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:
deactivateAllListeners()
- Deactivates all registered listeners.publishEvent
- Publishes an event to all registered listeners.publishEventToOneNode
- Publishes an event to one Network Gatekeeper instance.registerEventListener
- Registers an EventListener
.unregisterEventListener
- Unregisters an EventListener
.
This interface is used to receive events published using EventChannel
.
The following method is available:
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.
Base classes and annotations for giving the Network 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.*
See Annotations, EDRs, Alarms, and CDRs.. Also see the JavaDoc for the packages com.bea.wlcp.wlng.api.edr.*
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.
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:
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
I it is not possible to extend the SLA schema. The SLA schema represents a contract supported by Network Gatekeeper base product and is defined by the XSD. It is version controlled and corresponds to the product release that implements the contracted functionality. Extensions cannot restrict or expand the same XSD/contract for specific solutions. Other contracts or configuration mechanisms must be used for specific extensions. However, it is possible to customize the way requests are enforced and filtered using one or both of the following methods:
It is often the case that service providers would like to be able to bundle what are to Network 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 Network Gatekeeper services need to be grouped into a single service charging unit. To do this, Network 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). Network Gatekeeper does not check whether or not it is unique. The SCID is stored in WLS 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.
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.
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.
This class manages the transport and storage of the Service Correlation ID across multiple service invocations.
There are four basic steps in creating a 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;
}
}
$DOMAIN_Home/lib
.
Parameter tunneling is a feature that allows an application to send additional parameters to Network 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 can not be found, null is returned.
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.
The storage services provided in Network Gatekeeper are of two types, described below:
The Network Gatekeeper Core 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:
ConfigurationStore
are persisted to database.ConfigurationStores
are also cached in memory.ConfigurationStore
is cached in memory per server.ConfigurationStore
is reflected in all cluster nodes.ConfigurationStore
only supports parameters of type Boolean, Integer, Long, String, and Serializable.
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:
ConfigurationStore
, a notification is broadcast to all other instances of the ConfigurationStore
. Listing 6-4 is an example of using the Configuration Store.
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);
}
}
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.
A store is created using the StoreFactory
singleton class, by specifying either a key/value class pair where the value class should be a class that is unique to the Store (recommended), or a Store name.
Since the Store interface extends the java.util.Map
interface, it can be used as any other Map, and it is extended to be a cluster-wide view of the store.
In addition to the standard java.util.Map
interface, Stores have support for a StoreQuery
interface. The behaviors of these named queries are configured as part of the Storage Service configuration files. There is an option to define a cache filter and/or SQL query. If there is an index specified for the Store, this index can be used by implementing the IndexFilter
interface for the cache filter. The index is automatically used for SQL queries that can make use of these indexes.
The Store API has support for registering StoreListeners
. These listeners get notified if the Storage Service decides to automatically remove Store entries (based on configuration parameters). It will not be notified if the extension itself removes entries from the Store.
Cluster wide locking can be done using the Store interface. This should be used if the same entry in a Store may be modified on multiple servers at the same time, to avoid getting errors due to concurrent modification when a transaction commits.
A Communication Service extension uses the StorageService through an API. The API functionality is implemented by a storage provider. Network 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 use configuration files that defines 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.0.0.0.jar/wlng-cachestore-config.xsd
in $BEA_HOME/wlng400/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 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(); }
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.
Store<Serializable,Serializable> store = StoreFactory.getInstance().getStore("A", this.getClass().getClassLoader());
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.0.0.0.jar/wlng-cachestore-config.xsd
in $BEA_HOME/wlng400/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.
<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:
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 Network 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:
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:
...
<db_table name="single_key_store">
<key_column name="sample_key_1" data_type="VARCHAR(30)">
<methods>
<get_method name="getSampleKey1"/>
<set_method name="setSampleKey1"/>
</methods>
</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>
...
<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>
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.
<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>
StoreQuery<String, NotificationData> storeQuery = store.getQuery("com.bea.wlcp.wlng.plugin.example.netex.Query");
storeQuery.setParameters(correlator);
set = storeQuery.entrySet();
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;
}
}
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.
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.
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.
![]() ![]() ![]() |