@Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    FlushRequest flushRequest = new FlushRequest(RestActions.splitIndices(request.param("index")));
    // we just send back a response, no need to fork a listener
    flushRequest.listenerThreaded(false);
    BroadcastOperationThreading operationThreading =
        BroadcastOperationThreading.fromString(
            request.param("operationThreading"), BroadcastOperationThreading.SINGLE_THREAD);
    if (operationThreading == BroadcastOperationThreading.NO_THREADS) {
      // since we don't spawn, don't allow no_threads, but change it to a single thread
      operationThreading = BroadcastOperationThreading.THREAD_PER_SHARD;
    }
    flushRequest.operationThreading(operationThreading);
    flushRequest.refresh(request.paramAsBoolean("refresh", flushRequest.refresh()));
    flushRequest.full(request.paramAsBoolean("full", flushRequest.full()));
    client
        .admin()
        .indices()
        .flush(
            flushRequest,
            new ActionListener<FlushResponse>() {
              @Override
              public void onResponse(FlushResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder.startObject();
                  builder.field("ok", true);

                  buildBroadcastShardsHeader(builder, response);

                  builder.endObject();
                  channel.sendResponse(new XContentRestResponse(request, OK, builder));
                } catch (Exception e) {
                  onFailure(e);
                }
              }

              @Override
              public void onFailure(Throwable e) {
                try {
                  channel.sendResponse(new XContentThrowableRestResponse(request, e));
                } catch (IOException e1) {
                  logger.error("Failed to send failure response", e1);
                }
              }
            });
  }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    BroadcastPingRequest broadcastPingRequest =
        new BroadcastPingRequest(RestActions.splitIndices(request.param("index")));
    broadcastPingRequest.queryHint(request.param("query_hint"));
    BroadcastOperationThreading operationThreading =
        BroadcastOperationThreading.fromString(
            request.param("operation_threading"), BroadcastOperationThreading.SINGLE_THREAD);
    if (operationThreading == BroadcastOperationThreading.NO_THREADS) {
      // since we don't spawn, don't allow no_threads, but change it to a single thread
      operationThreading = BroadcastOperationThreading.SINGLE_THREAD;
    }
    broadcastPingRequest.operationThreading(operationThreading);
    client
        .admin()
        .cluster()
        .ping(
            broadcastPingRequest,
            new ActionListener<BroadcastPingResponse>() {
              @Override
              public void onResponse(BroadcastPingResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder.startObject();
                  builder.field("ok", true);
                  buildBroadcastShardsHeader(builder, response);
                  builder.endObject();
                  channel.sendResponse(new XContentRestResponse(request, OK, builder));
                } catch (Exception e) {
                  onFailure(e);
                }
              }

              @Override
              public void onFailure(Throwable e) {
                try {
                  channel.sendResponse(new XContentThrowableRestResponse(request, e));
                } catch (IOException e1) {
                  logger.error("Failed to send failure response", e1);
                }
              }
            });
  }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    OptimizeRequest optimizeRequest =
        new OptimizeRequest(RestActions.splitIndices(request.param("index")));
    optimizeRequest.listenerThreaded(false);
    if (request.hasParam("ignore_indices")) {
      optimizeRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
    }
    try {
      optimizeRequest.waitForMerge(
          request.paramAsBoolean("wait_for_merge", optimizeRequest.waitForMerge()));
      optimizeRequest.maxNumSegments(
          request.paramAsInt("max_num_segments", optimizeRequest.maxNumSegments()));
      optimizeRequest.onlyExpungeDeletes(
          request.paramAsBoolean("only_expunge_deletes", optimizeRequest.onlyExpungeDeletes()));
      optimizeRequest.flush(request.paramAsBoolean("flush", optimizeRequest.flush()));
      optimizeRequest.refresh(request.paramAsBoolean("refresh", optimizeRequest.refresh()));

      BroadcastOperationThreading operationThreading =
          BroadcastOperationThreading.fromString(
              request.param("operation_threading"), BroadcastOperationThreading.SINGLE_THREAD);
      if (operationThreading == BroadcastOperationThreading.NO_THREADS) {
        // since we don't spawn, don't allow no_threads, but change it to a single thread
        operationThreading = BroadcastOperationThreading.THREAD_PER_SHARD;
      }
      optimizeRequest.operationThreading(operationThreading);
    } catch (Exception e) {
      try {
        XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
        channel.sendResponse(
            new XContentRestResponse(
                request,
                BAD_REQUEST,
                builder.startObject().field("error", e.getMessage()).endObject()));
      } catch (IOException e1) {
        logger.error("Failed to send failure response", e1);
      }
      return;
    }
    client
        .admin()
        .indices()
        .optimize(
            optimizeRequest,
            new ActionListener<OptimizeResponse>() {
              @Override
              public void onResponse(OptimizeResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder.startObject();
                  builder.field("ok", true);

                  buildBroadcastShardsHeader(builder, response);

                  builder.endObject();
                  channel.sendResponse(new XContentRestResponse(request, OK, builder));
                } catch (Throwable e) {
                  onFailure(e);
                }
              }

              @Override
              public void onFailure(Throwable e) {
                try {
                  channel.sendResponse(new XContentThrowableRestResponse(request, e));
                } catch (IOException e1) {
                  logger.error("Failed to send failure response", e1);
                }
              }
            });
  }