ElasticSearch 2 Plugin 插件开发
ElasticSearch 2 Plugin 插件开发
南湖船老大 发表于1年前
ElasticSearch 2 Plugin 插件开发
  • 发表于 1年前
  • 阅读 205
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

最近有一个需求,因为自己用的是最新版本的elasticsearch,网上现有的东东满足不了要求,就想自己写一个,不过苦于找不到中文文档,也没有最新的英文资料。最后结合一些1.x的中文资料和官方插件的源码,算是把elasticsearch插件开发的基本套路摸清楚了。此文也仅是一个demo,还没开发出可用的插件,后续会继续深入。

    由于elasticSearch是Java开发的,所以二次开发是很轻松的,稍微看了下,弄了个原型。

    先建立一个mvn工程,加入elasticsearch的依赖。然后,需要一个继承自plugin的类

package me.baicai.elasticplusdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestModule;

public class MyDemoPlugin extends Plugin {
	final ESLogger logger = Loggers.getLogger(getClass());
	private final Settings settings;
	
	public MyDemoPlugin(Settings settings) {
		this.settings = settings;
	}
	
	/**
	 * 插件的简单描述
	 */
	@Override
	public String description() {
		return "this is a demo by baicai";
	}
	
	/**
	 * 插件的名字,区分大小写,放到plugins文件夹要注意了
	 */
	@Override
	public String name() {
		return "myDemo";
	}
	
	/**
	 * 节点级别的模块,也可以是index级别
	 */
	@Override
	public Collection nodeModules() {
		// 创建自己的模块集合
		// 如果没有自定义模块,则可以返回空
		// if (settings.getAsBoolean("bc.enabled", true)) {
		return Collections. singletonList(new HelloModule());
		// }
	}

	@Override
	public Collection<Class<? extends LifecycleComponent>> nodeServices() {
		Collection<Class<? extends LifecycleComponent>> services = new ArrayList();
		services.add(AwesomePluginService.class);
		return services;
	}
	
	/**
	 * 所有模块初始化的时候会调用这里
	 * @param module
	 */
	public void onModule(Module module) {
		String isPluginEnabled = settings.get("bc.enabled");
		// logger.info("bc.enable="+isPluginEnabled);
		if (module instanceof RestModule) {
			((RestModule) module).addRestAction(HelloWorldHandler.class);
		}
		if (module instanceof HelloModule) {
			logger.info("############## process hello module #####################");
		}
	}

}

    在2.4之前的版本,没有plugin这个父类,而是一个叫做abstractPlugin的抽象类。到了2.4,abstract这个前缀被去掉了,当然它还是一个抽象类。另外和之前版本不同的是,现在的module有不同级别的module了,node、index、shard级别,可以作用在不同的层级,而之前统一都叫module。

    如果只是一个简单的Plugin的话,其实到这里就算是搭好骨架了。但是Plugin总要做一些事情的,那这个做事情的代码在哪呢?主要就是这里了:

public void onModule(Module module) {
		String isPluginEnabled = settings.get("bc.enabled");
		// logger.info("bc.enable="+isPluginEnabled);
		if (module instanceof RestModule) {
			((RestModule) module).addRestAction(HelloWorldHandler.class);
		}
		if (module instanceof HelloModule) {
			logger.info("############## process hello module #####################");
		}
	}

    这段代码在RestModule那里做了个扩展,也就是如果调用到了RestModule,那就执行我自己定义的HelloWorldHandler方法。让我们来看看这个类

package me.baicai.elasticplusdemo;

import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
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.RestResponse;
import org.elasticsearch.rest.RestStatus;

public class HelloWorldHandler extends BaseRestHandler{
	final ESLogger logger = Loggers.getLogger(getClass());  
	
	@Inject
	public HelloWorldHandler(Settings settings, RestController controller, Client client) {
		super(settings, controller, client);
		//将该Handler绑定到某访问路径  
        controller.registerHandler(Method.GET, "/hello/", this);
        controller.registerHandler(Method.GET, "/hello/{name}", this);  
	}
	
	//处理绑定路径的请求访问 
	@Override
	public void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {  	logger.debug("HelloWorldAction.handleRequest called");  
        final String name = request.hasParam("name") ? request.param("name") : "world";   
        String content = "{\"success\":true, \"message\":\"hello " +name+ "\"}";  
        RestResponse response = new BytesRestResponse(RestStatus.OK, BytesRestResponse.TEXT_CONTENT_TYPE, content);  
        channel.sendResponse(response);  
		
	}

}

  这个方法很简单,就是拦截了形如 /hello/* 这样的请求,并加入了自己的逻辑,最后输出一段处理过的JSON。

   其实到这里就算差不多了,最后就是添加一个plugin-descriptor.properties 文件,内容如下:

description=Hello Plugin By Baicai
version=2.4.0
name=myDemo
site=false
jvm=true
java.version=1.7
elasticsearch.version=2.4.0
isolated=false

mvn编译后,在elasticsearch/plugin目录下新建一个myDemo文件夹,扔进去jar包和plugin-descriptor.properties 文件即可。重启elasticsearch后,如下图

可以看到,myDemo已经在plugin列表里了。

完整的源码:https://github.com/iminto/elasticplugindemo

共有 人打赏支持
粉丝 673
博文 12
码字总数 11172
×
南湖船老大
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: