public void testReplicaToPrimaryPromotion() throws Exception {
    Path dataPath = createTempDir();
    Settings nodeSettings = nodeSettings(dataPath);

    String node1 = internalCluster().startNode(nodeSettings);
    String IDX = "test";

    Settings idxSettings =
        Settings.builder()
            .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
            .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
            .put(IndexMetaData.SETTING_DATA_PATH, dataPath.toAbsolutePath().toString())
            .put(IndexMetaData.SETTING_SHADOW_REPLICAS, true)
            .put(IndexMetaData.SETTING_SHARED_FILESYSTEM, true)
            .build();

    prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=text").get();
    client().prepareIndex(IDX, "doc", "1").setSource("foo", "bar").get();
    client().prepareIndex(IDX, "doc", "2").setSource("foo", "bar").get();

    GetResponse gResp1 = client().prepareGet(IDX, "doc", "1").get();
    GetResponse gResp2 = client().prepareGet(IDX, "doc", "2").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("bar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("bar"));

    // Node1 has the primary, now node2 has the replica
    String node2 = internalCluster().startNode(nodeSettings);
    ensureGreen(IDX);
    client().admin().cluster().prepareHealth().setWaitForNodes("2").get();
    flushAndRefresh(IDX);

    logger.info("--> stopping node1 [{}]", node1);
    internalCluster().stopRandomNode(InternalTestCluster.nameFilter(node1));
    ensureYellow(IDX);

    logger.info("--> performing query");
    SearchResponse resp = client().prepareSearch(IDX).setQuery(matchAllQuery()).get();
    assertHitCount(resp, 2);

    gResp1 = client().prepareGet(IDX, "doc", "1").get();
    gResp2 = client().prepareGet(IDX, "doc", "2").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.toString(), gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("bar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("bar"));

    client().prepareIndex(IDX, "doc", "1").setSource("foo", "foobar").get();
    client().prepareIndex(IDX, "doc", "2").setSource("foo", "foobar").get();
    gResp1 = client().prepareGet(IDX, "doc", "1").get();
    gResp2 = client().prepareGet(IDX, "doc", "2").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.toString(), gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("foobar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("foobar"));
  }
  public void testPrimaryRelocation() throws Exception {
    Path dataPath = createTempDir();
    Settings nodeSettings = nodeSettings(dataPath);

    String node1 = internalCluster().startNode(nodeSettings);
    String IDX = "test";

    Settings idxSettings =
        Settings.builder()
            .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
            .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
            .put(IndexMetaData.SETTING_DATA_PATH, dataPath.toAbsolutePath().toString())
            .put(IndexMetaData.SETTING_SHADOW_REPLICAS, true)
            .put(IndexMetaData.SETTING_SHARED_FILESYSTEM, true)
            .build();

    prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=text").get();
    client().prepareIndex(IDX, "doc", "1").setSource("foo", "bar").get();
    client().prepareIndex(IDX, "doc", "2").setSource("foo", "bar").get();

    GetResponse gResp1 = client().prepareGet(IDX, "doc", "1").get();
    GetResponse gResp2 = client().prepareGet(IDX, "doc", "2").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("bar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("bar"));

    // Node1 has the primary, now node2 has the replica
    String node2 = internalCluster().startNode(nodeSettings);
    ensureGreen(IDX);
    client().admin().cluster().prepareHealth().setWaitForNodes("2").get();
    flushAndRefresh(IDX);

    // now prevent primary from being allocated on node 1 move to node_3
    String node3 = internalCluster().startNode(nodeSettings);
    Settings build =
        Settings.builder().put("index.routing.allocation.exclude._name", node1).build();
    client().admin().indices().prepareUpdateSettings(IDX).setSettings(build).execute().actionGet();

    ensureGreen(IDX);
    logger.info("--> performing query");
    SearchResponse resp = client().prepareSearch(IDX).setQuery(matchAllQuery()).get();
    assertHitCount(resp, 2);

    gResp1 = client().prepareGet(IDX, "doc", "1").get();
    gResp2 = client().prepareGet(IDX, "doc", "2").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.toString(), gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("bar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("bar"));

    client().prepareIndex(IDX, "doc", "3").setSource("foo", "bar").get();
    client().prepareIndex(IDX, "doc", "4").setSource("foo", "bar").get();
    gResp1 = client().prepareGet(IDX, "doc", "3").setPreference("_primary").get();
    gResp2 = client().prepareGet(IDX, "doc", "4").setPreference("_primary").get();
    assertTrue(gResp1.isExists());
    assertTrue(gResp2.isExists());
    assertThat(gResp1.getSource().get("foo"), equalTo("bar"));
    assertThat(gResp2.getSource().get("foo"), equalTo("bar"));
  }