diff --git a/docs/changelog/109240.yaml b/docs/changelog/109240.yaml new file mode 100644 index 0000000000000..a9fad3abdc47f --- /dev/null +++ b/docs/changelog/109240.yaml @@ -0,0 +1,5 @@ +pr: 109240 +summary: Fix trappy timeout in allocation explain API +area: Allocation +type: bug +issues: [] diff --git a/docs/changelog/109241.yaml b/docs/changelog/109241.yaml new file mode 100644 index 0000000000000..b7343b9df1841 --- /dev/null +++ b/docs/changelog/109241.yaml @@ -0,0 +1,5 @@ +pr: 109241 +summary: Fix misc trappy allocation API timeouts +area: Allocation +type: bug +issues: [] diff --git a/docs/reference/data-streams/tsds-index-settings.asciidoc b/docs/reference/data-streams/tsds-index-settings.asciidoc index 6dd902ff1c3b0..3ecfc60c90f58 100644 --- a/docs/reference/data-streams/tsds-index-settings.asciidoc +++ b/docs/reference/data-streams/tsds-index-settings.asciidoc @@ -60,5 +60,5 @@ information, refer to <>. `index.mapping.dimension_fields.limit`:: (<>, integer) Maximum number of <> for the -index. Defaults to `21`. +index. Defaults to `32768`. // end::dimensions-limit[] diff --git a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/200_rollover_failure_store.yml b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/200_rollover_failure_store.yml index 11889a3153a98..8cdfe3d97bbb8 100644 --- a/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/200_rollover_failure_store.yml +++ b/modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/200_rollover_failure_store.yml @@ -218,7 +218,7 @@ teardown: - do: allowed_warnings: - - "index template [generic_logs_template] has index patterns [logs-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [generic_logs_template] will take precedence during new index creation" + - "index template [my-template] has index patterns [data-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-template] will take precedence during new index creation" indices.put_index_template: name: my-template body: diff --git a/muted-tests.yml b/muted-tests.yml index 303e0196782ad..40907992f58a3 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -35,10 +35,6 @@ tests: - class: "org.elasticsearch.upgrades.MlTrainedModelsUpgradeIT" issue: "https://github.com/elastic/elasticsearch/issues/108993" method: "testTrainedModelInference" -- class: "org.elasticsearch.datastreams.DataStreamsClientYamlTestSuiteIT" - issue: "https://github.com/elastic/elasticsearch/issues/109154" - method: "test {p0=data_stream/200_rollover_failure_store/Lazily roll over a data\ - \ stream's failure store after an ingest failure}" - class: "org.elasticsearch.xpack.security.CoreWithSecurityClientYamlTestSuiteIT" issue: "https://github.com/elastic/elasticsearch/issues/109188" method: "test {yaml=search/180_locale_dependent_mapping/Test Index and Search locale\ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.delete_desired_balance.json b/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.delete_desired_balance.json index d95efed82052b..b5c4eaa7fc6f9 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.delete_desired_balance.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.delete_desired_balance.json @@ -18,6 +18,12 @@ ] } ] + }, + "params": { + "master_timeout":{ + "type":"time", + "description":"Timeout for connection to master node" + } } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.get_desired_balance.json b/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.get_desired_balance.json index aa6285b1f9d1d..5922d77d99dc0 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.get_desired_balance.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/_internal.get_desired_balance.json @@ -18,6 +18,12 @@ ] } ] + }, + "params": { + "master_timeout":{ + "type":"time", + "description":"Timeout for connection to master node" + } } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.allocation_explain.json b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.allocation_explain.json index e828af8a569ed..a3922033ec2a8 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.allocation_explain.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.allocation_explain.json @@ -22,6 +22,10 @@ ] }, "params":{ + "master_timeout":{ + "type":"time", + "description":"Timeout for connection to master node" + }, "include_yes_decisions":{ "type":"boolean", "description":"Return 'YES' decisions in explanation (default: false)" diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java index 1c358fe06b68f..26b33acfcbe98 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java @@ -158,12 +158,7 @@ public void testUnassignedReplicaDelayedAllocation() throws Exception { // wait till we have passed any pending shard data fetching assertEquals( AllocationDecision.ALLOCATION_DELAYED, - clusterAdmin().prepareAllocationExplain() - .setIndex("idx") - .setShard(0) - .setPrimary(false) - .get() - .getExplanation() + ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), "idx", 0, false) .getShardAllocationDecision() .getAllocateDecision() .getAllocationDecision() @@ -1076,12 +1071,12 @@ public void testCannotAllocateStaleReplicaExplanation() throws Exception { // wait until the system has fetched shard data and we know there is no valid shard copy assertBusy(() -> { - ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex("idx") - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); + ClusterAllocationExplanation explanation = ClusterAllocationExplanationUtils.getClusterAllocationExplanation( + client(), + "idx", + 0, + true + ); assertTrue(explanation.getShardAllocationDecision().getAllocateDecision().isDecisionTaken()); assertEquals( AllocationDecision.NO_VALID_SHARD_COPY, @@ -1223,19 +1218,11 @@ private ClusterAllocationExplanation runExplain(boolean primary, boolean include return runExplain(primary, null, includeYesDecisions, includeDiskInfo); } - private ClusterAllocationExplanation runExplain(boolean primary, String nodeId, boolean includeYesDecisions, boolean includeDiskInfo) - throws Exception { - - ClusterAllocationExplanation explanation = admin().cluster() - .prepareAllocationExplain() - .setIndex("idx") - .setShard(0) - .setPrimary(primary) - .setIncludeYesDecisions(includeYesDecisions) - .setIncludeDiskInfo(includeDiskInfo) - .setCurrentNode(nodeId) - .get() - .getExplanation(); + private ClusterAllocationExplanation runExplain(boolean primary, String nodeId, boolean includeYesDecisions, boolean includeDiskInfo) { + final var request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT, "idx", 0, primary, nodeId); + request.includeYesDecisions(includeYesDecisions); + request.includeDiskInfo(includeDiskInfo); + final var explanation = safeGet(client().execute(TransportClusterAllocationExplainAction.TYPE, request)).getExplanation(); if (logger.isDebugEnabled()) { logger.debug("--> explain json output: \n{}", Strings.toString(explanation, true, true)); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionIT.java index a4cf7843beb41..d0e0543bcca03 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionIT.java @@ -40,8 +40,9 @@ public void testDesiredBalanceOnMultiNodeCluster() throws Exception { var clusterHealthResponse = clusterAdmin().health(new ClusterHealthRequest().waitForStatus(ClusterHealthStatus.GREEN)).get(); assertEquals(RestStatus.OK, clusterHealthResponse.status()); - DesiredBalanceResponse desiredBalanceResponse = client().execute(TransportGetDesiredBalanceAction.TYPE, new DesiredBalanceRequest()) - .get(); + final var desiredBalanceResponse = safeGet( + client().execute(TransportGetDesiredBalanceAction.TYPE, new DesiredBalanceRequest(TEST_REQUEST_TIMEOUT)) + ); assertEquals(1, desiredBalanceResponse.getRoutingTable().size()); Map shardsMap = desiredBalanceResponse.getRoutingTable().get(index); @@ -75,8 +76,9 @@ public void testDesiredBalanceWithUnassignedShards() throws Exception { var clusterHealthResponse = clusterAdmin().health(new ClusterHealthRequest(index).waitForStatus(ClusterHealthStatus.YELLOW)).get(); assertEquals(RestStatus.OK, clusterHealthResponse.status()); - DesiredBalanceResponse desiredBalanceResponse = client().execute(TransportGetDesiredBalanceAction.TYPE, new DesiredBalanceRequest()) - .get(); + final var desiredBalanceResponse = safeGet( + client().execute(TransportGetDesiredBalanceAction.TYPE, new DesiredBalanceRequest(TEST_REQUEST_TIMEOUT)) + ); assertEquals(1, desiredBalanceResponse.getRoutingTable().size()); Map shardsMap = desiredBalanceResponse.getRoutingTable().get(index); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/PrevalidateShardPathIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/PrevalidateShardPathIT.java index 77bcaf1e1970c..dd701244756cf 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/PrevalidateShardPathIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/PrevalidateShardPathIT.java @@ -9,8 +9,7 @@ package org.elasticsearch.cluster; import org.apache.lucene.tests.util.LuceneTestCase; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; -import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.cluster.node.shutdown.NodePrevalidateShardPathResponse; import org.elasticsearch.action.admin.cluster.node.shutdown.PrevalidateShardPathRequest; import org.elasticsearch.action.admin.cluster.node.shutdown.PrevalidateShardPathResponse; @@ -90,13 +89,12 @@ public void testCheckShards() throws Exception { .filter(s -> node2ShardIds.contains(s.shardId())) .filter(s -> s.currentNodeId().equals(node2Id)) .toList()) { - var explanation = client().execute( - TransportClusterAllocationExplainAction.TYPE, - new ClusterAllocationExplainRequest().setIndex(node2Shard.getIndexName()) - .setCurrentNode(node2Shard.currentNodeId()) - .setShard(node2Shard.id()) - .setPrimary(node2Shard.primary()) - ).get(); + var explanation = ClusterAllocationExplanationUtils.getClusterAllocationExplanation( + client(), + node2Shard.getIndexName(), + node2Shard.id(), + node2Shard.primary() + ); logger.info( "Shard: {} is still located on relocation source node: {}. Allocation explanation: {}", node2Shard.shardId(), diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java index 012cb826a4403..784a6e8f419c8 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java @@ -8,14 +8,13 @@ package org.elasticsearch.cluster.routing; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.indices.stats.ShardStats; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.cluster.routing.allocation.AllocationDecision; -import org.elasticsearch.cluster.routing.allocation.ShardAllocationDecision; import org.elasticsearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexService; @@ -199,14 +198,12 @@ private void putFakeCorruptionMarker(IndexSettings indexSettings, ShardId shardI private void checkNoValidShardCopy(String indexName, ShardId shardId) throws Exception { assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(shardId.id()) - .setPrimary(true) - .get() - .getExplanation(); - - final ShardAllocationDecision shardAllocationDecision = explanation.getShardAllocationDecision(); + final var shardAllocationDecision = ClusterAllocationExplanationUtils.getClusterAllocationExplanation( + client(), + indexName, + shardId.id(), + true + ).getShardAllocationDecision(); assertThat(shardAllocationDecision.isDecisionTaken(), equalTo(true)); assertThat( shardAllocationDecision.getAllocateDecision().getAllocationDecision(), diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java index 6c691c0a14440..f43aaf0bacad4 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java @@ -19,7 +19,6 @@ import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.NativeFSLockFactory; import org.elasticsearch.ExceptionsHelper; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse; @@ -37,7 +36,6 @@ import org.elasticsearch.cluster.routing.ShardRoutingState; import org.elasticsearch.cluster.routing.UnassignedInfo; import org.elasticsearch.cluster.routing.allocation.AllocationDecision; -import org.elasticsearch.cluster.routing.allocation.ShardAllocationDecision; import org.elasticsearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; @@ -78,6 +76,7 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import static org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils.getClusterAllocationExplanation; import static org.elasticsearch.common.util.CollectionUtils.iterableAsArrayList; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @@ -173,14 +172,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { // shard should be failed due to a corrupted index assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - - final ShardAllocationDecision shardAllocationDecision = explanation.getShardAllocationDecision(); + final var shardAllocationDecision = getClusterAllocationExplanation(client(), indexName, 0, true).getShardAllocationDecision(); assertThat(shardAllocationDecision.isDecisionTaken(), equalTo(true)); assertThat( shardAllocationDecision.getAllocateDecision().getAllocationDecision(), @@ -219,14 +211,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { // there is only _stale_ primary (due to new allocation id) assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - - final ShardAllocationDecision shardAllocationDecision = explanation.getShardAllocationDecision(); + final var shardAllocationDecision = getClusterAllocationExplanation(client(), indexName, 0, true).getShardAllocationDecision(); assertThat(shardAllocationDecision.isDecisionTaken(), equalTo(true)); assertThat( shardAllocationDecision.getAllocateDecision().getAllocationDecision(), @@ -237,13 +222,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, nodeId, true)).get(); assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - + final var explanation = getClusterAllocationExplanation(client(), indexName, 0, true); assertThat(explanation.getCurrentNode(), notNullValue()); assertThat(explanation.getShardState(), equalTo(ShardRoutingState.STARTED)); }); @@ -331,13 +310,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { // all shards should be failed due to a corrupted translog assertBusy(() -> { - final UnassignedInfo unassignedInfo = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation() - .getUnassignedInfo(); + final UnassignedInfo unassignedInfo = getClusterAllocationExplanation(client(), indexName, 0, true).getUnassignedInfo(); assertThat(unassignedInfo.getReason(), equalTo(UnassignedInfo.Reason.ALLOCATION_FAILED)); assertThat(ExceptionsHelper.unwrap(unassignedInfo.getFailure(), TranslogCorruptedException.class), not(nullValue())); }); @@ -392,14 +365,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { // there is only _stale_ primary (due to new allocation id) assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - - final ShardAllocationDecision shardAllocationDecision = explanation.getShardAllocationDecision(); + final var shardAllocationDecision = getClusterAllocationExplanation(client(), indexName, 0, true).getShardAllocationDecision(); assertThat(shardAllocationDecision.isDecisionTaken(), equalTo(true)); assertThat( shardAllocationDecision.getAllocateDecision().getAllocationDecision(), @@ -410,13 +376,7 @@ public Settings onNodeStopped(String nodeName) throws Exception { clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, primaryNodeId, true)).get(); assertBusy(() -> { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setIndex(indexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - + final var explanation = getClusterAllocationExplanation(client(), indexName, 0, true); assertThat(explanation.getCurrentNode(), notNullValue()); assertThat(explanation.getShardState(), equalTo(ShardRoutingState.STARTED)); }); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedTranslogIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedTranslogIT.java index 9618dcf761be9..ac5a10d246cfc 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedTranslogIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedTranslogIT.java @@ -9,7 +9,6 @@ package org.elasticsearch.index.store; import org.elasticsearch.ExceptionsHelper; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.cluster.routing.UnassignedInfo; @@ -32,6 +31,7 @@ import java.util.Arrays; import java.util.Collection; +import static org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils.getClusterAllocationExplanation; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.containsString; @@ -79,13 +79,9 @@ public void onAllNodesStopped() throws Exception { assertBusy(() -> { // assertBusy since the shard starts out unassigned with reason CLUSTER_RECOVERED, then it's assigned, and then it fails. - final ClusterAllocationExplainResponse allocationExplainResponse = clusterAdmin().prepareAllocationExplain() - .setIndex("test") - .setShard(0) - .setPrimary(true) - .get(); - final String description = Strings.toString(allocationExplainResponse.getExplanation()); - final UnassignedInfo unassignedInfo = allocationExplainResponse.getExplanation().getUnassignedInfo(); + final var allocationExplainResponse = getClusterAllocationExplanation(client(), "test", 0, true); + final var description = Strings.toString(allocationExplainResponse); + final var unassignedInfo = allocationExplainResponse.getUnassignedInfo(); assertThat(description, unassignedInfo, not(nullValue())); assertThat(description, unassignedInfo.getReason(), equalTo(UnassignedInfo.Reason.ALLOCATION_FAILED)); var failure = unassignedInfo.getFailure(); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java index 91561814fea1a..11731c0ccade5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java @@ -13,6 +13,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.TimeValue; import org.elasticsearch.xcontent.ObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContentParser; @@ -48,8 +49,8 @@ public class ClusterAllocationExplainRequest extends MasterNodeRequest { - - public ClusterAllocationExplainRequestBuilder(ElasticsearchClient client) { - super(client, TransportClusterAllocationExplainAction.TYPE, new ClusterAllocationExplainRequest()); - } - - /** The index name to use when finding the shard to explain */ - public ClusterAllocationExplainRequestBuilder setIndex(String index) { - request.setIndex(index); - return this; - } - - /** The shard number to use when finding the shard to explain */ - public ClusterAllocationExplainRequestBuilder setShard(int shard) { - request.setShard(shard); - return this; - } - - /** Whether the primary or replica should be explained */ - public ClusterAllocationExplainRequestBuilder setPrimary(boolean primary) { - request.setPrimary(primary); - return this; - } - - /** Whether to include "YES" decider decisions in the response instead of only "NO" decisions */ - public ClusterAllocationExplainRequestBuilder setIncludeYesDecisions(boolean includeYesDecisions) { - request.includeYesDecisions(includeYesDecisions); - return this; - } - - /** Whether to include information about the gathered disk information of nodes in the cluster */ - public ClusterAllocationExplainRequestBuilder setIncludeDiskInfo(boolean includeDiskInfo) { - request.includeDiskInfo(includeDiskInfo); - return this; - } - - /** - * Requests the explain API to explain an already assigned replica shard currently allocated to - * the given node. - */ - public ClusterAllocationExplainRequestBuilder setCurrentNode(String currentNode) { - request.setCurrentNode(currentNode); - return this; - } - - /** - * Signal that the first unassigned shard should be used - */ - public ClusterAllocationExplainRequestBuilder useAnyUnassignedShard() { - request.setIndex(null); - request.setShard(null); - request.setPrimary(null); - return this; - } - -} diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/DesiredBalanceRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/DesiredBalanceRequest.java index b34ba313894b9..d01c05b63ab67 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/DesiredBalanceRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/DesiredBalanceRequest.java @@ -10,12 +10,13 @@ import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.MasterNodeReadRequest; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.core.TimeValue; import java.io.IOException; public class DesiredBalanceRequest extends MasterNodeReadRequest { - public DesiredBalanceRequest() { - super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); + public DesiredBalanceRequest(TimeValue masterNodeTimeout) { + super(masterNodeTimeout); } public DesiredBalanceRequest(StreamInput in) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetAllocationStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetAllocationStatsAction.java index f26921fd47260..560ef6feae1e4 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetAllocationStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetAllocationStatsAction.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.TimeValue; import org.elasticsearch.features.FeatureService; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -102,8 +103,8 @@ protected ClusterBlockException checkBlock(Request request, ClusterState state) public static class Request extends MasterNodeReadRequest { - public Request(TaskId parentTaskId) { - super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); + public Request(TimeValue masterNodeTimeout, TaskId parentTaskId) { + super(masterNodeTimeout); setParentTask(parentTaskId); } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java index 4829f309e1f30..a84905e7f4c8e 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.node.NodeService; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -37,6 +38,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; public class TransportNodesStatsAction extends TransportNodesAction< @@ -89,7 +91,10 @@ protected void newResponseAsync( || NodesStatsRequestParameters.Metric.FS.containedIn(metrics)) { client.execute( TransportGetAllocationStatsAction.TYPE, - new TransportGetAllocationStatsAction.Request(new TaskId(clusterService.localNode().getId(), task.getId())), + new TransportGetAllocationStatsAction.Request( + Objects.requireNonNullElse(request.timeout(), RestUtils.REST_MASTER_TIMEOUT_DEFAULT), + new TaskId(clusterService.localNode().getId(), task.getId()) + ), listener.delegateFailure((l, r) -> { ActionListener.respondAndRelease( l, diff --git a/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java index daae078ed9a68..d2ac07cf16479 100644 --- a/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java @@ -13,10 +13,6 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequestBuilder; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; -import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequestBuilder; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; @@ -455,18 +451,6 @@ public SimulatePipelineRequestBuilder prepareSimulatePipeline(BytesReference sou return new SimulatePipelineRequestBuilder(this, source, xContentType); } - public void allocationExplain(ClusterAllocationExplainRequest request, ActionListener listener) { - execute(TransportClusterAllocationExplainAction.TYPE, request, listener); - } - - public ActionFuture allocationExplain(ClusterAllocationExplainRequest request) { - return execute(TransportClusterAllocationExplainAction.TYPE, request); - } - - public ClusterAllocationExplainRequestBuilder prepareAllocationExplain() { - return new ClusterAllocationExplainRequestBuilder(this); - } - public PutStoredScriptRequestBuilder preparePutStoredScript() { return new PutStoredScriptRequestBuilder(this); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java index a3ab6ad8e2f04..c28dcb109b294 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java @@ -9,9 +9,11 @@ package org.elasticsearch.rest.action.admin.cluster; import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; +import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.rest.Scope; import org.elasticsearch.rest.ServerlessScope; import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener; @@ -46,19 +48,19 @@ public boolean allowSystemIndexAccessByDefault() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - ClusterAllocationExplainRequest req; - if (request.hasContentOrSourceParam() == false) { - // Empty request signals "explain the first unassigned shard you find" - req = new ClusterAllocationExplainRequest(); - } else { + final var req = new ClusterAllocationExplainRequest(RestUtils.getMasterNodeTimeout(request)); + if (request.hasContentOrSourceParam()) { try (XContentParser parser = request.contentOrSourceParamParser()) { - req = ClusterAllocationExplainRequest.parse(parser); + ClusterAllocationExplainRequest.parse(req, parser); } - } - + } // else ok, an empty body means "explain the first unassigned shard you find" req.includeYesDecisions(request.paramAsBoolean("include_yes_decisions", false)); req.includeDiskInfo(request.paramAsBoolean("include_disk_info", false)); - return channel -> client.admin().cluster().allocationExplain(req, new RestRefCountedChunkedToXContentListener<>(channel)); + return channel -> client.execute( + TransportClusterAllocationExplainAction.TYPE, + req, + new RestRefCountedChunkedToXContentListener<>(channel) + ); } @Override diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteDesiredBalanceAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteDesiredBalanceAction.java index f0b516a876622..6a42e9a2a3f40 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteDesiredBalanceAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteDesiredBalanceAction.java @@ -13,6 +13,7 @@ import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.rest.Scope; import org.elasticsearch.rest.ServerlessScope; import org.elasticsearch.rest.action.RestToXContentListener; @@ -35,10 +36,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - return channel -> client.execute( - TransportDeleteDesiredBalanceAction.TYPE, - new DesiredBalanceRequest(), - new RestToXContentListener<>(channel) - ); + final var req = new DesiredBalanceRequest(RestUtils.getMasterNodeTimeout(request)); + return channel -> client.execute(TransportDeleteDesiredBalanceAction.TYPE, req, new RestToXContentListener<>(channel)); } } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetDesiredBalanceAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetDesiredBalanceAction.java index 0bb7cc5ff7473..cb7b3780be234 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetDesiredBalanceAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetDesiredBalanceAction.java @@ -13,6 +13,7 @@ import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.rest.Scope; import org.elasticsearch.rest.ServerlessScope; import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener; @@ -35,9 +36,10 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + final var req = new DesiredBalanceRequest(RestUtils.getMasterNodeTimeout(request)); return restChannel -> client.execute( TransportGetDesiredBalanceAction.TYPE, - new DesiredBalanceRequest(), + req, new RestRefCountedChunkedToXContentListener<>(restChannel) ); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainActionTests.java index f68e83e13496c..f9483bd23f216 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainActionTests.java @@ -133,13 +133,13 @@ public ShardAllocationDecision decideShardAllocation(ShardRouting shard, Routing public void testFindAnyUnassignedShardToExplain() { // find unassigned primary ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), ShardRoutingState.UNASSIGNED); - ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest(); + ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT); ShardRouting shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals(clusterState.getRoutingTable().index("idx").shard(0).primaryShard(), shard); // find unassigned replica clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), ShardRoutingState.STARTED, ShardRoutingState.UNASSIGNED); - request = new ClusterAllocationExplainRequest(); + request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT); shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals(clusterState.getRoutingTable().index("idx").shard(0).replicaShards().get(0), shard); @@ -168,7 +168,7 @@ public void testFindAnyUnassignedShardToExplain() { routingTableBuilder.add(indexBuilder); } clusterState = ClusterState.builder(clusterState).routingTable(routingTableBuilder.build()).build(); - request = new ClusterAllocationExplainRequest(); + request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT); shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals(clusterState.getRoutingTable().index(redIndex).shard(0).primaryShard(), shard); @@ -179,7 +179,7 @@ public void testFindAnyUnassignedShardToExplain() { ShardRoutingState.STARTED, ShardRoutingState.STARTED ); - final ClusterAllocationExplainRequest anyUnassignedShardsRequest = new ClusterAllocationExplainRequest(); + final ClusterAllocationExplainRequest anyUnassignedShardsRequest = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT); assertThat( expectThrows( IllegalArgumentException.class, @@ -195,7 +195,7 @@ public void testFindAnyUnassignedShardToExplain() { public void testFindPrimaryShardToExplain() { ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), randomFrom(ShardRoutingState.values())); - ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest("idx", 0, true, null); + ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT, "idx", 0, true, null); ShardRouting shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals(clusterState.getRoutingTable().index("idx").shard(0).primaryShard(), shard); } @@ -209,7 +209,7 @@ public void testFindAnyReplicaToExplain() { ShardRoutingState.STARTED, ShardRoutingState.UNASSIGNED ); - ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest("idx", 0, false, null); + ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT, "idx", 0, false, null); ShardRouting shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals( clusterState.getRoutingTable() @@ -231,7 +231,7 @@ public void testFindAnyReplicaToExplain() { randomFrom(ShardRoutingState.RELOCATING, ShardRoutingState.INITIALIZING), ShardRoutingState.STARTED ); - request = new ClusterAllocationExplainRequest("idx", 0, false, null); + request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT, "idx", 0, false, null); shard = findShardToExplain(request, routingAllocation(clusterState)); assertEquals( clusterState.getRoutingTable().index("idx").shard(0).replicaShards().stream().filter(ShardRouting::started).findFirst().get(), @@ -250,7 +250,13 @@ public void testFindShardAssignedToNode() { ShardRouting shardToExplain = primary ? clusterState.getRoutingTable().index("idx").shard(0).primaryShard() : clusterState.getRoutingTable().index("idx").shard(0).replicaShards().get(0); - ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest("idx", 0, primary, shardToExplain.currentNodeId()); + ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest( + TEST_REQUEST_TIMEOUT, + "idx", + 0, + primary, + shardToExplain.currentNodeId() + ); RoutingAllocation allocation = routingAllocation(clusterState); ShardRouting foundShard = findShardToExplain(request, allocation); assertEquals(shardToExplain, foundShard); @@ -263,7 +269,13 @@ public void testFindShardAssignedToNode() { break; } } - final ClusterAllocationExplainRequest failingRequest = new ClusterAllocationExplainRequest("idx", 0, primary, explainNode); + final ClusterAllocationExplainRequest failingRequest = new ClusterAllocationExplainRequest( + TEST_REQUEST_TIMEOUT, + "idx", + 0, + primary, + explainNode + ); expectThrows(IllegalArgumentException.class, () -> findShardToExplain(failingRequest, allocation)); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequestTests.java index 625a01094792d..cc00207997e9d 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequestTests.java @@ -15,6 +15,7 @@ public class ClusterAllocationExplainRequestTests extends ESTestCase { public void testSerialization() throws Exception { ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest( + randomTimeValue(), randomAlphaOfLength(4), randomIntBetween(0, Integer.MAX_VALUE), randomBoolean(), @@ -26,6 +27,7 @@ public void testSerialization() throws Exception { request.writeTo(output); ClusterAllocationExplainRequest actual = new ClusterAllocationExplainRequest(output.bytes().streamInput()); + assertEquals(request.masterNodeTimeout(), actual.masterNodeTimeout()); assertEquals(request.getIndex(), actual.getIndex()); assertEquals(request.getShard(), actual.getShard()); assertEquals(request.isPrimary(), actual.isPrimary()); diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceActionTests.java index 6eb3310623b92..6885e6851c77d 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportDeleteDesiredBalanceActionTests.java @@ -76,7 +76,7 @@ public void testReturnsErrorIfAllocatorIsNotDesiredBalanced() throws Exception { mock(IndexNameExpressionResolver.class), mock(AllocationService.class), mock(ShardsAllocator.class) - ).masterOperation(mock(Task.class), new DesiredBalanceRequest(), ClusterState.EMPTY_STATE, listener); + ).masterOperation(mock(Task.class), new DesiredBalanceRequest(TEST_REQUEST_TIMEOUT), ClusterState.EMPTY_STATE, listener); var exception = expectThrows(ResourceNotFoundException.class, listener); assertThat(exception.getMessage(), equalTo("Desired balance allocator is not in use, no desired balance found")); @@ -156,7 +156,7 @@ public DesiredBalance compute( allocator ); - action.masterOperation(mock(Task.class), new DesiredBalanceRequest(), clusterState, listener); + action.masterOperation(mock(Task.class), new DesiredBalanceRequest(TEST_REQUEST_TIMEOUT), clusterState, listener); try { assertThat(listener.get(), notNullValue()); diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionTests.java index 69cd9b4026108..414dc45ee458f 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/TransportGetDesiredBalanceActionTests.java @@ -91,7 +91,7 @@ private static DesiredBalanceResponse execute(TransportGetDesiredBalanceAction a return PlainActionFuture.get( future -> action.masterOperation( new Task(1, "test", TransportGetDesiredBalanceAction.TYPE.name(), "", TaskId.EMPTY_TASK_ID, Map.of()), - new DesiredBalanceRequest(), + new DesiredBalanceRequest(TEST_REQUEST_TIMEOUT), clusterState, future ), diff --git a/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanationUtils.java b/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanationUtils.java new file mode 100644 index 0000000000000..b72d95cb02b8f --- /dev/null +++ b/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanationUtils.java @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.action.admin.cluster.allocation; + +import org.elasticsearch.client.internal.ElasticsearchClient; + +import static org.elasticsearch.test.ESTestCase.TEST_REQUEST_TIMEOUT; +import static org.elasticsearch.test.ESTestCase.safeGet; + +public class ClusterAllocationExplanationUtils { + private ClusterAllocationExplanationUtils() {/* no instances */} + + public static ClusterAllocationExplanation getClusterAllocationExplanation( + ElasticsearchClient client, + String index, + int shard, + boolean primary + ) { + return safeGet( + client.execute( + TransportClusterAllocationExplainAction.TYPE, + new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT, index, shard, primary, null) + ) + ).getExplanation(); + } +} diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index fb6105005201f..db6fc9ea696d5 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -24,7 +24,9 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; +import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; @@ -992,7 +994,11 @@ private ClusterHealthStatus ensureColor( final var detailsFuture = new PlainActionFuture(); try (var listeners = new RefCountingListener(detailsFuture)) { - clusterAdmin().prepareAllocationExplain().execute(listeners.acquire(allocationExplainRef::set)); + client().execute( + TransportClusterAllocationExplainAction.TYPE, + new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT), + listeners.acquire(allocationExplainRef::set) + ); clusterAdmin().prepareState().execute(listeners.acquire(clusterStateRef::set)); client().execute( TransportPendingClusterTasksAction.TYPE, diff --git a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java index 17e48c91a4eab..6e6a11fbddc93 100644 --- a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java +++ b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java @@ -139,9 +139,10 @@ private long computeLengthOfRanges() { } /** - * Called before reading a range from the file to ensure that this range is present. Returns a list of gaps for the caller to fill. The - * range from the file is defined by {@code range} but the listener is executed as soon as a (potentially smaller) sub range - * {@code subRange} becomes available. + * Called before reading a range from the file to ensure that this range is present. Returns a list of gaps for the caller to fill, + * unless the {@code subRange} is already present in which case the listener is executed immediately without returning gaps. The range + * from the file is defined by {@code range} but the listener is executed as soon as a (potentially smaller) sub range {@code subRange} + * becomes available. * * @param range A ByteRange that contains the (inclusive) start and (exclusive) end of the desired range * @param subRange A ByteRange that contains the (inclusive) start and (exclusive) end of the listener's range @@ -173,7 +174,7 @@ public List waitForRange(final ByteRange range, final ByteRange subRange, f ); } - if (complete >= range.end()) { + if (subRange.end() <= complete) { listener.onResponse(null); return List.of(); } diff --git a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java index 6f1635e67ca4b..5973b90c814d5 100644 --- a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java +++ b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java @@ -10,6 +10,8 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionTestUtils; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.blobcache.BlobCacheUtils; import org.elasticsearch.common.util.concurrent.DeterministicTaskQueue; import org.elasticsearch.test.ESTestCase; @@ -22,7 +24,9 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.stream.LongStream; import static org.elasticsearch.blobcache.BlobCacheTestUtils.mergeContiguousRanges; import static org.elasticsearch.blobcache.BlobCacheTestUtils.randomRanges; @@ -35,6 +39,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; public class SparseFileTrackerTests extends ESTestCase { @@ -119,7 +124,50 @@ public void testInvalidRange() { } } - public void testCallsListenerWhenRangeIsCompleted() { + public void testListenerCompletedImmediatelyWhenSubRangeIsAvailable() { + final byte[] bytes = new byte[randomIntBetween(8, 1024)]; + final var tracker = new SparseFileTracker(getTestName(), bytes.length); + + // wraps a future to assert that the sub range bytes are available + BiFunction, ActionListener> wrapper = (range, future) -> ActionListener.runBefore( + future, + () -> LongStream.range(range.start(), range.end()) + .forEach(pos -> assertThat(bytes[BlobCacheUtils.toIntBytes(pos)], equalTo(AVAILABLE))) + ); + + var completeUpTo = randomIntBetween(2, bytes.length); + { + long subRangeStart = randomLongBetween(0, completeUpTo - 2); + long subRangeEnd = randomLongBetween(subRangeStart + 1, completeUpTo - 1); + var subRange = ByteRange.of(subRangeStart, subRangeEnd); + var range = ByteRange.of(0, completeUpTo); + var future = new PlainActionFuture(); + + var gaps = tracker.waitForRange(range, subRange, wrapper.apply(subRange, future)); + assertThat(future.isDone(), equalTo(false)); + assertThat(gaps, notNullValue()); + assertThat(gaps, hasSize(1)); + + fillGap(bytes, gaps.get(0)); + + assertThat(future.isDone(), equalTo(true)); + } + { + long subRangeStart = randomLongBetween(0L, Math.max(0L, completeUpTo - 1)); + long subRangeEnd = randomLongBetween(subRangeStart, completeUpTo); + var subRange = ByteRange.of(subRangeStart, subRangeEnd); + + var range = ByteRange.of(randomLongBetween(0L, subRangeStart), randomLongBetween(subRangeEnd, bytes.length)); + var future = new PlainActionFuture(); + + var gaps = tracker.waitForRange(range, subRange, wrapper.apply(subRange, future)); + assertThat(future.isDone(), equalTo(true)); + assertThat(gaps, notNullValue()); + assertThat(gaps, hasSize(0)); + } + } + + public void testCallsListenerWhenWholeRangeIsAvailable() { final byte[] fileContents = new byte[between(0, 1000)]; final SparseFileTracker sparseFileTracker = new SparseFileTracker("test", fileContents.length); @@ -278,9 +326,14 @@ public void testCallsListenerWhenRangeIsAvailable() { assertThat(gap.start(), greaterThanOrEqualTo(range.start())); assertThat(gap.end(), lessThanOrEqualTo(range.end())); + final boolean completeBeforeEndOfGap = triggeringProgress < gap.end() - 1L; // gap.end is exclusive + long from = gap.start(); + long written = 0L; + for (long i = gap.start(); i < gap.end(); i++) { assertThat(fileContents[toIntBytes(i)], equalTo(UNAVAILABLE)); fileContents[toIntBytes(i)] = AVAILABLE; + written += 1L; if (triggeringProgress == i) { assertFalse(expectNotification.getAndSet(true)); } @@ -294,19 +347,35 @@ public void testCallsListenerWhenRangeIsAvailable() { equalTo(triggeringProgress < i) ); - gap.onProgress(i + 1L); + long progress = from + written; + gap.onProgress(progress); + + if (completeBeforeEndOfGap) { + assertThat( + "Listener should not have been called before [" + + triggeringProgress + + "] is reached, but it was triggered after progress got updated to [" + + i + + ']', + wasNotified.get() && waitIfPendingWasNotified.get(), + equalTo(triggeringProgress < progress) + ); + } else { + assertThat( + "Listener should not have been called before gap [" + + gap + + "] is completed, but it was triggered after progress got updated to [" + + i + + ']', + wasNotified.get() && waitIfPendingWasNotified.get(), + equalTo(false) + ); + } - assertThat( - "Listener should not have been called before [" - + triggeringProgress - + "] is reached, but it was triggered after progress got updated to [" - + i - + ']', - wasNotified.get() && waitIfPendingWasNotified.get(), - equalTo(triggeringProgress < i + 1L) - ); + if (progress == gap.end()) { + gap.onCompletion(); + } } - gap.onCompletion(); assertThat( "Listener should not have been called before [" @@ -544,4 +613,15 @@ private static boolean processGap(byte[] fileContents, SparseFileTracker.Gap gap return true; } } + + private static void fillGap(byte[] fileContents, SparseFileTracker.Gap gap) { + for (long i = gap.start(); i < gap.end(); i++) { + assertThat(fileContents[toIntBytes(i)], equalTo(UNAVAILABLE)); + } + for (long i = gap.start(); i < gap.end(); i++) { + fileContents[toIntBytes(i)] = AVAILABLE; + gap.onProgress(i + 1L); + } + gap.onCompletion(); + } } diff --git a/x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/PrimaryFollowerAllocationIT.java b/x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/PrimaryFollowerAllocationIT.java index 50750f629b993..16a2de7bf5b0f 100644 --- a/x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/PrimaryFollowerAllocationIT.java +++ b/x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/PrimaryFollowerAllocationIT.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.ccr; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; @@ -66,14 +66,7 @@ public void testDoNotAllocateFollowerPrimaryToNodesWithoutRemoteClusterClientRol final PutFollowAction.Response response = followerClient().execute(PutFollowAction.INSTANCE, putFollowRequest).get(); assertFalse(response.isFollowIndexShardsAcked()); assertFalse(response.isIndexFollowingStarted()); - final ClusterAllocationExplanation explanation = followerClient().admin() - .cluster() - .prepareAllocationExplain() - .setIndex(followerIndex) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); + final var explanation = ClusterAllocationExplanationUtils.getClusterAllocationExplanation(followerClient(), followerIndex, 0, true); for (NodeAllocationResult nodeDecision : explanation.getShardAllocationDecision().getAllocateDecision().getNodeDecisions()) { assertThat(nodeDecision.getNodeDecision(), equalTo(AllocationDecision.NO)); if (dataOnlyNodes.contains(nodeDecision.getNode().getName())) { diff --git a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderIT.java b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderIT.java index 7261ee1f66036..6fe63548a1430 100644 --- a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderIT.java +++ b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderIT.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.cluster.routing.allocation; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.cluster.desirednodes.UpdateDesiredNodesAction; import org.elasticsearch.action.admin.cluster.desirednodes.UpdateDesiredNodesRequest; import org.elasticsearch.action.admin.indices.shrink.ResizeType; @@ -541,7 +542,7 @@ private DiscoveryNode getPrimaryShardAssignedNode(int shard) { private String explainAllocation(int shard) { return Strings.toString( - clusterAdmin().prepareAllocationExplain().setIndex(index).setShard(shard).setPrimary(true).get().getExplanation(), + ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), index, shard, true), true, true ); diff --git a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierShardAvailabilityHealthIndicatorIT.java b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierShardAvailabilityHealthIndicatorIT.java index 628e2c18de2f9..368946d79682c 100644 --- a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierShardAvailabilityHealthIndicatorIT.java +++ b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierShardAvailabilityHealthIndicatorIT.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.cluster.routing.allocation; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -110,12 +110,7 @@ public void testIncreaseTierCapacityDiagnosisWhenTierShrinksUnexpectedly() throw GetHealthAction.INSTANCE, new GetHealthAction.Request(ShardsAvailabilityHealthIndicatorService.NAME, true, 1000) ).get(); - ClusterAllocationExplanation explain = clusterAdmin().prepareAllocationExplain() - .setIndex("test") - .setShard(0) - .setPrimary(false) - .get() - .getExplanation(); + final var explain = ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), "test", 0, false); logger.info(XContentHelper.toXContent(explain, XContentType.JSON, true).utf8ToString()); HealthIndicatorResult indicatorResult = healthResponse.findIndicator(ShardsAvailabilityHealthIndicatorService.NAME); assertThat(indicatorResult.status(), equalTo(HealthStatus.YELLOW)); diff --git a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/DataTiersMigrationsTests.java b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/DataTiersMigrationsTests.java index 01288b4135d15..7a0e00e5c4147 100644 --- a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/DataTiersMigrationsTests.java +++ b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/ilm/DataTiersMigrationsTests.java @@ -7,8 +7,7 @@ package org.elasticsearch.xpack.ilm; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.cluster.node.DiscoveryNodeRole; import org.elasticsearch.cluster.routing.ShardRoutingState; @@ -222,10 +221,9 @@ public void testUserOptsOutOfTierMigration() throws Exception { } private void assertReplicaIsUnassigned() { - ClusterAllocationExplainRequest explainReplicaShard = new ClusterAllocationExplainRequest().setIndex(managedIndex) - .setPrimary(false) - .setShard(0); - ClusterAllocationExplainResponse response = clusterAdmin().allocationExplain(explainReplicaShard).actionGet(); - assertThat(response.getExplanation().getShardState(), is(ShardRoutingState.UNASSIGNED)); + assertThat( + ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), managedIndex, 0, false).getShardState(), + is(ShardRoutingState.UNASSIGNED) + ); } } diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/FrozenSearchableSnapshotsIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/FrozenSearchableSnapshotsIntegTests.java index 4b9e1b0d9211e..be37cc2184d15 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/FrozenSearchableSnapshotsIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/FrozenSearchableSnapshotsIntegTests.java @@ -12,6 +12,8 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.FilterDirectory; import org.elasticsearch.ResourceNotFoundException; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest; +import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotIndexShardStatus; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; @@ -334,13 +336,11 @@ public void testCreateAndRestorePartialSearchableSnapshot() throws Exception { assertThat(indicesAdmin().prepareGetAliases(aliasName).get().getAliases().size(), equalTo(1)); assertTotalHits(aliasName, originalAllHits, originalBarHits); - final Decision diskDeciderDecision = clusterAdmin().prepareAllocationExplain() - .setIndex(restoredIndexName) + final var request = new ClusterAllocationExplainRequest(TEST_REQUEST_TIMEOUT).setIndex(restoredIndexName) .setShard(0) - .setPrimary(true) - .setIncludeYesDecisions(true) - .get() - .getExplanation() + .setPrimary(true); + request.includeYesDecisions(true); + final var diskDeciderDecision = safeGet(client().execute(TransportClusterAllocationExplainAction.TYPE, request)).getExplanation() .getShardAllocationDecision() .getMoveDecision() .getCanRemainDecision() diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java index 8fc95ad4491e8..50be307fe16a4 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java @@ -10,7 +10,6 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionFuture; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.TransportListTasksAction; @@ -80,6 +79,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils.getClusterAllocationExplanation; import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING; import static org.elasticsearch.index.IndexSettings.INDEX_SOFT_DELETES_SETTING; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; @@ -972,13 +972,7 @@ public void testSnapshotOfSearchableSnapshotCanBeRestoredBeforeRepositoryRegiste ); assertBusy(() -> { - final ClusterAllocationExplanation clusterAllocationExplanation = clusterAdmin().prepareAllocationExplain() - .setIndex(restoredIndexName) - .setShard(0) - .setPrimary(true) - .get() - .getExplanation(); - + final var clusterAllocationExplanation = getClusterAllocationExplanation(client(), restoredIndexName, 0, true); final String description = Strings.toString(clusterAllocationExplanation); final AllocateUnassignedDecision allocateDecision = clusterAllocationExplanation.getShardAllocationDecision() .getAllocateDecision(); diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/shared/PartiallyCachedShardAllocationIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/shared/PartiallyCachedShardAllocationIntegTests.java index a55521394f548..28da64b4ceaec 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/shared/PartiallyCachedShardAllocationIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/cache/shared/PartiallyCachedShardAllocationIntegTests.java @@ -9,7 +9,6 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionFuture; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanation; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.support.ActionTestUtils; import org.elasticsearch.action.support.SubscribableListener; @@ -49,6 +48,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import static org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils.getClusterAllocationExplanation; import static org.elasticsearch.blobcache.shared.SharedBlobCacheService.SHARED_CACHE_SIZE_SETTING; import static org.elasticsearch.cluster.routing.allocation.DataTier.TIER_PREFERENCE; import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING; @@ -109,12 +109,7 @@ public void testPartialSearchableSnapshotNotAllocatedToNodesWithoutCache() throw final ClusterState state = clusterAdmin().prepareState().clear().setRoutingTable(true).get().getState(); assertTrue(state.toString(), state.routingTable().index(req.mountedIndexName()).allPrimaryShardsUnassigned()); - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setPrimary(true) - .setIndex(req.mountedIndexName()) - .setShard(0) - .get() - .getExplanation(); + final var explanation = getClusterAllocationExplanation(client(), req.mountedIndexName(), 0, true); for (NodeAllocationResult nodeDecision : explanation.getShardAllocationDecision().getAllocateDecision().getNodeDecisions()) { assertTrue( nodeDecision.getNode() + " vs " + Strings.toString(explanation), @@ -232,13 +227,7 @@ public void testPartialSearchableSnapshotDelaysAllocationUntilNodeCacheStatesKno assertBusy(() -> { try { - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setPrimary(true) - .setIndex(req.mountedIndexName()) - .setShard(0) - .get() - .getExplanation(); - + final var explanation = getClusterAllocationExplanation(client(), req.mountedIndexName(), 0, true); assertTrue(Strings.toString(explanation), explanation.getShardAllocationDecision().getAllocateDecision().isDecisionTaken()); assertThat( @@ -257,13 +246,7 @@ public void testPartialSearchableSnapshotDelaysAllocationUntilNodeCacheStatesKno // Still won't be allocated assertFalse(responseFuture.isDone()); - final ClusterAllocationExplanation explanation = clusterAdmin().prepareAllocationExplain() - .setPrimary(true) - .setIndex(req.mountedIndexName()) - .setShard(0) - .get() - .getExplanation(); - + final var explanation = getClusterAllocationExplanation(client(), req.mountedIndexName(), 0, true); assertThat( Strings.toString(explanation), explanation.getShardAllocationDecision().getAllocateDecision().getAllocationStatus(), diff --git a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java index 0c70fd5a252c4..1594f78e04140 100644 --- a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java +++ b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.shutdown; -import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainResponse; +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.cluster.ClusterState; @@ -148,15 +148,8 @@ public void testNodeReplacementOnlyAllowsShardsFromReplacedNode() throws Excepti ensureYellow("other"); - // Explain the replica for the "other" index - ClusterAllocationExplainResponse explainResponse = clusterAdmin().prepareAllocationExplain() - .setIndex("other") - .setShard(0) - .setPrimary(false) - .get(); - // Validate that the replica cannot be allocated to nodeB because it's the target of a node replacement - explainResponse.getExplanation() + ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), "other", 0, false) .getShardAllocationDecision() .getAllocateDecision() .getNodeDecisions() @@ -209,15 +202,8 @@ public void testNodeReplacementOverridesFilters() throws Exception { ensureYellow("other"); - // Explain the replica for the "other" index - ClusterAllocationExplainResponse explainResponse = clusterAdmin().prepareAllocationExplain() - .setIndex("other") - .setShard(0) - .setPrimary(false) - .get(); - // Validate that the replica cannot be allocated to nodeB because it's the target of a node replacement - explainResponse.getExplanation() + ClusterAllocationExplanationUtils.getClusterAllocationExplanation(client(), "other", 0, false) .getShardAllocationDecision() .getAllocateDecision() .getNodeDecisions()