Elasticsearch自定义插件

检索引擎Elasticsearch支持插件模式,有些时候你可能需要安装一些插件,甚至自己开发插件,这里就提供一个开始ES插件开发示例,ES版本为2.2.0。


自定义插件类继承org.elasticsearch.plugins.Plugin


HelloWorldPlugin:

package org.elasticsearch.plugin.helloworld;

import java.util.Collection;  
import java.util.Collections;  
  
import org.elasticsearch.common.inject.Module;  
import org.elasticsearch.plugins.Plugin;  
  
public class HelloWorldPlugin extends Plugin {  
    @Override  
    public String name() {  
        return "hello-world";  
    }  
    @Override  
    public String description() {  
        return "hello-world";  
    }  
    @Override  
    public Collection<Module> nodeModules() {  
        //加入自定义处理模块  
        return Collections.<Module> singletonList(new HelloWorldModule());  
    }  
  
}

HelloWorldModule:

package org.elasticsearch.plugin.helloworld;

import org.elasticsearch.common.inject.AbstractModule;  
import org.elasticsearch.rest.action.helloworld.HelloWorldAction;  
  
  
public class HelloWorldModule extends AbstractModule {  
  
    @Override  
    protected void configure() {  
        bind(HelloWorldAction.class).asEagerSingleton();  
    }  
}

HelloWorldAction:
package org.elasticsearch.rest.action.helloworld;

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

import java.io.IOException;  
  
import org.elasticsearch.action.ActionListener;  
import org.elasticsearch.action.get.GetRequest;  
import org.elasticsearch.action.get.GetResponse;  
import org.elasticsearch.client.Client;  
import org.elasticsearch.common.inject.Inject;  
import org.elasticsearch.common.io.stream.BytesStreamOutput;  
import org.elasticsearch.common.settings.Settings;  
import org.elasticsearch.common.xcontent.XContentBuilder;  
import org.elasticsearch.common.xcontent.XContentBuilderString;  
import org.elasticsearch.common.xcontent.XContentFactory;  
import org.elasticsearch.common.xcontent.XContentType;  
import org.elasticsearch.index.get.GetField;  
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.RestStatus;  
  
public class HelloWorldAction extends BaseRestHandler {  
  
    public static String INDEX = "example";  
    public static String TYPE = "person";  
  
    @Inject  
    public HelloWorldAction(Settings settings, Client client,  
            RestController controller) {  
        super(settings, controller, client);  
  
        // Define REST endpoints  
        controller.registerHandler(GET, "/_hello/", this);  
        controller.registerHandler(GET, "/_hello/{name}", this);  
    }  
    public static XContentBuilder restContentBuilder(RestRequest request)  
            throws IOException {  
        XContentType contentType = XContentType  
                .fromRestContentType(request.header("Content-Type"));  
        if (contentType == null) {  
            // try and guess it from the body, if exists  
            if (request.hasContent()) {  
                contentType = XContentFactory.xContentType(request.content());  
            }  
        }  
        if (contentType == null) {  
            // default to JSON  
            contentType = XContentType.JSON;  
        }  
        BytesStreamOutput out = new BytesStreamOutput();  
        XContentBuilder builder = new XContentBuilder(  
                XContentFactory.xContent(contentType), out);  
  
        if (request.paramAsBoolean("pretty", false)) {  
            builder.prettyPrint();  
        }  
        String casing = request.param("case");  
        if (casing != null && "camelCase".equals(casing)) {  
            builder.fieldCaseConversion(  
                    XContentBuilder.FieldCaseConversion.CAMELCASE);  
        } else {  
            builder.fieldCaseConversion(  
                    XContentBuilder.FieldCaseConversion.NONE);  
        }  
        return builder;  
    }  
  
