BEA Logo BEA WebLogic Enterprise Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   WLE Doc Home   |   CORBA Programming & Related Topics   |   Previous   |   Next   |   Contents   |   Index

Developing Java Interceptors

Developing a Java request-level interceptor typically involves the following steps:

The preceding steps are usually iterative. For example, the first time you build and test your interceptor, you might have only the most basic code in the interceptor that merely verifies that the interceptor is running. With subsequent builds and tests, you gradually implement the full functionality of the interceptor.

The sections that follow explain each of these steps in detail, using the sample interceptors packaged with the WLE software for examples, and also provides notes about implementing Java interceptors.

Step 1: Identify the Interfaces of Your WLE Applications

Deploying an interceptor on a given machine constitutes a significant overhead because that interceptor will be invoked every time any application on that machine issues (in the case of a client-side interceptor) or receives (target-side interceptor) a request. Therefore, any interceptor you create must be well-matched to those applications.

For example, a security interceptor typically needs to know about what kinds of requests are of concern, and what kinds of data are being handled in the request.

Any interceptor that deals with specific requests needs to be able to extract the interface repository ID from the request. With that interface knowledge, the interceptor then has a way of knowing what kind of data is in the request, and can then handle that data in a request-specific fashion.

In addition, if a request is sent that is not of interest, the interceptor needs to be able to pass the request through quickly and efficiently.

The PersonQuery example described in PersonQuery Sample Application, uses an interceptor that determines whether the user of the PersonQuery client application can receive addresses. If the identity of the user matches specific criteria, the interceptor allows the full address to be returned to the client. If no match exists, the interceptor returns only the string of x characters to the log file in place of the address.

Step 2: Write the Interceptor Implementation Code

For your first pass on implementing an interceptor, keep it simple. For example, you might decide to implement a statement in each of the interceptor's methods that prints a message to a log file. This would simply verify that the interceptor is properly built, registered, and running. Once you know your interceptor is working properly, you can iteratively add code until you have all the functionality you need.

The topics that follow discuss implementation considerations that may be typical of many interceptors. Examples from the InterceptorData interceptors, which are described in InterceptorData Sample Interceptors, are provided.

Starting the Implementation File

You can use the code fragments included in Appendix B as a place to start implementing your interceptor. You may use the code included in Appendix B, or you may copy the intercep.java starter file available at the WLE Developer Center on the BEA Web site. For information about getting this starter file from the WLE Developer Center, see the Release Notes.

Note that in WLE version 5.0, the ORB will always pass nil references for the ServiceContextList and CORBA.DataOutputStream parameters. You should not use or reference those parameters. You should not test those parameters for nil because this restriction may change in a future version.

Implementing the Interceptor's Constructor

All interceptors are instantiated when the ORB is initialized. At no other time are request-level interceptors instantiated. The instances of any interceptor instantiated are then returned from the initialization routine and registered with the ORB run time.

The set of interceptors registered with an ORB is processed during ORB initialization, and an instance of each interceptor is created via Java Reflection APIs. There is no need to implement an initialization routine for Java interceptors as in the C++ ORB implementation.

When a Java interceptor is instantiated, the interceptor expects to find the org.omg.CORBA.ORB parameter, which is the reference to the ORB, in the interceptor's constructor. This constructor can store this ORB reference only at instantiation; and although the ORB has just been initialized, the TP Framework has yet to be initialized. Therefore, any attempt to do ORB-related work, such as an invocation on the ORB, results in undefined behavior.

If the ORB cannot find the expected constructor, the ORB attempts to load the default construction, which contains no arguments.

The following code fragment shows the constructor for the InterceptorData sample interceptor:

public InterceptorData(org.omg.CORBA.ORB orb)
{
theOrb = orb;
}

Obtaining the Interface Name from a Request

If you have an interceptor that works with specific interfaces or requests, the interceptor needs a way to extract the interface ID associated with a request so that the interceptor can identify it and thus know how to handle the data in the request. For example, the InterceptorData interceptor manipulates the data sent in requests from the PersonQuery application. To manipulate that data, the interceptor needs to know which request is being sent.

The following code fragment from the InterceptorData sample shows the interface ID extracted from the RequestContext structure. In this fragment, the interceptor is checking to see if the request is an invocation on the PersonQuery interface.

TP.userlog("Interface Id: " + request_context.interface_id);
if(request_context.interface_id.equals("IDL:beasys.com/PersonQuery:1.0"))
{
TP.userlog("Operation: " + request_context.operation);
}

Identifying Operations in the Request

Using the extracted interface ID, the InterceptorData sample uses a series of if-else statements to identify the operation in the client request. That way, the interceptor will know what to do with the data contained in the request.

The following code fragment checks for the operation to query the database for a person by name. Note the use of the parsePerson method, which extracts the value of a parameter from the DataInputStream object.

if(request_context.operation.equals("findPerson"))
{
TP.userlog("Person = " + parsePerson(request_arg_stream));
}
else if(request_context.operation.equals("findPersonByName"))
{
TP.userlog("Name = " + parseName(request_arg_stream));
}

Implementing the Interceptor's Response Operation

Extracting an interface ID out of a client request is fairly straightforward. However, it's not quite as simple to do that with a target response. If an interceptor needs to know what invocation is associated with the response it receives from the target, it needs to have special logic for doing that.

The InterceptorData interceptor uses a hashtable to track target-bound requests, so that the interceptor can then matches the target responses to them when those responses arrive back at the interceptor.

The following code fragment shows the InterceptorData interceptor putting the request key into the hashtable, instanceOP :

instanceOP.put(id(), request_context.operation);

The target_response operation on the InterceptorData interceptor extracts interface and operation information from the hashtable when responses are returned from the target.

The following InterceptorData code fragment extracts the request associated with a response:

String operation = (String) instanceOP.get(id());

Now that the interceptor has obtained the request associated with the response, the interceptor can handle the data in the response appropriately.

Reading Data Out of a Data Input Stream

The following code fragment shows an example of how the InterceptorData sample places the data from a data stream into a structure:

private addr_ parseAddress(org.omg.CORBA.DataInputStream stream)
{
short number = stream.read_short();
String street = stream.read_string();
String town = stream.read_string();
String state = stream.read_string();
String country = stream.read_string();

addr_ addr = new addr_(number, street, town, state, country);
return addr;
}

Step 3: Build the Interceptor

Interceptors implemented in Java are packaged as JAR files. Therefore, the steps for building interceptors are platform-specific. For details about the specific commands and options used to build interceptors on any particular platform, execute the makefile that builds the interceptor sample applications provided with the WLE software, and view the results of the build in the log file that results from the build.

The command to build the sample interceptors is as follows:

Windows NT:

> nmake -f makefile.nt

UNIX:

> make -f makefile.mk

For more information about building and running the sample interceptors provided with the WLE software, see PersonQuery Sample Application.

Step 4: Test the Interceptor

Testing an interceptor requires you to perform the following tasks:

For information about registering interceptors, see the topic Deploying the Interceptor.

Notes About Implementing Java Interceptors

Note the following about implementing interceptors in the Java programming languages: