2019년 3월 30일 토요일

Elasticsearch 플러그인(Plugin) 만들기

❝Elasticsearch 플러그인❞을 만들기 위해서 여러가지 찾아보고 내용을 정리해본다.

* Elasticsearch 7.x로 업데이트 되면서 BaseRestHandler 인터페이스를 상속받아서 구현하는 방법이 바뀌어서 내용을 업데이트 합니다.

환경


  • open jdk 11
  • maven
  • elasticsearch 7.15.1


참고

여기의 코드를 참고함.


구현


우선 plugin으로 호출되는 클래스 부터 구현한다.
package org.elasticsearch.plugin.example;

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;

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 Arrays.asList(
new ExampleNocodeAction(settings, restController));
}
}

이 plugin으로 호출되는 클래스는
src / main / resources / plugin-descriptor.properties 에 정의한다.
version=${project.version}
description=${project.description}
name=example-plugin
classname=org.elasticsearch.plugin.example.ExamplePlugin
java.version=11
elasticsearch.version=${elasticsearch.version}


그리고, 위 ExamplePlugin에서 실제로 호출되고 처리를하는 클래스는 ExampleNocodeAction 클래스이다.

package org.elasticsearch.plugin.example;

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

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;

/**
* Example action with a plugin.
*/
public class ExampleNocodeAction extends BaseRestHandler {

public ExampleNocodeAction(final Settings settings,
final RestController controller) {
// nothing
}

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

@Override
public List<Route> routes() {
return Collections.unmodifiableList(Arrays.asList(
new Route(GET, "/{index}/_nocode"),
new Route(GET, "/_nocode")));
}


@Override
protected RestChannelConsumer prepareRequest(final RestRequest request,
final NodeClient client) throws IOException {
final boolean isPretty = request.hasParam("pretty");
final String index = request.param("index");
return channel -> {
final XContentBuilder builder = JsonXContent.contentBuilder();
if (isPretty) {
builder.prettyPrint().lfAtEnd();
}
builder.startObject();
if (index != null) {
builder.field("index", index);
}
builder.field("description",
"This is a example response: " + new Date().toString());
builder.endObject();
channel.sendResponse(new BytesRestResponse(OK, builder));
};
}


}

구현은 여기까지 하면 완성이다.
이제 mvn install을 실행하여 elasticsearch-example-plugin-7.15.1.zip 플러그인 파일을 생성하자.

마지막으로 Elasticsearch에 elasticsearch-example-plugin-7.15.1.zip plugin을 install 해본다.
./bin/elasticsearch-plugin install file:///elasticsearch/elasticsearch-example-plugin-7.15.1.zip

그리고, 이제 Elasticsearch을 시작한다.
시작 로그에서 다음과 같이
"loaded plugin :[example-plugin]"가 표시되면 성공적으로 install이 된 것이다.

[2021-10-15T08:16:36,445][INFO ][o.e.p.PluginsService ] [local] loaded module [x-pack-watcher] [2021-10-15T08:16:36,445][INFO ][o.e.p.PluginsService ] [local] loaded plugin [example-plugin] [2021-10-15T08:16:36,482][INFO ][o.e.e.NodeEnvironment ] [local] using [1] data paths, mounts [[/ (/dev/disk1s1)]], net usable_space [35gb], net total_space [233.4gb], types [apfs] [2021-10-15T08:16:36,482][INFO ][o.e.e.NodeEnvironment ] [local] heap size [989.8mb], compressed ordinary object pointers [true] [2021-10-15T08:16:36,555][INFO ][o.e.n.Node ] [local] node name [local], node ID [6pG_WeHkSEKR3FLLjResXg], cluster name [elasticsearch], roles [transform, data_frozen, master, remote_cluster_client, data, ml, data_content, data_hot, data_warm, data_cold, ingest] [2021-10-15T08:16:40,472][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [local] [controller/67091] [Main.cc@122] controller (64 bit): Version 7.15.1 (Build 96c59930f1bbe9) Copyright (c) 2021 Elasticsearch BV




테스트로 플러그인 API를 호출해 본다.
http://localhost:9200/_nocode




댓글 없음:

댓글 쓰기