Skip to content

Latest commit

 

History

History
196 lines (156 loc) · 10.2 KB

File metadata and controls

196 lines (156 loc) · 10.2 KB
description
Learn how to build and deploy your own policies

Custom Policies

Overview

Policies are rules or logic that can be executed by the API Gateway. A policy acts as a proxy controller by guaranteeing that a given business rule is fulfilled during the processing of an API transaction.

Policy skeleton generation

{% hint style="warning" %} Ensure OSS repositories are activated in your Maven settings {% endhint %}

To demonstrate how to develop a policy, the following example creates the FooHeaderCheck policy to validate if requests contain the X-Foo header.

{% hint style="info" %} The gravitee-policy-maven-archetype automatically adds "Policy" to the policy name you specify {% endhint %}

The skeleton for this policy can be generated with the following code:

mvn archetype:generate\
    -DarchetypeGroupId=io.gravitee.maven.archetypes\
    -DarchetypeArtifactId=gravitee-policy-maven-archetype\
    -DarchetypeVersion=1.10.1\
    -DartifactId=foo-header-check-policy\
    -DgroupId=my.gravitee.extension.policy\
    -Dversion=1.0.0-SNAPSHOT\
    -DpolicyName=FooHeaderCheck

This generates the foo-header-check-policy directory with the following structure:

.
├── pom.xml
├── README.md
└── src
    ├── assembly
    │   └── policy-assembly.xml
    ├── main
    │   ├── java
    │   │   └── my
    │   │       └── gravitee
    │   │           └── extension
    │   │               └── policy
    │   │                   ├── FooHeaderCheckPolicyConfiguration.java
    │   │                   └── FooHeaderCheckPolicy.java
    │   └── resources
    │       └── plugin.properties
    └── test
        └── java
            └── my
                └── gravitee
                    └── extension
                        └── policy
                            └── FooHeaderCheckPolicyTest.java

The following files are generated:

File Description
pom.xml The main Maven POM file
README.md The main entry point for the policy documentation
policy-assembly.xml The common Maven assembly descriptor for any policies
FooHeaderCheckPolicyConfiguration.java The policy configuration class
plugin.properties The policy descriptor file
FooHeaderCheckPolicyTest.java The JUnit unit test class for this policy
FooHeaderCheckPolicy.java The main policy class that contains business code to implement the policy

{% tabs %} {% tab title="pom.xml" %} Gravitee projects are Maven-managed. A policy project is described via the Maven Project Object Model file. {% endtab %}

{% tab title="README.md" %} Each policy should by documented by a dedicated README.md file that contains comprehensive information related to the use of your policy. {% endtab %}

{% tab title="undefined" %} A policy is a type of Gravitee plugin. It can be integrated into the APIM Gateway using the distribution file built from policy-assembly.xml. Below is the distribution file structure for the example FooCheckHeader policy:

.
├── foo-header-check-policy-1.0.0-SNAPSHOT.jar
├── lib
└── schemas
    └── urn:jsonschema:my:gravitee:extension:policy:FooHeaderCheckPolicyConfiguration.json

The following files/folders are generated:

FileDescription
foo-header-check-policy-1.0.0-SNAPSHOT.jarThe main policy Jar file
lib/Where the external dependencies are stored (from the Maven POM file dependencies)
schemas/Where the JSON configuration schemas are stored
{% endtab %}

{% tab title="FooHeaderCheckPolicyConfiguration.java" %} This is the policy configuration. It is described by one or several Java Bean class(es) where each attribute is a configuration parameter. During packaging, the configuration is compiled into JSON schemas using Gravitee's json-schema-generator-maven-plugin. These are read by the Gateway and used to parse API definitions. Policy configuration is injected into the policy class instance at runtime and can be used during implementation. {% endtab %}

{% tab title="plugin.properties" %} Each policy plugin is described by the plugin.properties descriptor, which declares the following parameters:

ParameterDescriptionDefault value
idThe policy identifierpolicy artifact id
nameThe policy nameN/A (mandatory parameter)
versionThe policy versionN/A (mandatory parameter)
descriptionThe policy description"Description of the Policy name Gravitee Policy"
classThe main policy classPath to the generated class file
typeThe type of Gravitee pluginpolicy
categoryThe policy category
iconThe policy icon
proxyThe policy's proxy manifest dataN/A (options include REQUEST, RESPONSE)
messageThe policy's message manifest dataN/A (options include REQUEST, RESPONSE, MESSAGE_REQUEST, MESSAGE_RESPONSE)

{% hint style="info" %} Policy ID

A policy is enabled when declared in the API definition. Ensure the policy identifier is defined correctly. It may be hard to rename if many API definitions link to it. {% endhint %} {% endtab %} {% endtabs %}

Policy Application

A policy can be applied to the Request phase of the proxy chain, the Response phase, or both.

{% tabs %} {% tab title="Apply to Request" %} A policy can be applied to the proxy Request phase by implementing a method that handles the io.gravitee.gateway.api.policy.annotations.OnRequest annotation. For example:

@OnRequest
public void onRequest(Request request, Response response, PolicyChain policyChain) {
    // Add a dummy header
    request.headers().set("X-DummyHeader", configuration.getDummyHeaderValue());

    // Finally continue chaining
    policyChain.doNext(request, response);
}

{% hint style="info" %} The PolicyChain must always be called with PolicyChain#doNext() or PolicyChain#failWith() to properly terminate onRequest processing {% endhint %} {% endtab %}

{% tab title="Apply to Response" %} A policy can be applied to the proxy Response phase by implementing a method that handles the io.gravitee.gateway.api.policy.annotations.OnResponse annotation. For example:

@OnResponse
public void onResponse(Request request, Response response, PolicyChain policyChain) {
    if (isASuccessfulResponse(response)) {
        policyChain.doNext(request, response);
    } else {
        policyChain.failWith(new PolicyResult() {
            @Override
            public boolean isFailure() {
                return true;
            }

            @Override
            public int httpStatusCode() {
                return HttpStatusCode.INTERNAL_SERVER_ERROR_500;
            }

            @Override
            public String message() {
                return "Not a successful response :-(";
            }
        });
    }
}

private static boolean isASuccessfulResponse(Response response) {
    switch (response.status() / 100) {
        case 1:
        case 2:
        case 3:
            return true;
        default:
            return false;
    }
}

{% hint style="info" %} The PolicyChain must always be called with PolicyChain#doNext() or PolicyChain#failWith() to properly terminate onResponse processing {% endhint %} {% endtab %}

{% tab title="Apply to both" %} A policy is not restricted to only one Gateway proxy phase. It can be applied during both the Request and Response phases by using both annotations in the same class. {% endtab %} {% endtabs %}

Provided parameters

Annotated methods can declare parameters which are automatically provided by the Gateway at runtime. Available parameters are:

Parameter classMandatoryDescription
io.gravitee.gateway.api.RequestNoWrapper to the Request object containing all information about the processed request (URI, parameters, headers, input stream, …)
io.gravitee.gateway.api.ResponseNoWrapper to the Response object containing all information about the processed response (status, headers, output stream, …)
io.gravitee.gateway.api.policy.PolicyChainYesThe current policy chain that gives control to the policy to continue (doNext) or reject (failWith) the chain
io.gravitee.gateway.api.policy.PolicyContextNoThe policy context that can be used to get contextualized objects (API store, …)