/**
   * Only handles reroute but *without* any reassignment of unassigned shards or rebalancing. Does
   * make sure to handle removed nodes, but only moved the shards to UNASSIGNED, does not reassign
   * them.
   */
  public RoutingAllocation.Result rerouteWithNoReassign(ClusterState clusterState, boolean debug) {
    RoutingNodes routingNodes = clusterState.routingNodes();
    // shuffle the unassigned nodes, just so we won't have things like poison failed shards
    routingNodes.unassigned().shuffle();
    RoutingAllocation allocation =
        new RoutingAllocation(
            allocationDeciders,
            routingNodes,
            clusterState.nodes(),
            clusterInfoService.getClusterInfo());
    allocation.debugDecision(debug);
    boolean changed = false;
    // first, clear from the shards any node id they used to belong to that is now dead
    changed |= deassociateDeadNodes(allocation);

    // create a sorted list of from nodes with least number of shards to the maximum ones
    applyNewNodes(allocation);

    // elect primaries *before* allocating unassigned, so backups of primaries that failed
    // will be moved to primary state and not wait for primaries to be allocated and recovered
    // (*from gateway*)
    changed |= electPrimariesAndUnassignedDanglingReplicas(allocation);

    if (!changed) {
      return new RoutingAllocation.Result(false, clusterState.routingTable());
    }
    return new RoutingAllocation.Result(
        true,
        new RoutingTable.Builder()
            .updateNodes(routingNodes)
            .build()
            .validateRaiseException(clusterState.metaData()));
  }
 public RoutingAllocation.Result reroute(
     ClusterState clusterState, AllocationCommands commands, boolean explain)
     throws ElasticsearchException {
   RoutingNodes routingNodes = clusterState.routingNodes();
   // we don't shuffle the unassigned shards here, to try and get as close as possible to
   // a consistent result of the effect the commands have on the routing
   // this allows systems to dry run the commands, see the resulting cluster state, and act on it
   RoutingAllocation allocation =
       new RoutingAllocation(
           allocationDeciders,
           routingNodes,
           clusterState.nodes(),
           clusterInfoService.getClusterInfo());
   // don't short circuit deciders, we want a full explanation
   allocation.debugDecision(true);
   // we ignore disable allocation, because commands are explicit
   allocation.ignoreDisable(true);
   RoutingExplanations explanations = commands.execute(allocation, explain);
   // we revert the ignore disable flag, since when rerouting, we want the original setting to take
   // place
   allocation.ignoreDisable(false);
   // the assumption is that commands will move / act on shards (or fail through exceptions)
   // so, there will always be shard "movements", so no need to check on reroute
   reroute(allocation);
   return new RoutingAllocation.Result(
       true,
       new RoutingTable.Builder()
           .updateNodes(routingNodes)
           .build()
           .validateRaiseException(clusterState.metaData()),
       explanations);
 }
 /**
  * Reroutes the routing table based on the live nodes.
  *
  * <p>
  *
  * <p>If the same instance of the routing table is returned, then no change has been made.
  */
 public RoutingAllocation.Result reroute(ClusterState clusterState, boolean debug) {
   RoutingNodes routingNodes = clusterState.routingNodes();
   // shuffle the unassigned nodes, just so we won't have things like poison failed shards
   routingNodes.unassigned().shuffle();
   RoutingAllocation allocation =
       new RoutingAllocation(
           allocationDeciders,
           routingNodes,
           clusterState.nodes(),
           clusterInfoService.getClusterInfo());
   allocation.debugDecision(debug);
   if (!reroute(allocation)) {
     return new RoutingAllocation.Result(false, clusterState.routingTable());
   }
   return new RoutingAllocation.Result(
       true,
       new RoutingTable.Builder()
           .updateNodes(routingNodes)
           .build()
           .validateRaiseException(clusterState.metaData()));
 }