diff --git a/changelog/unreleased/SOLR-18391.yml b/changelog/unreleased/SOLR-18391.yml new file mode 100644 index 000000000000..f802da0b92f5 --- /dev/null +++ b/changelog/unreleased/SOLR-18391.yml @@ -0,0 +1,7 @@ +title: Fail collection creation cleanly when the collection is missing from cluster state during replica assignment. +type: fixed +authors: + - name: Nick Shanin +links: + - name: SOLR-18391 + url: https://issues.apache.org/jira/browse/SOLR-18391 diff --git a/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginAssignStrategy.java b/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginAssignStrategy.java index 13e2a0b53a4c..95af695c26f1 100644 --- a/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginAssignStrategy.java +++ b/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginAssignStrategy.java @@ -27,6 +27,7 @@ import org.apache.solr.cloud.api.collections.Assign; import org.apache.solr.cluster.Node; import org.apache.solr.cluster.Replica.ReplicaType; +import org.apache.solr.cluster.SolrCollection; import org.apache.solr.cluster.placement.BalanceRequest; import org.apache.solr.cluster.placement.DeleteCollectionRequest; import org.apache.solr.cluster.placement.DeleteReplicasRequest; @@ -67,11 +68,21 @@ public List assign( List placementRequests = new ArrayList<>(assignRequests.size()); for (Assign.AssignRequest assignRequest : assignRequests) { + SolrCollection solrCollection = + placementContext.getCluster().getCollection(assignRequest.collectionName); + if (solrCollection == null) { + // The collection can be missing from cluster state here (race between + // CreateCollectionCmd.waitForState and getClusterState). Fail with + // AssignmentException so the collection create is cleaned up instead of + // NPEing and leaving a zombie collection with no replicas. + throw new Assign.AssignmentException( + "Collection " + + assignRequest.collectionName + + " not found in cluster state; cannot assign replicas"); + } placementRequests.add( PlacementRequestImpl.toPlacementRequest( - placementContext.getCluster(), - placementContext.getCluster().getCollection(assignRequest.collectionName), - assignRequest)); + placementContext.getCluster(), solrCollection, assignRequest)); } final List replicaPositions = new ArrayList<>();