public static void buildBroadcastShardsHeader(
     JsonBuilder builder, BroadcastOperationResponse response) throws IOException {
   builder.startObject("_shards");
   builder.field("total", response.totalShards());
   builder.field("successful", response.successfulShards());
   builder.field("failed", response.failedShards());
   if (!response.shardFailures().isEmpty()) {
     builder.startArray("failures");
     for (ShardOperationFailedException shardFailure : response.shardFailures()) {
       builder.startObject();
       if (shardFailure.index() != null) {
         builder.field("index", shardFailure.index());
       }
       if (shardFailure.shardId() != -1) {
         builder.field("shard", shardFailure.shardId());
       }
       builder.field("reason", shardFailure.reason());
       builder.endObject();
     }
     builder.endArray();
   }
   builder.endObject();
 }
  @Test
  public void testBroadcastOperations() throws IOException {
    startNode("server1");

    client("server1").admin().indices().prepareCreate("test").execute().actionGet(5000);

    logger.info("Running Cluster Health");
    ClusterHealthResponse clusterHealth =
        client("server1")
            .admin()
            .cluster()
            .health(clusterHealthRequest().waitForYellowStatus())
            .actionGet();
    logger.info("Done Cluster Health, status " + clusterHealth.status());
    assertThat(clusterHealth.timedOut(), equalTo(false));
    assertThat(clusterHealth.status(), equalTo(ClusterHealthStatus.YELLOW));

    client("server1")
        .index(indexRequest("test").type("type1").id("1").source(source("1", "test")))
        .actionGet();
    FlushResponse flushResponse =
        client("server1").admin().indices().flush(flushRequest("test")).actionGet();
    assertThat(flushResponse.totalShards(), equalTo(10));
    assertThat(flushResponse.successfulShards(), equalTo(5));
    assertThat(flushResponse.failedShards(), equalTo(0));
    client("server1")
        .index(indexRequest("test").type("type1").id("2").source(source("2", "test")))
        .actionGet();
    RefreshResponse refreshResponse =
        client("server1").admin().indices().refresh(refreshRequest("test")).actionGet();
    assertThat(refreshResponse.totalShards(), equalTo(10));
    assertThat(refreshResponse.successfulShards(), equalTo(5));
    assertThat(refreshResponse.failedShards(), equalTo(0));

    logger.info("Count");
    // check count
    for (int i = 0; i < 5; i++) {
      // test successful
      CountResponse countResponse =
          client("server1")
              .count(
                  countRequest("test")
                      .query(termQuery("_type", "type1"))
                      .operationThreading(BroadcastOperationThreading.NO_THREADS))
              .actionGet();
      assertThat(countResponse.count(), equalTo(2l));
      assertThat(countResponse.totalShards(), equalTo(5));
      assertThat(countResponse.successfulShards(), equalTo(5));
      assertThat(countResponse.failedShards(), equalTo(0));
    }

    for (int i = 0; i < 5; i++) {
      CountResponse countResponse =
          client("server1")
              .count(
                  countRequest("test")
                      .query(termQuery("_type", "type1"))
                      .operationThreading(BroadcastOperationThreading.SINGLE_THREAD))
              .actionGet();
      assertThat(countResponse.count(), equalTo(2l));
      assertThat(countResponse.totalShards(), equalTo(5));
      assertThat(countResponse.successfulShards(), equalTo(5));
      assertThat(countResponse.failedShards(), equalTo(0));
    }

    for (int i = 0; i < 5; i++) {
      CountResponse countResponse =
          client("server1")
              .count(
                  countRequest("test")
                      .query(termQuery("_type", "type1"))
                      .operationThreading(BroadcastOperationThreading.THREAD_PER_SHARD))
              .actionGet();
      assertThat(countResponse.count(), equalTo(2l));
      assertThat(countResponse.totalShards(), equalTo(5));
      assertThat(countResponse.successfulShards(), equalTo(5));
      assertThat(countResponse.failedShards(), equalTo(0));
    }

    for (int i = 0; i < 5; i++) {
      // test failed (simply query that can't be parsed)
      CountResponse countResponse =
          client("server1")
              .count(
                  countRequest("test")
                      .query(Unicode.fromStringAsBytes("{ term : { _type : \"type1 } }")))
              .actionGet();

      assertThat(countResponse.count(), equalTo(0l));
      assertThat(countResponse.totalShards(), equalTo(5));
      assertThat(countResponse.successfulShards(), equalTo(0));
      assertThat(countResponse.failedShards(), equalTo(5));
      for (ShardOperationFailedException exp : countResponse.shardFailures()) {
        assertThat(exp.reason(), containsString("QueryParsingException"));
      }
    }
  }
  public void testWithDocsOnly() throws Exception {
    createIndex("test");
    ensureGreen();

    NumShards test = getNumShards("test");

    int numQueries = randomIntBetween(50, 100);
    logger.info("--> register a queries");
    for (int i = 0; i < numQueries; i++) {
      client()
          .prepareIndex("test", PercolatorService.TYPE_NAME, Integer.toString(i))
          .setSource(jsonBuilder().startObject().field("query", matchAllQuery()).endObject())
          .execute()
          .actionGet();
    }

    MultiPercolateRequestBuilder builder = client().prepareMultiPercolate();
    int numPercolateRequest = randomIntBetween(50, 100);
    for (int i = 0; i < numPercolateRequest; i++) {
      builder.add(
          client()
              .preparePercolate()
              .setIndices("test")
              .setDocumentType("type")
              .setPercolateDoc(
                  docBuilder()
                      .setDoc(jsonBuilder().startObject().field("field", "a").endObject())));
    }

    MultiPercolateResponse response = builder.execute().actionGet();
    assertThat(response.items().length, equalTo(numPercolateRequest));
    for (MultiPercolateResponse.Item item : response) {
      assertThat(item.isFailure(), equalTo(false));
      assertMatchCount(item.getResponse(), numQueries);
      assertThat(item.getResponse().getMatches().length, equalTo(numQueries));
    }

    // All illegal json
    builder = client().prepareMultiPercolate();
    for (int i = 0; i < numPercolateRequest; i++) {
      builder.add(
          client()
              .preparePercolate()
              .setIndices("test")
              .setDocumentType("type")
              .setSource("illegal json"));
    }

    response = builder.execute().actionGet();
    assertThat(response.items().length, equalTo(numPercolateRequest));
    for (MultiPercolateResponse.Item item : response) {
      assertThat(item.isFailure(), equalTo(false));
      assertThat(item.getResponse().getSuccessfulShards(), equalTo(0));
      assertThat(item.getResponse().getShardFailures().length, equalTo(test.numPrimaries));
      for (ShardOperationFailedException shardFailure : item.getResponse().getShardFailures()) {
        assertThat(shardFailure.reason(), containsString("Failed to derive xcontent"));
        assertThat(shardFailure.status().getStatus(), equalTo(400));
      }
    }

    // one valid request
    builder = client().prepareMultiPercolate();
    for (int i = 0; i < numPercolateRequest; i++) {
      builder.add(
          client()
              .preparePercolate()
              .setIndices("test")
              .setDocumentType("type")
              .setSource("illegal json"));
    }
    builder.add(
        client()
            .preparePercolate()
            .setIndices("test")
            .setDocumentType("type")
            .setPercolateDoc(
                docBuilder().setDoc(jsonBuilder().startObject().field("field", "a").endObject())));

    response = builder.execute().actionGet();
    assertThat(response.items().length, equalTo(numPercolateRequest + 1));
    assertThat(response.items()[numPercolateRequest].isFailure(), equalTo(false));
    assertMatchCount(response.items()[numPercolateRequest].getResponse(), numQueries);
    assertThat(
        response.items()[numPercolateRequest].getResponse().getMatches().length,
        equalTo(numQueries));
  }