创建 Elasticsearch 插件 (2)
创作Elasticsearch插件的第二弹。
上一次基于cat插件仅仅展示了简单的字符串,而这一次我们将增加一些功能,以展示Elasticsearch内部的信息。
代码在这里。
现在我会用中国母语给您简单解释一下
环境
与上次没有变化
-
- Java8
-
- Maven3
- Elasticsearch6.5.4
实施
无论插件如何,被首先调用的类都是不变的。
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的信息,并显示所安装的插件的信息。