@Test
  public void rerouteExplain() {
    Settings commonSettings = settingsBuilder().build();

    logger.info("--> starting a node");
    String node_1 = cluster().startNode(commonSettings);

    assertThat(cluster().size(), equalTo(1));
    ClusterHealthResponse healthResponse =
        client().admin().cluster().prepareHealth().setWaitForNodes("1").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));

    logger.info("--> create an index with 1 shard");
    client()
        .admin()
        .indices()
        .prepareCreate("test")
        .setSettings(
            settingsBuilder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0))
        .execute()
        .actionGet();

    ensureGreen("test");

    logger.info("--> disable allocation");
    Settings newSettings =
        settingsBuilder()
            .put(
                EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE,
                EnableAllocationDecider.Allocation.NONE.name())
            .build();
    client()
        .admin()
        .cluster()
        .prepareUpdateSettings()
        .setTransientSettings(newSettings)
        .execute()
        .actionGet();

    logger.info("--> starting a second node");
    String node_2 = cluster().startNode(commonSettings);
    assertThat(cluster().size(), equalTo(2));
    healthResponse =
        client().admin().cluster().prepareHealth().setWaitForNodes("2").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));

    logger.info("--> try to move the shard from node1 to node2");
    MoveAllocationCommand cmd = new MoveAllocationCommand(new ShardId("test", 0), node_1, node_2);
    ClusterRerouteResponse resp =
        client().admin().cluster().prepareReroute().add(cmd).setExplain(true).execute().actionGet();
    RoutingExplanations e = resp.getExplanations();
    assertThat(e.explanations().size(), equalTo(1));
    RerouteExplanation explanation = e.explanations().get(0);
    assertThat(explanation.command().name(), equalTo(cmd.name()));
    assertThat(((MoveAllocationCommand) explanation.command()).shardId(), equalTo(cmd.shardId()));
    assertThat(((MoveAllocationCommand) explanation.command()).fromNode(), equalTo(cmd.fromNode()));
    assertThat(((MoveAllocationCommand) explanation.command()).toNode(), equalTo(cmd.toNode()));
    assertThat(explanation.decisions().type(), equalTo(Decision.Type.YES));
  }
 @Test
 public void rerouteWithCommands_enableAllocationSettings() throws Exception {
   Settings commonSettings =
       settingsBuilder()
           .put(
               EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE,
               EnableAllocationDecider.Allocation.NONE.name())
           .put("gateway.type", "local")
           .build();
   rerouteWithCommands(commonSettings);
 }
  public void testClusterUpdateSettingsWithBlocks() {
    String key1 = "cluster.routing.allocation.enable";
    Settings transientSettings =
        Settings.builder().put(key1, EnableAllocationDecider.Allocation.NONE.name()).build();

    String key2 = "cluster.routing.allocation.node_concurrent_recoveries";
    Settings persistentSettings = Settings.builder().put(key2, "5").build();

    ClusterUpdateSettingsRequestBuilder request =
        client()
            .admin()
            .cluster()
            .prepareUpdateSettings()
            .setTransientSettings(transientSettings)
            .setPersistentSettings(persistentSettings);

    // Cluster settings updates are blocked when the cluster is read only
    try {
      setClusterReadOnly(true);
      assertBlocked(request, MetaData.CLUSTER_READ_ONLY_BLOCK);

      // But it's possible to update the settings to update the "cluster.blocks.read_only" setting
      Settings settings =
          Settings.builder().put(MetaData.SETTING_READ_ONLY_SETTING.getKey(), false).build();
      assertAcked(
          client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get());

    } finally {
      setClusterReadOnly(false);
    }

    // It should work now
    ClusterUpdateSettingsResponse response = request.execute().actionGet();

    assertAcked(response);
    assertThat(response.getTransientSettings().get(key1), notNullValue());
    assertThat(response.getTransientSettings().get(key2), nullValue());
    assertThat(response.getPersistentSettings().get(key1), nullValue());
    assertThat(response.getPersistentSettings().get(key2), notNullValue());
  }
  public void testClusterSettingsUpdateResponse() {
    String key1 = IndexStoreConfig.INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING.getKey();
    int value1 = 10;

    String key2 = EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING.getKey();
    String value2 = EnableAllocationDecider.Allocation.NONE.name();

    Settings transientSettings1 = Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).build();
    Settings persistentSettings1 = Settings.builder().put(key2, value2).build();

    ClusterUpdateSettingsResponse response1 =
        client()
            .admin()
            .cluster()
            .prepareUpdateSettings()
            .setTransientSettings(transientSettings1)
            .setPersistentSettings(persistentSettings1)
            .execute()
            .actionGet();

    assertAcked(response1);
    assertThat(response1.getTransientSettings().get(key1), notNullValue());
    assertThat(response1.getTransientSettings().get(key2), nullValue());
    assertThat(response1.getPersistentSettings().get(key1), nullValue());
    assertThat(response1.getPersistentSettings().get(key2), notNullValue());

    Settings transientSettings2 =
        Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).put(key2, value2).build();
    Settings persistentSettings2 = Settings.EMPTY;

    ClusterUpdateSettingsResponse response2 =
        client()
            .admin()
            .cluster()
            .prepareUpdateSettings()
            .setTransientSettings(transientSettings2)
            .setPersistentSettings(persistentSettings2)
            .execute()
            .actionGet();

    assertAcked(response2);
    assertThat(response2.getTransientSettings().get(key1), notNullValue());
    assertThat(response2.getTransientSettings().get(key2), notNullValue());
    assertThat(response2.getPersistentSettings().get(key1), nullValue());
    assertThat(response2.getPersistentSettings().get(key2), nullValue());

    Settings transientSettings3 = Settings.EMPTY;
    Settings persistentSettings3 =
        Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).put(key2, value2).build();

    ClusterUpdateSettingsResponse response3 =
        client()
            .admin()
            .cluster()
            .prepareUpdateSettings()
            .setTransientSettings(transientSettings3)
            .setPersistentSettings(persistentSettings3)
            .execute()
            .actionGet();

    assertAcked(response3);
    assertThat(response3.getTransientSettings().get(key1), nullValue());
    assertThat(response3.getTransientSettings().get(key2), nullValue());
    assertThat(response3.getPersistentSettings().get(key1), notNullValue());
    assertThat(response3.getPersistentSettings().get(key2), notNullValue());
  }