ITPub博客

首页 > IT基础架构 > > elasticsearch自定义插件

elasticsearch自定义插件

作者:格伯纳 时间:2020-06-01 13:45:48 0 删除 编辑

一直想尝试自己造轮子,毕竟用了header,smartcn等插件,也很好奇es插件如何自定义。

搞了好几天,今天终于成功了,虽然只是一个hello world,但基本的流程,我相关的java类我大致搞清楚了,再次纪录一下。


es官网找到了一个链接:Writing an Elasticsearch Plugin: Getting Started,让人失望透顶,es的版本不一的情况下,我2.3.1es版本,根本没有org.elasticsearch.plugins.AbstractPlugin,

没办法继续碰壁,网上千篇一律的抄来抄去,让人厌恶。

只能继续深耕es官网文档。Help for plugin authors,


先得到一个基本的插件框架。1:如果时网页插件,必需包含

  • The plugin-descriptor.properties file
  • The _site/ directory
  • The _site/index.html file

2:非site插件,必需包含

The plugin-descriptor.properties file

和java类文件。

基本的plugin-descriptor.properties,

description=hello - A web front end for an elastic search cluster
version=master
name=hello

version=2.3.1

### mandatory elements for site plugins:
#
# 'site': set to true to indicate contents of the _site/
#  directory in the root of the plugin should be served.
site=false
#
### mandatory elements for jvm plugins :
#
# 'jvm': true if the 'classname' class should be loaded
#  from jar files in the root directory of the plugin.
#  Note that only jar files in the root directory are
#  added to the classpath for the plugin! If you need
#  other resources, package them into a resources jar.
jvm=true
#
# 'classname': the name of the class to load, fully-qualified.
classname=${elasticsearch.plugin.classname}
#
# 'java.version' version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.7
#
# 'elasticsearch.version' version of elasticsearch compiled against
# You will have to release a new version of the plugin for each new
# elasticsearch release. This version is checked when the plugin
# is loaded so Elasticsearch will refuse to start in the presence of
# plugins with the incorrect elasticsearch.version.
elasticsearch.version=2.3.1
#
### deprecated elements for jvm plugins :
#
# 'isolated': true if the plugin should have its own classloader.
# passing false is deprecated, and only intended to support plugins 
# that have hard dependencies against each other. If this is
# not specified, then the plugin is isolated by default.
#isolated=true

这里面要主要的是,你自定义的java类名字,the name of the class to load, fully-qualified,

记住是此处的类名,必需你自己能够import到的,不然es会报错

Exception in thread "main" ElasticsearchException[Could not find plugin class [elasticsearch.plugin.HelloPlugin]]; nested: ClassNotFoundException[elasticsearch.plugin.HelloPlugin];
Likely root cause: java.lang.ClassNotFoundException: elasticsearch.plugin.HelloPlugin
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:810)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.elasticsearch.plugins.PluginsService.loadPluginClass(PluginsService.java:463)
	at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:431)
	at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:129)
	at org.elasticsearch.node.Node.<init>(Node.java:158)
	at org.elasticsearch.node.Node.<init>(Node.java:140)
	at org.elasticsearch.node.NodeBuilder.build(NodeBuilder.java:143)
	at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:178)
	at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:270)
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Refer to the log for complete error details.


可怜我,傻乎乎直接写了个elasticsearch.plugin.HelloPlugin,以为照着github上别人的写法肯定不会有问题,哈哈哈,等我打完jar包后,这个错误让我必应了好几天。其实就是自己的不认真读文档内容。

classname = 你的java包文件.类名字。

这是我的文件结构

那我的classname=es_client.yxp.HelloPlugin

就这么简单。


ok,了解完es的文件结构。2.3版本esjar下,我们来看自定义插件类,需要继承、实现那些类、接口。

package es_client.yxp;

import java.util.Arrays;
import java.util.List;

import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.RestModule;


public class HelloPlugin extends Plugin {
	public List<Class<HelloRestAction>> getRestHandlers() {
	       return Arrays.asList(HelloRestAction.class);
	}

	@Override
	public String name() {
		// TODO Auto-generated method stub
		return "hello";
	}

	@Override
	public String description() {
		// TODO Auto-generated method stub
		return "diyici使用插件";
	}
	
	public void onModule(RestModule module) { 
		module.addRestAction(HelloRestAction.class); 
		} 
}


Plugin,必需override 两个函数,name、description。

最关键的是onModule函数,就是由于我先前没有实现onModule函数,我的插件安装成功后,没有错误就是不执行。onModule函数的作用就是注册你的自定义Action类。

How to Create Custom Elasticsearch Plugins,可以参考外国大佬们的过时文章,理解原理即可,他们的类在2.3上几乎都已经废弃。


定义好我们的插件类,就得完善我们的HelloRestAction

package es_client.yxp;

import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestRequest.Method;
import org.elasticsearch.rest.RestStatus;

public class HelloRestAction extends BaseRestHandler {
    @Inject   
	public HelloRestAction (Settings settings, RestController controller, Client client) {
		super(settings, controller, client);    
		controller.registerHandler(Method.GET, "/_hello", this);
	}

	@Override
	protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
		// TODO Auto-generated method stub
		 String clustername = client.settings().get("cluster.name");
	      channel.sendResponse(new BytesRestResponse(RestStatus.OK, XContentFactory.jsonBuilder().startObject().field("hello", "This is cluster –"+clustername).endObject()));

	}
}


当请求_hello,触发handleRequest。

handleRequest,函数就是控制http request请求。


到此,咱们的2.3es插件代码完成了。现在要做的就是将代码打包成jar文件,和plugin-descriptor.properties,后,zip -q -r hello.zip under_floder,现在你的插件hello.zip文件生成了。


./plugin install file://你的文件目录hello.zip,

-> Installing from file:/Users/yinxingpan/Downloads/hello.zip...
Trying file:/你的目录hello.zip ...
Downloading .DONE
Verifying file:/你的目录/hello.zip checksums if available ...
NOTE: Unable to verify checksum for downloaded plugin (unable to find .sha1 or .md5 file to verify)
Installed hello into /你的目录/elasticsearch-2.3.1/plugins/hello


激动不,127.0.0.1:9200/_hello/,成功:返回:

完成啦,第一个es插件。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31509949/viewspace-3134503/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
管理员

注册时间:2018-03-30

  • 博文量
    2383
  • 访问量
    984279