Skip Headers
Oracle® Communications Services Gatekeeper Platform Development Studio Developer's Guide
Release 5.0

Part Number E16619-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

8 Service Interceptors

This chapter provides a high-level overview of service interceptors (interceptors) and describes both the standard interceptors that ship with Oracle Communications Services Gatekeeper and the process of developing your own custom interceptors and deploying them in Services Gatekeeper.

About Service Interceptors in Services Gatekeeper

Service interceptors provide a mechanism to intercept and manipulate a request flowing through any arbitrary communication service in Services Gatekeeper. (See Chapter 2 for a description of communication services.) Additionally, service interceptors supply an easy way to modify the flow for a request and simplify the routing mechanism for plug-ins associated with a request.

Often, interceptors may make a decision to permit, deny, or stay neutral to a particular request. Some typical use cases for service interceptors are to:

Service Interceptors in Services Gatekeeper

Each interceptor in Services Gatekeeper is identified by the class name of the entry point of the interceptor, that is, the class that implements the Service Provider Interface (SPI) Interceptor.

For example, the EnforceBlacklistedMethodFromSLA interceptor is identified by com.bea.wlcp.wlng.interceptor.EnforceBlacklistedMethodFromSLA. (See the entry for EnforceBlacklistedMethodFromSLA in Example 8-1.)

A set of standard interceptors are provided with Services Gatekeeper. Some interceptors are required, while others provide extra functionality. In addition, Services Gatekeeper enables you to develop and deploy custom interceptors. The invocation order of the interceptors currently active in Services Gatekeeper is defined in an XML-based configuration file, described later in this chapter.

Request Flow

Figure 8-1 illustrates where interceptors are triggered, both for application-initiated and network-triggered requests.

Figure 8-1 Interceptors and Request Flow

Surrounding text describes Figure 8-1 .

Plug-in Manager

As Figure 8-1 shows, the Plug-in Manager is responsible for calling the first interceptor in the chain of interceptors as defined in the interceptor configuration file, described later in this chapter.

For application-initiated requests, the Plug-in Manager is called automatically by the service Enterprise Java Beans (EJB) for the application-facing interface. For network-triggered requests, the Plug-in Manager is called by an Aspect that is woven prior to calling the service callback EJB for the application-facing interface. For more information on Aspect, see "About Aspects and Annotations".

The interceptor chain is invoked at the point-cut that is a Java representation of the application-facing interface. Some application-initiated requests are not necessarily propagated to the network, and some network-triggered requests are not necessarily forwarded to the service callback client.

Request Context Data Used to Handle Request Flow

Interceptors in Services Gatekeeper have access to context data associated with each request and use that data to arrive at the appropriate decisions to forward, return or abort the request.

The actual data that is available to an interceptor depends on the context of the request. In general, the application-facing interface defines the data that is available. This data includes the following:

  • The RequestContext for the request, including:

    • Service provider account ID

    • Application account ID

    • Application User ID

    • Transaction ID

    • Session ID

    • A Java Map containing arbitrary request-specific data

    For information on RequestContext, see "Interface: RequestContext".

  • The type of plug-in targeted by the request for (application-initiated requests)

  • The type of object targeted by the request (network-triggered requests)

  • The method targeted by the request

  • The arguments that will be used in the method targeted by the request

  • The set of RequestInfo available to the request, including:

    • method name

    • arguments to the method

    • plug-in type

    For information on RequestInfo, see "Class: RequestInfo".

  • A list of plug-ins that matches the specified RequestInfo

  • The interception point that indicates whether the request is network-triggered or application-initiated.

Example 8-6 shows the method used to retrieve data located in RequestContext.

Data Available for Modification

Custom interceptors that you develop can be designed to access and modify certain elements of the data in RequestContext.

Interceptors can set the following data in a request:

  • In the RequestContext:

    • Session ID

    • Transaction ID

    • Java Map

  • A list of plug-ins that matches the specified RequestInfo. For information on RequestInfo, see "Class: RequestInfo".

  • Arguments to the method targeted by the request

Decisions Taken by Service Interceptors

Each interceptor is responsible for deciding whether to proceed with the request flow (by forwarding the request down the chain of interceptors) or to break the flow. The interceptor may break the request flow in one of two ways, either by returning the request or by aborting it.

Figure 8-2 Decisions and the Interceptor Chain

This graphic is described in the surrounding text.

Decision to Proceed with the Request Flow

The decision to proceed with the request flow translates to continuing down the invocation chain by calling the next interceptor in the chain.

The request is passed on to the next interceptor in the chain and ultimately to the network protocol plug-in or to the application. When the request is returned from either one of these points in the flow, the return path traverses the interceptors that were used in the calling path. Doing so makes it possible for interceptors to manipulate the request on its return path and ultimately return it to the originator of the request, the application or the network node.

Decision to Return the Request

The decision to return a request may be arrived at because the needs of the request may have been fulfilled and, therefore, there maybe no need to call the plug-in or the application. The remaining and final step is simply to return the request.

In such a scenario, the request is rolled back through the previous interceptors using a regular return statement. Doing so makes it possible for the previous interceptors to manipulate the request in the rollback path which ends with the originator of the request, the application or the network node.

Decision to Abort the Request

