[Rest] reroute API response didn't filter metadata
By default the reroute API should return the new cluster state, excluding the metadata. It was however it was wrongly using an old parameter (filter_metadata) and thus failed to do so. This commits restores but wiring it to the correct `metric` parameter. We also add an enum representing the possible metrics, to avoid similar future mistakes. Closes #7520 Closes #7523
This commit is contained in:
parent
ab555e0a33
commit
4f8ddd97bf
|
@ -16,9 +16,10 @@
|
|||
"type" : "boolean",
|
||||
"description" : "Return an explanation of why the commands can or cannot be executed"
|
||||
},
|
||||
"filter_metadata": {
|
||||
"type" : "boolean",
|
||||
"description" : "Don't return cluster state metadata (default: false)"
|
||||
"metric": {
|
||||
"type": "list",
|
||||
"options": ["_all", "blocks", "metadata", "nodes", "routing_table", "master_node", "version"],
|
||||
"description": "Limit the information returned to the specified metrics. Defaults to all but metadata"
|
||||
},
|
||||
"master_timeout": {
|
||||
"type" : "time",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
"Do not return metadata by default":
|
||||
- do:
|
||||
cluster.reroute: {}
|
||||
- is_false: state.metadata
|
||||
---
|
||||
"return metadata if requested":
|
||||
- do:
|
||||
cluster.reroute:
|
||||
metric: metadata
|
||||
|
||||
- is_true: state.metadata
|
||||
- is_false: state.nodes
|
||||
|
|
@ -51,10 +51,10 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
|||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -262,20 +262,71 @@ public class ClusterState implements ToXContent {
|
|||
}
|
||||
}
|
||||
|
||||
public enum Metric {
|
||||
VERSION("version"),
|
||||
MASTER_NODE("master_node"),
|
||||
BLOCKS("blocks"),
|
||||
NODES("nodes"),
|
||||
METADATA("metadata"),
|
||||
ROUTING_TABLE("routing_table"),
|
||||
CUSTOMS("customs");
|
||||
|
||||
private static Map<String, Metric> valueToEnum;
|
||||
|
||||
static {
|
||||
valueToEnum = new HashMap<>();
|
||||
for (Metric metric : Metric.values()) {
|
||||
valueToEnum.put(metric.value, metric);
|
||||
}
|
||||
}
|
||||
|
||||
private final String value;
|
||||
|
||||
private Metric(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static EnumSet<Metric> parseString(String param, boolean ignoreUnknown) {
|
||||
String[] metrics = Strings.splitStringByCommaToArray(param);
|
||||
EnumSet<Metric> result = EnumSet.noneOf(Metric.class);
|
||||
for (String metric : metrics) {
|
||||
if ("_all".equals(metric)) {
|
||||
result = EnumSet.allOf(Metric.class);
|
||||
break;
|
||||
}
|
||||
Metric m = valueToEnum.get(metric);
|
||||
if (m == null) {
|
||||
if (!ignoreUnknown) {
|
||||
throw new ElasticsearchIllegalArgumentException("Unknown metric [" + metric + "]");
|
||||
}
|
||||
} else {
|
||||
result.add(m);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
Set<String> metrics = Strings.splitStringByCommaToSet(params.param("metric", "_all"));
|
||||
boolean isAllMetricsOnly = metrics.size() == 1 && metrics.contains("_all");
|
||||
EnumSet<Metric> metrics = Metric.parseString(params.param("metric", "_all"), true);
|
||||
|
||||
if (isAllMetricsOnly || metrics.contains("version")) {
|
||||
if (metrics.contains(Metric.VERSION)) {
|
||||
builder.field("version", version);
|
||||
}
|
||||
|
||||
if (isAllMetricsOnly || metrics.contains("master_node")) {
|
||||
if (metrics.contains(Metric.MASTER_NODE)) {
|
||||
builder.field("master_node", nodes().masterNodeId());
|
||||
}
|
||||
|
||||
if (isAllMetricsOnly || metrics.contains("blocks")) {
|
||||
if (metrics.contains(Metric.BLOCKS)) {
|
||||
builder.startObject("blocks");
|
||||
|
||||
if (!blocks().global().isEmpty()) {
|
||||
|
@ -302,7 +353,7 @@ public class ClusterState implements ToXContent {
|
|||
}
|
||||
|
||||
// nodes
|
||||
if (isAllMetricsOnly || metrics.contains("nodes")) {
|
||||
if (metrics.contains(Metric.NODES)) {
|
||||
builder.startObject("nodes");
|
||||
for (DiscoveryNode node : nodes()) {
|
||||
builder.startObject(node.id(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
@ -321,7 +372,7 @@ public class ClusterState implements ToXContent {
|
|||
}
|
||||
|
||||
// meta data
|
||||
if (isAllMetricsOnly || metrics.contains("metadata")) {
|
||||
if (metrics.contains(Metric.METADATA)) {
|
||||
builder.startObject("metadata");
|
||||
|
||||
builder.startObject("templates");
|
||||
|
@ -407,7 +458,7 @@ public class ClusterState implements ToXContent {
|
|||
}
|
||||
|
||||
// routing table
|
||||
if (isAllMetricsOnly || metrics.contains("routing_table")) {
|
||||
if (metrics.contains(Metric.ROUTING_TABLE)) {
|
||||
builder.startObject("routing_table");
|
||||
builder.startObject("indices");
|
||||
for (IndexRoutingTable indexRoutingTable : routingTable()) {
|
||||
|
@ -428,7 +479,7 @@ public class ClusterState implements ToXContent {
|
|||
}
|
||||
|
||||
// routing nodes
|
||||
if (isAllMetricsOnly || metrics.contains("routing_table")) {
|
||||
if (metrics.contains(Metric.ROUTING_TABLE)) {
|
||||
builder.startObject("routing_nodes");
|
||||
builder.startArray("unassigned");
|
||||
for (ShardRouting shardRouting : readOnlyRoutingNodes().unassigned()) {
|
||||
|
@ -448,8 +499,7 @@ public class ClusterState implements ToXContent {
|
|||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (isAllMetricsOnly || metrics.contains("customs")) {
|
||||
if (metrics.contains(Metric.CUSTOMS)) {
|
||||
for (ObjectObjectCursor<String, Custom> cursor : customs) {
|
||||
builder.startObject(cursor.key);
|
||||
lookupFactorySafe(cursor.key).toXContent(cursor.value, builder, params);
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest;
|
|||
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.Requests;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
|
@ -32,6 +34,7 @@ import org.elasticsearch.rest.*;
|
|||
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -39,6 +42,8 @@ public class RestClusterRerouteAction extends BaseRestHandler {
|
|||
|
||||
private final SettingsFilter settingsFilter;
|
||||
|
||||
private static String DEFAULT_METRICS = Strings.arrayToCommaDelimitedString(EnumSet.complementOf(EnumSet.of(ClusterState.Metric.METADATA)).toArray());
|
||||
|
||||
@Inject
|
||||
public RestClusterRerouteAction(Settings settings, RestController controller,
|
||||
SettingsFilter settingsFilter, RestClientFactory restClientFactory) {
|
||||
|
@ -63,9 +68,9 @@ public class RestClusterRerouteAction extends BaseRestHandler {
|
|||
@Override
|
||||
protected void addCustomFields(XContentBuilder builder, ClusterRerouteResponse response) throws IOException {
|
||||
builder.startObject("state");
|
||||
// by default, filter metadata
|
||||
if (request.param("filter_metadata") == null) {
|
||||
request.params().put("filter_metadata", "true");
|
||||
// by default, return everything but metadata
|
||||
if (request.param("metric") == null) {
|
||||
request.params().put("metric", DEFAULT_METRICS);
|
||||
}
|
||||
response.getState().settingsFilter(settingsFilter).toXContent(builder, request);
|
||||
builder.endObject();
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
|
|||
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.Requests;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -32,7 +33,7 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
|||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.EnumSet;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -66,13 +67,13 @@ public class RestClusterStateAction extends BaseRestHandler {
|
|||
clusterStateRequest.indices(indices);
|
||||
}
|
||||
|
||||
Set<String> metrics = Strings.splitStringByCommaToSet(request.param("metric", "_all"));
|
||||
boolean isAllMetricsOnly = metrics.size() == 1 && metrics.contains("_all");
|
||||
if (!isAllMetricsOnly) {
|
||||
clusterStateRequest.nodes(metrics.contains("nodes") || metrics.contains("master_node"));
|
||||
clusterStateRequest.routingTable(metrics.contains("routing_table"));
|
||||
clusterStateRequest.metaData(metrics.contains("metadata"));
|
||||
clusterStateRequest.blocks(metrics.contains("blocks"));
|
||||
if (request.hasParam("metric")) {
|
||||
EnumSet<ClusterState.Metric> metrics = ClusterState.Metric.parseString(request.param("metric"), true);
|
||||
// do not ask for what we do not need.
|
||||
clusterStateRequest.nodes(metrics.contains(ClusterState.Metric.NODES) || metrics.contains(ClusterState.Metric.MASTER_NODE));
|
||||
clusterStateRequest.routingTable(metrics.contains(ClusterState.Metric.ROUTING_TABLE));
|
||||
clusterStateRequest.metaData(metrics.contains(ClusterState.Metric.METADATA));
|
||||
clusterStateRequest.blocks(metrics.contains(ClusterState.Metric.BLOCKS));
|
||||
}
|
||||
|
||||
client.admin().cluster().state(clusterStateRequest, new RestBuilderListener<ClusterStateResponse>(channel) {
|
||||
|
|
Loading…
Reference in New Issue