From 05eb458609ae07e706cfcc3916d3c2c2d2c4f352 Mon Sep 17 00:00:00 2001 From: abumarjikar Date: Tue, 23 Sep 2025 11:22:09 +0530 Subject: [PATCH 1/9] Initial Commit --- solr/CHANGES.txt | 2 ++ .../client/api/model/BalanceReplicasRequestBody.java | 2 +- .../client/api/model/MigrateReplicasRequestBody.java | 2 +- .../solr/client/api/model/ReplaceNodeRequestBody.java | 2 +- .../solr/cloud/api/collections/AddReplicaCmd.java | 2 +- .../solr/cloud/api/collections/BalanceReplicasCmd.java | 2 +- .../cloud/api/collections/CreateCollectionCmd.java | 2 +- .../solr/cloud/api/collections/CreateShardCmd.java | 2 +- .../solr/cloud/api/collections/MigrateReplicasCmd.java | 2 +- .../solr/cloud/api/collections/MoveReplicaCmd.java | 2 +- .../solr/cloud/api/collections/ReplaceNodeCmd.java | 2 +- .../solr/cloud/api/collections/SplitShardCmd.java | 2 +- .../handler/admin/api/CreateCollectionAPITest.java | 4 ++-- .../deployment-guide/pages/collection-management.adoc | 10 +++++----- .../apache/solr/common/params/CommonAdminParams.java | 1 + 15 files changed, 21 insertions(+), 18 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0584672fa1c..279fe29427c 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -236,6 +236,8 @@ Other Changes overseerEnabled cluster property and an env var SOLR_CLOUD_OVERSEER_ENABLED. Read more in the upgrade guide. (David Smiley) +* SOLR-17712: Changing default behaviour of `waitForFinalState` while handling the collection creation and collection management to true and is now deprecated. (Abhishek Umarjikar) + ================== 9.10.0 ================== New Features --------------------- diff --git a/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java index f270a48b269..e4a1a9060f7 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java @@ -42,7 +42,7 @@ public BalanceReplicasRequestBody(Set nodes, Boolean waitForFinalState, + "If false, the API will return the status of the single action, which may be " + "before the new replica is online and active.") @JsonProperty("waitForFinalState") - public Boolean waitForFinalState = false; + public Boolean waitForFinalState = true; @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty("async") diff --git a/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java index 8970d6b7c4d..7ca1bb7cfed 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java @@ -48,7 +48,7 @@ public MigrateReplicasRequestBody( + "If false, the API will return the status of the single action, which may be " + "before the new replicas are online and active.") @JsonProperty - public Boolean waitForFinalState = false; + public Boolean waitForFinalState = true; @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java index 303fd64e8db..35fc5d5d64a 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java @@ -42,7 +42,7 @@ public ReplaceNodeRequestBody(String targetNodeName, Boolean waitForFinalState, + "If false, the API will return the status of the single action, which may be " + "before the new replica is online and active.") @JsonProperty("waitForFinalState") - public Boolean waitForFinalState = false; + public Boolean waitForFinalState = true; @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty("async") diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java index a71a515c56d..8f9863d8568 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java @@ -114,7 +114,7 @@ List addReplica( "Collection: " + collectionName + " shard: " + shard + " does not exist"); } - boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, true); boolean skipCreateReplicaInClusterState = message.getBool(SKIP_CREATE_REPLICA_IN_CLUSTER_STATE, false); final String asyncId = message.getStr(ASYNC); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/BalanceReplicasCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/BalanceReplicasCmd.java index 7d84c7c6633..7e6ee573dd2 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/BalanceReplicasCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/BalanceReplicasCmd.java @@ -59,7 +59,7 @@ public void call(ClusterState state, ZkNodeProps message, NamedList resu "'nodes' was not passed as a correct type (Set/List/String): " + nodesRaw.getClass().getName()); } - boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, true); String async = message.getStr(ASYNC); int timeout = message.getInt("timeout", 10 * 60); // 10 minutes boolean parallel = message.getBool("parallel", false); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java index 34ca3d0e288..1e99529c6d4 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java @@ -109,7 +109,7 @@ public void call(ClusterState clusterState, ZkNodeProps message, NamedList resu ZkStateReader zkStateReader = ccc.getZkStateReader(); Set sourceNodes = getNodesFromParam(message, CollectionParams.SOURCE_NODES); Set targetNodes = getNodesFromParam(message, CollectionParams.TARGET_NODES); - boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, true); if (sourceNodes.isEmpty()) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "sourceNodes is a required param"); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java index 48f065f537e..319d90a70fb 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java @@ -73,7 +73,7 @@ private void moveReplica( CollectionHandlingUtils.checkRequired(message, COLLECTION_PROP, CollectionParams.TARGET_NODE); String extCollection = message.getStr(COLLECTION_PROP); String targetNode = message.getStr(CollectionParams.TARGET_NODE); - boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, true); boolean inPlaceMove = message.getBool(IN_PLACE_MOVE, true); int timeout = message.getInt(TIMEOUT, 10 * 60); // 10 minutes diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReplaceNodeCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReplaceNodeCmd.java index 5134e9953bd..93bf263ac85 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReplaceNodeCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReplaceNodeCmd.java @@ -50,7 +50,7 @@ public void call(ClusterState state, ZkNodeProps message, NamedList resu ZkStateReader zkStateReader = ccc.getZkStateReader(); String source = message.getStr(CollectionParams.SOURCE_NODE); String target = message.getStr(CollectionParams.TARGET_NODE); - boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, true); if (source == null) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "sourceNode is a required param"); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/SplitShardCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/SplitShardCmd.java index b16027f8f4b..3e042f5d9de 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/SplitShardCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/SplitShardCmd.java @@ -136,7 +136,7 @@ public boolean split(ClusterState clusterState, ZkNodeProps message, NamedList Date: Thu, 25 Sep 2025 17:33:44 +0530 Subject: [PATCH 2/9] Changes made as per the review --- solr/CHANGES.txt | 5 +++-- .../client/api/model/BalanceReplicasRequestBody.java | 11 +---------- .../client/api/model/CreateCollectionRequestBody.java | 2 -- .../client/api/model/CreateReplicaRequestBody.java | 1 - .../solr/client/api/model/CreateShardRequestBody.java | 2 -- .../client/api/model/MigrateReplicasRequestBody.java | 11 +---------- .../solr/client/api/model/ReplaceNodeRequestBody.java | 11 +---------- .../apache/solr/handler/admin/CollectionsHandler.java | 1 - .../solr/handler/admin/api/BalanceReplicas.java | 2 -- .../solr/handler/admin/api/CreateCollection.java | 3 --- .../apache/solr/handler/admin/api/CreateReplica.java | 3 --- .../apache/solr/handler/admin/api/CreateShard.java | 3 --- .../solr/handler/admin/api/MigrateReplicas.java | 2 -- .../apache/solr/handler/admin/api/ReplaceNode.java | 2 -- .../org/apache/solr/cloud/BalanceReplicasTest.java | 2 +- .../org/apache/solr/cloud/MigrateReplicasTest.java | 8 ++++---- .../handler/admin/api/CreateCollectionAPITest.java | 3 --- .../solr/handler/admin/api/CreateReplicaAPITest.java | 5 ----- .../solr/handler/admin/api/CreateShardAPITest.java | 5 ----- .../handler/admin/api/MigrateReplicasAPITest.java | 11 ++++------- .../solr/handler/admin/api/ReplaceNodeAPITest.java | 9 ++------- .../deployment-guide/pages/collection-management.adoc | 10 ---------- 22 files changed, 17 insertions(+), 95 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 279fe29427c..9153e0f604e 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -63,6 +63,9 @@ Improvements * GITHUB#3666: Removing redundant check if field exists in TextToVectorUpdateProcessorFactory (Renato Haeberli via Alessandro Benedetti) +* SOLR-17712: SolrCloud admin commands should more reliably be fully completed when Solr returns a response. + The `waitForFinalState` param now defaults to true and is deprecated. (Abhishek Umarjikar) + Optimizations --------------------- * SOLR-17568: The CLI bin/solr export tool now contacts the appropriate nodes directly for data instead of proxying through one. @@ -236,8 +239,6 @@ Other Changes overseerEnabled cluster property and an env var SOLR_CLOUD_OVERSEER_ENABLED. Read more in the upgrade guide. (David Smiley) -* SOLR-17712: Changing default behaviour of `waitForFinalState` while handling the collection creation and collection management to true and is now deprecated. (Abhishek Umarjikar) - ================== 9.10.0 ================== New Features --------------------- diff --git a/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java index e4a1a9060f7..d7458d16df0 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/BalanceReplicasRequestBody.java @@ -24,9 +24,8 @@ public class BalanceReplicasRequestBody { public BalanceReplicasRequestBody() {} - public BalanceReplicasRequestBody(Set nodes, Boolean waitForFinalState, String async) { + public BalanceReplicasRequestBody(Set nodes, String async) { this.nodes = nodes; - this.waitForFinalState = waitForFinalState; this.async = async; } @@ -36,14 +35,6 @@ public BalanceReplicasRequestBody(Set nodes, Boolean waitForFinalState, @JsonProperty(value = "nodes") public Set nodes; - @Schema( - description = - "If true, the request will complete only when all affected replicas become active. " - + "If false, the API will return the status of the single action, which may be " - + "before the new replica is online and active.") - @JsonProperty("waitForFinalState") - public Boolean waitForFinalState = true; - @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty("async") public String async; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CreateCollectionRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/CreateCollectionRequestBody.java index 5dce5840102..70cc842dda1 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/CreateCollectionRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/CreateCollectionRequestBody.java @@ -38,8 +38,6 @@ public class CreateCollectionRequestBody { @JsonProperty public Integer nrtReplicas; - @JsonProperty public Boolean waitForFinalState; - @JsonProperty public Boolean perReplicaState; @JsonProperty public String alias; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CreateReplicaRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/CreateReplicaRequestBody.java index a669cdaf414..316ce6933ee 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/CreateReplicaRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/CreateReplicaRequestBody.java @@ -30,7 +30,6 @@ public class CreateReplicaRequestBody { @JsonProperty public Integer nrtReplicas; @JsonProperty public Integer tlogReplicas; @JsonProperty public Integer pullReplicas; - @JsonProperty public Boolean waitForFinalState; @JsonProperty public Boolean followAliases; @JsonProperty public String async; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/CreateShardRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/CreateShardRequestBody.java index ea871998cca..6dd97f0083e 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/CreateShardRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/CreateShardRequestBody.java @@ -40,8 +40,6 @@ public class CreateShardRequestBody { @JsonProperty("nodeSet") public List nodeSet; - @JsonProperty public Boolean waitForFinalState; - @JsonProperty public Boolean followAliases; @JsonProperty public String async; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java index 7ca1bb7cfed..a4e00a59561 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/MigrateReplicasRequestBody.java @@ -25,10 +25,9 @@ public class MigrateReplicasRequestBody { public MigrateReplicasRequestBody() {} public MigrateReplicasRequestBody( - Set sourceNodes, Set targetNodes, Boolean waitForFinalState, String async) { + Set sourceNodes, Set targetNodes, String async) { this.sourceNodes = sourceNodes; this.targetNodes = targetNodes; - this.waitForFinalState = waitForFinalState; this.async = async; } @@ -42,14 +41,6 @@ public MigrateReplicasRequestBody( @JsonProperty public Set targetNodes; - @Schema( - description = - "If true, the request will complete only when all affected replicas become active. " - + "If false, the API will return the status of the single action, which may be " - + "before the new replicas are online and active.") - @JsonProperty - public Boolean waitForFinalState = true; - @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty public String async; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java index 35fc5d5d64a..0ee145c918d 100644 --- a/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/ReplaceNodeRequestBody.java @@ -23,9 +23,8 @@ public class ReplaceNodeRequestBody { public ReplaceNodeRequestBody() {} - public ReplaceNodeRequestBody(String targetNodeName, Boolean waitForFinalState, String async) { + public ReplaceNodeRequestBody(String targetNodeName, String async) { this.targetNodeName = targetNodeName; - this.waitForFinalState = waitForFinalState; this.async = async; } @@ -36,14 +35,6 @@ public ReplaceNodeRequestBody(String targetNodeName, Boolean waitForFinalState, @JsonProperty("targetNodeName") public String targetNodeName; - @Schema( - description = - "If true, the request will complete only when all affected replicas become active. " - + "If false, the API will return the status of the single action, which may be " - + "before the new replica is online and active.") - @JsonProperty("waitForFinalState") - public Boolean waitForFinalState = true; - @Schema(description = "Request ID to track this action which will be processed asynchronously.") @JsonProperty("async") public String async; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java index c2cd0148938..9b650595d09 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java @@ -1154,7 +1154,6 @@ public Map execute( final RequiredSolrParams requiredParams = req.getParams().required(); final var requestBody = new ReplaceNodeRequestBody(); requestBody.targetNodeName = params.get(TARGET_NODE); - requestBody.waitForFinalState = params.getBool(WAIT_FOR_FINAL_STATE); requestBody.async = params.get(ASYNC); final ReplaceNode replaceNodeAPI = new ReplaceNode(h.coreContainer, req, rsp); final SolrJerseyResponse replaceNodeResponse = diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicas.java b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicas.java index b582e39464b..263c64212a9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicas.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicas.java @@ -19,7 +19,6 @@ import static org.apache.solr.cloud.Overseer.QUEUE_OPERATION; import static org.apache.solr.common.params.CollectionParams.NODES; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; @@ -75,7 +74,6 @@ public ZkNodeProps createRemoteMessage(BalanceReplicasRequestBody requestBody) { final Map remoteMessage = new HashMap<>(); if (requestBody != null) { insertIfNotNull(remoteMessage, NODES, requestBody.nodes); - insertIfNotNull(remoteMessage, WAIT_FOR_FINAL_STATE, requestBody.waitForFinalState); insertIfNotNull(remoteMessage, ASYNC, requestBody.async); } remoteMessage.put(QUEUE_OPERATION, CollectionAction.BALANCE_REPLICAS.toLower()); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollection.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollection.java index fef25cfdb52..19584a21828 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollection.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollection.java @@ -34,7 +34,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.REPLICATION_FACTOR; import static org.apache.solr.common.params.CollectionAdminParams.TLOG_REPLICAS; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.common.params.CoreAdminParams.NAME; import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT; import static org.apache.solr.handler.admin.CollectionsHandler.waitForActiveCollection; @@ -173,7 +172,6 @@ public static ZkNodeProps createRemoteMessage(CreateCollectionRequestBody reqBod rawProperties.put(SHARDS_PROP, String.join(",", reqBody.shardNames)); rawProperties.put(PULL_REPLICAS, reqBody.pullReplicas); rawProperties.put(TLOG_REPLICAS, reqBody.tlogReplicas); - rawProperties.put(WAIT_FOR_FINAL_STATE, reqBody.waitForFinalState); rawProperties.put(PER_REPLICA_STATE, reqBody.perReplicaState); rawProperties.put(ALIAS, reqBody.alias); rawProperties.put(ASYNC, reqBody.async); @@ -266,7 +264,6 @@ public static CreateCollectionRequestBody createRequestBodyFromV1Params( requestBody.tlogReplicas = params.getInt(ZkStateReader.TLOG_REPLICAS); requestBody.pullReplicas = params.getInt(ZkStateReader.PULL_REPLICAS); requestBody.nrtReplicas = params.getInt(ZkStateReader.NRT_REPLICAS); - requestBody.waitForFinalState = params.getBool(WAIT_FOR_FINAL_STATE); requestBody.perReplicaState = params.getBool(PER_REPLICA_STATE); requestBody.alias = params.get(ALIAS); requestBody.async = params.get(ASYNC); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplica.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplica.java index 72c8eb058b1..91b99c0f737 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplica.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplica.java @@ -30,7 +30,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_PREFIX; import static org.apache.solr.common.params.CollectionAdminParams.SKIP_NODE_ASSIGNMENT; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.common.params.CoreAdminParams.DATA_DIR; import static org.apache.solr.common.params.CoreAdminParams.INSTANCE_DIR; import static org.apache.solr.common.params.CoreAdminParams.NAME; @@ -114,7 +113,6 @@ public static ZkNodeProps createRemoteMessage( insertIfNotNull(remoteMessage, DATA_DIR, requestBody.dataDir); insertIfNotNull(remoteMessage, ULOG_DIR, requestBody.ulogDir); insertIfNotNull(remoteMessage, REPLICA_TYPE, requestBody.type); - insertIfNotNull(remoteMessage, WAIT_FOR_FINAL_STATE, requestBody.waitForFinalState); insertIfNotNull(remoteMessage, NRT_REPLICAS, requestBody.nrtReplicas); insertIfNotNull(remoteMessage, TLOG_REPLICAS, requestBody.tlogReplicas); insertIfNotNull(remoteMessage, PULL_REPLICAS, requestBody.pullReplicas); @@ -146,7 +144,6 @@ public static CreateReplicaRequestBody createRequestBodyFromV1Params(SolrParams requestBody.nrtReplicas = params.getInt(NRT_REPLICAS); requestBody.tlogReplicas = params.getInt(TLOG_REPLICAS); requestBody.pullReplicas = params.getInt(PULL_REPLICAS); - requestBody.waitForFinalState = params.getBool(WAIT_FOR_FINAL_STATE); requestBody.followAliases = params.getBool(FOLLOW_ALIASES); requestBody.async = params.get(ASYNC); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShard.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShard.java index 2912fbd8e07..66d581a894f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShard.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShard.java @@ -31,7 +31,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_PREFIX; import static org.apache.solr.common.params.CollectionAdminParams.SHARD; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.common.params.CommonParams.NAME; import static org.apache.solr.handler.admin.api.CreateCollection.copyPrefixedPropertiesWithoutPrefix; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; @@ -113,7 +112,6 @@ public static CreateShardRequestBody createRequestBodyFromV1Params(SolrParams pa requestBody.nodeSet = Arrays.asList(nodeSetStr.split(",")); } } - requestBody.waitForFinalState = params.getBool(WAIT_FOR_FINAL_STATE); requestBody.followAliases = params.getBool(FOLLOW_ALIASES); requestBody.async = params.get(ASYNC); requestBody.properties = @@ -152,7 +150,6 @@ public static ZkNodeProps createRemoteMessage( insertIfNotNull(remoteMessage, NRT_REPLICAS, requestBody.nrtReplicas); insertIfNotNull(remoteMessage, TLOG_REPLICAS, requestBody.tlogReplicas); insertIfNotNull(remoteMessage, PULL_REPLICAS, requestBody.pullReplicas); - insertIfNotNull(remoteMessage, WAIT_FOR_FINAL_STATE, requestBody.waitForFinalState); insertIfNotNull(remoteMessage, FOLLOW_ALIASES, requestBody.followAliases); insertIfNotNull(remoteMessage, ASYNC, requestBody.async); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicas.java b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicas.java index 670540b4f74..d5bc6dbc983 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicas.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicas.java @@ -20,7 +20,6 @@ import static org.apache.solr.common.params.CollectionParams.SOURCE_NODES; import static org.apache.solr.common.params.CollectionParams.TARGET_NODES; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; @@ -83,7 +82,6 @@ public ZkNodeProps createRemoteMessage(MigrateReplicasRequestBody requestBody) { } insertIfNotNull(remoteMessage, SOURCE_NODES, requestBody.sourceNodes); insertIfNotNull(remoteMessage, TARGET_NODES, requestBody.targetNodes); - insertIfNotNull(remoteMessage, WAIT_FOR_FINAL_STATE, requestBody.waitForFinalState); insertIfNotNull(remoteMessage, ASYNC, requestBody.async); } else { throw new SolrException( diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNode.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNode.java index bb36f2036df..d9b035d0655 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNode.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNode.java @@ -20,7 +20,6 @@ import static org.apache.solr.common.params.CollectionParams.SOURCE_NODE; import static org.apache.solr.common.params.CollectionParams.TARGET_NODE; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; @@ -82,7 +81,6 @@ public ZkNodeProps createRemoteMessage(String nodeName, ReplaceNodeRequestBody r remoteMessage.put(SOURCE_NODE, nodeName); if (requestBody != null) { insertIfValueNotNull(remoteMessage, TARGET_NODE, requestBody.targetNodeName); - insertIfValueNotNull(remoteMessage, WAIT_FOR_FINAL_STATE, requestBody.waitForFinalState); insertIfValueNotNull(remoteMessage, ASYNC, requestBody.async); } remoteMessage.put(QUEUE_OPERATION, CollectionAction.REPLACENODE.toLower()); diff --git a/solr/core/src/test/org/apache/solr/cloud/BalanceReplicasTest.java b/solr/core/src/test/org/apache/solr/cloud/BalanceReplicasTest.java index b93d5bc3f34..26af7debe01 100644 --- a/solr/core/src/test/org/apache/solr/cloud/BalanceReplicasTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/BalanceReplicasTest.java @@ -149,7 +149,7 @@ public void testSomeNodes() throws Exception { cluster.getSolrClient(), "/api/cluster/replicas/balance", Utils.getReflectWriter( - new BalanceReplicasRequestBody(new HashSet<>(l.subList(1, 4)), true, null))); + new BalanceReplicasRequestBody(new HashSet<>(l.subList(1, 4)), null))); collection = cloudClient.getClusterState().getCollectionOrNull(coll, false); log.debug("### After balancing: {}", collection); diff --git a/solr/core/src/test/org/apache/solr/cloud/MigrateReplicasTest.java b/solr/core/src/test/org/apache/solr/cloud/MigrateReplicasTest.java index 296dcf001a5..db31a8b1d89 100644 --- a/solr/core/src/test/org/apache/solr/cloud/MigrateReplicasTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/MigrateReplicasTest.java @@ -126,7 +126,7 @@ public void test() throws Exception { callMigrateReplicas( cloudClient, new MigrateReplicasRequestBody( - Set.of(nodeToBeDecommissioned), Set.of(emptyNode), true, null)); + Set.of(nodeToBeDecommissioned), Set.of(emptyNode), null)); assertEquals( "MigrateReplicas request was unsuccessful", 0L, @@ -154,7 +154,7 @@ public void test() throws Exception { callMigrateReplicas( cloudClient, new MigrateReplicasRequestBody( - Set.of(emptyNode), Set.of(nodeToBeDecommissioned), true, null)); + Set.of(emptyNode), Set.of(nodeToBeDecommissioned), null)); assertEquals( "MigrateReplicas request was unsuccessful", 0L, @@ -279,7 +279,7 @@ public void testWithNoTarget() throws Exception { callMigrateReplicas( cloudClient, new MigrateReplicasRequestBody( - new HashSet<>(nodesToBeDecommissioned), Collections.emptySet(), true, null)); + new HashSet<>(nodesToBeDecommissioned), Collections.emptySet(), null)); assertEquals( "MigrateReplicas request was unsuccessful", 0L, @@ -328,7 +328,7 @@ public void testFailOnSingleNode() throws Exception { Map response = callMigrateReplicas( cloudClient, - new MigrateReplicasRequestBody(Set.of(liveNode), Collections.emptySet(), true, null)); + new MigrateReplicasRequestBody(Set.of(liveNode), Collections.emptySet(), null)); assertNotNull( "No error in response, when the request should have failed", response.get("error")); assertEquals( diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateCollectionAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateCollectionAPITest.java index d4edc1a987b..c7f91ed7425 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateCollectionAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateCollectionAPITest.java @@ -31,7 +31,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.REPLICATION_FACTOR; import static org.apache.solr.common.params.CollectionAdminParams.TLOG_REPLICAS; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.common.params.CoreAdminParams.NAME; import java.util.List; @@ -134,7 +133,6 @@ public void testCreateRemoteMessageAllProperties() { requestBody.shardNames = List.of("shard1", "shard2"); requestBody.pullReplicas = 789; requestBody.tlogReplicas = 987; - requestBody.waitForFinalState = true; requestBody.perReplicaState = true; requestBody.alias = "someAliasName"; requestBody.properties = Map.of("propName", "propValue"); @@ -157,7 +155,6 @@ public void testCreateRemoteMessageAllProperties() { assertEquals(789, remoteMessage.get(PULL_REPLICAS)); assertEquals(987, remoteMessage.get(TLOG_REPLICAS)); assertEquals(123, remoteMessage.get(NRT_REPLICAS)); // replicationFactor value used - assertEquals(true, remoteMessage.get(WAIT_FOR_FINAL_STATE)); assertEquals(true, remoteMessage.get(PER_REPLICA_STATE)); assertEquals("someAliasName", remoteMessage.get(ALIAS)); assertEquals("propValue", remoteMessage.get("property.propName")); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java index 2abe5d13397..8cf119dd14e 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java @@ -28,7 +28,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.FOLLOW_ALIASES; import static org.apache.solr.common.params.CollectionAdminParams.SKIP_NODE_ASSIGNMENT; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.apache.solr.common.params.CoreAdminParams.DATA_DIR; import static org.apache.solr.common.params.CoreAdminParams.INSTANCE_DIR; import static org.apache.solr.common.params.CoreAdminParams.NAME; @@ -105,7 +104,6 @@ public void testCreateRemoteMessageAllProperties() { requestBody.nodeSet = List.of("node1", "node2"); requestBody.node = "node3"; requestBody.skipNodeAssignment = Boolean.TRUE; - requestBody.waitForFinalState = true; requestBody.followAliases = true; requestBody.async = "someAsyncId"; requestBody.properties = Map.of("propName1", "propVal1", "propName2", "propVal2"); @@ -130,7 +128,6 @@ public void testCreateRemoteMessageAllProperties() { assertEquals("node1,node2", remoteMessage.get(CREATE_NODE_SET_PARAM)); assertEquals("node3", remoteMessage.get(NODE)); assertEquals(Boolean.TRUE, remoteMessage.get(SKIP_NODE_ASSIGNMENT)); - assertEquals(true, remoteMessage.get(WAIT_FOR_FINAL_STATE)); assertEquals(true, remoteMessage.get(FOLLOW_ALIASES)); assertEquals("someAsyncId", remoteMessage.get(ASYNC)); assertEquals("propVal1", remoteMessage.get("property.propName1")); @@ -154,7 +151,6 @@ public void testCanConvertV1ParamsToV2RequestBody() { v1Params.add(CREATE_NODE_SET_PARAM, "node1,node2"); v1Params.add(NODE, "node3"); v1Params.set(SKIP_NODE_ASSIGNMENT, true); - v1Params.set(WAIT_FOR_FINAL_STATE, true); v1Params.set(FOLLOW_ALIASES, true); v1Params.add(ASYNC, "someAsyncId"); v1Params.add("property.propName1", "propVal1"); @@ -174,7 +170,6 @@ public void testCanConvertV1ParamsToV2RequestBody() { assertEquals(List.of("node1", "node2"), requestBody.nodeSet); assertEquals("node3", requestBody.node); assertEquals(Boolean.TRUE, requestBody.skipNodeAssignment); - assertEquals(Boolean.TRUE, requestBody.waitForFinalState); assertEquals(Boolean.TRUE, requestBody.followAliases); assertEquals("someAsyncId", requestBody.async); assertEquals("propVal1", requestBody.properties.get("propName1")); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java index a8bc3edf658..5e17887a729 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java @@ -27,7 +27,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_PARAM; import static org.apache.solr.common.params.CollectionAdminParams.FOLLOW_ALIASES; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; -import static org.apache.solr.common.params.CommonAdminParams.WAIT_FOR_FINAL_STATE; import static org.hamcrest.Matchers.containsString; import java.util.List; @@ -113,7 +112,6 @@ public void testCreateRemoteMessageAllProperties() { requestBody.pullReplicas = 789; requestBody.createReplicas = true; requestBody.nodeSet = List.of("node1", "node2"); - requestBody.waitForFinalState = true; requestBody.followAliases = true; requestBody.async = "someAsyncId"; requestBody.properties = Map.of("propName1", "propVal1", "propName2", "propVal2"); @@ -130,7 +128,6 @@ public void testCreateRemoteMessageAllProperties() { assertEquals(456, remoteMessage.get(TLOG_REPLICAS)); assertEquals(789, remoteMessage.get(PULL_REPLICAS)); assertEquals("node1,node2", remoteMessage.get(CREATE_NODE_SET_PARAM)); - assertEquals(true, remoteMessage.get(WAIT_FOR_FINAL_STATE)); assertEquals(true, remoteMessage.get(FOLLOW_ALIASES)); assertEquals("someAsyncId", remoteMessage.get(ASYNC)); assertEquals("propVal1", remoteMessage.get("property.propName1")); @@ -147,7 +144,6 @@ public void testCanConvertV1ParamsToV2RequestBody() { v1Params.set(TLOG_REPLICAS, 456); v1Params.set(PULL_REPLICAS, 789); v1Params.add(CREATE_NODE_SET_PARAM, "node1,node2"); - v1Params.set(WAIT_FOR_FINAL_STATE, true); v1Params.set(FOLLOW_ALIASES, true); v1Params.add(ASYNC, "someAsyncId"); v1Params.add("property.propName1", "propVal1"); @@ -162,7 +158,6 @@ public void testCanConvertV1ParamsToV2RequestBody() { assertEquals(Integer.valueOf(789), requestBody.pullReplicas); assertNull(requestBody.createReplicas); assertEquals(List.of("node1", "node2"), requestBody.nodeSet); - assertEquals(Boolean.TRUE, requestBody.waitForFinalState); assertEquals(Boolean.TRUE, requestBody.followAliases); assertEquals("someAsyncId", requestBody.async); assertEquals("propVal1", requestBody.properties.get("propName1")); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java index 85f0ffc1d3c..fda249948d7 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java @@ -81,8 +81,7 @@ public void setUp() throws Exception { @Test public void testCreatesValidOverseerMessage() throws Exception { MigrateReplicasRequestBody requestBody = - new MigrateReplicasRequestBody( - Set.of("demoSourceNode"), Set.of("demoTargetNode"), false, "async"); + new MigrateReplicasRequestBody(Set.of("demoSourceNode"), Set.of("demoTargetNode"), "async"); migrateReplicasAPI.migrateReplicas(requestBody); verify(mockCommandRunner).runCollectionCommand(messageCapturer.capture(), any(), anyLong()); @@ -91,7 +90,6 @@ public void testCreatesValidOverseerMessage() throws Exception { assertEquals(5, createdMessageProps.size()); assertEquals(Set.of("demoSourceNode"), createdMessageProps.get("sourceNodes")); assertEquals(Set.of("demoTargetNode"), createdMessageProps.get("targetNodes")); - assertEquals(false, createdMessageProps.get("waitForFinalState")); assertEquals("async", createdMessageProps.get("async")); assertEquals("migrate_replicas", createdMessageProps.get("operation")); } @@ -99,7 +97,7 @@ public void testCreatesValidOverseerMessage() throws Exception { @Test public void testNoTargetNodes() throws Exception { MigrateReplicasRequestBody requestBody = - new MigrateReplicasRequestBody(Set.of("demoSourceNode"), null, null, null); + new MigrateReplicasRequestBody(Set.of("demoSourceNode"), null, null); migrateReplicasAPI.migrateReplicas(requestBody); verify(mockCommandRunner).runCollectionCommand(messageCapturer.capture(), any(), anyLong()); @@ -113,11 +111,10 @@ public void testNoTargetNodes() throws Exception { @Test public void testNoSourceNodesThrowsError() throws Exception { MigrateReplicasRequestBody requestBody1 = - new MigrateReplicasRequestBody( - Collections.emptySet(), Set.of("demoTargetNode"), null, null); + new MigrateReplicasRequestBody(Collections.emptySet(), Set.of("demoTargetNode"), null); assertThrows(SolrException.class, () -> migrateReplicasAPI.migrateReplicas(requestBody1)); MigrateReplicasRequestBody requestBody2 = - new MigrateReplicasRequestBody(null, Set.of("demoTargetNode"), null, null); + new MigrateReplicasRequestBody(null, Set.of("demoTargetNode"), null); assertThrows(SolrException.class, () -> migrateReplicasAPI.migrateReplicas(requestBody2)); } } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java index a325da55e7d..6868f753d9f 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java @@ -77,7 +77,7 @@ public void setUp() throws Exception { @Test public void testCreatesValidOverseerMessage() throws Exception { - final var requestBody = new ReplaceNodeRequestBody("demoTargetNode", false, "async"); + final var requestBody = new ReplaceNodeRequestBody("demoTargetNode", "async"); replaceNodeApi.replaceNode("demoSourceNode", requestBody); verify(mockCommandRunner).runCollectionCommand(messageCapturer.capture(), any(), anyLong()); @@ -86,7 +86,6 @@ public void testCreatesValidOverseerMessage() throws Exception { assertEquals(5, createdMessageProps.size()); assertEquals("demoSourceNode", createdMessageProps.get("sourceNode")); assertEquals("demoTargetNode", createdMessageProps.get("targetNode")); - assertEquals(false, createdMessageProps.get("waitForFinalState")); assertEquals("async", createdMessageProps.get("async")); assertEquals("replacenode", createdMessageProps.get("operation")); } @@ -105,7 +104,7 @@ public void testRequestBodyCanBeOmittedAltogether() throws Exception { @Test public void testOptionalValuesNotAddedToRemoteMessageIfNotProvided() throws Exception { - final var requestBody = new ReplaceNodeRequestBody("demoTargetNode", null, null); + final var requestBody = new ReplaceNodeRequestBody("demoTargetNode", null); replaceNodeApi.replaceNode("demoSourceNode", requestBody); verify(mockCommandRunner).runCollectionCommand(messageCapturer.capture(), any(), anyLong()); @@ -116,10 +115,6 @@ public void testOptionalValuesNotAddedToRemoteMessageIfNotProvided() throws Exce assertEquals("demoSourceNode", createdMessageProps.get("sourceNode")); assertEquals("demoTargetNode", createdMessageProps.get("targetNode")); assertEquals("replacenode", createdMessageProps.get("operation")); - assertFalse( - "Expected message to not contain value for waitForFinalState: " - + createdMessageProps.get("waitForFinalState"), - createdMessageProps.containsKey("waitForFinalState")); assertFalse( "Expected message to not contain value for async: " + createdMessageProps.get("async"), createdMessageProps.containsKey("async")); diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/collection-management.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/collection-management.adoc index 3f91e25941d..c62cbc33e14 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/collection-management.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/collection-management.adoc @@ -259,16 +259,6 @@ Overriding entries can result in unusable collections. Altering these entries by specifying `property._name_=_value_` is an expert-level option and should only be used if you have a thorough understanding of the consequences. ==== -`waitForFinalState`:: -+ -[%autowidth,frame=none] -|=== -|Optional |Default: true -|=== -+ -Default is `true`, which means that the request will complete only when all affected replicas become active. -If `false`, the API will return the status of the single action, which may be before the new replica is online and active. - `alias`:: + [%autowidth,frame=none] From d8cbb8eda6afea0a201ef348e08994f0836d6119 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Mon, 6 Oct 2025 09:00:35 -0400 Subject: [PATCH 3/9] TellPullReplica: processAsync --- .../src/test/org/apache/solr/cloud/TestPullReplica.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java b/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java index a5642b81942..84bacbe1557 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestPullReplica.java @@ -761,11 +761,11 @@ public void testSkipLeaderRecoveryProperty() throws Exception { numDocsAdded, getCollectionState(collectionName).getReplicas(EnumSet.of(Replica.Type.PULL))); - // Add yetanother PULL replica while the leader is down. - // This new replica will immediately stall going into recoveery, since the leader is down. + // Add yet another PULL replica while the leader is down. + // This new replica will immediately stall going into recovery, since the leader is down. CollectionAdminRequest.addReplicaToShard(collectionName, "shard1", Replica.Type.PULL) .setCreateNodeSet(pullFollowerJetty.getNodeName()) - .process(cluster.getSolrClient()); + .processAsync(cluster.getSolrClient()); waitForState( "3rd PULL replica should be down", collectionName, From 3e3342249f2acfde26c197093896d275861603c4 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Mon, 6 Oct 2025 09:01:00 -0400 Subject: [PATCH 4/9] replica props don't need locks? --- .../org/apache/solr/common/params/CollectionParams.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java index 73e2e9518a1..653e8597ee3 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java @@ -101,7 +101,7 @@ enum CollectionAction { ADDROLE(true, LockLevel.NONE), REMOVEROLE(true, LockLevel.NONE), CLUSTERPROP(true, LockLevel.NONE), - COLLECTIONPROP(true, LockLevel.COLLECTION), + COLLECTIONPROP(true, LockLevel.COLLECTION), // nocommit no lock? discuss REQUESTSTATUS(false, LockLevel.NONE), DELETESTATUS(false, LockLevel.NONE), ADDREPLICA(true, LockLevel.SHARD), @@ -111,8 +111,8 @@ enum CollectionAction { DISTRIBUTEDAPIPROCESSING(false, LockLevel.NONE), LIST(false, LockLevel.NONE), CLUSTERSTATUS(false, LockLevel.NONE), - ADDREPLICAPROP(true, LockLevel.REPLICA), - DELETEREPLICAPROP(true, LockLevel.REPLICA), + ADDREPLICAPROP(true, LockLevel.NONE), // nocommit discuss + DELETEREPLICAPROP(true, LockLevel.NONE), // nocommit discuss BALANCESHARDUNIQUE(true, LockLevel.COLLECTION), REBALANCELEADERS(true, LockLevel.COLLECTION), MODIFYCOLLECTION(true, LockLevel.COLLECTION), From 8c09b33e1815da213157babbb9b3f387db1a151d Mon Sep 17 00:00:00 2001 From: David Smiley Date: Mon, 6 Oct 2025 16:40:36 -0400 Subject: [PATCH 5/9] Fix ActiveReplicaWatcher when PRS (add replica, move replica, migrate, replace, balance) --- .../java/org/apache/solr/cloud/ActiveReplicaWatcher.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java b/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java index 30cd1ba165d..3e85ca9081b 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java +++ b/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java @@ -19,10 +19,12 @@ import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; import org.apache.solr.common.SolrCloseableLatch; import org.apache.solr.common.cloud.CollectionStateWatcher; import org.apache.solr.common.cloud.DocCollection; +import org.apache.solr.common.cloud.PerReplicaStates; import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.ZkStateReader; @@ -45,6 +47,7 @@ public class ActiveReplicaWatcher implements CollectionStateWatcher { private final List activeReplicas = new ArrayList<>(); private int lastZkVersion = -1; + private PerReplicaStates lastPrs; private SolrCloseableLatch latch; @@ -150,11 +153,13 @@ public synchronized boolean onStateChanged(Set liveNodes, DocCollection log.debug("-- already done, exiting..."); return true; } - if (collectionState.getZNodeVersion() == lastZkVersion) { + if (collectionState.getZNodeVersion() == lastZkVersion + && Objects.equals(lastPrs, collectionState.getPerReplicaStates())) { log.debug("-- spurious call with already seen zkVersion= {}, ignoring...", lastZkVersion); return false; } lastZkVersion = collectionState.getZNodeVersion(); + lastPrs = collectionState.getPerReplicaStates(); for (Slice slice : collectionState.getSlices()) { for (Replica replica : slice.getReplicas()) { From 76f7a32e51d8fd89f3d137a0d29365f9a2c25421 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Mon, 6 Oct 2025 23:02:20 -0400 Subject: [PATCH 6/9] AddReplicaCmd: don't wait if there are failures --- .../cloud/api/collections/AddReplicaCmd.java | 22 +++++++++++++------ .../collections/CollectionHandlingUtils.java | 14 +++++++++++- .../solrj/request/CollectionAdminRequest.java | 3 ++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java index 8f9863d8568..9b651d88922 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java @@ -177,21 +177,29 @@ List addReplica( shardRequestTracker.sendShardRequest(createReplica.node, params, shardHandler); } + SolrCloseableLatch waitForFinalStateLatch = + new SolrCloseableLatch(totalReplicas, ccc.getCloseableToLatchOn()); + Runnable runnable = () -> { shardRequestTracker.processResponses( results, shardHandler, true, "ADDREPLICA failed to create replica"); - for (CreateReplica replica : createReplicas) { - CollectionHandlingUtils.waitForCoreNodeName( - collectionName, replica.node, replica.coreName, ccc.getZkStateReader()); + // if there were errors, don't do any more waiting + if (results.get("failure") != null) { + while (waitForFinalStateLatch.getCount() > 0) { + waitForFinalStateLatch.countDown(); + } + } else { + for (CreateReplica replica : createReplicas) { + CollectionHandlingUtils.waitForCoreNodeName( + collectionName, replica.node, replica.coreName, ccc.getZkStateReader()); + } } if (onComplete != null) onComplete.run(); }; if (!parallel || waitForFinalState) { if (waitForFinalState) { - SolrCloseableLatch latch = - new SolrCloseableLatch(totalReplicas, ccc.getCloseableToLatchOn()); ActiveReplicaWatcher watcher = new ActiveReplicaWatcher( collectionName, @@ -199,11 +207,11 @@ List addReplica( createReplicas.stream() .map(createReplica -> createReplica.coreName) .collect(Collectors.toList()), - latch); + waitForFinalStateLatch); try { zkStateReader.registerCollectionStateWatcher(collectionName, watcher); runnable.run(); - if (!latch.await(timeout, TimeUnit.SECONDS)) { + if (!waitForFinalStateLatch.await(timeout, TimeUnit.SECONDS)) { throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "Timeout waiting " + timeout + " seconds for replica to become active."); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java index ba02a828724..be10bba0188 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java @@ -671,6 +671,18 @@ public void sendShardRequest( shardHandler.submit(sreq, replica, sreq.params); } + /** + * Processes all responses (waiting, if necessary), populating "success" or "failure" keyed data + * into {@code results} per shard response in turn keyed by node. If {@code asyncId} mode, will + * wait for their completion. + * + * @param results will hold shard request results aggregated to "success" and "failure" keys. + * @param abortOnError if any shard request has an exception, throw it. This doesn't apply to + * "STATUS=failed" responses. + * @param msgOnError the exception message for {@code abortOnError} + */ + // TODO it's too confusing how we sometime abort on error yet if async or find STATUS=FAILED not + // Recommend not doing any abort. Have a separate utility method that looks for "failure". void processResponses( NamedList results, ShardHandler shardHandler, @@ -703,8 +715,8 @@ void processResponses( } while (srsp != null); // If request is async wait for the core admin to complete before returning + // note: ignore abortOnError when async if (asyncId != null) { - // TODO: Shouldn't we abort with msgOnError exception when failure? waitForAsyncCallsToComplete(results); shardAsyncIdByNode.clear(); } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java index 3bff75b840e..7c6e1b3e098 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java @@ -1864,7 +1864,8 @@ public RequestStatusState waitFor(SolrClient client, long timeoutSeconds) long finishTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSeconds); RequestStatusState state = RequestStatusState.NOT_FOUND; while (System.nanoTime() < finishTime) { - state = this.process(client).getRequestStatus(); + RequestStatusResponse response = this.process(client); + state = response.getRequestStatus(); if (state == RequestStatusState.COMPLETED || state == RequestStatusState.FAILED) { propagateBasicAuthCreds(deleteAsyncId(requestId)).process(client); return state; From 5ef92a9352ddcfbf08cacfc7ef192a6e44801a21 Mon Sep 17 00:00:00 2001 From: abumarjikar Date: Tue, 7 Oct 2025 14:19:44 +0530 Subject: [PATCH 7/9] fixed some tests Please enter the commit message for your changes. Lines starting --- .../org/apache/solr/handler/admin/api/CreateReplicaAPITest.java | 2 +- .../org/apache/solr/handler/admin/api/CreateShardAPITest.java | 2 +- .../apache/solr/handler/admin/api/MigrateReplicasAPITest.java | 2 +- .../org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java index 8cf119dd14e..03dc620654b 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateReplicaAPITest.java @@ -112,7 +112,7 @@ public void testCreateRemoteMessageAllProperties() { CreateReplica.createRemoteMessage("someCollectionName", "someShardName", requestBody) .getProperties(); - assertEquals(20, remoteMessage.size()); + assertEquals(19, remoteMessage.size()); assertEquals("addreplica", remoteMessage.get(QUEUE_OPERATION)); assertEquals("someCollectionName", remoteMessage.get(COLLECTION)); assertEquals("someShardName", remoteMessage.get(SHARD_ID_PROP)); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java index 5e17887a729..58e9cac866f 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/CreateShardAPITest.java @@ -119,7 +119,7 @@ public void testCreateRemoteMessageAllProperties() { final var remoteMessage = CreateShard.createRemoteMessage("someCollectionName", requestBody).getProperties(); - assertEquals(13, remoteMessage.size()); + assertEquals(12, remoteMessage.size()); assertEquals("createshard", remoteMessage.get(QUEUE_OPERATION)); assertEquals("someCollectionName", remoteMessage.get(COLLECTION)); assertEquals("someShardName", remoteMessage.get(SHARD_ID_PROP)); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java index fda249948d7..3b0a333a9d7 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/MigrateReplicasAPITest.java @@ -87,7 +87,7 @@ public void testCreatesValidOverseerMessage() throws Exception { final ZkNodeProps createdMessage = messageCapturer.getValue(); final Map createdMessageProps = createdMessage.getProperties(); - assertEquals(5, createdMessageProps.size()); + assertEquals(4, createdMessageProps.size()); assertEquals(Set.of("demoSourceNode"), createdMessageProps.get("sourceNodes")); assertEquals(Set.of("demoTargetNode"), createdMessageProps.get("targetNodes")); assertEquals("async", createdMessageProps.get("async")); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java index 6868f753d9f..079e401b715 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/ReplaceNodeAPITest.java @@ -83,7 +83,7 @@ public void testCreatesValidOverseerMessage() throws Exception { final ZkNodeProps createdMessage = messageCapturer.getValue(); final Map createdMessageProps = createdMessage.getProperties(); - assertEquals(5, createdMessageProps.size()); + assertEquals(4, createdMessageProps.size()); assertEquals("demoSourceNode", createdMessageProps.get("sourceNode")); assertEquals("demoTargetNode", createdMessageProps.get("targetNode")); assertEquals("async", createdMessageProps.get("async")); From 77892bd5bbb10a1c48648ef89ef476e2b04f6569 Mon Sep 17 00:00:00 2001 From: abumarjikar Date: Thu, 9 Oct 2025 13:54:22 +0530 Subject: [PATCH 8/9] changes done in the tests --- .../src/test/org/apache/solr/cloud/TestLockTree.java | 10 +++++----- .../apache/solr/common/params/CollectionParams.java | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/TestLockTree.java b/solr/core/src/test/org/apache/solr/cloud/TestLockTree.java index 33455cc2f0c..55486a9c411 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestLockTree.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestLockTree.java @@ -48,7 +48,7 @@ public void testLocks() throws Exception { .getSession() .lock(CollectionAction.BALANCESHARDUNIQUE, Arrays.asList("coll1", "shard1"))); - assertNull( + assertNotNull( lockTree.getSession().lock(ADDREPLICAPROP, Arrays.asList("coll1", "shard1", "core_node2"))); coll1Lock.unlock(); Lock shard1Lock = @@ -71,9 +71,9 @@ public void testLocks() throws Exception { List> orderOfExecution = Arrays.asList( - Set.of("coll1/shard1/core_node2", "coll2/shard2"), - Set.of("coll1", "coll2"), - Set.of("coll1/shard1", "coll2/shard1")); + Set.of("coll1", "coll2/shard2"), + Set.of("coll1/shard1", "coll2"), + Set.of("coll2/shard1")); lockTree = new LockTree(); for (int counter = 0; counter < orderOfExecution.size(); counter++) { LockTree.Session session = lockTree.getSession(); @@ -82,7 +82,7 @@ public void testLocks() throws Exception { List threads = new ArrayList<>(); for (Pair> operation : operations) { final Lock lock = session.lock(operation.first(), operation.second()); - if (lock != null) { + if (lock != null && !lock.equals(LockTree.FREELOCK)) { Thread thread = new Thread(getRunnable(completedOps, operation, locks, lock)); threads.add(thread); thread.start(); diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java index 653e8597ee3..21ef3a6bd59 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java @@ -101,7 +101,7 @@ enum CollectionAction { ADDROLE(true, LockLevel.NONE), REMOVEROLE(true, LockLevel.NONE), CLUSTERPROP(true, LockLevel.NONE), - COLLECTIONPROP(true, LockLevel.COLLECTION), // nocommit no lock? discuss + COLLECTIONPROP(true, LockLevel.COLLECTION), // no commit no lock? discuss REQUESTSTATUS(false, LockLevel.NONE), DELETESTATUS(false, LockLevel.NONE), ADDREPLICA(true, LockLevel.SHARD), @@ -111,8 +111,8 @@ enum CollectionAction { DISTRIBUTEDAPIPROCESSING(false, LockLevel.NONE), LIST(false, LockLevel.NONE), CLUSTERSTATUS(false, LockLevel.NONE), - ADDREPLICAPROP(true, LockLevel.NONE), // nocommit discuss - DELETEREPLICAPROP(true, LockLevel.NONE), // nocommit discuss + ADDREPLICAPROP(true, LockLevel.NONE), // no commit discuss + DELETEREPLICAPROP(true, LockLevel.NONE), // no commit discuss BALANCESHARDUNIQUE(true, LockLevel.COLLECTION), REBALANCELEADERS(true, LockLevel.COLLECTION), MODIFYCOLLECTION(true, LockLevel.COLLECTION), From 2d403f5c881fc6190deec5440e8988e44fd60adb Mon Sep 17 00:00:00 2001 From: abumarjikar Date: Thu, 9 Oct 2025 19:06:11 +0530 Subject: [PATCH 9/9] changes done to deprecate --- .../apache/solr/client/solrj/request/CollectionAdminRequest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java index 7c6e1b3e098..e6251c17f1b 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java @@ -167,6 +167,7 @@ public String getAsyncId() { return asyncId; } + @Deprecated(since = "10.0") public void setWaitForFinalState(boolean waitForFinalState) { this.waitForFinalState = waitForFinalState; }