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

Service Interceptors

The following sections give a high-level overview of service interceptors and describe both the out-of-the-box interceptors that ship with Network Gatekeeper and how to develop your won custom interceptors:

 


Overview

Interceptors are used to:

Some typical use cases for interceptors are to:

A set of standard interceptors are provided out-of-the-box. Some are required, while others provide extra functionality. In addition, custom interceptors can be developed.

 


Interceptor Decisions and Request Flow

An interceptor makes a decision whether to permit, deny or stay neutral to a particular request: see Decisions. The Plug-in Manager is responsible for calling the first interceptor in the chain of interceptors as defined in the interceptor configuration file: see Flow Control. When changing the chain of interceptors, the interceptor module normally needs to be redeployed: see Changing the invocation order.

Decisions

For application-initiated requests, the Plug-in Manager is called automatically by the service 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.

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

Figure 11-1 Interceptors and the request flow

Interceptors and the request flow

The interceptor chain is invoked at the point-cut that is a Java representation of the application-facing interface. Note that 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.

Each interceptor is responsible for deciding whether to continue to proceed down the chain of interceptors or to break it. The interceptor has two ways to break the chain, either to return or to abort.

Figure 11-2 Proceeding or breaking the interceptor chain

Proceeding or breaking the interceptor chain

When the decision is to:

The interceptors have access to context data for the request. The actual data that is available depends on the context of the request. In general, the data available is the data that is defined by the application-facing interface, and includes the following items:

The following data can be set by the interceptor:

Flow Control

The invocation order of interceptors is defined in an XML-based configuration file that contains the interceptors: see Standard Interceptors.

Each interceptor 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.

The configuration file, which is expressed in XML, contains the tags described in Table 11-1.

Table 11-1 Description of interceptor configuration file
Tag
Description
<interceptor-config>
Main tag. Contains zero or more <position> tags.
<position>
Contains one or more <interceptor> tags.
Has an attribute name which is either:
  • MT_NORTH, which indicates that all <interceptor> tags encapsulated by this tag are valid for application-initiated (mobile terminated) requests.
  • MO_NORTH, which indicates that all <interceptor> tags encapsulated by this tag are valid for network-triggered (mobile originated) requests.

An interceptor may be present in both.

<interceptor>
Has the following attributes:
  • class, which identifies the class for the interceptor implementation, see above.
  • index, which indicates the invocation order relative to other interceptors within the same <position> tag. The order is ascending. Must be unique.

Listing 11-1 Example of an interceptor configuration file
<?xml version="1.0" encoding="UTF-8"?>
<interceptor-config xmlns="http://www.bea.com/ns/wlng/30"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.bea.com/ns/wlng/30 config.xsd">
  <position name="MT_NORTH">
    <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceApplicationState" index="100"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceSpAppBudget" index="200"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.ValidateRequestUsingRequestFactory" index="300"/>
    <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.RemoveInvalidAddressPlugin" index="600"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.FilterPluginListUsingCustomMatch" index="700"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.RoundRobinPluginList" index="800"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.EnforceNodeBudget" index="900"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeServiceCorrelation" index="1000"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.FindAndValidateSLAContract" index="1100"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.CreatePolicyData" 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.EvaluateILOGPolicy" index="1600"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.InvokePlugin" index="1700"/>
  </position>
  <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.CreatePolicyData" index="300"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.EvaluateILOGPolicy" index="400"/>
    <interceptor class="com.bea.wlcp.wlng.interceptor.InvokeApplication" index="500"/>
  </position>
</interceptor-config>

Each interceptor is responsible for calling the next interceptor in the chain, as opposed to being invoked by a delegator. This means that:

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 true subscriber telephone number.

For application-initiated requests, the last interceptor in the chain is responsible for calling the plug-in. The out-of-the-box interceptor InvokePlugin does this.

For network-triggered requests, the last interceptor in the chain is responsible for calling the callback service EJB, which calls the application. The out-of-the-box interceptor InvokeApplication does this.

In either scenario, the first interceptor is called by the Plug-in Manager. The Plug-in Manager is, for application-triggered requests, invoked by the service EJB. For network triggered requests, the Plug-in Manager is invoked by an aspect applied to the north interface of the plug-in.

Changing the invocation order

As described in Flow Control, the invocation order of the interceptors is defined in the interceptor configuration file, see Table 11-3.

To rearrange the invocation chain, explode the ear file, edit the config.xml file and change the attribute index in the tag <interceptor>. Repackage the ear file and deploy it.

To exclude an interceptor chain, explode the ear file and delete or comment out the <interceptor> tag for it. Repackage the ear file and deploy it.

