基于docker的apisix网关的java插件开发

本文使用Docker + Apisix + apisix-plugin-java-runner,完成Java的插件开发。

一、搭建docker环境

在安装目录下,克隆apisix官方的docker示例文件:

1
git clone https://github.com/apache/apisix-docker.git

拉取后进入

1
cd apisix-docker/example

可得到以下文件:

20220624103118

二、搭建分层镜像

apisix服务与java插件中通信是基于某个.sock的文件,所以官网给出这样的解释:

1
2
apisix-java-plugin-runner 和 APISIX 使用 Unix Domain Socket 进行进程间通信,因此需要部署在同一个实例中。
apisix-java-plugin-runner 由 APISIX 管理。APISIX 在启动时启动 apisix-java-plugin-runner 并在结束时结束它。如果 apisix-java-plugin-runner 中涂退出,APISIX 会自动重启

这意味着在docker里搭建的apisix容器,同时也需要有java的运行环境,才可以进行java插件的开发。

由于apisix的java插件开发需要继续 jdk11,并且刚才example目录下的docker-comse.yaml中,apisix的基础镜像并没有带jdk,所以这里我们搭建一个新的docker镜像

前往oracle官网下载jdk-11,并将其拷贝至宿主机,与Dockerfile同级目录。

开始编写Dockerfile文件,来构建一个定制化的镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 路径自己选择
vim Dockerfile

#进入文件后
#依赖镜像名称和ID
FROM apache/apisix:2.13.1-centos
#指定镜像创建者信息
MAINTAINER cisco
#将宿主机的文件拷贝到容器的具体目录中。这里使用ADD,拷贝后自动解压,如果不需要解压,可以使用COPY
ADD jdk-11.0.15_linux-x64_bin.tar.gz /jdk
## 配置jdk环境
ENV JAVA_HOME /jdk/jdk-11.0.15
ENV PATH ${JAVA_HOME}/bin:$PATH

这里选择的镜像源是apache/apisix:2.13.1-centos

最开始使用的是官网的apache/apisix:2.14.1-alpine,由于alpine源的原因, 在后续的开发的时候碰到了一些问题, 这里我们避免后续其他的“坑”,采用centos的。

继续在当前目录构建镜像

1
docker build -t apisix-jdk11 .

20220624105827

构建成功后,回到example目录,修改docker-compose.yaml

20220624105722

执行

1
docker-compose -f docker-compose.yml up -d

此阶段可检查有无端口冲突,及处理。

查看docker容器运行状态

1
docker ps -a

无异常即可访问 http://宿主机ip:9000, 访问APISIX DashBoard,进行对应操作及配置。

三、基于Java的Ext-Plugin开发

可参考官网的文档: https://apisix.apache.org/docs/java-plugin-runner/next/development

给插件命名为TestExtPluginDemo,插件属性如下

1
2
3
4
{
"validate_header": "token",
"rejected_code": "403"
}

在APISIX上配置一个路由/get,指定该路由需要使用的外部插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri":"/get",
"plugins":{
"ext-plugin-pre-req":{
"conf":[
{
"name":"TestExtPluginDemo",
"value":"{\"validate_header\":\"token\",\"rejected_code\":\"403\"}"
}
]
}
},
"upstream":{
"nodes":{
"httpbin.org:80":1
},
"type":"roundrobin"
}
}

需要注意的是,TestExtPluginDemo 的属性需要经过 json 转义,作为 string 类型进行配置。

(这里上游地址配置为 httpbin.org,方便调试)

克隆apisix-java-plugin-runner项目。

runner-plugin模块中,org.apache.apisix.plugin.runner.filter的路径下编写插件。

20220624111959

在此路径下创建插件类,需实现PluginFilter接口,其中***name()***的返回值, 将作为apisix的插件名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package org.apache.apisix.plugin.runner.filter;

import com.google.gson.Gson;
import org.apache.apisix.plugin.runner.HttpRequest;
import org.apache.apisix.plugin.runner.HttpResponse;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @Description:
* @Author: cisco
* @Date: 2022/6/22 11:25
*/
@Component
public class TestExtPluginDemo implements PluginFilter {

@Override
public String name() {
//此处返回值为插件的名称
return "TestExtPluginDemo";
}

@Override
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
// parse `conf` to json
String configStr = request.getConfig(this);
Gson gson = new Gson();
Map<String, Object> conf = new HashMap<>();
conf = gson.fromJson(configStr, conf.getClass());

// get configuration parameters
String token = request.getHeader((String) conf.get("validate_header"));

// token verification results
if (!Strings.isNotBlank(token)) {
String rejectedCode = (String) conf.get("rejected_code");
response.setStatusCode(Integer.parseInt(rejectedCode));
chain.filter(request, response);
}
chain.filter(request, response);
}

@Override
public List<String> requiredVars() {
return null;
}

@Override
public Boolean requiredBody() {
return null;
}
}

编写完插件后, maven install。

1
2
3
./mvnw install
#或者
./mvnw package

然后你会看到dist目录下,生成一个apache-apisix-java-plugin-runner-0.2.0-bin.tar.gz

将其复制到docker的宿主机上,再通过docker cp命令 复制到 docker容器内部

1
docker cp apache-apisix-java-plugin-runner-0.2.0-bin.tar.gz apisix-11:/opt/

修改外部挂载的 APISIX配置文件。位于apisix-docker/exaple/apisix_conf文件夹中的config.yaml

添加如下配置:

1
2
ext-plugin:
cmd: ['java', '-jar', '/opt/apisix-runner-bin/apisix-java-plugin-runner.jar']

重启docker容器,进行测试。使用之前配置使用此插件的路由。

1
2
curl -H 'token: 123456' 192.168.56.102:9080/get
curl 192.168.56.102:9080/get

执行结果如下:

20220624115010

评论加载中...