Chapter 12. Customizing OpenIG
Prev |  | Next

# Chapter 12. Customizing OpenIG

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

Prev |  | Next
Chapter 11. Configuration Templates | Home | Chapter 13. Troubleshooting