@SuppressWarnings({"unchecked"})
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    PutIndexTemplateRequest putRequest = new PutIndexTemplateRequest(request.param("name"));

    try {
      putRequest.create(request.paramAsBoolean("create", false));
      putRequest.cause(request.param("cause", ""));
      putRequest.timeout(request.paramAsTime("timeout", timeValueSeconds(10)));
      putRequest.source(
          request.contentByteArray(), request.contentByteArrayOffset(), request.contentLength());
    } catch (Exception e) {
      try {
        channel.sendResponse(new XContentThrowableRestResponse(request, e));
      } catch (IOException e1) {
        logger.warn("Failed to send response", e1);
      }
      return;
    }

    putRequest.template(request.param("template", putRequest.template()));
    putRequest.order(request.paramAsInt("order", putRequest.order()));

    client
        .admin()
        .indices()
        .putTemplate(
            putRequest,
            new ActionListener<PutIndexTemplateResponse>() {
              @Override
              public void onResponse(PutIndexTemplateResponse response) {
                try {
                  XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
                  builder
                      .startObject()
                      .field(Fields.OK, true)
                      .field(Fields.ACKNOWLEDGED, response.acknowledged())
                      .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);
                }
              }
            });
  }
 /** The template source definition. */
 public PutIndexTemplateRequest source(Map templateSource) {
   Map<String, Object> source = templateSource;
   if (source.containsKey("template")) {
     template(source.get("template").toString());
   }
   if (source.containsKey("order")) {
     order(XContentMapValues.nodeIntegerValue(source.get("order"), order()));
   }
   if (source.containsKey("settings")) {
     if (!(source.get("settings") instanceof Map)) {
       throw new ElasticSearchIllegalArgumentException(
           "Malformed settings section, should include an inner object");
     }
     settings((Map<String, Object>) source.get("settings"));
   }
   if (source.containsKey("mappings")) {
     Map<String, Object> mappings = (Map<String, Object>) source.get("mappings");
     for (Map.Entry<String, Object> entry : mappings.entrySet()) {
       if (!(entry.getValue() instanceof Map)) {
         throw new ElasticSearchIllegalArgumentException(
             "Malformed mappings section for type ["
                 + entry.getKey()
                 + "], should include an inner object describing the mapping");
       }
       mapping(entry.getKey(), (Map<String, Object>) entry.getValue());
     }
   }
   return this;
 }
  @Override
  protected void masterOperation(
      final PutIndexTemplateRequest request,
      final ClusterState state,
      final ActionListener<PutIndexTemplateResponse> listener) {
    String cause = request.cause();
    if (cause.length() == 0) {
      cause = "api";
    }

    indexTemplateService.putTemplate(
        new MetaDataIndexTemplateService.PutRequest(cause, request.name())
            .template(request.template())
            .order(request.order())
            .settings(request.settings())
            .mappings(request.mappings())
            .aliases(request.aliases())
            .customs(request.customs())
            .create(request.create())
            .masterTimeout(request.masterNodeTimeout()),
        new MetaDataIndexTemplateService.PutListener() {
          @Override
          public void onResponse(MetaDataIndexTemplateService.PutResponse response) {
            listener.onResponse(new PutIndexTemplateResponse(response.acknowledged()));
          }

          @Override
          public void onFailure(Throwable t) {
            logger.debug("failed to put template [{}]", t, request.name());
            listener.onFailure(t);
          }
        });
  }
 /** The template source definition. */
 public PutIndexTemplateRequest source(Map templateSource) {
   Map<String, Object> source = templateSource;
   for (Map.Entry<String, Object> entry : source.entrySet()) {
     String name = entry.getKey();
     if (name.equals("template")) {
       template(entry.getValue().toString());
     } else if (name.equals("order")) {
       order(XContentMapValues.nodeIntegerValue(entry.getValue(), order()));
     } else if (name.equals("settings")) {
       if (!(entry.getValue() instanceof Map)) {
         throw new ElasticSearchIllegalArgumentException(
             "Malformed settings section, should include an inner object");
       }
       settings((Map<String, Object>) entry.getValue());
     } else if (name.equals("mappings")) {
       Map<String, Object> mappings = (Map<String, Object>) entry.getValue();
       for (Map.Entry<String, Object> entry1 : mappings.entrySet()) {
         if (!(entry1.getValue() instanceof Map)) {
           throw new ElasticSearchIllegalArgumentException(
               "Malformed mappings section for type ["
                   + entry1.getKey()
                   + "], should include an inner object describing the mapping");
         }
         mapping(entry1.getKey(), (Map<String, Object>) entry1.getValue());
       }
     } else {
       // maybe custom?
       IndexMetaData.Custom.Factory factory = IndexMetaData.lookupFactory(name);
       if (factory != null) {
         try {
           customs.put(name, factory.fromMap((Map<String, Object>) entry.getValue()));
         } catch (IOException e) {
           throw new ElasticSearchParseException(
               "failed to parse custom metadata for [" + name + "]");
         }
       }
     }
   }
   return this;
 }