上一篇我们怼插件的作用和地位做了一些简单的介绍,这一章,我们来介绍协一下如何研发一个自己的插件 首先,插件的目录结构是固定的如下:
├── 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
复制代码
我们在开发插件时必须严格遵守这个文件目录的机构,其中assembly.xml是用来给maven编译打包时使用的描述文件,plugin.properties中标识了插件的各个描述属性,这两个是最关键的
当然我们在写插件的时候不需要自己去手动创建这么多的文件夹,Gravitee为我们准备了一个maven的模板,我们只需要执行下面的命令就可以生成一套自己的文件机构,并且会帮我们引入关键的必须依赖:
下面这条命令会生成上图文件结构Tree
mvn archetype:generate\
-DarchetypeGroupId=io.gravitee.maven.archetypes\
-DarchetypeArtifactId=gravitee-policy-maven-archetype\
-DarchetypeVersion=1.9.0\
-DartifactId=foo-header-check-policy\
-DgroupId=my.gravitee.extension.policy\
-Dversion=1.0.0-SNAPSHOT\
-DpolicyName=FooHeaderCheck
复制代码
接下来我们来看一下自动生成的这几个文件的作用:
- Configuration 配置文件会需要实现PolicyConfiguration接口,实现这个接口后,在maven package的时候插件会生成一个json文件,到时候gravitee会这个json文件去生成对应的填写配置的页面
- Policy
policy文件中用于编写我们对http请求的操作,我们需要在方法上打上响应的注解,用来标识是在处理哪个阶段
处理请求
@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);
}
复制代码
处理响应
@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;
}
}
复制代码
Request, Response, PolicyChain 属于必选参数,必选按顺序进行声明,否则会导致插件无法被正常使用!
上面的是官方的示例,我贴一个自己的例子出来,我们可以看到在插件初始化的构造函数中,配置文件被赋值了,这个赋值操作是从ui界面传入的值,我们在插件里都可以读到。
public class XiaoCuiPolicyScPolicy {
/**
* The associated configuration to this XiaoCuiPolicySc Policy
*/
private XiaoCuiPolicyScPolicyConfiguration configuration;
private static final Logger logger= LoggerFactory.getLogger(XiaoCuiPolicyScPolicy.class);
/**
* Create a new XiaoCuiPolicySc Policy instance based on its associated configuration
*
* @param configuration the associated configuration to the new XiaoCuiPolicySc Policy instance
*/
public XiaoCuiPolicyScPolicy(XiaoCuiPolicyScPolicyConfiguration configuration) {
this.configuration = configuration;
}
@OnRequest
public void onRequest(Request request, Response response, PolicyChain policyChain) {
// Add a dummy header
logger.info("小崔的插件测试请求");
// Finally continue chaining
policyChain.doNext(request, response);
}
@OnResponse
public void onResponse(Request request, Response response, PolicyChain policyChain) {
logger.info("小崔的插件测试响应");
request.headers().set("X-DummyHeader", configuration.getStringParam());
if (isASuccessfulResponse(response)) {
policyChain.doNext(request, response);
} else {
policyChain.failWith(
PolicyResult.failure(HttpStatusCode.INTERNAL_SERVER_ERROR_500, "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;
}
}
}
复制代码
我们在写好插件的主要逻辑之后需要为插件写一个描述信息,来唯一的标识插件,信息写在plugin.properties里
id=XiaoCuiPolicySc
name=XiaoCuiPolicySc
version=${project.version}
description=${project.description}
class=my.xiaocui.policy.XiaoCuiPolicyScPolicy #插件核心类
type=policy
category=others #插件的分类
icon=tv.svg #可以自定义插件的图标,图标需要放在根目录
复制代码
我们把这些东西都配置好之后,执行maven package 会生成一个打好的zip,如果你发现你有些文件没有被压缩进来,就去查看修改assembly.xml,并且会生成我们前面说到的json文件,这个json文件在schemas文件夹下,我们解压一下ZIP正常的话会看到这些文件
然后我们把这个zip分别放到网关和APIM的plugins文件夹中,两个都要放,划重点。 重新编译部署项目,我们就可以在API设计面板里看到我们刚才自定义的插件,这样我们就能正常的使用自己的自定义插件了。