@Override
  public void handleRequest(
      final RestRequest request, final RestChannel channel, final NodeClient client)
      throws Exception {
    String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
    String alias = request.param("name");
    Map<String, Object> filter = null;
    String routing = null;
    String indexRouting = null;
    String searchRouting = null;

    if (request.hasContent()) {
      try (XContentParser parser =
          XContentFactory.xContent(request.content()).createParser(request.content())) {
        XContentParser.Token token = parser.nextToken();
        if (token == null) {
          throw new IllegalArgumentException("No index alias is specified");
        }
        String currentFieldName = null;
        while ((token = parser.nextToken()) != null) {
          if (token == XContentParser.Token.FIELD_NAME) {
            currentFieldName = parser.currentName();
          } else if (token.isValue()) {
            if ("index".equals(currentFieldName)) {
              indices = Strings.splitStringByCommaToArray(parser.text());
            } else if ("alias".equals(currentFieldName)) {
              alias = parser.text();
            } else if ("routing".equals(currentFieldName)) {
              routing = parser.textOrNull();
            } else if ("indexRouting".equals(currentFieldName)
                || "index-routing".equals(currentFieldName)
                || "index_routing".equals(currentFieldName)) {
              indexRouting = parser.textOrNull();
            } else if ("searchRouting".equals(currentFieldName)
                || "search-routing".equals(currentFieldName)
                || "search_routing".equals(currentFieldName)) {
              searchRouting = parser.textOrNull();
            }
          } else if (token == XContentParser.Token.START_OBJECT) {
            if ("filter".equals(currentFieldName)) {
              filter = parser.mapOrdered();
            }
          }
        }
      }
    }

    IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
    indicesAliasesRequest.timeout(request.paramAsTime("timeout", indicesAliasesRequest.timeout()));
    indicesAliasesRequest.masterNodeTimeout(
        request.paramAsTime("master_timeout", indicesAliasesRequest.masterNodeTimeout()));

    IndicesAliasesRequest.AliasActions aliasAction =
        AliasActions.add().indices(indices).alias(alias);
    if (routing != null) {
      aliasAction.routing(routing);
    }
    if (searchRouting != null) {
      aliasAction.searchRouting(searchRouting);
    }
    if (indexRouting != null) {
      aliasAction.indexRouting(indexRouting);
    }
    if (filter != null) {
      aliasAction.filter(filter);
    }
    indicesAliasesRequest.addAliasAction(aliasAction);
    client
        .admin()
        .indices()
        .aliases(indicesAliasesRequest, new AcknowledgedRestListener<>(channel));
  }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
    indicesAliasesRequest.listenerThreaded(false);
    indicesAliasesRequest.masterNodeTimeout(
        request.paramAsTime("master_timeout", indicesAliasesRequest.masterNodeTimeout()));
    XContentParser parser = null;
    try {
      // {
      //     actions : [
      //         { add : { index : "test1", alias : "alias1", filter : {"user" : "kimchy"} } }
      //         { remove : { index : "test1", alias : "alias1" } }
      //     ]
      // }
      indicesAliasesRequest.timeout(
          request.paramAsTime("timeout", indicesAliasesRequest.timeout()));
      parser = XContentFactory.xContent(request.content()).createParser(request.content());
      XContentParser.Token token = parser.nextToken();
      if (token == null) {
        throw new ElasticsearchIllegalArgumentException("No action is specified");
      }
      while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
        if (token == XContentParser.Token.START_ARRAY) {
          while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
            if (token == XContentParser.Token.FIELD_NAME) {
              String action = parser.currentName();
              AliasAction.Type type;
              if ("add".equals(action)) {
                type = AliasAction.Type.ADD;
              } else if ("remove".equals(action)) {
                type = AliasAction.Type.REMOVE;
              } else {
                throw new ElasticsearchIllegalArgumentException(
                    "Alias action [" + action + "] not supported");
              }
              String index = null;
              String alias = null;
              Map<String, Object> filter = null;
              String routing = null;
              boolean routingSet = false;
              String indexRouting = null;
              boolean indexRoutingSet = false;
              String searchRouting = null;
              boolean searchRoutingSet = false;
              String currentFieldName = null;
              while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                  currentFieldName = parser.currentName();
                } else if (token == XContentParser.Token.VALUE_STRING) {
                  if ("index".equals(currentFieldName)) {
                    index = parser.text();
                  } else if ("alias".equals(currentFieldName)) {
                    alias = parser.text();
                  } else if ("routing".equals(currentFieldName)) {
                    routing = parser.textOrNull();
                    routingSet = true;
                  } else if ("indexRouting".equals(currentFieldName)
                      || "index-routing".equals(currentFieldName)
                      || "index_routing".equals(currentFieldName)) {
                    indexRouting = parser.textOrNull();
                    indexRoutingSet = true;
                  } else if ("searchRouting".equals(currentFieldName)
                      || "search-routing".equals(currentFieldName)
                      || "search_routing".equals(currentFieldName)) {
                    searchRouting = parser.textOrNull();
                    searchRoutingSet = true;
                  }
                } else if (token == XContentParser.Token.START_OBJECT) {
                  if ("filter".equals(currentFieldName)) {
                    filter = parser.mapOrdered();
                  }
                }
              }

              if (type == AliasAction.Type.ADD) {
                AliasAction aliasAction = newAddAliasAction(index, alias).filter(filter);
                if (routingSet) {
                  aliasAction.routing(routing);
                }
                if (indexRoutingSet) {
                  aliasAction.indexRouting(indexRouting);
                }
                if (searchRoutingSet) {
                  aliasAction.searchRouting(searchRouting);
                }
                indicesAliasesRequest.addAliasAction(aliasAction);
              } else if (type == AliasAction.Type.REMOVE) {
                indicesAliasesRequest.removeAlias(index, alias);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      try {
        channel.sendResponse(new XContentThrowableRestResponse(request, e));
      } catch (IOException e1) {
        logger.warn("Failed to send response", e1);
      }
      return;
    } finally {
      parser.close();
    }
    client
        .admin()
        .indices()
        .aliases(
            indicesAliasesRequest,
            new AcknowledgedRestResponseActionListener<IndicesAliasesResponse>(
                request, channel, logger));
  }