检索引擎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 nodeModules() {
//加入自定义处理模块
return Collections. singletonList(new 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();
}
}
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() {
@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);
}
}
});
}
}
重启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.(PluginsService.java:129)
at org.elasticsearch.node.Node.(Node.java:146)
at org.elasticsearch.node.Node.(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"}
参考:
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