The decision to abort a request is arrived at when there is a violation. For example, a parameter in the request is out of bounds, or certain usage policies have been violated by this request. Such events lead to a PluginDenyException being thrown.

When the decision is made to abort a request, the interceptor breaks the chain for that request. The request is rolled back through each interceptor's exception catch-block rather than being returned in a regular mode.

  • For application-initiated requests, the exception is reported back to the application. It is possible to reuse the exception catalogue to map the exception thrown by the interceptor to an exception defined by the application-facing interface. For such a scenario, interceptors should use com.bea.wlcp.wlng.api.plugin.DenyPluginException.

  • For network-triggered requests, it is the responsibility of the plug-in to act on the thrown exception.

Invoking Next Service Interceptor to Handle the Request

Each interceptor is responsible for calling the next interceptor in the chain. This means that:

  • For an application-initiated request, the interceptors can change and add request-specific data. This data is then propagated to the next interceptor and ultimately to the network protocol plug-in. When the request returns from the plug-in, the data can be changed as the request returns through the invocation chain.

  • For network-triggered request, the interceptors can change and add request-specific data. This data is then propagated to the next interceptor and ultimately to the application. When the request returns from the application, the data can be changed as the request returns through the invocation chain.

This is useful for aliasing of data, where the interceptor anonymizes request data such as telephone numbers so that an application is not aware of the actual telephone number of the subscriber.

Last Service Interceptor in the Chain

For application-initiated requests, the last interceptor in the chain is responsible for calling the plug-in. The standard interceptor InvokePlugin performs this function. In Example 8-1, the example interceptor configuration file lists InvokePlugIn as the last entry for the tag called <position name="MT_NORTH">.

For network-triggered requests, the last interceptor in the chain is responsible for calling the callback service EJB, which calls the application. The standard interceptor InvokeApplication does this. In Example 8-2, the example interceptor configuration file lists InvokeApplication as the last entry for the tag called <position name="MO_NORTH">.

Standard Interceptors

Standard interceptors are service interceptors that are provided by Services gatekeeper. The

The standard interceptors in Services Gatekeeper can be:

Standard Interceptors in Services Gatekeeper

Table 8-1 provides a description of the standard interceptors that are available in Services Gatekeeper and lists any dependencies enforced by Services Gatekeeper.

Table 8-1 Standard Interceptors Provided by Services Gatekeeper

Interceptor Description Dependency Enforced

CheckMethodParametersFromSLA

Enabled at installation time.

Checks and enforces the specifications in the service provider group and application group SLAs with respect to the request parameters.

Is related to the SLA <parameterName> and <parameterValue> elements in <methodParameters>.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

CheckMethodParametersFromSLA must be invoked AFTER invoking:

  • FindAndValidateSLAContract

CreatePluginList

Enabled at installation time.

Creates a list of plug-ins that are capable of handling the given request.

Populates the RequestInfo object.

See "Class: RequestInfo".

CreatePluginList must be invoked BEFORE you invoke:

  • EnforceNodeBudget

  • EnforceSubscriberBudget

  • FilterPluginListUsingCustomMatch

  • RemoveInactivePlugin

  • RemoveInvalidRoute

  • RemoveOptional

  • RetryPlugin

  • RoundRobinPluginList

CreatePolicyData

Enabled at installation time.

Creates the policy request data object needed by other interceptors.

CreatePolicyData must be invoked BEFORE you invoke:

  • CheckMethodParametersFromSLA

  • RemoveInvalidRoute

EnforceApplicationState

Enabled at installation time.

Enforces the application state. Verifies that the application with which the request is related has established a session with Services Gatekeeper.

None

EnforceBlacklistedMethodFromSLA

Enabled at installation time.

Enforces the method blacklist as specified in the service provider group and application group SLAs.

Is related to the SLA <blacklistedMethod> element in the <methodAccess> element.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

EnforceBlacklistedMethodFromSLA must be invoked AFTER you invoke FindAndValidateSLAContract.

EnforceComposedBudget$1

Internal. Do not use.

Not Applicable

EnforceComposedBudget$GetAppSLA

Internal. Do not use.

Not Applicable

EnforceComposedBudget$GetGeoAppSLA

Internal. Do not use.

Not Applicable

EnforceComposedBudget$GetGeoSpSLA

Internal. Do not use.

Not Applicable

EnforceComposedBudget$GetSLA

Internal. Do not use.

Not Applicable

EnforceComposedBudget$GetSpSLA

Internal. Do not use.

Not Applicable

EnforceComposedBudget

Enabled at installation time.

Enforces all settings on composed service contract in both southbound and northbound traffic.

A Composed Service contract supports services implemented through the composition of OCSG communication services (for example, SMS+Terminal Location+....).

Foe more on Composed Services, see Accounts and SLA Guide.

None

EnforceNodeBudget

Enabled at installation time.

Enforces budgets related to the global and service provider node SLAs.

EnforceNodeBudget must be invoked AFTER you invoke CreatePluginList.

EnforceSpAppBudget

Enabled at installation time.

Enforces the budget defined in the service provider group SLA and application group SLA. Is related to the SLA <rate> element in <methodRestrictions>.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

EnforceSpAppBudget must be invoked BEFORE you invoke EnforceNodeBugdet.

EnforceSubscriberBudget

Enabled at installation time.

