@Override
 protected Settings nodeSettings(int nodeOrdinal) {
   return Settings.builder()
       // we really need local GW here since this also checks for corruption etc.
       // and we need to make sure primaries are not just trashed if we don't have replicas
       .put(super.nodeSettings(nodeOrdinal))
       // speed up recoveries
       .put(
           ThrottlingAllocationDecider
               .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING.getKey(),
           5)
       .put(
           ThrottlingAllocationDecider
               .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING.getKey(),
           5)
       .build();
 }
 @Override
 protected Settings nodeSettings(int nodeOrdinal) {
   return Settings.builder()
       .put(super.nodeSettings(nodeOrdinal))
       // make sure that enough concurrent reroutes can happen at the same time
       // we have a minimum of 2 nodes, and a maximum of 10 shards, thus 5 should be enough
       .put(
           ThrottlingAllocationDecider
               .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING.getKey(),
           5)
       .put(
           ThrottlingAllocationDecider
               .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING.getKey(),
           5)
       .put(
           ConcurrentRebalanceAllocationDecider
               .CLUSTER_ROUTING_ALLOCATION_CLUSTER_CONCURRENT_REBALANCE_SETTING.getKey(),
           10)
       .build();
 }
  /**
   * Tests that higher prioritized primaries and replicas are allocated first even on the balanced
   * shard allocator See https://github.com/elastic/elasticsearch/issues/13249 for details
   */
  public void testPrioritizedIndicesAllocatedFirst() {
    AllocationService allocation =
        createAllocationService(
            Settings.builder()
                .put(
                    ThrottlingAllocationDecider
                        .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getKey(),
                    1)
                .put(
                    ThrottlingAllocationDecider
                        .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING
                        .getKey(),
                    10)
                .put(
                    ThrottlingAllocationDecider
                        .CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES_SETTING
                        .getKey(),
                    1)
                .put(
                    ThrottlingAllocationDecider
                        .CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING
                        .getKey(),
                    1)
                .build());
    final String highPriorityName;
    final String lowPriorityName;
    final int priorityFirst;
    final int prioritySecond;
    if (randomBoolean()) {
      highPriorityName = "first";
      lowPriorityName = "second";
      prioritySecond = 1;
      priorityFirst = 100;
    } else {
      lowPriorityName = "first";
      highPriorityName = "second";
      prioritySecond = 100;
      priorityFirst = 1;
    }
    MetaData metaData =
        MetaData.builder()
            .put(
                IndexMetaData.builder("first")
                    .settings(
                        settings(Version.CURRENT)
                            .put(IndexMetaData.SETTING_PRIORITY, priorityFirst))
                    .numberOfShards(2)
                    .numberOfReplicas(1))
            .put(
                IndexMetaData.builder("second")
                    .settings(
                        settings(Version.CURRENT)
                            .put(IndexMetaData.SETTING_PRIORITY, prioritySecond))
                    .numberOfShards(2)
                    .numberOfReplicas(1))
            .build();
    RoutingTable routingTable =
        RoutingTable.builder()
            .addAsNew(metaData.index("first"))
            .addAsNew(metaData.index("second"))
            .build();
    ClusterState clusterState =
        ClusterState.builder(
                org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(
                    Settings.EMPTY))
            .metaData(metaData)
            .routingTable(routingTable)
            .build();

    clusterState =
        ClusterState.builder(clusterState)
            .nodes(DiscoveryNodes.builder().put(newNode("node1")).put(newNode("node2")))
            .build();
    RoutingAllocation.Result rerouteResult = allocation.reroute(clusterState, "reroute");
    clusterState =
        ClusterState.builder(clusterState).routingTable(rerouteResult.routingTable()).build();

    routingTable = allocation.reroute(clusterState, "reroute").routingTable();
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
    assertEquals(2, clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size());
    assertEquals(
        highPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(0).getIndexName());
    assertEquals(
        highPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(1).getIndexName());

    routingTable =
        allocation
            .applyStartedShards(
                clusterState, clusterState.getRoutingNodes().shardsWithState(INITIALIZING))
            .routingTable();
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
    assertEquals(2, clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size());
    assertEquals(
        lowPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(0).getIndexName());
    assertEquals(
        lowPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(1).getIndexName());

    routingTable =
        allocation
            .applyStartedShards(
                clusterState, clusterState.getRoutingNodes().shardsWithState(INITIALIZING))
            .routingTable();
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
    assertEquals(
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).toString(),
        2,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size());
    assertEquals(
        highPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(0).getIndexName());
    assertEquals(
        highPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(1).getIndexName());

    routingTable =
        allocation
            .applyStartedShards(
                clusterState, clusterState.getRoutingNodes().shardsWithState(INITIALIZING))
            .routingTable();
    clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
    assertEquals(2, clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size());
    assertEquals(
        lowPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(0).getIndexName());
    assertEquals(
        lowPriorityName,
        clusterState.getRoutingNodes().shardsWithState(INITIALIZING).get(1).getIndexName());
  }