Posted at

Elasticsearchのプラグインを作成する(2)

Elasticsearchのプラグインを作成する第2弾。

前回はcatプラグインをベースに単純に文字列を表示するものでしたが、今回はもう少しやる事を増やして、Elasticsearchの内部の情報を表示させるようにしようと思います。

コードはこちらになります。

では簡単に説明を


環境

前回と変わらずで


  • Java8

  • Maven3

  • Elasticsearch6.5.4


実装

pluginで最初に呼ばれるクラスは変わりありません。


ExamplePlugin.java

  1 package org.elasticsearch.plugin.example;

2
3 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
4 import org.elasticsearch.cluster.node.DiscoveryNodes;
5 import org.elasticsearch.common.settings.ClusterSettings;
6 import org.elasticsearch.common.settings.IndexScopedSettings;
7 import org.elasticsearch.common.settings.Settings;
8 import org.elasticsearch.common.settings.SettingsFilter;
9 import org.elasticsearch.plugins.ActionPlugin;
10 import org.elasticsearch.plugins.Plugin;
11 import org.elasticsearch.rest.RestController;
12 import org.elasticsearch.rest.RestHandler;
13
14 import java.util.List;
15 import java.util.function.Supplier;
16
17 import static java.util.Collections.singletonList;
18
19 public class ExamplePlugin extends Plugin implements ActionPlugin {
20 @Override
21 public List<RestHandler> getRestHandlers(final Settings settings,
22 final RestController restController,
23 final ClusterSettings clusterSettings,
24 final IndexScopedSettings indexScopedSettings,
25 final SettingsFilter settingsFilter,
26 final IndexNameExpressionResolver indexNameExpressionResolver,
27 final Supplier<DiscoveryNodes> nodesInCluster) {
28
29 return singletonList(new ExampleDogAction(settings, restController));
30 }
31 }

実際に処理を行なっているのはこのExampleDogActionクラスです。

  1 package org.elasticsearch.plugin.example;

2
3 import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
4 import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
5 import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
6 import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
7 import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
8 import org.elasticsearch.client.node.NodeClient;
9 import org.elasticsearch.cluster.node.DiscoveryNode;
10 import org.elasticsearch.cluster.node.DiscoveryNodes;
11 import org.elasticsearch.client.node.NodeClient;
12 import org.elasticsearch.common.inject.Inject;
13 import org.elasticsearch.common.Table;
14 import org.elasticsearch.common.settings.Settings;
15 import org.elasticsearch.plugins.PluginInfo;
16 import org.elasticsearch.http.HttpInfo;
17 import org.elasticsearch.monitor.os.OsInfo;
18 import org.elasticsearch.rest.BaseRestHandler;
19 import org.elasticsearch.rest.BytesRestResponse;
20 import org.elasticsearch.rest.RestController;
21 import org.elasticsearch.rest.RestRequest;
22 import org.elasticsearch.rest.RestStatus;
23 import org.elasticsearch.rest.RestResponse;
24 import org.elasticsearch.rest.action.RestActionListener;
25 import org.elasticsearch.rest.action.RestResponseListener;
26 import org.elasticsearch.rest.action.cat.RestTable;
27
28 import static org.elasticsearch.rest.RestRequest.Method.GET;
29 import static org.elasticsearch.rest.RestRequest.Method.POST;
30
31 import java.io.IOException;
32 import java.util.List;
33
34 /**
35 * Example of adding a cat action with a plugin.
36 */
37 public class ExampleDogAction extends BaseRestHandler {
38 @Inject
39 ExampleDogAction(final Settings settings, final RestController controller) {
40 super(settings);
41 controller.registerHandler(GET, "/_dog", this);
42 }
43
44 @Override
45 public String getName() {
46 return "rest_handler_dog_example";
47 }
48
49 @Override
50 public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
51 // Clusterの情報を引っ張り出す
52 final ClusterStateRequest clusterStateRequest = new ClusterStateRequest();
53 clusterStateRequest.clear().nodes(true);
54 clusterStateRequest.local(request.paramAsBoolean("local", clusterStateRequest.local()));
55 clusterStateRequest.masterNodeTimeout(request.paramAsTime("master_timeout", clusterStateRequest.masterNodeTimeout()));
56
57 return channel -> client.admin().cluster().state(clusterStateRequest, new RestActionListener<ClusterStateResponse>(channel) {
58 @Override
59 public void processResponse(final ClusterStateResponse clusterStateResponse) throws Exception {
60 NodesInfoRequest nodesInfoRequest = new NodesInfoRequest();
61 nodesInfoRequest.clear().plugins(true);
62 client.admin().cluster().nodesInfo(nodesInfoRequest, new RestResponseListener<NodesInfoResponse>(channel) {
63 @Override
64 public RestResponse buildResponse(final NodesInfoResponse nodesInfoResponse) throws Exception {
65 return RestTable.buildResponse(buildTable(request, clusterStateResponse, nodesInfoResponse), channel);
66 }
67 });
68 }
69 });
70 }
71
72 protected Table getTableWithHeader(final RestRequest request) {
73 Table table = new Table();
74 table.startHeaders();
75 table.addCell("id", "default:false;desc:unique node id");
76 table.addCell("name", "alias:n;desc:node name");
77 table.addCell("hostName", "alias:n;desc:node host name");
78 table.addCell("component", "alias:c;desc:component");
79 table.addCell("version", "alias:v;desc:component version");
80 table.addCell("description", "alias:d;default:false;desc:plugin details");
81 table.endHeaders();
82 return table;
83 }
84
85
86 private Table buildTable(RestRequest req, ClusterStateResponse state, NodesInfoResponse nodesInfo) {
87 DiscoveryNodes nodes = state.getState().nodes();
88 Table table = getTableWithHeader(req);
89
90 for (DiscoveryNode node : nodes) {
91 NodeInfo info = nodesInfo.getNodesMap().get(node.getId());
92
93 for (PluginInfo pluginInfo : info.getPlugins().getPluginInfos()) {
94 table.startRow();
95 table.addCell(node.getId());
96 table.addCell(node.getName());
97 table.addCell(node.getHostName());
98 table.addCell(pluginInfo.getName());
99 table.addCell(pluginInfo.getVersion());
100 table.addCell(pluginInfo.getDescription());
101 table.endRow();
102 }
103 }
104
105 return table;
106 }
107 }

86行目あたりをみてください。このbuildTableメソッドの中でNodeの情報を取得し、インストールされているpluginの情報も表示するように書いてます。