Enforces budgets related to the Subscriber SLAs.

EnforceSubscriberBudget must be invoked AFTER you invoke CreatePluginList.

FilterPluginListUsingCustomMatch

Enabled at installation time.

Invokes the custom match method of each plug-in the current plug-in list. The custom match method either removes the plug-in from the current plug-in list or marks it as required.

FilterPluginListUsingCustomMatch must be invoked AFTER you invoke CreatePluginList.

FindAndValidateSLAContract

Enabled at installation time.

Enforces the existence of application level and service provider level SLAs for the given request. It also verifies that the dates given in the SLA are current.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

FindAndValidateSLAContract must be invoked BEFORE you invoke InjectValuesInRequestContextFromSLA.

InjectValuesInRequestContextFromSLA

Enabled at installation time.

Adds any optional request context attribute as specified in the service provider group and application group SLAs.

Is related to the SLA <attributeName>, <attributeValue>, and <contextAttribute> elements in <requestContext>.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

InjectValuesInRequestContextFromSLA must be invoked BEFORE you invoke:

  • FindAndValidateSLAContract

  • ResultFilter

InjectXParametersFromRequestContext

Enabled at installation time.

Takes tunnelled parameters from the RequestContext and puts them in the the SOAP header of either a request to an application or a response to a request from an application.

None

InvokeApplication

Enabled at installation time.

Invokes the Application via the service callback EJB. This should be the last interceptor for an network-triggered (mobile originated) request.

None

InvokeNetworkNode

Enabled at installation time.

Invokes the Network Node via the service callback EJB. This is the only interceptor for an network-triggered (mobile terminated) request.

None

InvokePlugin

Enabled at installation time.

Invokes the plug-in(s). This should be the last interceptor for an application-initiated (mobile terminated) request.

InvokePlugin must be invoked AFTER you invoke CreatePluginList.

InvokeServiceCorrelation

Enabled at installation time.

Invokes the service correlation feature.

See "Service Correlation".

None

NativeSMPPAddressRouting

Not enabled, by default

If enabled, ensures that, for networks having multiple SMSCs, SMS messages sent to the same address will be sent through the same plug-in instance.

If NativeSMPPAddressRouting is enabled, it must be invoked BEFORE you invoke RoundRobinPluginList

NativeUCPAddressRouting

Not enabled, by default

If enabled, ensures that messages sent to the same address are sent to the same SMSC.

If NativeUCPAddressRouting is enabled, it must be invoked BEFORE you invoke RoundRobinPluginList

RemoveInactivePlugin

Enabled at installation time.

Removes any plug-in that is not active from the current plug-in list.

RemoveInactivePlugin must be invoked AFTER you invoke CreatePluginList.

RemoveInvalidRoute

Enabled at installation time.

Enforces the plug-in routing logic.

RemoveInvalidRoute must be invoked AFTER you invoke:

  • CreatePluginList

  • CreatePolicyData

RemoveOptional

Enabled at installation time.

Removes any plug-in that is marked as optional if there is a at least one marked as required in the current plug-in list.

RemoveOptional must be invoked AFTER you invoke CreatePluginList.

ResultFilter

Enabled at installation time.

Applies result filters as specified in the service provider group and application group SLAs.

Relates to the SLA <resultRestriction> element.

See the discussion on service provider groups and service level agreements in Accounts and SLA Guide.

ResultFilter must be invoked AFTER you invoke InjectValuesInRequestContextFromSLA.

RetryPlugin

Enabled at installation time.

Performs retries of request. See "Retry Functionality for plug-ins".

RetryPlugin must be invoked AFTER you invoke CreatePluginList.

RoundRobinPluginList

Enabled at installation time.

Performs a round-robin of the list of available plug-ins. This is not a strict round-robin, but a function of the number of plug-ins that match the request and the number of destination or target addresses in the request. If these parameters are consistent, a true round-robin is performed.

RoundRobinPluginList must be invoked AFTER you invoke CreatePluginList.

ValidateRequestUsingRequestFactory

Enabled at installation time.

Validates the request using the RequestFactory corresponding to the type of plug-in the request is intended for. For a description of RequestFactory, see "Class: RequestFactory".

None


Location

All the standard interceptors can be found packaged in Middleware_Home/ocsg_5.0/applications/interceptors.ear. (See Table 8-3.)

Retry Functionality for plug-ins

When a RetryPluginExeption exception is thrown during the handling of a request, a retry is attempted among the plug-ins that were chosen based on the data provided in the request. Retries are performed among the plug-ins in the same Services Gatekeeper instance only.

When a plug-in throws a RetryPluginExeption, the RetryPlugin interceptor is triggered. The RetryPlugin interceptor captures the RetryPluginExeption, removes the plug-in that threw the exception from the list of chosen plug-ins, and calls the next interceptor in the chain.

The different decision scenarios are described below in Table 8-2.

Table 8-2 Retry Plugin Interceptor Scenarios

Objects with which the RequestInfo objects in the RequestContext are associated Action(s) Taken by RetryPlugin interceptor

PluginHolder objects that are marked as optional

Remove the failed RequestInfo from RequestContext and invoke the next interceptor in the chain.

PluginHolder objects that are marked as required

Treat the request itself as failed. No retry is performed, and an exception is thrown.


