description |
---|
Learn how to build and deploy your own policies |
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.
{% 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:
File | Description |
---|---|
foo-header-check-policy-1.0.0-SNAPSHOT.jar | The 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 |
{% 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:
Parameter | Description | Default value |
---|---|---|
id | The policy identifier | policy artifact id |
name | The policy name | N/A (mandatory parameter) |
version | The policy version | N/A (mandatory parameter) |
description | The policy description | "Description of the Policy name Gravitee Policy" |
class | The main policy class | Path to the generated class file |
type | The type of Gravitee plugin | policy |
category | The policy category | |
icon | The policy icon | |
proxy | The policy's proxy manifest data | N/A (options include REQUEST, RESPONSE) |
message | The policy's message manifest data | N/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 %}
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 %}
Annotated methods can declare parameters which are automatically provided by the Gateway at runtime. Available parameters are:
Parameter class | Mandatory | Description |
---|---|---|
io.gravitee.gateway.api.Request | No | Wrapper to the Request object containing all information about the processed request (URI, parameters, headers, input stream, …) |
io.gravitee.gateway.api.Response | No | Wrapper to the Response object containing all information about the processed response (status, headers, output stream, …) |
io.gravitee.gateway.api.policy.PolicyChain | Yes | The current policy chain that gives control to the policy to continue (doNext ) or reject (failWith ) the chain |
io.gravitee.gateway.api.policy.PolicyContext | No | The policy context that can be used to get contextualized objects (API store, …) |