diff --git a/modules/reindex/build.gradle b/modules/reindex/build.gradle index c0a64200e1ca3..d21bef458c85a 100644 --- a/modules/reindex/build.gradle +++ b/modules/reindex/build.gradle @@ -16,6 +16,7 @@ apply plugin: 'elasticsearch.test-with-dependencies' apply plugin: 'elasticsearch.jdk-download' apply plugin: 'elasticsearch.yaml-rest-test' apply plugin: 'elasticsearch.java-rest-test' +apply plugin: 'elasticsearch.yaml-rest-compat-test' apply plugin: 'elasticsearch.internal-cluster-test' esplugin { diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java index 4161243ddd087..83080ef4af61b 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java @@ -55,7 +55,11 @@ protected ReindexRequest buildRequest(RestRequest request, NamedWriteableRegistr ReindexRequest internal; try (XContentParser parser = request.contentParser()) { - internal = ReindexRequest.fromXContent(parser); + if (parser.useCompatibility()) { + internal = ReindexRequestV7.fromXContentV7(parser); + } else { + internal = ReindexRequest.fromXContent(parser); + } } if (request.hasParam("scroll")) { diff --git a/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java b/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java index 997f7743842fe..2cdb4af838617 100644 --- a/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java +++ b/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java @@ -364,7 +364,7 @@ public static ReindexRequest fromXContent(XContentParser parser) throws IOExcept * Yank a string array from a map. Emulates XContent's permissive String to * String array conversions and allow comma separated String. */ - private static String[] extractStringArray(Map source, String name) { + static String[] extractStringArray(Map source, String name) { Object value = source.remove(name); if (value == null) { return null; @@ -465,7 +465,7 @@ static void setMaxDocsValidateIdentical(AbstractBulkByScrollRequest request, } } - private static void failOnSizeSpecified() { + static void failOnSizeSpecified() { throw new IllegalArgumentException("invalid parameter [size], use [max_docs] instead"); } } diff --git a/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequestV7.java b/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequestV7.java new file mode 100644 index 0000000000000..1fe0a33beb6cd --- /dev/null +++ b/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequestV7.java @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.index.reindex; + +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.VersionType; +import org.elasticsearch.script.Script; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * A V7 version of ReindexRequest parser +*/ +public class ReindexRequestV7 { + + static final ObjectParser PARSER = new ObjectParser<>("reindex_v7"); + + static { + ObjectParser.Parser sourceParser = (parser, request, context) -> { + // Funky hack to work around Search not having a proper ObjectParser and us wanting to extract query if using remote. + Map source = parser.map(); + String[] indices = ReindexRequest.extractStringArray(source, "index"); + if (indices != null) { + request.getSearchRequest().indices(indices); + } + request.setRemoteInfo(ReindexRequest.buildRemoteInfo(source)); + XContentBuilder builder = XContentFactory.contentBuilder(parser.contentType()); + builder.map(source); + try (InputStream stream = BytesReference.bytes(builder).streamInput(); + XContentParser innerParser = parser.contentType().xContent() + .createParser(parser.getXContentRegistry(), parser.getDeprecationHandler(), stream)) { + request.getSearchRequest().source().parseXContent(innerParser, false); + } + }; + + ObjectParser destParser = new ObjectParser<>("dest"); + destParser.declareString(IndexRequest::index, new ParseField("index")); + destParser.declareString(IndexRequest::routing, new ParseField("routing")); + destParser.declareString(IndexRequest::opType, new ParseField("op_type")); + destParser.declareString(IndexRequest::setPipeline, new ParseField("pipeline")); + destParser.declareString((s, i) -> s.versionType(VersionType.fromString(i)), new ParseField("version_type")); + + PARSER.declareField(sourceParser::parse, new ParseField("source"), ObjectParser.ValueType.OBJECT); + PARSER.declareField((p, v, c) -> destParser.parse(p, v.getDestination(), c), new ParseField("dest"), ObjectParser.ValueType.OBJECT); + + PARSER.declareInt(ReindexRequest::setMaxDocsValidateIdentical, new ParseField("max_docs", "size")); + + PARSER.declareField((p, v, c) -> v.setScript(Script.parse(p)), new ParseField("script"), + ObjectParser.ValueType.OBJECT); + PARSER.declareString(ReindexRequest::setConflicts, new ParseField("conflicts")); + } + + public static ReindexRequest fromXContentV7(XContentParser parser) throws IOException { + ReindexRequest reindexRequest = new ReindexRequest(); + PARSER.parse(parser, reindexRequest, null); + return reindexRequest; + } + + +}