Note that the Subscriber Profile/LDAPv3 is the only (standard) plug-in that throws the RetryPluginException.

Custom plug-ins can use the infrastructure for retries as provided by the RetryPlugin interceptor. This exception should be thrown if the communication with the underlying network node fails, or if an unexpected error is reported back from the plug-in.

Interceptor.ear File

The interceptors.ear file is located at Middleware_Home/ocsg_5.0/applications.

File Contents

Table 8-3 describes the contents of the top-level of the multi-level folder in the interceptors.ear file.

Table 8-3 Contents of interceptor.ear File

Folder Name/File Name Content

APP-INF

A multi-level folder which contains information about the applications.

  • classes: A multi-level folder where the sub-folder /APP-INF/classes/com/bea/wlcp/wlng/interceptor contains the standard interceptor classes.

  • config.xml: Interceptor configuration file. See "Config.xml File".

  • config.xsd: Schema for config.xml.

dummy.war

Empty WAR file. Present in order to deploy the interceptors.

Do not remove or change this file.

META-INF

This folder contains the following files:

  • application.xml: Deployment descriptor.

  • MANIFEST.MF: Manifest file for the interceptor infrastructure.

  • weblogic-application.xml: WebLogic extensions to application.xml.

Do not edit or remove the contents of META-INF.

WEB-INF

For internal use.

Do not edit or remove its contents.


Maintaining Interceptor Data Integrity

If you deploy a new interceptor, you will need to update the interceptors.ear file to support the functionality for your custom interceptor.

At all times when you do so, be sure to maintain the general structure shown in Table 8-3. The following data must not be changed:

  • Data listed in Table 8-3 as not be changed or removed.

  • /APP-INF/classes/com/bea/wlcp/wlng/interceptor/deploy: (Infrastructure for the interceptor functionality.)

  • /APP-INF/classes/com/bea/wlcp/wlng/interceptor/util

Location for All Standard Interceptor Classes

All standard interceptors provided with Services Gatekeeper (and described in Table 8-1) are located in /APP-INF/classes/com/bea/wlcp/wlng/interceptor/.

Config.xml File

The config.xml located at /interceptors/APP-INF/classes displays the standard interceptors that are currently enabled in Services Gatekeeper.

To access this file, expand the compressed Middleware_Home/ocsg_5.0/applications/interceptors.ear to a folder at a suitable location. It would be good practice to create and store a backup of the original config.xml file to keep the base version that was provided at installation time.

Elements in Config.xml

Table 8-4 describes the structure of config.xml.

Table 8-4 Description of Interceptor Configuration File

Element Description

<interceptor-config>

Main element. Contains zero or more <position> elements.

<position>

The <position> element separates the interceptors according to the following four attributes.

  • MT_NORTH: This position name indicates that all <interceptor> elements encapsulated by this element are valid for application-initiated (mobile terminated) requests.

  • MO_NORTH: This position name indicates that all <interceptor> elements encapsulated by this element are valid for network-triggered (mobile originated) requests.

  • MO_SOUTH: Currently, the interceptors listed for MO_SOUTH attribute are internal to Services Gatekeeper. They should not be altered in anyway.

  • MT_SOUTH: Currently, the interceptors listed for MO_SOUTH attribute are internal to Services Gatekeeper. They should not be altered in anyway.

<interceptor>

Has the following attributes:

  • class: The class attribute identifies the class for the interceptor implementation.

  • index: The index attribute indicates the invocation order relative to other interceptors within the same <position> element. The order is ascending. The index value must be unique within the same <position> element.


Standard Interceptors in the MT_NORTH Section

The standard interceptors found in the MT_NORTH section of the default configuration file are listed here for your convenience. Note that InvokePlugin (with the fully classified name com.bea.wlcp.wlng.interceptor.InvokePlugin) is the last interceptor in this section.

Example 8-1 MT_NORTH Position Interceptors

<position name="MT_NORTH">
  <interceptor class="com.bea.wlcp.wlng.interceptor.ValidateRequestUsingRequestFactory" index="100" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceApplicationState" index="200" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceSpAppBudget" index="300" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceComposedBudget" index="350" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.CreatePluginList" index="400" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RemoveInactivePlugin" index="500" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.CreatePolicyData" index="600" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RemoveInvalidRoute" index="700" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.FilterPluginListUsingCustomMatch" index="800" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RemoveOptional" index="900" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RoundRobinPluginList" index="1000" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeServiceCorrelation" index="1100" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.FindAndValidateSLAContract" index="1200" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.CheckMethodParametersFromSLA" index="1300" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceBlacklistedMethodFromSLA" index="1400" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InjectValuesInRequestContextFromSLA" index="1500" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.ResultFilter" index="1600" /> 
- <!-- <interceptor class="com.bea.wlcp.wlng.interceptor.EvaluateILOGPolicy" index="1700"/>
  --> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InjectXParametersFromRequestContext" index="1800" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RetryPlugin" index="1900" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceNodeBudget" index="2000" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceSubscriberBudget" index="2100" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokePlugin" index="2200" /> 
  </position>

Standard Interceptors in the MO_NORTH Section

The standard interceptors found in the MO_NORTH section of the default configuration file are listed here for your convenience. Note that InvokeApplication with the fully classified name com.bea.wlcp.wlng.interceptor.InvokeApplication is the last interceptor in this section.