    @Override  
    protected void handleRequest(final RestRequest request,  
            final RestChannel channel, Client client) throws Exception {  
        logger.info("HelloWorldAction.handleRequest called");  
  
        final String name = request.hasParam("name")  
                ? request.param("name")  
                : "world";  
        logger.info("name={}", name);  
        final GetRequest getRequest = new GetRequest(INDEX, TYPE, name);  
        getRequest.operationThreaded(true);  
  
        String[] fields = {"msg"};  
        getRequest.fields(fields);  
  
        client.get(getRequest, new ActionListener<GetResponse>() {  
            @Override  
            public void onResponse(GetResponse response) {  
  
                try {  
                    XContentBuilder builder = restContentBuilder(request);  
                    GetField field = response.getField("msg");  
                    String greeting = (field != null)  
                            ? (String) field.getValues().get(0)  
                            : "Sorry, do I know you?";  
                    builder.startObject()  
                            .field(new XContentBuilderString("hello"), name)  
                            .field(new XContentBuilderString("greeting"),  
                                    greeting)  
                            .endObject();  
  
                    if (!response.isExists()) {  
                        channel.sendResponse(new BytesRestResponse(  
                                RestStatus.NOT_FOUND, builder));  
                    } else {  
                        channel.sendResponse(  
                                new BytesRestResponse(RestStatus.OK, builder));  
                    }  
                } catch (Exception e) {  
                    onFailure(e);  
                }  
            }  
  
            @Override  
            public void onFailure(Throwable e) {  
                try {  
                    channel.sendResponse(  
                            new BytesRestResponse(channel, RestStatus.OK, e));  
                } catch (IOException e1) {  
                    logger.error("Failed to send failure response", e1);  
                }  
            }  
        });  
  
    }  
}

打包后j将jar包上传至${ES_HOME}/plugins/HelloWorld目录下(新建HelloWorld)
HelloWorld目录下新建文件plugin-descriptor.properties,文件内容如下
description=hello for ElasticSearch
version=1.0
name=HelloWorldPlugin
jvm=true
classname=org.elasticsearch.plugin.helloworld.HelloWorldPlugin
java.version=1.7(当时我这里写的是1.7但实际装的是jdk1.8.0_91倒也能正常运行)
elasticsearch.version=2.2.0


重启es,插件便安装成功了。


注意:在编写plugin-descriptor.properties文件的时候每行的后面一定不要有空格,我一开始就是直接粘贴过去的,结果每行末尾都有两个空格,重启es会报下面这个错,耗费了很长时间,这里吐槽一下CSDN,当你在它的文本编辑器中将这个josn复制过去再展示的时候你会发现每行后面自动就会有两个空格,真是坑死我了!

[hadoop@h153 ~]$ ./elasticsearch-2.2.0/bin/elasticsearch
[2017-10-12 01:19:08,902][INFO ][node                     ] [node-1] version[2.2.0], pid[8548], build[8ff36d1/2016-01-27T13:32:39Z]
[2017-10-12 01:19:08,903][INFO ][node                     ] [node-1] initializing ...
Exception in thread "main" ElasticsearchException[Could not find plugin class [org.elasticsearch.plugin.helloworld.HelloWorldPlugin]]; nested: ClassNotFoundException[org.elasticsearch.plugin.helloworld.HelloWorldPlugin];
Likely root cause: java.lang.ClassNotFoundException: org.elasticsearch.plugin.helloworld.HelloWorldPlugin
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814)
        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:146)
        at org.elasticsearch.node.Node.<init>(Node.java:128)
        at org.elasticsearch.node.NodeBuilder.build(NodeBuilder.java:145)
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:178)
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:285)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Refer to the log for complete error details.

下面进行插件的验证:

先创建相应的索引:
[hadoop@h153 ~]$ curl -XPOST http://192.168.205.153:9200/example
{"acknowledged":true}

[hadoop@h153 ~]$ curl -XGET http://192.168.205.153:9200/_hello
{"hello":"world","greeting":"Sorry, do I know you?"}

[hadoop@h153 ~]$ curl -XGET http://192.168.205.153:9200/_hello/xmine
{"hello":"xmine","greeting":"Sorry, do I know you?"}

[hadoop@h153 ~]$ curl -XPUT  http://192.168.205.153:9200/example/person/xmine?pretty -d '{"msg":"elasticsearch"}'
{
  "_index" : "example",
  "_type" : "person",
  "_id" : "xmine",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}
[hadoop@h153 ~]$ curl -XGET http://192.168.205.153:9200/_hello/xmine
{"hello":"xmine","greeting":"elasticsearch"}

补充:为插件添加页面
如果你想为你的插件添加访问页面,则可以在ES_HOME/plugins/HelloWorld目录下创建一个名为"_site"的目录,该目录名称必须为_site,然后将相应的html页面放置进_site目录即可,如果放置了一个名为index.html文件,则可以通过localhost:9200/_plugin/HelloWorld/index.html进行访问。
由于Elasticsearch提供了js客户端API,所以使用html静态页面与js就可以完成相应的功能了。


参考:
http://blog.csdn.net/xtayfjpk/article/details/47005219
http://blog.csdn.net/l253272670/article/details/54141169
https://stackoverflow.com/questions/33538903/elasticsearch-2-0-plugin-installation-info

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值