Elasticsearch:从零开始创建一个 REST handler 插件

2022年9月7日   |   by mebius

在 Kibana 的 console 中,我们可以使用一些命令对 Elasticsearch 进行交互。那么我们是否可以扩展我们需要的一些命令呢?比如:

%title插图%num

在上面,我们打入 GET _cat/example,它将显示右边的输出。这个是我们扩展的一个命令。

Elasticsearch 带有一组可以执行各种任务的功能。 但是,如果你想实现自己的任何功能,则需要在 Elasticsearch 的主代码库中实现。 为了保护你免受所有这些额外步骤的影响,Elasticsearch 提供了在 Elasticsearch 代码中添加插件的选项,该插件能够实现你的功能。

在今天的展示中,我将使用最新的 Elastic Stack 8.4.0 来进行展示。

安装

如果你还没有安装好自己的 Elastic Stack,请参考如下的文章来安装 Elasticsearch 及 Kibana:

创建插件模板

在我之前的文章

我已经展示了如何为 ingest pipeline 创建processors。在上面的第二篇文章中,我使用了一个叫做 elasticsearch-plugin-archtype 的插件。我们可以使用如下的命令来创建一个最为基本的插件模板:

mvn archetype:generate 
    -DarchetypeGroupId=org.codelibs 
    -DarchetypeArtifactId=elasticsearch-plugin-archetype 
    -DarchetypeVersion=6.6.0 
    -DgroupId=com.liuxg 
    -DartifactId=elasticsearch-plugin 
    -Dversion=1.0-SNAPSHOT 
    -DpluginName=rest_handler 

%title插图%num

上面已经帮我们创建了一个最为基本的插件模板。它在当前的目录下创建了一个叫做 elasticsearch-plugin 的目录。我们首先进入到该目录中:

$ pwd
/Users/liuxg/java/plugins/elasticsearch-plugin
$ tree -L 8
.
├── pom.xml
└── src
    └── main
        ├── assemblies
        │ └── plugin.xml
        ├── java
        │ └── com
        │     └── liuxg
        │         ├── rest
        │         │ └── Restrest_handlerAction.java
        │         └── rest_handlerPlugin.java
        └── plugin-metadata
            └── plugin-descriptor.properties

上面是它的文件结构。因为我们想为 Elastic Stack 8.4.0 构建插件,所以,我们必须在 pom.xml 中修改相应的版本信息:

pom.xml



	elasticsearch-plugin
	4.0.0
	com.liuxg
	elasticsearch-plugin
	1.0-SNAPSHOT
	jar
	elasticsearch rest_handler plugin
	2019
	
		
			The Apache Software License, Version 2.0
			http://www.apache.org/licenses/LICENSE-2.0.txt
			repo
		
	
	
		8.4.0
		com.liuxg.rest_handlerPlugin
		2.11.1
		1.8
		1.8
	
	
		
			
				maven-compiler-plugin
				3.8.0
				
					${maven.compiler.source}
					${maven.compiler.target}
					UTF-8
				
			
			
				maven-surefire-plugin
				2.22.1
				
					
						**/*Tests.java
					
				
	tgcode		
			
				maven-source-plugin
				3.0.1
				
					
						attach-sources
						
							jar
						
					
				
			
			
				maven-assembly-plugin
				3.1.0
				
					false
					${project.build.directory}/releases/
					
						${basedir}/src/main/assemblies/plugin.xml
					
				
				
					
						package
						
							single
						
					
				
			
		
	
	
		
			org.elasticsearch
			elasticsearch
			${elasticsearch.version}
			provided
		
		
			org.apache.logging.log4j
			log4j-api
			${log4j.version}
			provided
		
	

在上面,我们把 elasticsearch.version 设置为 8.4.0。其它的保持不变。

接下来,我们来修改rest_handlerPlugin.java 文件:

rest_handlerPlugin.java

package com.liuxg;

import java.util.List;
import java.util.function.Supplier;

import com.liuxg.rest.Restrest_handlerAction;
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 static java.util.Collections.singletonList;

public class rest_handlerPlugin extends Plugin implements ActionPlugin {
    @Override
    public List getRestHandlers(final Settings settings,
                                             final RestController restController,
                                             final ClusterSettings clusterSettings,
                                             final IndexScopedSettings indexScopedSettings,
                                             final SettingsFilter settingsFilter,
                                             final IndexNameExpressionResolver indexNameExpressionResolver,
                                             final Supplier nodesInCluster) {
        return singletonList(new Restrest_handlerAction());
    }
}

这个文件会让 Elasticsearch 知道你的插件。

我们接下来修改Restrest_handlerAction.java 文件如下:

Restrest_handlerAction.java

package com.liuxg.rest;

import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.common.Table;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.action.cat.AbstractCatAction;
import org.elasticsearch.rest.action.cat.RestTable;

import java.util.List;

import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;


public class Restrest_handlerAction extends AbstractCatAction {
    @Override
    public List routes() {
        return List.of(
                new Route(GET, "/_cat/example"),
                new Route(POST, "/_cat/example"));
    }

    @Override
    public String getName() {
        return "rest_handler_cat_example";
    }

    @Override
    protected RestChannelConsumer doCatRequest(final RestRequest request, final NodeClient client) {
        final String message = request.param("message", "Hello from Cat Example action");

        Table table = getTableWithHeader(request);
        table.startRow();
        table.addCell(message);
        table.endRow();
        return channel -> {
            try {
                channel.sendResponse(RestTable.buildResponse(table, channel));
            } catch (final Exception e) {
                channel.sendResponse(new RestResponse(channel, e));
            }
        };
    }

    @Override
    protected void documentation(StringBuilder sb) {
        sb.append(documentation());
    }

    public static String documentation() {
        return "/_cat/examplen";
    }

    @Override
    protected Table getTableWithHeader(RestRequest request) {
        final Table table = new Table();
        table.startHeaders();
        table.addCell("test", "desc:test");
        table.endHeaders();
        return table;
    }
}

该文件将定义插件的路由和处理这些路由的代码。

这样我们就修改完了我们的代码。

编译

我们在项目的根目录下使人如下的命令来进行编译:

mvn clean install
$ mvn clean install
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------------------------
[INFO] Building elasticsearch-plugin 1.0-SNAPSHOT
[INFO] ------------------tgcode--------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ elasticsearch-plugin ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ elasticsetgcodearch-plugin ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ elasticsearch-plugin ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/liuxg/java/plugins/elasticsearch-plugin/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ elasticsearch-plugin ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ elasticsearch-plugin ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ elasticsearch-plugin ---
[INFO] No tests to run.
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ elasticsearch-plugin ---
[INFO] Building jar: /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT.jar
[INFO] 
[INFO] >>> maven-source-plugin:3.0.1:jar (attach-sources) > generate-sources @ elasticsearch-plugin >>>
[INFO] 
[INFO] 

编译成功后,我们可以在 targe 目录先看到如下的安装文件:

$ pwd
/Users/liuxg/java/plugins/elasticsearch-plugin
$ ls target/releases
elasticsearch-plugin-1.0-SNAPSHOT.zip

上面显示的elasticsearch-plugin-1.0-SNAPSHOT.zip 就是我们可以安装的插件文件。

安装插件并测试插件

我们接下来换到 Elasticsearch 的安装目录下,并打入如下的命令:

$ pwd
/Users/liuxg/elastic0/elasticsearch-8.4.0
$ bin/elasticsearch-plugin install file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
-> Installing file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
-> Downloading file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
[=================================================] 100% 
-> Installed rest_handler
-> Please restart Elasticsearch to activate any plugins installed
$ ./bin/elasticsearch-plugin list
rest_handler

从上面的显示中,我们可以看出来 rest_handler 插件已经被成功地安装。我们接下来需要重新启动 Elasticsearch。这个非常重要!

我们打开 Kibana,并打入如下的命令:

%title插图%num

我们也可以直接在 terminal 中打入如下的命令:

curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
$ curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
Hello from Cat Example action

整个项目的代码可以在地址下载:GitHub – liu-xiao-guo/rest_handler_plugin

参考:

【1】elasticsearch/plugins/examples at main elastic/elasticsearch GitHub

文章来源于互联网:Elasticsearch:从零开始创建一个 REST handler 插件

相关推荐: Elasticsearch:LDAP 用户鉴权

使用凭证访问 Elasticsearch 集群。 凭证可以是存储在 Elasticsearch 内部的标准用户/密码,也可以使用更复杂的解决方案,例如 Active Directory 和轻量级目录访问协议 (LDAP)。 你可以将 Elastic Stack…