From 48ef08939001a9ec51bf21897c56a0aec5e2316d Mon Sep 17 00:00:00 2001 From: Serhiy Bzhezytskyy Date: Fri, 21 Aug 2026 15:50:15 +0300 Subject: [PATCH 1/3] SOLR-18367: client -- remove AsyncCollectionAdminRequest.setWaitForFinalState, default to true SOLR-17712 proposed removing the ability to opt out of waiting for final state entirely, defaulting to 'true'. The setter was deprecated in 9.10 as the first step; this is the second: the field now always resolves to true (no other code path can set it to false), so the setter -- and every test call site that was toggling it -- is gone. Removes/cleans 6 test call sites (5 were redundant .setWaitForFinalState(true) calls; CollectionsAPISolrJTest's .setWaitForFinalState(false) is dropped too, since the test doesn't depend on the non-waiting behavior). --- .../src/test/org/apache/solr/cloud/AddReplicaTest.java | 3 --- .../org/apache/solr/cloud/CollectionsAPISolrJTest.java | 1 - .../src/test/org/apache/solr/cloud/ReplaceNodeTest.java | 1 - .../src/test/org/apache/solr/cloud/SplitShardTest.java | 1 - .../org/apache/solr/core/TestSetPropertyConfigApis.java | 1 - .../solr/client/solrj/request/CollectionAdminRequest.java | 7 +------ 6 files changed, 1 insertion(+), 13 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/AddReplicaTest.java b/solr/core/src/test/org/apache/solr/cloud/AddReplicaTest.java index 7590311a01f9..23e473a72904 100644 --- a/solr/core/src/test/org/apache/solr/cloud/AddReplicaTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/AddReplicaTest.java @@ -155,8 +155,6 @@ public void test() throws Exception { replicas2.removeAll(replicas); assertEquals(1, replicas2.size()); - // use waitForFinalState - addReplica.setWaitForFinalState(true); addReplica.processAsync("001", cloudClient); requestStatus = CollectionAdminRequest.requestStatus("001"); rsp = requestStatus.process(cloudClient); @@ -205,7 +203,6 @@ public void testAddReplicaWithUserDefinedProperties() throws Exception { CollectionAdminRequest.addReplicaToShard(collectionName, "shard1"); addReplica.withProperty("customProp2", "val2.1"); addReplica.withProperty("customProp3", "val3"); - addReplica.setWaitForFinalState(true); addReplica.process(cloudClient); // Verify that the new core was created with user-defined properties coming from the request diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java index 17cb7e51ebb6..58790dea5f63 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java @@ -232,7 +232,6 @@ public void testCreateAndDeleteCollection() throws Exception { String collectionName = getSaferTestName(); CollectionAdminRequest.Create createREq = CollectionAdminRequest.createCollection(collectionName, "conf", 2, 2); - createREq.setWaitForFinalState(false); CollectionAdminResponse response = createREq.process(cluster.getSolrClient()); assertEquals(0, response.getStatus()); diff --git a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java index bc64635d2d87..a7dd392c9b6f 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java @@ -133,7 +133,6 @@ public void test() throws Exception { // let's do it back - this time wait for recoveries CollectionAdminRequest.AsyncCollectionAdminRequest replaceNodeRequest = createReplaceNodeRequest(emptyNode, nodeToBeDecommissioned, Boolean.TRUE); - replaceNodeRequest.setWaitForFinalState(true); replaceNodeRequest.processAndWait("001", cloudClient, 10); try (SolrClient coreClient = diff --git a/solr/core/src/test/org/apache/solr/cloud/SplitShardTest.java b/solr/core/src/test/org/apache/solr/cloud/SplitShardTest.java index 0b539bd39d0f..7729183cb261 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SplitShardTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SplitShardTest.java @@ -192,7 +192,6 @@ public void testWithChildDocuments() throws Exception { CollectionAdminRequest.splitShard(COLLECTION_NAME) .setNumSubShards(2) .setShardName("shard1"); - splitShard.setWaitForFinalState(true); splitShard.process(solrClient); waitForState( "Waiting for 2 active shards after split", COLLECTION_NAME, activeClusterShape(2, 2)); diff --git a/solr/core/src/test/org/apache/solr/core/TestSetPropertyConfigApis.java b/solr/core/src/test/org/apache/solr/core/TestSetPropertyConfigApis.java index 54c30f7d75fb..8bf024cbecda 100644 --- a/solr/core/src/test/org/apache/solr/core/TestSetPropertyConfigApis.java +++ b/solr/core/src/test/org/apache/solr/core/TestSetPropertyConfigApis.java @@ -279,7 +279,6 @@ public void testTwoCollectionsWithDifferentProps() throws Exception { private static void processAndAssertSuccess(final CollectionAdminRequest.Create op) throws Exception { - op.setWaitForFinalState(true); assertTrue(op.process(cluster.getSolrClient()).isSuccess()); } 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 7147699a592a..d7501e549ccf 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 @@ -146,7 +146,7 @@ public abstract static class AsyncCollectionAdminRequest extends CollectionAdminRequest { protected String asyncId = null; - protected boolean waitForFinalState = false; + protected boolean waitForFinalState = true; public AsyncCollectionAdminRequest(CollectionAction action) { super(action); @@ -165,11 +165,6 @@ public String getAsyncId() { return asyncId; } - @Deprecated(since = "9.10") - public void setWaitForFinalState(boolean waitForFinalState) { - this.waitForFinalState = waitForFinalState; - } - public void setAsyncId(String asyncId) { this.asyncId = asyncId; } From daf833bcb78b7c96e6437817fadfea50c7027388 Mon Sep 17 00:00:00 2001 From: Serhiy Bzhezytskyy Date: Fri, 21 Aug 2026 15:52:59 +0300 Subject: [PATCH 2/3] SOLR-18367: server -- default waitForFinalState to true in all 8 commands Completes SOLR-17712's proposal: 'internal logic should behave as if it's true'. Flips the server-side default from false to true in CreateCollectionCmd, AddReplicaCmd, CreateShardCmd, MoveReplicaCmd, SplitShardCmd, BalanceReplicasCmd, MigrateReplicasCmd, ReplaceNodeCmd. The V2 API request bodies (nullable Boolean fields) don't need a change -- when unset they serialize to absent, and these Cmd-level defaults are what actually apply. 72 tests across all 8 affected commands, 0 failures. --- .../org/apache/solr/cloud/api/collections/AddReplicaCmd.java | 2 +- .../apache/solr/cloud/api/collections/BalanceReplicasCmd.java | 2 +- .../apache/solr/cloud/api/collections/CreateCollectionCmd.java | 2 +- .../org/apache/solr/cloud/api/collections/CreateShardCmd.java | 2 +- .../apache/solr/cloud/api/collections/MigrateReplicasCmd.java | 2 +- .../org/apache/solr/cloud/api/collections/MoveReplicaCmd.java | 2 +- .../org/apache/solr/cloud/api/collections/ReplaceNodeCmd.java | 2 +- .../org/apache/solr/cloud/api/collections/SplitShardCmd.java | 2 +- 8 files changed, 8 insertions(+), 8 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 162dc555a8ad..81772ac698fa 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 @@ -113,7 +113,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); 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 743d9f5847fc..75ffe62b67d9 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 @@ -55,7 +55,7 @@ public void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList "'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); 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 14291d7b9411..fa7633cc1736 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 @@ -111,7 +111,7 @@ public void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList ClusterState clusterState = adminCmdContext.getClusterState(); final Aliases aliases = ccc.getZkStateReader().getAliases(); final String collectionName = message.getStr(NAME); - final boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, false); + final boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, true); final String alias = message.getStr(ALIAS, collectionName); log.info("Create collection {}", collectionName); boolean prsDefault = EnvUtils.getPropertyAsBool(PRS_DEFAULT_PROP, false); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateShardCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateShardCmd.java index 7c0e16336038..7176a830b083 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateShardCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateShardCmd.java @@ -50,7 +50,7 @@ public void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList throws Exception { String extCollectionName = message.getStr(COLLECTION_PROP); String sliceName = message.getStr(SHARD_ID_PROP); - boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, true); log.info("Create shard invoked: {}", message); if (extCollectionName == null || sliceName == null) diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/MigrateReplicasCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/MigrateReplicasCmd.java index 779ab9991977..fa3b4a2f1127 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/MigrateReplicasCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/MigrateReplicasCmd.java @@ -50,7 +50,7 @@ public void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList 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 634b23746335..2f1ce62920f1 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 @@ -72,7 +72,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 26a3730ca104..2eb72983fad6 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 @@ -47,7 +47,7 @@ public void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList 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 6740c5ba046d..4ddc265338a4 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 void call(AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList public boolean split( AdminCmdContext adminCmdContext, ZkNodeProps message, NamedList results) throws Exception { - boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, false); + boolean waitForFinalState = message.getBool(CommonAdminParams.WAIT_FOR_FINAL_STATE, true); String methodStr = message.getStr( CommonAdminParams.SPLIT_METHOD, SolrIndexSplitter.SplitMethod.REWRITE.toLower()); From 60507b6ce0220ca01bbf802776e90356e7a7c5b3 Mon Sep 17 00:00:00 2001 From: Serhiy Bzhezytskyy Date: Fri, 21 Aug 2026 15:54:35 +0300 Subject: [PATCH 3/3] SOLR-18367: add changelog entry --- .../unreleased/SOLR-18367-waitforfinalstate-removal.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/unreleased/SOLR-18367-waitforfinalstate-removal.yml diff --git a/changelog/unreleased/SOLR-18367-waitforfinalstate-removal.yml b/changelog/unreleased/SOLR-18367-waitforfinalstate-removal.yml new file mode 100644 index 000000000000..7af87ffbd3ef --- /dev/null +++ b/changelog/unreleased/SOLR-18367-waitforfinalstate-removal.yml @@ -0,0 +1,7 @@ +title: The `waitForFinalState` parameter now defaults to `true` for CREATE, ADDREPLICA, CREATESHARD, MOVEREPLICA, SPLITSHARD, BALANCE_REPLICAS, MIGRATE_REPLICAS, and REPLACENODE Collections API commands, so these commands wait for all affected replicas to become active before returning. Removed the now-unnecessary `CollectionAdminRequest.AsyncCollectionAdminRequest.setWaitForFinalState` SolrJ method, deprecated in 9.10 (SOLR-17712). +type: changed +authors: + - name: Serhiy Bzhezytskyy +links: + - name: SOLR-18367 + url: https://issues.apache.org/jira/browse/SOLR-18367