# 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 自定义开发插件类路径 见下图 ![开发目录结构](.README_images/304aee05.png) ## 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` 效果如下 ![效果图](.README_images/251f4c4e.png) 以上这些内容即我们开发一个ElasticSearch插件包的完整示例