@Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    String text = request.param("text");
    if (text == null && request.hasContent()) {
      text = request.content().toUtf8();
    }
    if (text == null) {
      try {
        channel.sendResponse(
            new XContentThrowableRestResponse(
                request, new ElasticsearchIllegalArgumentException("text is missing")));
      } catch (IOException e1) {
        logger.warn("Failed to send response", e1);
      }
      return;
    }

    AnalyzeRequest analyzeRequest = new AnalyzeRequest(request.param("index"), text);
    analyzeRequest.listenerThreaded(false);
    analyzeRequest.preferLocal(
        request.paramAsBoolean("prefer_local", analyzeRequest.preferLocalShard()));
    analyzeRequest.analyzer(request.param("analyzer"));
    analyzeRequest.field(request.param("field"));
    analyzeRequest.tokenizer(request.param("tokenizer"));
    analyzeRequest.tokenFilters(
        request.paramAsStringArray(
            "token_filters", request.paramAsStringArray("filters", analyzeRequest.tokenFilters())));
    analyzeRequest.charFilters(
        request.paramAsStringArray("char_filters", analyzeRequest.charFilters()));
    client
        .admin()
        .indices()
        .analyze(
            analyzeRequest,
            new ActionListener<AnalyzeResponse>() {
              @Override
              public void onResponse(AnalyzeResponse response) {
                try {
                  XContentBuilder builder = restContentBuilder(request, null);
                  builder.startObject();
                  response.toXContent(builder, request);
                  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);
                }
              }
            });
  }
 @Override
 public void handleRequest(
     final RestRequest request, final RestChannel channel, final Client client) {
   ClusterStatsRequest clusterStatsRequest =
       new ClusterStatsRequest().nodesIds(request.paramAsStringArray("nodeId", null));
   clusterStatsRequest.timeout(request.param("timeout"));
   client
       .admin()
       .cluster()
       .clusterStats(clusterStatsRequest, new RestToXContentListener<>(channel));
 }
  private Table buildTable(
      RestRequest req,
      ClusterStateResponse state,
      NodesInfoResponse nodesInfo,
      NodesStatsResponse nodesStats) {
    final String[] threadPools = req.paramAsStringArray("thread_pool_patterns", new String[] {"*"});
    final DiscoveryNodes nodes = state.getState().nodes();
    final Table table = getTableWithHeader(req);

    // collect all thread pool names that we see across the nodes
    final Set<String> candidates = new HashSet<>();
    for (final NodeStats nodeStats : nodesStats.getNodes()) {
      for (final ThreadPoolStats.Stats threadPoolStats : nodeStats.getThreadPool()) {
        candidates.add(threadPoolStats.getName());
      }
    }

    // collect all thread pool names that match the specified thread pool patterns
    final Set<String> included = new HashSet<>();
    for (final String candidate : candidates) {
      if (Regex.simpleMatch(threadPools, candidate)) {
        included.add(candidate);
      }
    }

    for (final DiscoveryNode node : nodes) {
      final NodeInfo info = nodesInfo.getNodesMap().get(node.getId());
      final NodeStats stats = nodesStats.getNodesMap().get(node.getId());

      final Map<String, ThreadPoolStats.Stats> poolThreadStats;
      final Map<String, ThreadPool.Info> poolThreadInfo;

      if (stats == null) {
        poolThreadStats = Collections.emptyMap();
        poolThreadInfo = Collections.emptyMap();
      } else {
        // we use a sorted map to ensure that thread pools are sorted by name
        poolThreadStats = new TreeMap<>();
        poolThreadInfo = new HashMap<>();

        ThreadPoolStats threadPoolStats = stats.getThreadPool();
        for (ThreadPoolStats.Stats threadPoolStat : threadPoolStats) {
          poolThreadStats.put(threadPoolStat.getName(), threadPoolStat);
        }
        if (info != null) {
          for (ThreadPool.Info threadPoolInfo : info.getThreadPool()) {
            poolThreadInfo.put(threadPoolInfo.getName(), threadPoolInfo);
          }
        }
      }
      for (Map.Entry<String, ThreadPoolStats.Stats> entry : poolThreadStats.entrySet()) {

        if (!included.contains(entry.getKey())) continue;

        table.startRow();

        table.addCell(node.getName());
        table.addCell(node.getId());
        table.addCell(node.getEphemeralId());
        table.addCell(info == null ? null : info.getProcess().getId());
        table.addCell(node.getHostName());
        table.addCell(node.getHostAddress());
        table.addCell(node.getAddress().address().getPort());
        final ThreadPoolStats.Stats poolStats = entry.getValue();
        final ThreadPool.Info poolInfo = poolThreadInfo.get(entry.getKey());

        Long maxQueueSize = null;
        String keepAlive = null;
        Integer minThreads = null;
        Integer maxThreads = null;

        if (poolInfo != null) {
          if (poolInfo.getQueueSize() != null) {
            maxQueueSize = poolInfo.getQueueSize().singles();
          }
          if (poolInfo.getKeepAlive() != null) {
            keepAlive = poolInfo.getKeepAlive().toString();
          }
          if (poolInfo.getMin() >= 0) {
            minThreads = poolInfo.getMin();
          }
          if (poolInfo.getMax() >= 0) {
            maxThreads = poolInfo.getMax();
          }
        }

        table.addCell(entry.getKey());
        table.addCell(poolInfo == null ? null : poolInfo.getThreadPoolType().getType());
        table.addCell(poolStats == null ? null : poolStats.getActive());
        table.addCell(poolStats == null ? null : poolStats.getThreads());
        table.addCell(poolStats == null ? null : poolStats.getQueue());
        table.addCell(maxQueueSize);
        table.addCell(poolStats == null ? null : poolStats.getRejected());
        table.addCell(poolStats == null ? null : poolStats.getLargest());
        table.addCell(poolStats == null ? null : poolStats.getCompleted());
        table.addCell(minThreads);
        table.addCell(maxThreads);
        table.addCell(keepAlive);

        table.endRow();
      }
    }

    return table;
  }
  @Override
  public void handleRequest(
      final RestRequest request, final RestChannel channel, final Client client) {
    IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
    indicesStatsRequest.indicesOptions(
        IndicesOptions.fromRequest(request, indicesStatsRequest.indicesOptions()));
    indicesStatsRequest.indices(Strings.splitStringByCommaToArray(request.param("index")));
    indicesStatsRequest.types(Strings.splitStringByCommaToArray(request.param("types")));

    Set<String> metrics = Strings.splitStringByCommaToSet(request.param("metric", "_all"));
    // short cut, if no metrics have been specified in URI
    if (metrics.size() == 1 && metrics.contains("_all")) {
      indicesStatsRequest.all();
    } else {
      indicesStatsRequest.clear();
      indicesStatsRequest.docs(metrics.contains("docs"));
      indicesStatsRequest.store(metrics.contains("store"));
      indicesStatsRequest.indexing(metrics.contains("indexing"));
      indicesStatsRequest.search(metrics.contains("search"));
      indicesStatsRequest.get(metrics.contains("get"));
      indicesStatsRequest.merge(metrics.contains("merge"));
      indicesStatsRequest.refresh(metrics.contains("refresh"));
      indicesStatsRequest.flush(metrics.contains("flush"));
      indicesStatsRequest.warmer(metrics.contains("warmer"));
      indicesStatsRequest.queryCache(metrics.contains("query_cache"));
      indicesStatsRequest.percolate(metrics.contains("percolate"));
      indicesStatsRequest.segments(metrics.contains("segments"));
      indicesStatsRequest.fieldData(metrics.contains("fielddata"));
      indicesStatsRequest.completion(metrics.contains("completion"));
      indicesStatsRequest.suggest(metrics.contains("suggest"));
      indicesStatsRequest.requestCache(metrics.contains("request_cache"));
      indicesStatsRequest.recovery(metrics.contains("recovery"));
      indicesStatsRequest.translog(metrics.contains("translog"));
    }

    if (request.hasParam("groups")) {
      indicesStatsRequest.groups(Strings.splitStringByCommaToArray(request.param("groups")));
    }

    if (request.hasParam("types")) {
      indicesStatsRequest.types(Strings.splitStringByCommaToArray(request.param("types")));
    }

    if (indicesStatsRequest.completion()
        && (request.hasParam("fields") || request.hasParam("completion_fields"))) {
      indicesStatsRequest.completionFields(
          request.paramAsStringArray(
              "completion_fields", request.paramAsStringArray("fields", Strings.EMPTY_ARRAY)));
    }

    if (indicesStatsRequest.fieldData()
        && (request.hasParam("fields") || request.hasParam("fielddata_fields"))) {
      indicesStatsRequest.fieldDataFields(
          request.paramAsStringArray(
              "fielddata_fields", request.paramAsStringArray("fields", Strings.EMPTY_ARRAY)));
    }

    client
        .admin()
        .indices()
        .stats(
            indicesStatsRequest,
            new RestBuilderListener<IndicesStatsResponse>(channel) {
              @Override
              public RestResponse buildResponse(
                  IndicesStatsResponse response, XContentBuilder builder) throws Exception {
                builder.startObject();
                buildBroadcastShardsHeader(builder, request, response);
                response.toXContent(builder, request);
                builder.endObject();
                return new BytesRestResponse(OK, builder);
              }
            });
  }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    String[] nodesIds = Strings.splitStringByCommaToArray(request.param("nodeId"));
    Set<String> metrics = Strings.splitStringByCommaToSet(request.param("metric", "_all"));

    NodesStatsRequest nodesStatsRequest = new NodesStatsRequest(nodesIds);
    nodesStatsRequest.listenerThreaded(false);

    if (metrics.size() == 1 && metrics.contains("_all")) {
      nodesStatsRequest.all();
      nodesStatsRequest.indices(CommonStatsFlags.ALL);
    } else {
      nodesStatsRequest.clear();
      nodesStatsRequest.os(metrics.contains("os"));
      nodesStatsRequest.jvm(metrics.contains("jvm"));
      nodesStatsRequest.threadPool(metrics.contains("thread_pool"));
      nodesStatsRequest.network(metrics.contains("network"));
      nodesStatsRequest.fs(metrics.contains("fs"));
      nodesStatsRequest.transport(metrics.contains("transport"));
      nodesStatsRequest.http(metrics.contains("http"));
      nodesStatsRequest.indices(metrics.contains("indices"));
      nodesStatsRequest.process(metrics.contains("process"));
      nodesStatsRequest.breaker(metrics.contains("breaker"));

      // check for index specific metrics
      if (metrics.contains("indices")) {
        Set<String> indexMetrics =
            Strings.splitStringByCommaToSet(request.param("indexMetric", "_all"));
        if (indexMetrics.size() == 1 && indexMetrics.contains("_all")) {
          nodesStatsRequest.indices(CommonStatsFlags.ALL);
        } else {
          CommonStatsFlags flags = new CommonStatsFlags();
          for (Flag flag : CommonStatsFlags.Flag.values()) {
            flags.set(flag, indexMetrics.contains(flag.getRestName()));
          }
          nodesStatsRequest.indices(flags);
        }
      }
    }

    if (nodesStatsRequest.indices().isSet(Flag.FieldData)
        && (request.hasParam("fields") || request.hasParam("fielddata_fields"))) {
      nodesStatsRequest
          .indices()
          .fieldDataFields(
              request.paramAsStringArray(
                  "fielddata_fields", request.paramAsStringArray("fields", null)));
    }
    if (nodesStatsRequest.indices().isSet(Flag.Completion)
        && (request.hasParam("fields") || request.hasParam("completion_fields"))) {
      nodesStatsRequest
          .indices()
          .completionDataFields(
              request.paramAsStringArray(
                  "completion_fields", request.paramAsStringArray("fields", null)));
    }
    if (nodesStatsRequest.indices().isSet(Flag.Search) && (request.hasParam("groups"))) {
      nodesStatsRequest.indices().groups(request.paramAsStringArray("groups", null));
    }
    if (nodesStatsRequest.indices().isSet(Flag.Indexing) && (request.hasParam("types"))) {
      nodesStatsRequest.indices().types(request.paramAsStringArray("types", null));
    }

    client
        .admin()
        .cluster()
        .nodesStats(
            nodesStatsRequest,
            new ActionListener<NodesStatsResponse>() {
              @Override
              public void onResponse(NodesStatsResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder.startObject();
                  response.toXContent(builder, request);
                  builder.endObject();
                  channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder));
                } catch (Throwable e) {
                  onFailure(e);
                }
              }

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