创建Elasticsearch插件(1)

我打算自己制作Elasticsearch的插件,所以进行了各种调查,以下是我的备忘录。

环境

首先要使用的是Java开发语言。由于Elasticsearch也是使用Java编写的,所以这里选择了Java语言。虽然主要的构建工具是gradle,但我不熟悉gradle,所以这次选择了maven(在这个方面做了一些妥协)。

    • java8

 

    • maven

 

    elasticsearch6系

请看以下内容。

这次我参考了这里的代码。
为了不完全相同,我稍微做了一些改变。

实施

这是作为插件的初始调用类。

package org.elasticsearch.plugin.example;

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 java.util.List;
import java.util.function.Supplier;

import static java.util.Collections.singletonList;

public class ExamplePlugin extends Plugin implements ActionPlugin {
    @Override
    public List<RestHandler> getRestHandlers(final Settings settings,
                                             final RestController restController,
                                             final ClusterSettings clusterSettings,
                                             final IndexScopedSettings indexScopedSettings,
                                             final SettingsFilter settingsFilter,
                                             final IndexNameExpressionResolver indexNameExpressionResolver,
                                             final Supplier<DiscoveryNodes> nodesInCluster) {

        return singletonList(new ExampleDogAction(settings, restController));
    }
}

这个插件的入口类在src/main/resources/plugin-descriptor.properties中定义。

version=${project.version}
description=${project.description}
name=example-plugin
classname=org.elasticsearch.plugin.example.ExamplePlugin
java.version=1.8
elasticsearch.version=${elasticsearch.version}

于是,实际处理被从ExamplePlugin调用的类是ExampleDogAction类。

package org.elasticsearch.plugin.example;

import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.Table;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.cat.AbstractCatAction;
import org.elasticsearch.rest.action.cat.RestTable;

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

/**
 * Example of adding a cat action with a plugin.
 */
public class ExampleDogAction extends AbstractCatAction {

    ExampleDogAction(final Settings settings, final RestController controller) {
        super(settings);
        controller.registerHandler(GET, "/_cat/example", this);
        controller.registerHandler(POST, "/_cat/example", this);
    }

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

    @Override
    protected RestChannelConsumer doCatRequest(final RestRequest request, final NodeClient client) {
        final String message = request.param("message", "Hello from Dogt 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 BytesRestResponse(channel, e));
            }
        };
    }

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

    public static String documentation() {
        return "/_cat/example\n";
    }

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

这是实施的步骤。该插件继承了源代码中的cat API处理方式。将其压缩为zip文件,然后在Docker或本地上启动Elasticsearch并安装该插件。本次将在Docker上启动的Elasticsearch上安装该插件。

FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.5.0

RUN elasticsearch-plugin install analysis-kuromoji
RUN elasticsearch-plugin install analysis-icu

ADD elasticsearch-example-plugin-6.5.0.1.zip /usr/share/elasticsearch/elasticsearch-example-plugin-6.5.0.zip
RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///usr/share/elasticsearch/elasticsearch-example-plugin-6.5.0.zip

COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml

那么,通过这样做就可以启动Elasticsearch。当启动日志中显示出现”loaded plugin [example-plugin]”这样的内容时,说明成功安装了插件。

スクリーンショット 2018-12-29 23.48.00.png

让我们试着调用API看看。

$ curl -XGET 'localhost:9200/_cat/example'
Hello from Dogt Example action

在ExampleDogAction的doCatRequest方法中,将根据上述所定义的内容在控制台输出。

首先,我们将在这里迈出自制插件的第一步。下一次,我打算创建一个进化更高的插件,并撰写更多步骤。

bannerAds