Always use the interceptors.ear deployed on the Administration server as the master and use standard WebLogic procedures to redeploy the application interceptor.ear to all servers in the network tier cluster from the Administration server.

 


Standard Interceptors

Below is a description of the interceptors that are available out of the box as a part of Network Gatekeeper. The name of the interceptor in the configuration file is the fully qualified class name. That is, it is prefixed with com.bea.wlcp.wlng.interceptor.

Table 11-2 Out-of-the-box interceptors
Interceptor
Description
EnforceApplicationState
 
Enforces the application state. Verifies that the application with which the request is related has established a session with Network Gatekeeper.
EnforceSpAppBudget
 
Enforces the budget defined in the service provider group SLA and application group SLA. Is related to the SLA tag <rate> in <methodRestrictions>: see Defining Service Provider Level and Application Level Service Agreements.
ValidateRequestUsingRequestFactory
 
Validates the request using the RequestFactory corresponding to the type of plug-in the request is intended for. See description of the class RequestFactory.
CreatePluginList
 
 
Creates a list of plug-ins that are capable of handling the given request.
RemoveInactivePlugin
 
Removes any plug-in that is not active from the current plug-in list.
CreatePluginList must have been invoked prior to this.
RemoveInvalidAddressPlugin
 
Matches configured plug-in routes with plug-ins.
Removes any plug-in which does not support the address provided in the request from the current plug-in list.
CreatePluginList must have been invoked prior to this.
FilterPluginListUsingCustomMatch
 
Invokes the custom match method of each plug-in 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.
CreatePluginList must have been invoked prior to this.
RoundRobinPluginList
 
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.
CreatePluginList must have been invoked prior to this.
EnforceNodeBugdet
 
Enforces all settings in the service provider node SLA and global node SLA, including validity of the dates and the budgets. See Writing Node SLAs.
EnforceSpAppBudget must have been invoked prior to this.
InvokeServiceCorrelation
 
Invokes the service correlation feature, see Service Correlation.
FindAndValidateSLAContract
 
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 Defining Service Provider Level and Application Level Service Agreements.
CreatePolicyRequestData
 
Creates the policy request data object needed by other interceptors.
CheckMethodParametersFromSLA
 
Checks and enforces that the request parameters are allowed as specified in the service provider group and application group SLAs.
Is related to the SLA tags <parameterName> and <parameterValue> in <methodParameters>, see Defining Service Provider Level and Application Level Service Agreements.
FindAndValidateSLAContract and CreatePolicyRequest must have been invoked prior to this.
EnforceBlacklistedMethodFromSLA
 
Enforces the method blacklist as specified in the service provider group and application group SLAs.
Is related to the SLA tag <blacklistedMethod> in <methodAccess>. See Defining Service Provider Level and Application Level Service Agreements.
FindAndValidateSLAContract must have been invoked prior to this.
InjectValuesInRequestContextFromSLA
 
Adds any optional request context attribute as specified in the service provider group and application group SLAs.
Is related to the SLA tags <attributeName>, <attributeValue>, and <contextAttribute> in <requestContext>. See Defining Service Provider Level and Application Level Service Agreements.
FindAndValidateSLAContract must have been invoked prior to this.
EvaluateILOGPolicy
 
Evaluates any custom ILOG policy rules.
CreatePolicyRequestData must have been invoked prior to this.
InvokePlugin
 
Invokes the plug-in(s). This should be the last interceptor for an application-initiated (mobile terminated) request.
CreatePluginList must have been invoked prior to this.
InvokeApplication
 
Invokes the Application via the service callback EJB. This should be the last interceptor for an network-triggered (mobile originated) request.
RetryPlugin
 
Performs retries of request. See Retry functionality for plug-ins.
CreatePluginList must have been invoked prior to this.
ResultFilter
 
Applies result filters as specified in the service provider group and application group SLAs.
Relates to the SLA tag <resultRestriction>. See Defining Service Provider Level and Application Level Service Agreements.
InjectValuesInRequestContextFromSLA must have been invoked prior to this.

Note: Some interceptors must be invoked before others can be invoked. A quick overview of the necessary sequences is seen in Figure 11-3
Figure 11-3 Required Interceptor Sequences

Required Interceptor Sequences

All out-of-the-box interceptors are classes packaged in $DOMAIN_HOME/interceptors.ear.

Below is a description of the contents of this ear:

Table 11-3 Contents of interceptor.ear
Path
Content
/
 
dummy.war
Empty war file. Present in order to deploy the interceptors. Do not remove or change.
/APP-INF/classes/
 
