# elasticsearch-plugin-develop-example
**Repository Path**: darkranger/elasticsearch-plugin-devlop-example
## Basic Information
- **Project Name**: elasticsearch-plugin-develop-example
- **Description**: ElasticSearch插件开发学习实践代码
- **Primary Language**: Java
- **License**: MulanPSL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2022-08-16
- **Last Updated**: 2022-08-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: ElasticSearch
## README
# 0. 写在前面
项目配置
JAVA GraalVM 17
ElasticSearch 8.3.3
# 1. 插件开发目的
让更多的开发者增强ElasticSearch功能
# 2. 插件类型
| 类型 | 用途 |
|:-----------------|:-------------|
| ActionPlugin | rest命令请求,定制化符合自身需求的rest命令|
| AnalysisPlugin | 分析,弥补es自身分析功能不足|
| ClusterPlugin | 集群|
| DiscoveryPlugin | 发现|
| IngestPlugin | 预处理|
| MapperPlugin | 映射,增加强es数据类型|
| NetworkPlugin | 网络|
| RepositoryPlugin | 存储,提供快照和恢复|
| ScriptPlugin | 脚本,调用任何语言写的自定义脚本|
| SearchPlugin | 查询,扩展es本身的查询功能|
表格中插件类型都是java接口类,具体可见github上ElasticSearch的[源码](https://github.com/elastic/elasticsearch/tree/main/server/src/main/java/org/elasticsearch/plugins)
# 3. 插件开发举例
## 3.1 自定义开发插件类路径
见下图

## 3.2 开发步骤
### 3.2.1 新建plugin-descriptor.properties
在reousrces目录下新建plugin-descriptor.properties,内容如下
``` properties
name=${elasticsearch.plugin.name}
version=${project.version}
description=${project.description}
classname=${elasticsearch.plugin.classname}
java.version=${maven.compiler.target}
elasticsearch.version=${elasticsearch.version}
```
properties文件中各属性含义见下列表格
| 属性 | 描述 |
| :-----------|:-------------|
| name | 插件名字|
| version | 插件版本|
| description | 插件功能描述|
| classname | 插件入口class,完整路径|
| java.version | jdk版本|
| elasticsearch.version | elasticsearch版本|
### 3.2.2 定义pom文件,绑定properties中的配置项
properties中的配置项值在pom.xml文件中定义。如下
``` xml
...
plugin develop
com.wujunshen.plugin.PrintPlugin
17
8.3.3
${project.basedir}/src/main/assemblies/plugin.xml
...
```
> 注意
>
> 其中elasticsearch.version配置项的值
>
> 也就是ElasticSearch的版本号必须和你将要发布插件包的ElasticSearch安装版本号一致。
>
> 上述我写了8.3.3,打包后也必须解压到8.3.3版本的ElasticSearch中,否则插件执行效果会无效化
### 3.2.3 自定义plugin类型类
假设我们自定义的插件类型是ActionPlugin,则自定义一个plugin类型类,继承抽象类Plugin,然后实现ActionPlugin接口
代码示例
``` java
package com.wujunshen.plugin;
import com.wujunshen.plugin.handler.PrintPluginHandler;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.IndexScopedSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class PrintPlugin extends Plugin implements ActionPlugin {
private static final String ACTION_PREFIX = "print";
public PrintPlugin() {
super();
log.info("{} 插件实例化......", ACTION_PREFIX);
}
@Override
public List getRestHandlers(Settings settings, RestController restController,
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings
, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver,
Supplier nodesInCluster) {
return Collections.singletonList(new PrintPluginHandler(restController));
}
}
```
### 3.2.4 实现具体handler类
ElasticSearch插件真正要做的事情,需要实现的逻辑我们放在具体的handler类中,比如这个例子中,我们实现一个PrintPluginHandler类,打印消耗时间,请求参数,插件名等一些信息
``` java
package com.wujunshen.plugin.handler;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
/**
* @author wujunshen
*/
@Slf4j
public class PrintPluginHandler extends BaseRestHandler {
private static final String PRINT_NAME = "printPluginTest";
@Inject
public PrintPluginHandler(RestController restController) {
super();
// 注册
restController.registerHandler(new Route(Method.GET, "/print-plugin"), this);
}
@Override
public String getName() {
return PRINT_NAME;
}
/**
*
*/
@Override
public List routes() {
return List.of(new Route(Method.GET, "print"));
}
/**
* 处理业务逻辑
*/
@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
// 接收的参数
log.info("params=={}", request.params());
long startTime = System.currentTimeMillis();
String name = request.param("name");
long cost = System.currentTimeMillis() - startTime;
// 返回内容,这里返回消耗时间 请求参数 插件名称
return channel -> {
XContentBuilder builder = channel.newBuilder();
builder.startObject();
builder.field("cost", cost);
builder.field("name", name);
builder.field("time", new Date());
builder.field("pluginName", PRINT_NAME);
builder.field("print", "this is print plugin test");
builder.endObject();
channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder));
};
}
}
```
通过上述4步,我们完成了插件开发过程,接下来需要发布,使其生效
# 4. 发布插件
## 4.1 插件配置文件定义
首先在assemblies目录下新建plugin.xml中,配置好打包需要的各项属性,如下
``` xml
plugin-develop
zip
false
${project.basedir}/config
config
${project.basedir}/src/main/resources/plugin-descriptor.properties
true
true
true
org.elasticsearch:elasticsearch
true
true
org.apache.httpcomponents:httpclient
```
指定了打包成zip格式,并把需要打入插件包的依赖包和文件全部做好了声明。接下来我们就可以执行maven打包命令进行打包
## 4.2 maven命令打包
在maven的pom.xml中定义好build步骤
``` xml
。。。
UTF-8
UTF-8
UTF-8
17
17
8.3.3
17
${project.basedir}/src/main/assemblies/plugin.xml
plugin develop
com.wujunshen.plugin.PrintPlugin
。。。
src/main/resources
false
*.properties
org.apache.maven.plugins
maven-assembly-plugin
2.6
false
${project.build.directory}/releases/
${basedir}/src/main/assemblies/plugin.xml
package
single
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
${maven.compiler.target}
${maven.compiler.target}
${project.build.sourceEncoding}
。。。
```
通过maven命令
``` shell
mvn clean install
```
打包已开发完成的源码。
## 4.3 发布插件包
将打包成zip格式的插件包(在/target/releases目录下)
解压到ElasticSearch下的plugins子目录下,这样就发布完成了
# 5. 运行插件
## 5.1 启动ElasticSearch
在ElasticSearch目录下的bin子目录启动ElasticSearch
> 注意
>
> 不能用root账号启动
>
> 需要新建账号并赋权,然后启动ElasticSearch
## 5.2 查看效果
浏览器中输入 `http://127.0.0.1:9200/print-plugin?name=wujunshen`
效果如下

以上这些内容即我们开发一个ElasticSearch插件包的完整示例