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:
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.
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.
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.
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.
com.bea.wlcp.wlng.api.plugin.DenyPluginException
should be used by the interceptors for this scenario.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:
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.
<?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.
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.
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
.
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.
|
|
Validates the request using the RequestFactory corresponding to the type of plug-in the request is intended for. See description of the class
RequestFactory.
|
|
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.
|
|
Invokes the service correlation feature, see
Service Correlation.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
Performs retries of request. See Retry functionality for plug-ins.
|
|
Relates to the SLA tag <resultRestriction>. See
Defining Service Provider Level and Application Level Service Agreements.
|
Note: | Some interceptors must be invoked before others can be invoked. A quick overview of the necessary sequences is seen in Figure 11-3 |
All out-of-the-box interceptors are classes packaged in $DOMAIN_HOME/interceptors.ear
.
Below is a description of the contents of this ear:
Interceptor configuration file. See Flow Control.
|
||
Classes for the out-of-the-box interceptors, see Table 11-2.
|
||
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.
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.
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:
PluginDenyException
.See Interceptor Decisions and Request Flow.
Note: | The interceptor must be thread safe. |
Listing 11-2 illustrates a very basic 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.
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
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.
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.