From 8fe54b0658c443a580e377b4ddb03092f8e90a5e Mon Sep 17 00:00:00 2001 From: Chris Earle Date: Tue, 24 Apr 2018 10:56:09 -0400 Subject: [PATCH 1/4] _cluster/state should always return cluster_uuid Currently, the only way to get the REST response for the `/_cluster/state` call to return the `cluster_uuid` is to request the `metadata` metrics, which is one of the most expensive response structures. However, external monitoring agents will likely want the `cluster_uuid` to correlate the response with other API responses whether or not they want cluster metadata. --- docs/reference/cluster/state.asciidoc | 6 ++++++ .../rest-api-spec/test/cluster.state/10_basic.yml | 4 +++- .../rest-api-spec/test/cluster.state/20_filtering.yml | 9 +++++++++ .../test/cluster.state/30_expand_wildcards.yml | 5 +++++ .../java/org/elasticsearch/cluster/ClusterState.java | 3 +++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/reference/cluster/state.asciidoc b/docs/reference/cluster/state.asciidoc index d0ff3290c74d3..a20ff04d83f4a 100644 --- a/docs/reference/cluster/state.asciidoc +++ b/docs/reference/cluster/state.asciidoc @@ -15,6 +15,12 @@ of the cluster state (its size when serialized for transmission over the network), and the cluster state itself, which can be filtered to only retrieve the parts of interest, as described below. +The cluster's `cluster_uuid` is also returned as part of the top-level +response, in addition to the `metadata` section. added[6.4.0] + +NOTE: While the cluster is still forming, it is possible for the `cluster_uuid` + to be `_na_` as well as the cluster state's version to be `-1`. + By default, the cluster state request is routed to the master node, to ensure that the latest cluster state is returned. For debugging purposes, you can retrieve the cluster state local to a diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml index e3af21412ca7b..1fa70025f8df5 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml @@ -2,7 +2,8 @@ "get cluster state": - do: cluster.state: {} - + + - is_true: cluster_uuid - is_true: master_node --- @@ -15,6 +16,7 @@ cluster.state: human: true + - is_true: cluster_uuid - is_true: master_node - gte: { compressed_size_in_bytes: 50 } - is_true: compressed_size diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml index 1e1d57125601c..1a76e6025fd9f 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml @@ -13,6 +13,7 @@ setup: cluster.state: metric: [ blocks ] + - is_true: cluster_uuid - is_true: blocks - is_false: nodes - is_false: metadata @@ -31,6 +32,7 @@ setup: cluster.state: metric: [ blocks ] + - is_true: cluster_uuid - is_true: blocks - is_false: nodes - is_false: metadata @@ -50,6 +52,7 @@ setup: cluster.state: metric: [ nodes ] + - is_true: cluster_uuid - is_false: blocks - is_true: nodes - is_false: metadata @@ -62,6 +65,7 @@ setup: cluster.state: metric: [ metadata ] + - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_true: metadata @@ -75,6 +79,7 @@ setup: cluster.state: metric: [ routing_table ] + - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_false: metadata @@ -87,6 +92,7 @@ setup: cluster.state: metric: [ routing_nodes ] + - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_false: metadata @@ -108,6 +114,7 @@ setup: metric: [ routing_table, metadata ] index: [ testidx ] + - is_true: cluster_uuid - is_false: metadata.indices.another - is_false: routing_table.indices.another - is_true: metadata.indices.testidx @@ -120,6 +127,7 @@ setup: metric: [ '_all' ] index: [ '_all' ] + - is_true: cluster_uuid - is_true: blocks - is_true: nodes - is_true: metadata @@ -152,6 +160,7 @@ setup: - is_false: metadata.indices.testidx - is_false: routing_table.indices.testidx + - is_true: cluster_uuid - is_true: metadata.indices.index1 - is_true: routing_table.indices.index1 - is_true: metadata.indices.index2 diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml index 414620d13586d..d1342604e7df9 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml @@ -35,6 +35,7 @@ setup: index: test* expand_wildcards: [ closed ] + - is_true: cluster_uuid - is_false: metadata.indices.test_open_index - match: {metadata.indices.test_close_index.state: "close"} @@ -44,6 +45,7 @@ setup: index: test* expand_wildcards: [ open ] + - is_true: cluster_uuid - match: {metadata.indices.test_open_index.state: "open"} - is_false: metadata.indices.test_close_index @@ -53,6 +55,7 @@ setup: index: test* expand_wildcards: [ open,closed ] + - is_true: cluster_uuid - match: {metadata.indices.test_open_index.state: "open"} - match: {metadata.indices.test_close_index.state: "close"} @@ -65,6 +68,7 @@ setup: index: foobla ignore_unavailable: true + - is_true: cluster_uuid - match: {metadata.indices: {}} - do: @@ -82,6 +86,7 @@ setup: metric: [ metadata ] index: not_there* + - is_true: cluster_uuid - match: {metadata.indices: {}} - do: diff --git a/server/src/main/java/org/elasticsearch/cluster/ClusterState.java b/server/src/main/java/org/elasticsearch/cluster/ClusterState.java index 30c8df07ec1a5..2b991d1dc611a 100644 --- a/server/src/main/java/org/elasticsearch/cluster/ClusterState.java +++ b/server/src/main/java/org/elasticsearch/cluster/ClusterState.java @@ -326,6 +326,9 @@ public String toString() { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { EnumSet metrics = Metric.parseString(params.param("metric", "_all"), true); + // always provide the cluster_uuid as part of the top-level response (also part of the metadata response) + builder.field("cluster_uuid", metaData().clusterUUID()); + if (metrics.contains(Metric.VERSION)) { builder.field("version", version); builder.field("state_uuid", stateUUID); From 13c46a839bd629ffc9181c80a2e1de3dd368d78a Mon Sep 17 00:00:00 2001 From: Chris Earle Date: Wed, 25 Apr 2018 16:57:05 -0400 Subject: [PATCH 2/4] skip cluster_uuid check for earlier versions until it is backported --- .../test/cluster.state/10_basic.yml | 17 +++++++++++-- .../test/cluster.state/20_filtering.yml | 25 ++++++++++++------- .../cluster.state/30_expand_wildcards.yml | 5 ---- .../reroute/ClusterRerouteResponseTests.java | 3 +++ 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml index 1fa70025f8df5..93024bbeee6c3 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml @@ -3,7 +3,6 @@ - do: cluster.state: {} - - is_true: cluster_uuid - is_true: master_node --- @@ -16,7 +15,21 @@ cluster.state: human: true - - is_true: cluster_uuid - is_true: master_node - gte: { compressed_size_in_bytes: 50 } - is_true: compressed_size + +--- +"get cluster state returns cluster_uuid at the top level": + - skip: + version: " - 6.99.99" + reason: "cluster state including cluster_uuid at the top level is new in v6.4.0 and higher" + + - do: + cluster.state: + human: true + + - is_true: cluster_uuid + - is_true: master_node + - gte: { compressed_size_in_bytes: 50 } + - is_true: compressed_size \ No newline at end of file diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml index 1a76e6025fd9f..f9e5a0c03df5d 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/20_filtering.yml @@ -13,7 +13,6 @@ setup: cluster.state: metric: [ blocks ] - - is_true: cluster_uuid - is_true: blocks - is_false: nodes - is_false: metadata @@ -32,7 +31,6 @@ setup: cluster.state: metric: [ blocks ] - - is_true: cluster_uuid - is_true: blocks - is_false: nodes - is_false: metadata @@ -52,7 +50,6 @@ setup: cluster.state: metric: [ nodes ] - - is_true: cluster_uuid - is_false: blocks - is_true: nodes - is_false: metadata @@ -65,7 +62,6 @@ setup: cluster.state: metric: [ metadata ] - - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_true: metadata @@ -79,7 +75,6 @@ setup: cluster.state: metric: [ routing_table ] - - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_false: metadata @@ -92,7 +87,6 @@ setup: cluster.state: metric: [ routing_nodes ] - - is_true: cluster_uuid - is_false: blocks - is_false: nodes - is_false: metadata @@ -114,7 +108,6 @@ setup: metric: [ routing_table, metadata ] index: [ testidx ] - - is_true: cluster_uuid - is_false: metadata.indices.another - is_false: routing_table.indices.another - is_true: metadata.indices.testidx @@ -127,7 +120,6 @@ setup: metric: [ '_all' ] index: [ '_all' ] - - is_true: cluster_uuid - is_true: blocks - is_true: nodes - is_true: metadata @@ -160,8 +152,23 @@ setup: - is_false: metadata.indices.testidx - is_false: routing_table.indices.testidx - - is_true: cluster_uuid - is_true: metadata.indices.index1 - is_true: routing_table.indices.index1 - is_true: metadata.indices.index2 - is_true: routing_table.indices.index2 + +--- +"Filtering the cluster state returns cluster_uuid at the top level regardless of metric filters": + - skip: + version: " - 6.99.99" + reason: "cluster state including cluster_uuid at the top level is new in v6.4.0 and higher" + + - do: + cluster.state: + metric: [ master_node, version, metadata ] + + - is_true: cluster_uuid + - is_true: master_node + - is_true: version + - is_true: state_uuid + - is_true: metadata diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml index d1342604e7df9..414620d13586d 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/30_expand_wildcards.yml @@ -35,7 +35,6 @@ setup: index: test* expand_wildcards: [ closed ] - - is_true: cluster_uuid - is_false: metadata.indices.test_open_index - match: {metadata.indices.test_close_index.state: "close"} @@ -45,7 +44,6 @@ setup: index: test* expand_wildcards: [ open ] - - is_true: cluster_uuid - match: {metadata.indices.test_open_index.state: "open"} - is_false: metadata.indices.test_close_index @@ -55,7 +53,6 @@ setup: index: test* expand_wildcards: [ open,closed ] - - is_true: cluster_uuid - match: {metadata.indices.test_open_index.state: "open"} - match: {metadata.indices.test_close_index.state: "close"} @@ -68,7 +65,6 @@ setup: index: foobla ignore_unavailable: true - - is_true: cluster_uuid - match: {metadata.indices: {}} - do: @@ -86,7 +82,6 @@ setup: metric: [ metadata ] index: not_there* - - is_true: cluster_uuid - match: {metadata.indices: {}} - do: diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java index 4ced505717a2e..7d671096514f4 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java @@ -69,6 +69,7 @@ public void testToXContent() throws IOException { assertEquals("{\n" + " \"acknowledged\" : true,\n" + " \"state\" : {\n" + + " \"cluster_uuid\" : \"_na_\",\n" + " \"version\" : 0,\n" + " \"state_uuid\" : \"" + clusterState.stateUUID() + "\",\n" + " \"master_node\" : \"node0\",\n" + @@ -136,6 +137,7 @@ public void testToXContent() throws IOException { assertEquals("{\n" + " \"acknowledged\" : true,\n" + " \"state\" : {\n" + + " \"cluster_uuid\" : \"_na_\",\n" + " \"version\" : 0,\n" + " \"state_uuid\" : \"" + clusterState.stateUUID() + "\",\n" + " \"master_node\" : \"node0\"\n" + @@ -168,6 +170,7 @@ public void testToXContent() throws IOException { assertEquals("{\n" + " \"acknowledged\" : true,\n" + " \"state\" : {\n" + + " \"cluster_uuid\" : \"_na_\",\n" + " \"metadata\" : {\n" + " \"cluster_uuid\" : \"_na_\",\n" + " \"templates\" : { },\n" + From 64f49f55f5ac3c3c087bc115b05a915032931f55 Mon Sep 17 00:00:00 2001 From: Chris Earle Date: Wed, 25 Apr 2018 16:57:52 -0400 Subject: [PATCH 3/4] add missing newline to the end of the 10_basic.yml --- .../resources/rest-api-spec/test/cluster.state/10_basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml index 93024bbeee6c3..c38a33fdff198 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.state/10_basic.yml @@ -32,4 +32,4 @@ - is_true: cluster_uuid - is_true: master_node - gte: { compressed_size_in_bytes: 50 } - - is_true: compressed_size \ No newline at end of file + - is_true: compressed_size From fb669f37fbeccaaf606d198deded830ba608af2c Mon Sep 17 00:00:00 2001 From: Chris Earle Date: Thu, 26 Apr 2018 12:33:09 -0400 Subject: [PATCH 4/4] now that the repos are combined, they can be fixed together! --- .../collector/cluster/ClusterStatsMonitoringDocTests.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java index 4a096f0ca4a46..098f4190b0e88 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java @@ -17,6 +17,7 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.health.ClusterHealthStatus; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.routing.ShardRouting; @@ -188,6 +189,7 @@ public void testNodesHash() { @Override public void testToXContent() throws IOException { + final String clusterUuid = "_cluster"; final ClusterName clusterName = new ClusterName("_cluster_name"); final TransportAddress transportAddress = new TransportAddress(TransportAddress.META_ADDRESS, 9300); final DiscoveryNode discoveryNode = new DiscoveryNode("_node_name", @@ -201,6 +203,7 @@ public void testToXContent() throws IOException { Version.V_6_0_0_beta1); final ClusterState clusterState = ClusterState.builder(clusterName) + .metaData(MetaData.builder().clusterUUID(clusterUuid).build()) .stateUUID("_state_uuid") .version(12L) .nodes(DiscoveryNodes.builder() @@ -500,6 +503,7 @@ public void testToXContent() throws IOException { + "\"cluster_state\":{" + "\"nodes_hash\":1314980060," + "\"status\":\"green\"," + + "\"cluster_uuid\":\"_cluster\"," + "\"version\":12," + "\"state_uuid\":\"_state_uuid\"," + "\"master_node\":\"_node\","