public void bulk(Resource resource, TrackingBytesArray data) throws IOException {
    Retry retry = retryPolicy.init();
    int httpStatus = 0;

    do {
      Response response = execute(PUT, resource.bulk(), data);
      httpStatus =
          (retryFailedEntries(response.body(), data)
              ? HttpStatus.SERVICE_UNAVAILABLE
              : HttpStatus.OK);
    } while (data.length() > 0 && retry.retry(httpStatus));
  }
  public List<List<Map<String, Object>>> targetShards(Resource resource) throws IOException {
    List<List<Map<String, Object>>> shardsJson = null;

    if (indexReadMissingAsEmpty) {
      Response res = execute(GET, resource.targetShards(), false);
      if (res.status() == HttpStatus.NOT_FOUND) {
        shardsJson = Collections.emptyList();
      } else {
        shardsJson = parseContent(res.body(), "shards");
      }
    } else {
      shardsJson = get(resource.targetShards(), "shards");
    }

    return shardsJson;
  }
  Response execute(Request request, boolean checkStatus) throws IOException {
    Response response = network.execute(request);

    if (checkStatus && response.hasFailed()) {
      // check error first
      String msg = parseContent(response.body(), "error");
      if (!StringUtils.hasText(msg)) {
        msg =
            String.format(
                "[%s] on [%s] failed; server[%s] returned [%s:%s]",
                request.method().name(),
                request.path(),
                response.uri(),
                response.status(),
                response.statusDescription());
      }

      throw new IllegalStateException(msg);
    }

    return response;
  }