Chapter 12. Customizing OpenIG

Table of Contents
12.1. Key Extension Points
12.2. Implementing a Filter
12.3. Implementing a Handler
12.4. Heap Object Configuration
12.5. Including Servlets and Servlet Filters
12.6. Sample Filter

OpenIG includes a complete, stable application programming interface, designed to allow you to customize OpenIG as required. Customizing OpenIG can be necessary if you need to perform complex server interactions or intensive data transformations, and stock handlers, filters and expressions provided by the gateway are too basic to meet the task.

12.1. Key Extension Points

The two primary extension points are the interfaces: Filter (for processing a request and/or response en route) and Handler (for generating responses from requests). These interfaces are similar to the Java Enterprise Edition Filter and Servlet interfaces, with some differences in the semantics of messages. While you can simply implement these interfaces, there are also included convenience classes: GenericFilter and GenericHandler that you can use if you intend to make your extensions configurable through the OpenIG configuration resource.

OpenIG also allows standard Java Enterprise Edition servlets and servlet filters to be embedded in the gateway, with initialization parameters supplied through through the OpenIG configuration resource.

12.2. Implementing a Filter

The Filter interface exposes a filter method, which takes an Exchange object and the Chain of remaining filters and handler to dispatch to. Initially, exchange.request contains the request to be filtered. To pass the request to the next filter or handler in the chain, the filter calls chain.handle(exchange). After this call, exchange.response contains the response that can be filtered.

A filter might elect not to pass the request to the next filter or handler, and instead handle the request itself. It can achieve this by merely avoiding a call to chain.handle(exchange) and creating its own response object in the exchange. The filter is also at liberty to replace a response with another of its own. A filter can exist in more than one chain, therefore should make no assumptions or correlations using the chain it is supplied. The only valid use of a chain by a filter is to call its handle method to dispatch the exchange to the rest of the chain.

Note

If an existing response exists in the exchange object and the filter intends to replace it with its own, it must first check to see if the existing response has an entity, and if it does, must call its close method in order to signal that the processing of the response from a remote server is complete.

12.3. Implementing a Handler

The Handler interface exposes a handle method, which takes an Exchange object. It processes the request in exchange.request and produces a response in exchange.response. A handler can elect to dispatch the exchange to another handler or chain.

Note

If an existing response exists in the exchange object and the filter intends to replace it with its own, it must first check to see if the existing response has an entity, and if it does, must call its close method in order to signal that the processing of the response from a remote server is complete.

12.4. Heap Object Configuration

Objects are added to the heap and supplied with configuration artifacts at initialization time. To be integrated with the configuration, a class must have an accompanying implementation of the Heaplet interface. The easiest and most common way of exposing the heaplet is to extend the NestedHeaplet class in a nested class in the class you want to create and initialize and implementing its create method.

Within the create method, you can access the object's configuration through the config field.

12.5. Including Servlets and Servlet Filters

A servlet or servlet filter can be added as a heap object by including it in the classpath, and identifying it in the OpenIG heap configuration as an javax.servlet.http.HttpServlet or javax.servlet.Filter type, providing any appropriate initialization parameters. A servlet can be dispatched directly by the gateway servlet, and servlets and filters can be flexibly dispatched to through a DispatchServlet.

12.6. Sample Filter

The following sample filter sets an arbitrary header in the incoming request and outgoing response.

package com.example.filter;

// Java Standard Edition
import java.io.IOException;

// OpenIG Core Library
import org.forgerock.openig.filter.Chain;
import org.forgerock.openig.filter.GenericFilter;
import org.forgerock.openig.handler.HandlerException;
import org.forgerock.openig.heap.HeapException;
import org.forgerock.openig.heap.NestedHeaplet;
import org.forgerock.openig.http.Exchange;
import org.forgerock.openig.model.ModelException;

public class HelloWorldFilter extends GenericFilter {

    public String name;
    public String value;

    @Override
    public void filter(Exchange exchange, Chain chain)
            throws HandlerException, IOException {
        exchange.request.headers.put(name, value); // set header in request
        chain.handle(exchange); // pass to remaining filters & handler in chain
        exchange.response.headers.put(name, value); // set header in response
    }

    public static class Heaplet extends NestedHeaplet {

        @Override
        public Object create() throws HeapException, ModelException {
            HelloWorldFilter filter = new HelloWorldFilter();
            filter.name = config.get("name").required().asString(); // required
            filter.value = config.get("value").required().asString(); // req'd
            return filter;
        }
    }
}

The corresponding heap object configuration is as follows.

{
     "name": "HelloWorldFilter",
     "type": "com.example.filter.HelloWorldFilter",
     "config": {
         "name": "X-Hello",
         "value": "World" 
     }
}