Example 8-2 MO_NORTH Position Interceptors

<position name="MO_NORTH">
  <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceApplicationState" index="100" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeServiceCorrelation" index="200" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.FindAndValidateSLAContract" index="300" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.CreatePolicyData" index="400" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.CheckMethodParametersFromSLA" index="500" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InjectValuesInRequestContextFromSLA" index="600" /> 
- <!-- <interceptor class="com.bea.wlcp.wlng.interceptor.EvaluateILOGPolicy" index="700"/>
  --> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InjectXParametersFromRequestContext" index="800" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeApplication" index="900" /> 
  </position>

Standard Interceptors in the MO_SOUTH Section

The standard interceptors found in the MO_SOUTH position of the default configuration file are listed here for your convenience. The last interceptor in this section is InvokeApplication with the fully classified name com.bea.wlcp.wlng.interceptor.InvokeApplication.

Currently, the interceptors listed for MO_SOUTH are internal to Services Gatekeeper. They should not be altered in anyway.

Example 8-3 MO_SOUTH Position Interceptors

<position name="MO_SOUTH">
  <interceptor class="com.bea.wlcp.wlng.interceptor.CreatePluginList" index="100" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RemoveInactivePlugin" index="200" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.FilterPluginListUsingCustomMatch" index="300" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RemoveOptional" index="400" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RoundRobinPluginList" index="500" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.RetryPlugin" index="600" /> 
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokePlugin" index="700" /> 
  </position>

Standard Interceptors in the MT_SOUTH Section

Only one standard interceptor is found in the MT_SOUTH position of the default configuration file and is listed here for your convenience.

Currently, the interceptors listed for MT_SOUTH are internal to Services Gatekeeper. They should not be altered in anyway.

Example 8-4 MT_SOUTH Position Interceptor

<position name="MT_SOUTH">
  <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeNetworkNode" index="100" /> 
  </position>

Custom Interceptors

This section describes how you can develop and deploy custom interceptors to modify the handling of requests using the existing Services Gatekeeper software. The custom interceptors are developed using the Introspection method.

Example

Two examples are provided for your reference. In the first example, the custom interceptor makes some decisions, while the second shows how context data can be extracted from the RequestContext object.

For information on RequestContext, see "Interface: RequestContext".

General Example

This example shows the structure of a simple interceptor designed to make some decisions on a request. The code will require logic to determine the value for decision and for the ReturnValue object.

Example 8-5 General interceptor

import com.bea.wlcp.wlng.api.interceptor.Interceptor;

public class SampleInterceptor implements Interceptor {
  private final int ABORT = 0;
  private final int RETURN = 1;

  public Object invoke(Context ctx) throws Exception {
    int decision = // Logic that evaluates the request and makes a decision.
    if (decision == ABORT) {
      throw new Exception();
    } else if (decision == RETURN) {
      Object returnValue = // Define a returnValue here if desired.
      return returnValue; 
    } else {
      Object returnValue = ctx.invokeNext(this);
      // Define a new returnValue here if desired, for example for aliasing.
        return returnValue;
    }
  }
}

Interceptor that Extracts Context Data from RequestContext

The following example interceptor extracts some of the arguments present in the RequestContext data object. For more on the data in RequestContext that can be modified by a custom interceptor, see "Data Available for Modification".

As the code shows, the interceptor intercepts and retrieves the RequestContext data associated with SendSms requests only.

Example 8-6 Custom Interceptor to Extract Data from RequestContext Object

package com.bea.wlcp.wlng.interceptor;

// Provide all the Required Interfaces/Classes. This example imports:
// Java API for Method; 
// Context, the parameter passed to Invoke;
// the Interface Interceptor;
// the package which contains the required Plugin;
// the package which contains the required RequestContext;

import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import com.bea.wlcp.wlng.api.interceptor.Context;
import com.bea.wlcp.wlng.api.interceptor.Interceptor;
import com.bea.wlcp.wlng.api.plugin.Plugin;
import com.bea.wlcp.wlng.api.plugin.context.RequestContext;


// Example Interceptor implements Interface Interceptor
public class ExtractXParamExample implements Interceptor {

// Create a log object for ExtractXParamExample
       private Logger logger = Logger.getLogger(ExtractXParamExample.class);

// Define the tag and the value that must be extracted.
       public static final String TLV_OPTIONAL_INT_PARAM_TAGS = 
"smpp_optional_int_tlv_param_tags";
       public static final String TLV_OPTIONAL_INT_PARAM_VALUES = 
"smpp_optional_int_tlv_param_values";


// Method Override
       @Override


// Implement the invoke method of interceptor inteface
       public Object invoke(Context ctx) throws Exception {
              Object[] args = ctx.getArguments();

// Retrieve a class object corresponding to the Plugin type
              Class<? extends Plugin> pluginType = ctx.getType();

// Retrieve the name of the  method used
              Method calledMethod = ctx.getMethod();

// Check to see if the method is "SendSms" with the appropriate plugin
// If it is not what we're looking for, do nothing
// If it is Send Sms,
// Call extractTLVXParameters to retrieve contents of RequestContext object 

             if (pluginType.getName().equals(
                      "com.bea.wlcp.wlng.px21.plugin.SendSmsPlugin")&&
                     calledMethod.getName().equals("sendSms")) {
                                extractTLVXParameters(ctx, args[0]);
                   }

// All done. invokeNext must be called here.
    return ctx.invokeNext(this);
       }


       private void extractTLVXParameters(Context ctx, Object arg) {

               RequestContext rctx = ctx.getRequestContext();
             logger.info      ("Extracted XParams for: " + 
             TLV_OPTIONAL_INT_PARAM_TAGS +"::"+
             rctx.getXParam(TLV_OPTIONAL_INT_PARAM_TAGS)+
                              " and: " + TLV_OPTIONAL_INT_PARAM_VALUES+"::"
             +rctx.getXParam(TLV_OPTIONAL_INT_PARAM_VALUES));
       }

}

About Custom Interceptors

Custom interceptors, as their name suggests, are tailored to the individual needs of each application. This section describes the points to keep in mind when you develop custom interceptors.

How to Provide Your Custom Interceptors

When you create a custom interceptor, you will need to package it in an EAR file to enable Services Gatekeeper to use it.

You can set up your custom interceptor in one of two ways:

For each method, the description focuses on the creation of a single custom interceptor. In practice you can create as many interceptors as you require.

Required Packages, Interfaces and Methods

Determine and provide the required and relevant Java (or other) packages for your custom interceptor.

For example, all the classes necessary for SampleInterceptor in Example 8-5 are available in the package:

com.bea.wlcp.wlng.api.interceptor located in Middleware_Home/ocsg_pds_5.0/lib/api/wlng.jar.

All the publicly available classes for Services Gatekeeper can be found in the JavaDoc associated with the current release at Middleware_Home/ocsg_pds_5.0/doc/javadoc/index.html.

Creating a Backup

It would be good practice to create the necessary backups of the current configuration before you embark on any changes to the current setup.

For example, you should create a backup of the current version of the /applications/interceptors.ear file located at Middleware_Home/ocsg_5.0/applications and store it in a desired location.

On Customer Interceptor Implementation

Note the following points about a custom interceptor:

  • Application: The interceptor that you create can be placed in any type of JavaEE or WebLogic application.

  • Interface to implement: Your custom interceptor must implement the interface com.bea.wlcp.wlng.api.interceptor.Interceptor.

  • Override: Your custom interceptor must override the invoke method of that interface. See Example 8-5 and Example 8-6.

  • Actions: The logic in your custom interceptor depends on what it needs to do:

    • Some interceptors contain logic that results in a decision that may affect the request flow. (See Example 8-5). For decisions, see "Decisions Taken by Service Interceptors".

    • Other interceptors serve additional functions. For example, the custom interceptor ExtractXParamExample in Example 8-6 retrieves the context data in the RequestContext object for a specific type of request.

  • Registration: A custom interceptor can be registered or unregistered when the status of that application changes. The information used to register a custom interceptor must be synchronized with the existing data for interceptors in Services Gatekeeper.

  • Index value: The index value used to register the interceptor should be unique with respect to the entries in the config.xml file of /applications/interceptors.ear file and other custom interceptors.

    A collision will occur if more than one interceptor is registered with the same index value, In such a situation, only the last interceptor to register at the index will be executed. The other interceptor(s) with that index value will be overwritten.

  • Positioning with respect to RetryPlugin: Where you position your custom interceptor with respect to RetryPlugin will determine whether your custom interceptor is invoked once or more for a request:

    • Before RetryPlugin: If you add your custom interceptor before the RetryPlugin interceptor, your custom interceptor will be triggered only once for the request.

    • After RetryPlugin: If you add your custom interceptor after RetryPlugin, your custom interceptor will be triggered once for every plug-in that is attempted.

      Note that the Subscriber Profile/LDAPv3 is the only (standard) plug-in which throws the RetryPluginException. If you have a custom plug-in which throws RetryPluginException, place your custom interceptor after RetryPlugin interceptor if your custom interceptor should be invoked for each "tried" plug-in instance.

      For more information, see "Retry Functionality for plug-ins".

  • Request Flow: A custom interceptor is responsible for invoking the next interceptor in the chain by using the invokeNext method. See Example 8-5 and Example 8-6.

  • Thread safety: It must be thread-safe.

  • Debugging: Log statements at the debug level enable you to debug your custom interceptor. These statements will be needed to turn on the logging mechanism when you wish to debug your code.

Testing the Custom Interceptor

The Platform Test Environment (PTE) can be used to test your custom interceptor before you use it in a production environment. For more information, see Platform Test Environment Guide.

Using Common EAR File to Add a Custom Interceptor

This section describes how you can develop custom interceptors for use with the common interceptors.ear file. The interceptors.ear file has been described earlier. See "Interceptor.ear File".

Developing the Custom Interceptor for Deployment

Use the following procedure to develop your custom interceptor:

  1. Expand the /applications/interceptors.ear file and review its contents to determine the location for your new interceptor. If necessary, create a backup file at a desired location.

  2. Create the necessary customer interceptor class, (for example, MyCustomEnforceThis.class). For details, see "On Customer Interceptor Implementation".

  3. Update the config.xml file. Position the interceptor in the appropriate <position> section(s). See "Updating Config.xml File".

  4. Verify the changes to the invocation order in config.xml. See "Verifying the Changes".

  5. Repackage the interceptors.ear file. See "Rebuilding the Interceptors.ear File"

