创建Elasticsearch插件 编辑连载文章(1) 你好世界
在本系列中,我們將解釋Elasticsearch插件的基本寫法。第一部分我們將創建一個顯示”Hello World”的REST API。我們已經將創建的源碼放在github上。
追求完美
创建一个Elasticsearch插件,当访问指定的URL时,会显示“Hello World”。
实施摘要
为了创建Elasticsearch的插件,我们使用Gradle插件。这个插件包含在Elasticsearch的OSS中,但几乎没有文档和说明,而且在主要版本更新中可能会改变其功能规格。因此,在使用时必须考虑到这些风险。
7系的Gradle插件似乎将Elasticsearch模块的下载源设置为内部URL。因此,在gradle插件中,无法成功启动测试用的Elasticsearch。在本教程中,我们将单独下载Elasticsearch,并手动进行插件安装和Elasticsearch的启动。
行动环境
-
- Elasticsearch 7.4.2
-
- Gradle 6.0-rc2
-
- OracleJDK 13(OpenJDKでも問題ない)
- Windows(コマンドの実行例のみ。プラグインの作成、実行はElasticsearchの実行環境に準じます)
Elasticsearch 7.4.2的Gradle插件需要Java 12或更高版本。若要在Java 13上运行,需要Gradle 6.0以上版本。因此,目前制作Elasticsearch 7.4的插件需要使用此组合。
文章中的写法
- [~]は環境に応じた変数です。ご自分の環境に合わせて読みかえて下さい。
事前准备
-
- Elasticsearchのインストール OSS版 [ELASTICSEARCH_DIR]に展開
-
- Gradleのインストール RC版 [GRADLE_DIR]に展開
- JDKのインストール OracleJDK [JAVA_DIR]に配置
项目的准备
该项目将放置在[PROJECT_DIR]中。
项目的构成如下所示。
-
- src/main/java jarにバンドルされるclassの元になるjavaソースを配置します。
-
- src/main/resources jarにバンドルされる各種リソースを配置します。
-
- src/main/plugin-metadata セキュリティポリシー等のEclipseプラグインの固有設定を配置します。
-
- src/test/java テスト用のjavaソースを配置します。
-
- src/test/resources テスト用の各種リソースを配置します。
-
- settings.gradle プロジェクトの構成を設定するために必要なファイルです。
- build.gradle プロジェクトをビルドする際のタスク等の設定をするために必要なファイルです。
创建settings.gradle文件。
由于此次是单一项目结构,因此只需指定项目名称。项目名称可以作为JAR文件的前缀,也可以作为导入Eclipse等开发环境时的项目名称。
rootProject.name = 'elasticsearch-sample-plugins'
创建一个build.gradle文件。
进行针对JVM的操作环境版本(targetVersion)和创建Elasticsearch插件所需的特定配置。
buildscript {
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
// Elasticsearchはmavenのセントラルレポジトリにビルドツールを公開している。
// https://mvnrepository.com/artifact/org.elasticsearch.gradle/build-tools
classpath group: 'org.elasticsearch.gradle', name: 'build-tools', version: '7.4.2'
}
}
plugins {
id 'java'
// 依存関係の解決にmavenが必要
id 'maven'
// 開発環境としてEclipseを使用する場合には必要
id 'eclipse'
}
// プラグインをビルドするためのGradleプラグインの名前
apply plugin: 'elasticsearch.esplugin'
sourceCompatibility = 1.8
// ElasticsearchのruntimeがJDK1.8でも動作するようにしておく。
targetCompatibility = 1.8
group = 'taka8.elasticsearch.plugins'
version = '0.0.1'
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'
eclipse {
classpath {
containers.clear()
downloadSources = true
downloadJavadoc = true
}
}
ext {
// 以下の二つを設定しないとプラグインのビルドがエラーになる
licenseFile = project.file('LICENSE')
noticeFile = project.file('NOTICE')
}
esplugin {
// プラグイン名
name project.name
// プラグインの説明
description 'Elasticsearch sample plugin'
// プラグインの入口になるクラス
classname 'taka8.elasticsearch.plugins.SamplePlugin'
}
准备插件源代码的步骤
创建一个成为插件入口的类。
将在”src/main/java”文件夹下创建一个类,该类的名称(FQCN)已在build.gradle文件的esplugin.classname进行了配置。
package taka8.elasticsearch.plugins;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
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 taka8.elasticsearch.rest.HelloWorldAction;
// REST API用のプラグインを作成する際には、ActionPluginを実装する必要がある。
public class SamplePlugin extends Plugin implements ActionPlugin {
// このプラグインで定義するRestHandlerのリストを返す
@Override
public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
return Arrays.asList(//
// 独自定義のクラス(Hello World文字列を返却する
new HelloWorldAction(restController));
}
}
创建RestHandler。
package taka8.elasticsearch.rest;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.HEAD;
import java.io.IOException;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
// REST APIを受け付けるRestHandlerはBaseRestHandlerを継承すると作りやすい
public class HelloWorldAction extends BaseRestHandler {
public HelloWorldAction(final RestController controller) {
assert controller != null;
// 要求を受け付けるパスを定義する。
controller.registerHandler(GET, "/hello", this);
controller.registerHandler(HEAD, "/hello", this);
}
// RestHandlerの名前を定義する。
// 人が見て分かりやすい名前にする。
// 使用方法を返すAPIで使用される
@Override
public String getName() {
return "hello_word_action";
}
@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
return channel -> {
RestResponse response = new BytesRestResponse(RestStatus.OK, "Hello World");
// チャンネルに応答を書き込む
channel.sendResponse(response);
};
}
}
确认动作
设置环境变量
>set JAVA_HOME=[JAVA_DIR]
>set PATH=[GRADLE_DIR]\bin;%PATH%
建筑
>gradle install
安装插件
>cd [ELASTICSEARCH_DIR]
>.\bin\elasticsearch-plugin install file:/[PROJECT_DIR]/build/distributions/elasticsearch-sample-plugins-0.0.1.zip
把PROJECT_DIR以URL格式表示
启动Elasticsearch
>cd [ELASTICSEARCH_DIR]
>.\bin\elasticsearch
确认图像
请使用浏览器访问http://localhost:9200/hello,并确保显示“Hello World”。
作者のコメント
我使用用于创建Gradle插件的Gradle插件,轻松地创建了Elasticsearch插件。尽管在实际开发中几乎没有意义,但实际上Elasticsearch的API访问部分确实与插件非常相似,可以创建非常强大的插件。下次我们将介绍更高级的插件制作方法。