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.
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.
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.
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.
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.
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.
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.
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.
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"
}
}