OpenIG: A quick look at decorators

openig-logo

Guillaume recently added a cool new feature for the upcoming release of OpenIG: decorators. To use decorators before the release, take a nightly build, or build OpenIG yourself.

Decorators are objects that extend what other objects can do. For example, OpenIG now has a CaptureDecorator that lets Filters and Handlers capture requests and responses as they pass through, and a TimerDecorator that logs how long it takes for Filters and Handlers to do their processing.

You configure decorators in the heap alongside your other objects.

For example, to configure a CaptureDecorator itself that also captures the entity when logging a request or response, you add a configuration object that looks like this:

{
    "name": "capture",
    "type": "CaptureDecorator",
    "config": {
        "captureEntity": true
    }
}

To add decorations to other objects, you have two options. You can either set default “decorations” for all applicable objects in the heap, or you decorate individual objects. The scope of the former is everything in the heap to which the decoration applies. The scope of the latter is only the individual object.

You configure a decoration by using its “name” as a top-level property. For example, to add a “capture” decoration to all Filters and Handlers, capturing at all possible capture points, add the “decorations” to the heap like this.

{
    "heap": {
        "objects": [
            {
                "name": "capture",
                "type": "CaptureDecorator",
                "config": {
                    "captureEntity": false
                }
            },
            ... other objects ...,
            {
                "name": "ClientHandler",
                "type": "ClientHandler"
            }
        ],
        "decorations": {
            "capture": "all"
        }
    },
    "handler": "ClientHandler"
}

The configuration shown here results in a lot more capturing than when you use a CaptureFilter. A CaptureFilter captures only the request and response where it is configured in a chain. When you add capture decorations at all capture points to all your Filters and Handlers, then the capture happens for requests and responses as they enter and leave each Filter, and for requests as they enter and responses as they leave Handlers.

Also, notice that “decorations” is a heap property, rather than a global property of the server or the route.

Once you have narrowed down what you want to observe, and find for example that you only want to capture requests as they enter the “ClientHandler” and responses as they leave the “ClientHandler”, comment out “decorations” and decorate only the “ClientHandler”.

{
    "heap": {
        "objects": [
            {
                "name": "capture",
                "type": "CaptureDecorator",
                "config": {
                    "captureEntity": false
                }
            },
            ... other objects ...,
            {
                "name": "ClientHandler",
                "type": "ClientHandler",
                "capture": [ "request", "response" ]
            }
        ],
        "_decorations": {
            "capture": "all"
        }
    },
    "handler": "ClientHandler"
}

Notice what has changed in the configuration. “ClientHandler” now has the “capture” decoration, this time with an array of capture points rather than a single string. The field “_decorations” now employs Guillaume’s famous underscore commenting convention. (When OpenIG does not recognize a JSON field name, it ignores the field. The leading _ is a nice toggle.)

Decorators are likely to take the place of older, more cumbersome ways of configuring some capabilities. The CaptureFilter is deprecated starting in the next release, for example. For more about OpenIG Decorators see the draft OpenIG Reference.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.