config.xml
Interceptor configuration file. See Flow Control.
 
config.xsd
Schema for config.xml
/APP-INF/classes/com/bea/wlcp/wlng/interceptor/
 
Classes for the out-of-the-box interceptors, see Table 11-2.
Do not change the content of this directory.
/APP-INF/classes/com/bea/wlcp/wlng/interceptor/deploy/
 
Infrastructure for the interceptor functionality. Do not change the content of this directory.
META-INF/
 
MANIFEST.MF
Manifest file for the interceptor infrastructure.
 
application.xml
Deployment descriptor. Do not edit or remove.
 
weblogic-application.xml
WebLogic extensions to application.xml. Do not edit or remove.
WEB-INF/
 
No content.

Retry functionality for plug-ins

The RetryPlugin interceptor handles retry functionality for plug-ins. The retry is attempted among the plug-ins that were chosen based on the data provided in the request. Retries are only performed among the plug-ins in the same Network Gatekeeper instance.

The RetryPlugin is triggered when a plug-in throws a RetryPluginExeption. This exception is captured by the RetryPlugin interceptor, which 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.

If the RequestInfo objects in the RequestContext are associated with:
The RetryPlugin interceptor:
PluginHolder objects that are marked as optional
removes the failed RequestInfo from the RequestContext and the next interceptor in the chain is invoked.
PluginHolder objects that are marked as required
treats the request itself as failed. No retry is performed, and an exception is thrown.
some PluginHolder objects that are marked as optional, and some that are marked as required
removes the RequestInfo objects that are associated with the PluginHolder objects that are marked as optional from the RequestContext and the next interceptor in the chain is invoked.

The following out-of-the-box plug-in 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.

 


Custom Interceptors

Developing Custom Interceptors

An interceptor implements the interface com.bea.wlcp.wlng.api.interceptor.Interceptor.

This interface defines the method:

Object invoke(com.bea.wlcp.wlng.api.interceptor.Context context) throws Exception;

The interceptor is responsible for invoking the next interceptor in the invocation chain using the method:

Object com.bea.wlcp.wlng.api.interceptor.Context.invokeNext(Interceptor current) throws Exception;

Since the interceptors call each other, the normal case would be just to return the object that was returned by the called interceptor. But in some cases, the returned object may be changed in order to do, for example, aliasing.

The decisions within the interceptor are expressed in these ways:

See Interceptor Decisions and Request Flow.

Note: The interceptor must be thread safe.

Listing 11-2 illustrates a very basic interceptor.

Listing 11-2 Example 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;
    }
  }
}

All necessary classes are available in the package:

com.bea.wlcp.wlng.api.interceptor located in $BEA_HOME/wlng_pds400/lib/api/wlng.jar

As an alternative to embedding the interceptor in interceptors.ear and defining the invocation order in /APP-INF/classes/config.xml it is possible to put the new interceptor in a separate ear file. Using this alternative, the interceptor must register the interceptor using the InterceptorManager, which is retrieved using the InterceptorManagerFactory.

When registering the interceptor manually, data corresponding to the data set in /APP-INF/classes/config.xml in interceptors.ear is supplied as parameters to the method:

void register(Interceptor interceptor, InterceptionPoint ip, int index);

in the InterceptorManager interface.

The attribute name in the tag <position> corresponds to the argument ip, the attribute index in the tag <interceptor> corresponds to the argument index.

Listing 11-3 shows an example of how to register an interceptor manually.

Listing 11-3 Manually registering an interceptor
InterceptorManager im = InterceptorManagerFactory.getInstance(); // Get manager
im.register(myInterceptor, InterceptorManager.MT_NORTH, myIndex); // Register
im.update(); // Changes do not take effect until update() is called

Deploying Custom Interceptors

To deploy the interceptor in the common interceptor ear file, explode the interceptors.ear file and put the class files for the interceptor in /APP-INF/classes. Add a new <interceptor> tag 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.

For example:

If the interceptor main class is com.acompany.interceptor.DoStuff, the class DoStuff should be inserted into interceptors.ear in /APP-INF/classes/com/acompany/interceptor, and the corresponding entry in /APP-INF/classes/config.xml shall be

<interceptor class="com.acompany.interceptor.DoStuff" index="1150"/>

See Flow Control for more information about /APP-INF/classes/config.xml. See Standard Interceptors to get information about where in the invocation chain to insert the new interceptor.

If deploying the interceptor in a separate ear, always deploy it using the Administration server and use standard WebLogic procedures to deploy the application to all servers in the cluster from the Administration server.


  Back to Top       Previous  Next