Skip to content

Commit

Permalink
Add _cat/plugins endpoint
Browse files Browse the repository at this point in the history
If we want to have a full picture of versions running in a cluster, we need to add a `_cat/plugins` endpoint.

Response could look like:

```sh
% curl es2:9200/_cat/plugins?v
node component                        version   type url                                   desc
es1  mapper-attachments               1.7.0       j                                        Adds the attachment type allowing to parse difference attachment formats
es1  lang-javascript                  1.4.0       j                                        JavaScript plugin allowing to add javascript scripting support
es1  analysis-smartcn                 1.9.0       j                                        Smart Chinese analysis support
es1  marvel                           1.1.0      j/s http://localhost:9200/_plugins/marvel Elasticsearch Management & Monitoring
es1  kopf                             0.5.3       s  http://localhost:9200/_plugins/kopf   kopf - simple web administration tool for ElasticSearch
es2  mapper-attachments               2.0.0.RC1   j                                        Adds the attachment type allowing to parse difference attachment formats
es2  lang-javascript                  2.0.0.RC1   j                                        JavaScript plugin allowing to add javascript scripting support
es2  analysis-smartcn                 2.0.0.RC1   j                                        Smart Chinese analysis support
```

Closes elastic#4824.
  • Loading branch information
dadoonet committed Mar 14, 2014
1 parent 84b5b45 commit ab6f09b
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docs/reference/cat.asciidoc
Expand Up @@ -115,3 +115,6 @@ include::cat/recovery.asciidoc[]
include::cat/thread_pool.asciidoc[]

include::cat/shards.asciidoc[]

include::cat/plugins.asciidoc[]

20 changes: 20 additions & 0 deletions docs/reference/cat/plugins.asciidoc
@@ -0,0 +1,20 @@
[[cat-plugins]]
== Plugins

The `plugins` command provides a view per node of running plugins. This information *spans nodes*.

[source,shell]
------------------------------------------------------------------------------
% curl 'localhost:9200/_cat/plugins?v'
name component version type isolation url
Abraxas cloud-azure 2.1.0-SNAPSHOT j x
Abraxas lang-groovy 2.0.0 j x
Abraxas lang-javascript 2.0.0-SNAPSHOT j x
Abraxas marvel NA j/s x /_plugin/marvel/
Abraxas lang-python 2.0.0-SNAPSHOT j x
Abraxas inquisitor NA s /_plugin/inquisitor/
Abraxas kopf 0.5.2 s /_plugin/kopf/
Abraxas segmentspy NA s /_plugin/segmentspy/
-------------------------------------------------------------------------------

We can tell quickly how many plugins per node we have and which versions.
35 changes: 35 additions & 0 deletions rest-api-spec/api/cat.plugins.json
@@ -0,0 +1,35 @@
{
"cat.plugins": {
"documentation": "http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-plugins.html",
"methods": ["GET"],
"url": {
"path": "/_cat/plugins",
"paths": ["/_cat/plugins"],
"params": {
"local": {
"type" : "boolean",
"description" : "Return local information, do not retrieve the state from master node (default: false)"
},
"master_timeout": {
"type" : "time",
"description" : "Explicit operation timeout for connection to master node"
},
"h": {
"type": "list",
"description" : "Comma-separated list of column names to display"
},
"help": {
"type": "boolean",
"description": "Return help information",
"default": false
},
"v": {
"type": "boolean",
"description": "Verbose mode. Display column headers",
"default": false
}
}
},
"body": null
}
}
Expand Up @@ -224,6 +224,7 @@ protected void configure() {
catActionMultibinder.addBinding().to(org.elasticsearch.rest.action.cat.RestPendingClusterTasksAction.class).asEagerSingleton();
catActionMultibinder.addBinding().to(RestAliasAction.class).asEagerSingleton();
catActionMultibinder.addBinding().to(RestThreadPoolAction.class).asEagerSingleton();
catActionMultibinder.addBinding().to(RestPluginsAction.class).asEagerSingleton();
// no abstract cat action
bind(RestCatAction.class).asEagerSingleton();
}
Expand Down
132 changes: 132 additions & 0 deletions src/main/java/org/elasticsearch/rest/action/cat/RestPluginsAction.java
@@ -0,0 +1,132 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.rest.action.cat;

import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.action.admin.cluster.node.info.PluginInfo;
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.Table;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.AbstractRestResponseActionListener;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.support.RestTable;

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

public class RestPluginsAction extends AbstractCatAction {

@Inject
public RestPluginsAction(Settings settings, Client client, RestController controller) {
super(settings, client);
controller.registerHandler(GET, "/_cat/plugins", this);
}

@Override
void documentation(StringBuilder sb) {
sb.append("/_cat/plugins\n");
}

@Override
public void doRequest(final RestRequest request, final RestChannel channel) {
final ClusterStateRequest clusterStateRequest = new ClusterStateRequest();
clusterStateRequest.clear().nodes(true);
clusterStateRequest.local(request.paramAsBoolean("local", clusterStateRequest.local()));
clusterStateRequest.masterNodeTimeout(request.paramAsTime("master_timeout", clusterStateRequest.masterNodeTimeout()));

client.admin().cluster().state(clusterStateRequest, new AbstractRestResponseActionListener<ClusterStateResponse>(request, channel, logger) {
@Override
public void onResponse(final ClusterStateResponse clusterStateResponse) {
NodesInfoRequest nodesInfoRequest = new NodesInfoRequest();
nodesInfoRequest.clear().plugins(true);
client.admin().cluster().nodesInfo(nodesInfoRequest, new AbstractRestResponseActionListener<NodesInfoResponse>(request, channel, logger) {
@Override
public void onResponse(final NodesInfoResponse nodesInfoResponse) {
try {
channel.sendResponse(RestTable.buildResponse(buildTable(request, clusterStateResponse, nodesInfoResponse), request, channel));
} catch (Throwable e) {
onFailure(e);
}
}
});
}
});
}

@Override
Table getTableWithHeader(final RestRequest request) {
Table table = new Table();
table.startHeaders();
table.addCell("name", "alias:n;desc:node name");
table.addCell("component", "alias:c;desc:component");
table.addCell("version", "alias:v;desc:component version");
table.addCell("type", "alias:t;desc:type (j for JVM, s for Site)");
table.addCell("isolation", "alias:i;desc:isolation");
table.addCell("url", "alias:u;desc:url for site plugins");
table.addCell("description", "alias:d;default:false;desc:plugin details");
table.endHeaders();
return table;
}

private Table buildTable(RestRequest req, ClusterStateResponse state, NodesInfoResponse nodesInfo) {
DiscoveryNodes nodes = state.getState().nodes();
Table table = getTableWithHeader(req);

for (DiscoveryNode node : nodes) {
NodeInfo info = nodesInfo.getNodesMap().get(node.id());

for (PluginInfo pluginInfo : info.getPlugins().getInfos()) {
table.startRow();
table.addCell(node.name());
table.addCell(pluginInfo.getName());
table.addCell(pluginInfo.getVersion());
String type;
if (pluginInfo.isSite()) {
if (pluginInfo.isJvm()) {
type = "j/s";
} else {
type = "s";
}
} else {
if (pluginInfo.isJvm()) {
type = "j";
} else {
type = "";
}
}
table.addCell(type);
table.addCell(pluginInfo.isIsolation() ? "x" : "");
table.addCell(pluginInfo.getUrl());
table.addCell(pluginInfo.getDescription());
table.endRow();
}
}

return table;
}
}

0 comments on commit ab6f09b

Please sign in to comment.