Updating Config.xml File

This section describes how to update the config.xml file to provide the desired invocation order for the interceptors. For a description of this file, see "Config.xml File".

Creating a Backup of the Current Config.xml

To change the order in the interceptor configuration file, always use the current interceptors.ear file deployed on the Administration Server.

As a general rule, before you proceed with any changes to config.xml, be sure to back up that file in a secure location and using a different name, for example, config.xml_backup_as_of_May252011.

Adding the Custom Interceptor to the Current Chain

To add your custom interceptor to the interceptor chain:

  1. Access the config.xml file.

  2. Add the entry/entries for the custom interceptor(s).

    For every new custom interceptor, add a new <interceptor> element with the attribute class referring to the entry point of the interceptor and a numeric value in the attribute index that corresponds to the location in the interceptor invocation chain. Ensure that:

    • The entry for the interceptor is placed in the required <Position name=...> block(s).

    • The <class=...> attribute names the required class.

    • The <index=...> attribute contains a value that is appropriate and unique to the specific section.

    For example, if the interceptor main class is com.acompany.interceptor.DoStuff, and the chosen index value is 1150, the corresponding entry in /APP-INF/classes/config.xml would be

    <interceptor class="com.acompany.interceptor.DoStuff" index="1150"/>
    
  3. Save the config.xml file.

Rearranging the Invocation Order

To rearrange the invocation order for an interceptor chain:

  1. Access the config.xml file.

  2. Edit the config.xml file and change the index attribute for the appropriate <interceptor> element. Ensure that the new value is appropriate and unique within that <position> element.

  3. Save the config.xml.

Excluding an Interceptor from the chain

To exclude an interceptor element from an interceptor chain:

  1. Access the config.xml file.

  2. Edit the config.xml file and comment out the specific <interceptor> element(s).

  3. Save the config.xml.

Verifying the Changes

If you accessed the config.xml file and made any changes to it, ensure that all the remaining entries in config.xml are preserved.

For example, a diff operation between the updated and the backup versions of config.xml can be used to verify the changes made to the entries during the update.

Rebuilding the Interceptors.ear File

To re-build the common interceptors.ear file:

  1. Build the class file for the custom interceptor.

  2. Place the class file for the interceptor in the appropriate location where the other standard interceptors are located.

    • For example, an installation maintains the default settings provided by Services Gatekeeper at installation time. In such a scenario, the main class for the interceptor would be com.bea.wlcp.wlng.interceptor. All the standard interceptors would be located in /APP-INF/classes/.

    • If for example, the main class for your custom interceptor is com.mycompany.interceptor.DoStuff, place DoStuff.class in /APP-INF/classes/com/mycompany/interceptor.

  3. Repackage the EAR file, making sure that you maintain the original structure of common interceptors.ear file. See "Maintaining Interceptor Data Integrity".

Re-deploying Common Interceptors. ear File

Use standard WebLogic procedures to redeploy the application interceptor.ear to all servers in the network tier cluster from the Administration server. For more information on re-deploying applications on Oracle WebLogic Server, see the description in Developing Applications with WebLogic Server.

Using a Custom EAR File to Add a Custom Interceptor

This section describes how you can provide a custom EAR file for use with your custom interceptor.

Points to Note

If you use a custom EAR file for your custom interceptor:

  • A custom interceptor meant for use with a custom EAR file should not be included in the config.xml file in the common interceptors.ear file.

  • When providing index values for your custom interceptor, maintain the order for the indexes used in the current config.xml in the common interceptors.ear file.

  • Do not modify config.xml, the standard configuration file in Services Gatekeeper (and located in interceptors.ear). Services Gatekeeper will continue to use the default interceptors in that config.xml file.

  • If, currently, there is no custom EAR file:

  • If a custom EAR file exists, update that EAR file appropriately. This is described under "Updating an Existing Custom EAR to Add Custom Interceptors".

  • The custom interceptors can be placed in a JavaEE or Weblogic application. Ensure that the registration process handles these interceptors appropriately.

Steps to Build a Custom EAR for Use with a Custom Interceptor

To provide a separate EAR file for your custom interceptor:

  1. Create the necessary customer interceptor class, (for example, MyCustomEnforceThis.class). See "On Customer Interceptor Implementation".

  2. Create a listener to register the custom interceptor. (For example, MyCustomListener.class).

  3. Set up the registration process to handle the registration of the MyCustomEnforceThis.class custom interceptor.

  4. Build a Custom EAR file (for example, MyCustomEar.ear) which will be the active EAR in your deployment.

Information Needed to Register Custom Interceptors

The following information is necessary to register your custom interceptor and enable it in Services Gatekeeper:

  • The fully qualified name for your custom interceptor

  • Its position in the request flow associated with the <position> element seen in config.xml, (for example, MT_NORTH and/or MT_SOUTH)

  • The exact point in the invocation order, specified as the value for the index attribute. See Table 8-4.

Place this information (for example, as an XML file) in the custom ear to be parsed and used for the registration.

Synchronizing with Invocation Order in Config.xml

Check to make sure that the index values used to set up the invocation point(s) for your custom interceptors maintain the general order for the indexes currently used in config.xml in the common interceptors.ear file.

