@Override
 protected ClusterBlockException checkBlock(PutWarmerRequest request, ClusterState state) {
   String[] concreteIndices =
       clusterService
           .state()
           .metaData()
           .concreteIndices(
               request.searchRequest().indicesOptions(), request.searchRequest().indices());
   return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
 }
 @Override
 public void handleRequest(final RestRequest request, final RestChannel channel) {
   PutWarmerRequest putWarmerRequest = new PutWarmerRequest(request.param("name"));
   putWarmerRequest.listenerThreaded(false);
   SearchRequest searchRequest =
       new SearchRequest(Strings.splitStringByCommaToArray(request.param("index")))
           .types(Strings.splitStringByCommaToArray(request.param("type")))
           .source(request.content(), request.contentUnsafe());
   searchRequest.indicesOptions(
       IndicesOptions.fromRequest(request, searchRequest.indicesOptions()));
   putWarmerRequest.searchRequest(searchRequest);
   putWarmerRequest.timeout(request.paramAsTime("timeout", putWarmerRequest.timeout()));
   putWarmerRequest.masterNodeTimeout(
       request.paramAsTime("master_timeout", putWarmerRequest.masterNodeTimeout()));
   client
       .admin()
       .indices()
       .putWarmer(
           putWarmerRequest, new AcknowledgedRestResponseActionListener(request, channel, logger));
 }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    PutWarmerRequest putWarmerRequest = new PutWarmerRequest(request.param("name"));
    putWarmerRequest.listenerThreaded(false);
    SearchRequest searchRequest =
        new SearchRequest(RestActions.splitIndices(request.param("index")))
            .types(RestActions.splitTypes(request.param("type")))
            .source(request.content(), request.contentUnsafe());
    putWarmerRequest.searchRequest(searchRequest);
    client
        .admin()
        .indices()
        .putWarmer(
            putWarmerRequest,
            new ActionListener<PutWarmerResponse>() {
              @Override
              public void onResponse(PutWarmerResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder
                      .startObject()
                      .field("ok", true)
                      .field("acknowledged", response.isAcknowledged());
                  builder.endObject();
                  channel.sendResponse(new XContentRestResponse(request, OK, builder));
                } catch (IOException 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
  protected void masterOperation(
      final PutWarmerRequest request,
      final ClusterState state,
      final ActionListener<PutWarmerResponse> listener)
      throws ElasticsearchException {
    // first execute the search request, see that its ok...
    SearchRequest searchRequest = new SearchRequest(request.searchRequest(), request);
    searchAction.execute(
        searchRequest,
        new ActionListener<SearchResponse>() {
          @Override
          public void onResponse(SearchResponse searchResponse) {
            if (searchResponse.getFailedShards() > 0) {
              listener.onFailure(
                  new ElasticsearchException(
                      "search failed with failed shards: "
                          + Arrays.toString(searchResponse.getShardFailures())));
              return;
            }

            clusterService.submitStateUpdateTask(
                "put_warmer [" + request.name() + "]",
                new AckedClusterStateUpdateTask<PutWarmerResponse>(request, listener) {

                  @Override
                  protected PutWarmerResponse newResponse(boolean acknowledged) {
                    return new PutWarmerResponse(acknowledged);
                  }

                  @Override
                  public void onFailure(String source, Throwable t) {
                    logger.debug(
                        "failed to put warmer [{}] on indices [{}]",
                        t,
                        request.name(),
                        request.searchRequest().indices());
                    super.onFailure(source, t);
                  }

                  @Override
                  public ClusterState execute(ClusterState currentState) {
                    MetaData metaData = currentState.metaData();
                    String[] concreteIndices =
                        metaData.concreteIndices(
                            request.searchRequest().indicesOptions(),
                            request.searchRequest().indices());

                    BytesReference source = null;
                    if (request.searchRequest().source() != null
                        && request.searchRequest().source().length() > 0) {
                      source = request.searchRequest().source();
                    } else if (request.searchRequest().extraSource() != null
                        && request.searchRequest().extraSource().length() > 0) {
                      source = request.searchRequest().extraSource();
                    }

                    // now replace it on the metadata
                    MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());

                    for (String index : concreteIndices) {
                      IndexMetaData indexMetaData = metaData.index(index);
                      if (indexMetaData == null) {
                        throw new IndexMissingException(new Index(index));
                      }
                      IndexWarmersMetaData warmers =
                          indexMetaData.custom(IndexWarmersMetaData.TYPE);
                      if (warmers == null) {
                        logger.info("[{}] putting warmer [{}]", index, request.name());
                        warmers =
                            new IndexWarmersMetaData(
                                new IndexWarmersMetaData.Entry(
                                    request.name(),
                                    request.searchRequest().types(),
                                    request.searchRequest().queryCache(),
                                    source));
                      } else {
                        boolean found = false;
                        List<IndexWarmersMetaData.Entry> entries =
                            new ArrayList<>(warmers.entries().size() + 1);
                        for (IndexWarmersMetaData.Entry entry : warmers.entries()) {
                          if (entry.name().equals(request.name())) {
                            found = true;
                            entries.add(
                                new IndexWarmersMetaData.Entry(
                                    request.name(),
                                    request.searchRequest().types(),
                                    request.searchRequest().queryCache(),
                                    source));
                          } else {
                            entries.add(entry);
                          }
                        }
                        if (!found) {
                          logger.info("[{}] put warmer [{}]", index, request.name());
                          entries.add(
                              new IndexWarmersMetaData.Entry(
                                  request.name(),
                                  request.searchRequest().types(),
                                  request.searchRequest().queryCache(),
                                  source));
                        } else {
                          logger.info("[{}] update warmer [{}]", index, request.name());
                        }
                        warmers =
                            new IndexWarmersMetaData(
                                entries.toArray(new IndexWarmersMetaData.Entry[entries.size()]));
                      }
                      IndexMetaData.Builder indexBuilder =
                          IndexMetaData.builder(indexMetaData)
                              .putCustom(IndexWarmersMetaData.TYPE, warmers);
                      mdBuilder.put(indexBuilder);
                    }

                    return ClusterState.builder(currentState).metaData(mdBuilder).build();
                  }
                });
          }

          @Override
          public void onFailure(Throwable e) {
            listener.onFailure(e);
          }
        });
  }