diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java b/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java index 24714642d00..c774959d3a6 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java @@ -55,6 +55,7 @@ import org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings; import org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.Randomness; import org.elasticsearch.common.Strings; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.component.LifecycleListener; @@ -1895,51 +1896,30 @@ public final class InternalTestCluster extends TestCluster { public synchronized void fullRestart(RestartCallback callback) throws Exception { int numNodesRestarted = 0; final Settings[] newNodeSettings = new Settings[nextNodeId.get()]; - Map, List> nodesByRoles = new HashMap<>(); - Set[] rolesOrderedByOriginalStartupOrder = new Set[nextNodeId.get()]; final int minMasterNodes = autoManageMasterNodes ? getMinMasterNodes(getMasterNodesCount()) : -1; - final int nodeCount = nodes.size(); + final List toStartAndPublish = new ArrayList<>(); // we want to start nodes in one go for (NodeAndClient nodeAndClient : nodes.values()) { callback.doAfterNodes(numNodesRestarted++, nodeAndClient.nodeClient()); logger.info("Stopping and resetting node [{}] ", nodeAndClient.name); if (activeDisruptionScheme != null) { activeDisruptionScheme.removeFromNode(nodeAndClient.name, this); } - DiscoveryNode discoveryNode = getInstanceFromNode(ClusterService.class, nodeAndClient.node()).localNode(); final Settings newSettings = nodeAndClient.closeForRestart(callback, minMasterNodes); newNodeSettings[nodeAndClient.nodeAndClientId()] = newSettings; - rolesOrderedByOriginalStartupOrder[nodeAndClient.nodeAndClientId()] = discoveryNode.getRoles(); - nodesByRoles.computeIfAbsent(discoveryNode.getRoles(), k -> new ArrayList<>()).add(nodeAndClient); + toStartAndPublish.add(nodeAndClient); } callback.onAllNodesStopped(); - assert nodesByRoles.values().stream().mapToInt(List::size).sum() == nodeCount; + // randomize start up order + Randomness.shuffle(toStartAndPublish); - // randomize start up order, but making sure that: - // 1) A data folder that was assigned to a data node will stay so - // 2) Data nodes will get the same node lock ordinal range, so custom index paths (where the ordinal is used) - // will still belong to data nodes - for (List sameRoleNodes : nodesByRoles.values()) { - Collections.shuffle(sameRoleNodes, random); - } - final List startUpOrder = new ArrayList<>(); - for (Set roles : rolesOrderedByOriginalStartupOrder) { - if (roles == null) { - // if some nodes were stopped, we want have a role for that ordinal - continue; - } - final List nodesByRole = nodesByRoles.get(roles); - startUpOrder.add(nodesByRole.remove(0)); - } - assert nodesByRoles.values().stream().mapToInt(List::size).sum() == 0; - - for (NodeAndClient nodeAndClient : startUpOrder) { - logger.info("creating node [{}] ", nodeAndClient.name); - nodeAndClient.recreateNode(newNodeSettings[nodeAndClient.nodeAndClientId()], () -> rebuildUnicastHostFiles(startUpOrder)); + for (NodeAndClient nodeAndClient : toStartAndPublish) { + logger.info("recreating node [{}] ", nodeAndClient.name); + nodeAndClient.recreateNode(newNodeSettings[nodeAndClient.nodeAndClientId()], () -> rebuildUnicastHostFiles(toStartAndPublish)); } - startAndPublishNodesAndClients(startUpOrder); + startAndPublishNodesAndClients(toStartAndPublish); if (callback.validateClusterForming()) { validateClusterFormed();