Creating a Custom Listener

By default, Services Gatekeeper employs InterceptorListener to automatically register the standard interceptors in the common interceptors.ear file. It does this when the Administration Server starts (or when it restarts after a status change).

If this is the first time a custom EAR will be used for a custom interceptor, you need to create a custom listener for your custom interceptor. The custom listener that you create must do the work done by the standard InterceptorListener for the standard interceptors.

Implementing ApplicationLifecycleListener

In order to create such a custom listener, (for example, MyCustomListener.class), implement weblogic.application.ApplicationLifecycleListener. For more information on ApplicationLifecycleListener, see http://download.oracle.com/docs/cd/E11035_01/wls100/javadocs/weblogic/application/ApplicationLifecycleListener.html

Note that, the ApplicationLifecycleListener interface is only used with reference to the application state and not with reference to the state of the WebLogic server.

Ensure that, MyCustomListener.class is called whenever there is a change in myCustomEar.ear application status. When it is called, MyCustomListener.class must complete the registration process for your custom interceptors.

The Registration Process

You can select to hard-code the information necessary to register your interceptors or use the InterceptorManager interface.

Hard-coding the Information

If you have a limited set of custom interceptors, and their behavior may not often be changed, you can hard-code this information in MyCustomListener.class.

Providing a Data File for Registration

If you plan to use the InterceptorManager interface, create a data file that will contain the information necessary to register the custom interceptor as described in "Information Needed to Register Custom Interceptors"). This data (the position, and index information for each custom interceptor) will be used by MyCustomListener.class in the register method described below.

Registering (and unregistering) Your Custom Interceptors

If you are not hard-coding the registration information, ensure that you have the external data file necessary to parse and register your interceptors.

Use the register or unregister method in the InterceptorManager interface in your custom listener (MyCustomListener) to register/unregister your custom interceptor.

Note that:

  • Retrieve the using the getInstance method in com.bea.wlcp.wlng.api.interceptor.InterceptorManagerFactory. They are:

  • The InterceptorManager interface handles the registration, unregistration and invocation of the interceptors. Use the following methods in this interface:

    • register: The register method should be called in the postStart callback when the application has been started.

    • unregister: The unregister method should be called in the preStop callback when the application is being stopped.

    • update: The update method must be invoked immediately following register or unregister to activate the changes caused by each method.

Note that, unless update is called, the changes will not take effect.

Example

Example 8-7 shows an example of how to register an interceptor manually.

Example 8-7 Registering an interceptor

// Get Interceptor manager
InterceptorManager im = InterceptorManagerFactory.getInstance(); 

// Register the custom MyCustomEnforceThis interceptor
im.register(MyCustomEnforceThis, InterceptionPoint.MT_NORTH.MT_NORTH, myIndex);

// Changes do not take effect until update() is called
im.update();

Building a Custom EAR File

Build your custom EAR file, (for example, myCustomEar.ear), with the necessary elements. The structure of the common interceptors.ear file has been described in "File Contents".

Example 8-8 shows the structure:

Example 8-8 Example Structure for Custom EAR File

/APP-INF
+--/lib/name_your_jar.jar
/META-INF
+--application.xml
+--weblogic-application.xml
+--MANIFEST.MF

Contents of META-INF/weblogic-application.xml

The META-INF/weblogic-application.xml file should contain the fully qualified class name for your implementation of weblogic.application.ApplicationLifecycleListener. Here is an example:

Example 8-9 Custom META-INF/weblogic-application.xml

<?xml version='1.0' encoding='UTF-8'?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <listener>
    <listener-class>weblogic.application.ApplicationLifecycleListener.MyCustomListener</listener-class>
  </listener>
</weblogic-application>

Contents of META-INF/application.xml

The META-INF/application.xml file should specify the contents of the custom EAR. Here is an example:

Example 8-10 Custom META-INF/application.xml

<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
  <display-name>myCustomEAR</display-name>
    <module>
       <java>name_of_my_jar.jar</java>
  </module>
</application>

Deploying Your Custom EAR File

If you deploy custom interceptors in a custom EAR file, always deploy the EAR file using the Administration Server and use standard WebLogic procedures to deploy the application to all servers in the cluster from the Administration Server.

For more information, see Oracle WebLogic Server Documentation at http://www.oracle.com/technetwork/indexes/documentation/index.html

Updating an Existing Custom EAR to Add Custom Interceptors

If a custom EAR file exists in Services Gatekeeper,

  1. Access that custom EAR file and review its contents. Before you update this file, create a backup in a safe location.

  2. Create the necessary customer interceptor class, (for example, MyCustomEnforceThisToo.class). For details, see "On Customer Interceptor Implementation".

  3. Ensure that you have the information necessary to register your custom interceptor and that the index value(s) are synchronized appropriately. For details, see "Information Needed to Register Custom Interceptors".

  4. Check the existing custom listener to see whether the registration information currently in use was hard-coded in the custom listener or provided in a data file. (See the discussion under "Creating a Custom Listener".

  5. Ensure that the new registration information is made available to that custom listener in the same way. (See the discussion under "The Registration Process".

  6. Rebuild the custom EAR file making sure that you preserve its structure. (See the discussion under "Building a Custom EAR File".