diff --git a/benchmarks/src/main/java/org/elasticsearch/benchmark/search/fetch/subphase/FetchSourcePhaseBenchmark.java b/benchmarks/src/main/java/org/elasticsearch/benchmark/search/fetch/subphase/FetchSourcePhaseBenchmark.java index 776d2aa9fedfe..4d8d73ca0a026 100644 --- a/benchmarks/src/main/java/org/elasticsearch/benchmark/search/fetch/subphase/FetchSourcePhaseBenchmark.java +++ b/benchmarks/src/main/java/org/elasticsearch/benchmark/search/fetch/subphase/FetchSourcePhaseBenchmark.java @@ -12,8 +12,8 @@ import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -41,8 +41,7 @@ public class FetchSourcePhaseBenchmark { private FetchSourceContext fetchContext; private Set includesSet; private Set excludesSet; - private FilterPath[] includesFilters; - private FilterPath[] excludesFilters; + private XContentParserConfiguration parserConfig; @Param({ "tiny", "short", "one_4k_field", "one_4m_field" }) private String source; @@ -76,8 +75,7 @@ public void setup() throws IOException { ); includesSet = Set.of(fetchContext.includes()); excludesSet = Set.of(fetchContext.excludes()); - includesFilters = FilterPath.compile(Set.of(fetchContext.includes())); - excludesFilters = FilterPath.compile(Set.of(fetchContext.excludes())); + parserConfig = XContentParserConfiguration.EMPTY.withFiltering(includesSet, excludesSet); } private BytesReference read300BytesExample() throws IOException { @@ -102,16 +100,7 @@ public BytesReference filterObjects() throws IOException { public BytesReference filterXContentOnParser() throws IOException { BytesStreamOutput streamOutput = new BytesStreamOutput(Math.min(1024, sourceBytes.length())); XContentBuilder builder = new XContentBuilder(XContentType.JSON.xContent(), streamOutput); - try ( - XContentParser parser = XContentType.JSON.xContent() - .createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, - sourceBytes.streamInput(), - includesFilters, - excludesFilters - ) - ) { + try (XContentParser parser = XContentType.JSON.xContent().createParser(parserConfig, sourceBytes.streamInput())) { builder.copyCurrentStructure(parser); return BytesReference.bytes(builder); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index 61e4429ffb486..ef35fd1487f6b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -55,7 +55,6 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; import org.elasticsearch.index.VersionType; @@ -1257,17 +1256,16 @@ public void testMultiSearch() throws IOException { requests.add(searchRequest); }; MultiSearchRequest.readMultiLineFormat( - new BytesArray(EntityUtils.toByteArray(request.getEntity())), REQUEST_BODY_CONTENT_TYPE.xContent(), + parserConfig(), + new BytesArray(EntityUtils.toByteArray(request.getEntity())), consumer, null, multiSearchRequest.indicesOptions(), null, null, null, - xContentRegistry(), - true, - RestApiVersion.current() + true ); assertEquals(requests, multiSearchRequest.requests()); } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContent.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContent.java index 2d9eb09653251..7a204726bea9e 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContent.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContent.java @@ -8,9 +8,6 @@ package org.elasticsearch.xcontent; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.support.filtering.FilterPath; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -50,78 +47,67 @@ default XContentGenerator createGenerator(OutputStream os) throws IOException { /** * Creates a parser over the provided string content. */ - XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, String content) - throws IOException; + XContentParser createParser(XContentParserConfiguration config, String content) throws IOException; + + /** + * Creates a parser over the provided string content. + * @deprecated Use {@link #createParser(XContentParserConfiguration, InputStream)} + */ + @Deprecated + default XContentParser createParser(NamedXContentRegistry registry, DeprecationHandler deprecationHandler, String content) + throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecationHandler), content); + } /** * Creates a parser over the provided input stream. */ - XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, InputStream is) - throws IOException; + XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException; /** * Creates a parser over the provided input stream. + * @deprecated Use {@link #createParser(XContentParserConfiguration, InputStream)} */ - XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException; + @Deprecated + default XContentParser createParser(NamedXContentRegistry registry, DeprecationHandler deprecationHandler, InputStream is) + throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecationHandler), is); + } /** * Creates a parser over the provided bytes. */ - XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, byte[] data) - throws IOException; + default XContentParser createParser(XContentParserConfiguration config, byte[] data) throws IOException { + return createParser(config, data, 0, data.length); + } /** * Creates a parser over the provided bytes. + * @deprecated Use {@link #createParser(XContentParserConfiguration, byte[])} */ - XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length - ) throws IOException; + @Deprecated + default XContentParser createParser(NamedXContentRegistry registry, DeprecationHandler deprecationHandler, byte[] data) + throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecationHandler), data); + } - XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException; + /** + * Creates a parser over the provided bytes. + */ + XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException; /** * Creates a parser over the provided reader. */ - XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, Reader reader) - throws IOException; + XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException; /** - * Creates a parser over the provided input stream and with the indication that a request is using REST compatible API. - * - * @param restApiVersion - indicates if the N-1 or N compatible XContent parsing logic will be used. + * Creates a parser over the provided reader. + * @deprecated Use {@link #createParser(XContentParserConfiguration, Reader)} */ - XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - RestApiVersion restApiVersion - ) throws IOException; - - XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - RestApiVersion restApiVersion - ) throws IOException; - + @Deprecated + default XContentParser createParser(NamedXContentRegistry registry, DeprecationHandler deprecationHandler, Reader reader) + throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecationHandler), reader); + } } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentParserConfiguration.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentParserConfiguration.java new file mode 100644 index 0000000000000..b2e3ea504350a --- /dev/null +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentParserConfiguration.java @@ -0,0 +1,122 @@ +/* + * 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.xcontent; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.filter.FilteringParserDelegate; + +import org.elasticsearch.core.RestApiVersion; +import org.elasticsearch.xcontent.support.filtering.FilterPath; +import org.elasticsearch.xcontent.support.filtering.FilterPathBasedFilter; + +import java.util.Set; + +/** + * Configuration for {@link XContentParser}. + */ +public class XContentParserConfiguration { + /** + * Creates parsers that don't support {@link XContentParser#namedObject}, + * throw an exception when they see deprecated fields, that return the + * {@link RestApiVersion#current() current version} from + * {@link XContentParser#getRestApiVersion}, and do no filtering. + */ + public static final XContentParserConfiguration EMPTY = new XContentParserConfiguration( + NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, + RestApiVersion.current(), + null, + null + ); + + final NamedXContentRegistry registry; + final DeprecationHandler deprecationHandler; + final RestApiVersion restApiVersion; + final FilterPath[] includes; + final FilterPath[] excludes; + + private XContentParserConfiguration( + NamedXContentRegistry registry, + DeprecationHandler deprecationHandler, + RestApiVersion restApiVersion, + FilterPath[] includes, + FilterPath[] excludes + ) { + this.registry = registry; + this.deprecationHandler = deprecationHandler; + this.restApiVersion = restApiVersion; + this.includes = includes; + this.excludes = excludes; + } + + /** + * Replace the registry backing {@link XContentParser#namedObject}. + */ + public XContentParserConfiguration withRegistry(NamedXContentRegistry registry) { + return new XContentParserConfiguration(registry, deprecationHandler, restApiVersion, includes, excludes); + } + + public NamedXContentRegistry registry() { + return registry; + } + + /** + * Replace the behavior of {@link XContentParser} when it encounters + * a deprecated field. + */ + public XContentParserConfiguration withDeprecationHandler(DeprecationHandler deprecationHandler) { + return new XContentParserConfiguration(registry, deprecationHandler, restApiVersion, includes, excludes); + } + + public DeprecationHandler deprecationHandler() { + return deprecationHandler; + } + + /** + * Replace the {@link XContentParser#getRestApiVersion() claimed} + * {@link RestApiVersion}. + */ + public XContentParserConfiguration withRestApiVersion(RestApiVersion restApiVersion) { + return new XContentParserConfiguration(registry, deprecationHandler, restApiVersion, includes, excludes); + } + + public RestApiVersion restApiVersion() { + return restApiVersion; + } + + /** + * Replace the configured filtering. + */ + public XContentParserConfiguration withFiltering(Set includes, Set excludes) { + return new XContentParserConfiguration( + registry, + deprecationHandler, + restApiVersion, + FilterPath.compile(includes), + FilterPath.compile(excludes) + ); + } + + public JsonParser filter(JsonParser parser) { + JsonParser filtered = parser; + if (excludes != null) { + for (FilterPath e : excludes) { + if (e.hasDoubleWildcard()) { + // Fixed in Jackson 2.13 - https://github.com/FasterXML/jackson-core/issues/700 + throw new UnsupportedOperationException("double wildcards are not supported in filtered excludes"); + } + } + filtered = new FilteringParserDelegate(filtered, new FilterPathBasedFilter(excludes, false), true, true); + } + if (includes != null) { + filtered = new FilteringParserDelegate(filtered, new FilterPathBasedFilter(includes, true), true, true); + } + return filtered; + } +} diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContent.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContent.java index b0443b9b20008..90c88b979514e 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContent.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContent.java @@ -13,18 +13,14 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.dataformat.cbor.CBORFactory; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentGenerator; import org.elasticsearch.xcontent.XContentParseException; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -70,103 +66,22 @@ public XContentGenerator createGenerator(OutputStream os, Set includes, } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, String content) - throws IOException { - return new CborXContentParser(xContentRegistry, deprecationHandler, cborFactory.createParser(content)); + public XContentParser createParser(XContentParserConfiguration config, String content) throws IOException { + return new CborXContentParser(config, cborFactory.createParser(content)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, InputStream is) - throws IOException { - return new CborXContentParser(xContentRegistry, deprecationHandler, cborFactory.createParser(is)); + public XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException { + return new CborXContentParser(config, cborFactory.createParser(is)); } @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new CborXContentParser( - xContentRegistry, - deprecationHandler, - cborFactory.createParser(is), - RestApiVersion.current(), - includes, - excludes - ); + public XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException { + return new CborXContentParser(config, cborFactory.createParser(data, offset, length)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, byte[] data) - throws IOException { - return createParser(xContentRegistry, deprecationHandler, data, 0, data.length); + public XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException { + return new CborXContentParser(config, cborFactory.createParser(reader)); } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length - ) throws IOException { - return createParserForCompatibility(xContentRegistry, deprecationHandler, data, offset, length, RestApiVersion.current()); - } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new CborXContentParser( - xContentRegistry, - deprecationHandler, - cborFactory.createParser(new ByteArrayInputStream(data, offset, length)), - RestApiVersion.current(), - includes, - excludes - ); - } - - @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, Reader reader) - throws IOException { - return new CborXContentParser(xContentRegistry, deprecationHandler, cborFactory.createParser(reader)); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - RestApiVersion restApiVersion - ) throws IOException { - return new CborXContentParser(xContentRegistry, deprecationHandler, cborFactory.createParser(is), restApiVersion); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - RestApiVersion restApiVersion - ) throws IOException { - return new CborXContentParser( - xContentRegistry, - deprecationHandler, - cborFactory.createParser(new ByteArrayInputStream(data, offset, length)), - restApiVersion - ); - } - } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContentParser.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContentParser.java index 54a37935c8a8d..2b5c9c81f0790 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContentParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/cbor/CborXContentParser.java @@ -10,37 +10,14 @@ import com.fasterxml.jackson.core.JsonParser; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.json.JsonXContentParser; -import org.elasticsearch.xcontent.support.filtering.FilterPath; public class CborXContentParser extends JsonXContentParser { - public CborXContentParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, JsonParser parser) { - super(xContentRegistry, deprecationHandler, parser); - } - - public CborXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion); - } - - public CborXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion, - FilterPath[] includes, - FilterPath[] excludes - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion, includes, excludes); + public CborXContentParser(XContentParserConfiguration config, JsonParser parser) { + super(config, parser); } @Override diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContent.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContent.java index 126abc0dd1b79..b5542a3e1890e 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContent.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContent.java @@ -13,17 +13,13 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentGenerator; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -72,103 +68,22 @@ public XContentGenerator createGenerator(OutputStream os, Set includes, } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, String content) - throws IOException { - return new JsonXContentParser(xContentRegistry, deprecationHandler, jsonFactory.createParser(content)); + public XContentParser createParser(XContentParserConfiguration config, String content) throws IOException { + return new JsonXContentParser(config, jsonFactory.createParser(content)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, InputStream is) - throws IOException { - return new JsonXContentParser(xContentRegistry, deprecationHandler, jsonFactory.createParser(is)); + public XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException { + return new JsonXContentParser(config, jsonFactory.createParser(is)); } @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - FilterPath[] include, - FilterPath[] exclude - ) throws IOException { - return new JsonXContentParser( - xContentRegistry, - deprecationHandler, - jsonFactory.createParser(is), - RestApiVersion.current(), - include, - exclude - ); + public XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException { + return new JsonXContentParser(config, jsonFactory.createParser(data, offset, length)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, byte[] data) - throws IOException { - return createParser(xContentRegistry, deprecationHandler, data, 0, data.length); + public XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException { + return new JsonXContentParser(config, jsonFactory.createParser(reader)); } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length - ) throws IOException { - return createParserForCompatibility(xContentRegistry, deprecationHandler, data, offset, length, RestApiVersion.current()); - } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new JsonXContentParser( - xContentRegistry, - deprecationHandler, - jsonFactory.createParser(new ByteArrayInputStream(data, offset, length)), - RestApiVersion.current(), - includes, - excludes - ); - } - - @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, Reader reader) - throws IOException { - return new JsonXContentParser(xContentRegistry, deprecationHandler, jsonFactory.createParser(reader)); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - RestApiVersion restApiVersion - ) throws IOException { - return new JsonXContentParser(xContentRegistry, deprecationHandler, jsonFactory.createParser(is), restApiVersion); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - RestApiVersion restApiVersion - ) throws IOException { - return new JsonXContentParser( - xContentRegistry, - deprecationHandler, - jsonFactory.createParser(new ByteArrayInputStream(data, offset, length)), - restApiVersion - ); - } - } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContentParser.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContentParser.java index 13e2aeff45f7c..5a8ad19415009 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContentParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/json/JsonXContentParser.java @@ -11,17 +11,12 @@ import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.filter.FilteringParserDelegate; -import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.core.internal.io.IOUtils; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentLocation; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.support.AbstractXContentParser; -import org.elasticsearch.xcontent.support.filtering.FilterPath; -import org.elasticsearch.xcontent.support.filtering.FilterPathBasedFilter; import java.io.IOException; import java.nio.CharBuffer; @@ -30,44 +25,9 @@ public class JsonXContentParser extends AbstractXContentParser { final JsonParser parser; - public JsonXContentParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, JsonParser parser) { - super(xContentRegistry, deprecationHandler, RestApiVersion.current()); - this.parser = parser; - } - - public JsonXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion - ) { - super(xContentRegistry, deprecationHandler, restApiVersion); - this.parser = parser; - } - - public JsonXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion, - FilterPath[] include, - FilterPath[] exclude - ) { - super(xContentRegistry, deprecationHandler, restApiVersion); - JsonParser filtered = parser; - if (exclude != null) { - for (FilterPath e : exclude) { - if (e.hasDoubleWildcard()) { - // Fixed in Jackson 2.13 - https://github.com/FasterXML/jackson-core/issues/700 - throw new UnsupportedOperationException("double wildcards are not supported in filtered excludes"); - } - } - filtered = new FilteringParserDelegate(filtered, new FilterPathBasedFilter(exclude, false), true, true); - } - if (include != null) { - filtered = new FilteringParserDelegate(filtered, new FilterPathBasedFilter(include, true), true, true); - } - this.parser = filtered; + public JsonXContentParser(XContentParserConfiguration config, JsonParser parser) { + super(config.registry(), config.deprecationHandler(), config.restApiVersion()); + this.parser = config.filter(parser); } @Override diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContent.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContent.java index c88e63df50c08..b789e691030cb 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContent.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContent.java @@ -14,17 +14,13 @@ import com.fasterxml.jackson.dataformat.smile.SmileFactory; import com.fasterxml.jackson.dataformat.smile.SmileGenerator; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentGenerator; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -72,102 +68,22 @@ public XContentGenerator createGenerator(OutputStream os, Set includes, } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, String content) - throws IOException { - return new SmileXContentParser(xContentRegistry, deprecationHandler, smileFactory.createParser(content)); + public XContentParser createParser(XContentParserConfiguration config, String content) throws IOException { + return new SmileXContentParser(config, smileFactory.createParser(content)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, InputStream is) - throws IOException { - return new SmileXContentParser(xContentRegistry, deprecationHandler, smileFactory.createParser(is)); + public XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException { + return new SmileXContentParser(config, smileFactory.createParser(is)); } @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - FilterPath[] include, - FilterPath[] exclude - ) throws IOException { - return new SmileXContentParser( - xContentRegistry, - deprecationHandler, - smileFactory.createParser(is), - RestApiVersion.current(), - include, - exclude - ); + public XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException { + return new SmileXContentParser(config, smileFactory.createParser(data, offset, length)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, byte[] data) - throws IOException { - return createParser(xContentRegistry, deprecationHandler, data, 0, data.length); - } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length - ) throws IOException { - return createParserForCompatibility(xContentRegistry, deprecationHandler, data, offset, length, RestApiVersion.current()); - } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new SmileXContentParser( - xContentRegistry, - deprecationHandler, - smileFactory.createParser(new ByteArrayInputStream(data, offset, length)), - RestApiVersion.current(), - includes, - excludes - ); - } - - @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, Reader reader) - throws IOException { - return new SmileXContentParser(xContentRegistry, deprecationHandler, smileFactory.createParser(reader)); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - RestApiVersion restApiVersion - ) throws IOException { - return new SmileXContentParser(xContentRegistry, deprecationHandler, smileFactory.createParser(is), restApiVersion); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - RestApiVersion restApiVersion - ) throws IOException { - return new SmileXContentParser( - xContentRegistry, - deprecationHandler, - smileFactory.createParser(new ByteArrayInputStream(data, offset, length)), - restApiVersion - ); + public XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException { + return new SmileXContentParser(config, smileFactory.createParser(reader)); } } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContentParser.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContentParser.java index d7c15e182cdd8..414bb2efbeb46 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContentParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/smile/SmileXContentParser.java @@ -10,37 +10,14 @@ import com.fasterxml.jackson.core.JsonParser; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.json.JsonXContentParser; -import org.elasticsearch.xcontent.support.filtering.FilterPath; public class SmileXContentParser extends JsonXContentParser { - public SmileXContentParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, JsonParser parser) { - super(xContentRegistry, deprecationHandler, parser); - } - - public SmileXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion); - } - - public SmileXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion, - FilterPath[] include, - FilterPath[] exclude - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion, include, exclude); + public SmileXContentParser(XContentParserConfiguration config, JsonParser parser) { + super(config, parser); } @Override diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContent.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContent.java index 2f9e5bc941846..971bb6a28ebb7 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContent.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContent.java @@ -12,17 +12,13 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentGenerator; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -65,103 +61,22 @@ public XContentGenerator createGenerator(OutputStream os, Set includes, } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, String content) - throws IOException { - return new YamlXContentParser(xContentRegistry, deprecationHandler, yamlFactory.createParser(content)); + public XContentParser createParser(XContentParserConfiguration config, String content) throws IOException { + return new YamlXContentParser(config, yamlFactory.createParser(content)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, InputStream is) - throws IOException { - return new YamlXContentParser(xContentRegistry, deprecationHandler, yamlFactory.createParser(is)); + public XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException { + return new YamlXContentParser(config, yamlFactory.createParser(is)); } @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new YamlXContentParser( - xContentRegistry, - deprecationHandler, - yamlFactory.createParser(is), - RestApiVersion.current(), - includes, - excludes - ); + public XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException { + return new YamlXContentParser(config, yamlFactory.createParser(data, offset, length)); } @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, byte[] data) - throws IOException { - return createParser(xContentRegistry, deprecationHandler, data, 0, data.length); + public XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException { + return new YamlXContentParser(config, yamlFactory.createParser(reader)); } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length - ) throws IOException { - return createParserForCompatibility(xContentRegistry, deprecationHandler, data, offset, length, RestApiVersion.current()); - } - - @Override - public XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - FilterPath[] includes, - FilterPath[] excludes - ) throws IOException { - return new YamlXContentParser( - xContentRegistry, - deprecationHandler, - yamlFactory.createParser(new ByteArrayInputStream(data, offset, length)), - RestApiVersion.current(), - includes, - excludes - ); - } - - @Override - public XContentParser createParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, Reader reader) - throws IOException { - return new YamlXContentParser(xContentRegistry, deprecationHandler, yamlFactory.createParser(reader)); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - InputStream is, - RestApiVersion restApiVersion - ) throws IOException { - return new YamlXContentParser(xContentRegistry, deprecationHandler, yamlFactory.createParser(is), restApiVersion); - } - - @Override - public XContentParser createParserForCompatibility( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - byte[] data, - int offset, - int length, - RestApiVersion restApiVersion - ) throws IOException { - return new YamlXContentParser( - xContentRegistry, - deprecationHandler, - yamlFactory.createParser(new ByteArrayInputStream(data, offset, length)), - restApiVersion - ); - } - } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContentParser.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContentParser.java index 5f1e646f2e1e9..5b744c414a0bf 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContentParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/yaml/YamlXContentParser.java @@ -10,37 +10,14 @@ import com.fasterxml.jackson.core.JsonParser; -import org.elasticsearch.core.RestApiVersion; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.json.JsonXContentParser; -import org.elasticsearch.xcontent.support.filtering.FilterPath; public class YamlXContentParser extends JsonXContentParser { - public YamlXContentParser(NamedXContentRegistry xContentRegistry, DeprecationHandler deprecationHandler, JsonParser parser) { - super(xContentRegistry, deprecationHandler, parser); - } - - public YamlXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion); - } - - public YamlXContentParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - JsonParser parser, - RestApiVersion restApiVersion, - FilterPath[] includes, - FilterPath[] excludes - ) { - super(xContentRegistry, deprecationHandler, parser, restApiVersion, includes, excludes); + public YamlXContentParser(XContentParserConfiguration config, JsonParser parser) { + super(config, parser); } @Override diff --git a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/AbstractXContentFilteringTestCase.java b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/AbstractXContentFilteringTestCase.java index de64e7cc07cb9..a2f9b303343a6 100644 --- a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/AbstractXContentFilteringTestCase.java +++ b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/AbstractXContentFilteringTestCase.java @@ -17,6 +17,7 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.IOException; @@ -61,26 +62,19 @@ private XContentBuilder filter(Builder sample, Set includes, Set */ return filterOnBuilder(sample, includes, excludes); } - FilterPath[] includesFilter = FilterPath.compile(includes); - return filterOnParser(sample, includesFilter, excludesFilter); + return filterOnParser(sample, includes, excludes); } private XContentBuilder filterOnBuilder(Builder sample, Set includes, Set excludes) throws IOException { return sample.apply(XContentBuilder.builder(getXContentType(), includes, excludes)); } - private XContentBuilder filterOnParser(Builder sample, FilterPath[] includes, FilterPath[] excludes) throws IOException { + private XContentBuilder filterOnParser(Builder sample, Set includes, Set excludes) throws IOException { try (XContentBuilder builtSample = sample.apply(createBuilder())) { BytesReference sampleBytes = BytesReference.bytes(builtSample); try ( XContentParser parser = getXContentType().xContent() - .createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, - sampleBytes.streamInput(), - includes, - excludes - ); + .createParser(XContentParserConfiguration.EMPTY.withFiltering(includes, excludes), sampleBytes.streamInput()); ) { XContentBuilder result = createBuilder(); if (sampleBytes.get(sampleBytes.length() - 1) == '\n') { diff --git a/server/src/main/java/org/elasticsearch/action/bulk/BulkRequestParser.java b/server/src/main/java/org/elasticsearch/action/bulk/BulkRequestParser.java index 3b329a38db048..f83adf4e16e29 100644 --- a/server/src/main/java/org/elasticsearch/action/bulk/BulkRequestParser.java +++ b/server/src/main/java/org/elasticsearch/action/bulk/BulkRequestParser.java @@ -22,10 +22,10 @@ import org.elasticsearch.index.seqno.SequenceNumbers; import org.elasticsearch.rest.action.document.RestBulkAction; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.IOException; @@ -61,7 +61,10 @@ public final class BulkRequestParser { // TODO: Remove this parameter once the BulkMonitoring endpoint has been removed // for CompatibleApi V7 this means to deprecate on type, for V8+ it means to throw an error private final boolean deprecateOrErrorOnType; - private RestApiVersion restApiVersion; + /** + * Configuration for {@link XContentParser}. + */ + private final XContentParserConfiguration config; /** * Create a new parser. @@ -71,7 +74,8 @@ public final class BulkRequestParser { */ public BulkRequestParser(boolean deprecateOrErrorOnType, RestApiVersion restApiVersion) { this.deprecateOrErrorOnType = deprecateOrErrorOnType; - this.restApiVersion = restApiVersion; + this.config = XContentParserConfiguration.EMPTY.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE) + .withRestApiVersion(restApiVersion); } private static int findNextMarker(byte marker, int from, BytesReference data) { @@ -141,7 +145,7 @@ public void parse( line++; // now parse the action - try (XContentParser parser = createParser(data, xContent, from, nextMarker, restApiVersion)) { + try (XContentParser parser = createParser(xContent, data, from, nextMarker)) { // move pointers from = nextMarker + 1; @@ -379,9 +383,8 @@ public void parse( .routing(routing); try ( XContentParser sliceParser = createParser( - sliceTrimmingCarriageReturn(data, from, nextMarker, xContentType), xContent, - restApiVersion + sliceTrimmingCarriageReturn(data, from, nextMarker, xContentType) ) ) { updateRequest.fromXContent(sliceParser); @@ -403,64 +406,33 @@ public void parse( } } - private static XContentParser createParser(BytesReference data, XContent xContent, RestApiVersion restApiVersion) throws IOException { + private XContentParser createParser(XContent xContent, BytesReference data) throws IOException { if (data.hasArray()) { - return parseBytesArray(xContent, data, 0, data.length(), restApiVersion); + return parseBytesArray(xContent, data, 0, data.length()); } else { - return xContent.createParserForCompatibility( - NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, - data.streamInput(), - restApiVersion - ); + return xContent.createParser(config, data.streamInput()); } } // Create an efficient parser of the given bytes, trying to directly parse a byte array if possible and falling back to stream wrapping // otherwise. - private static XContentParser createParser( - BytesReference data, - XContent xContent, - int from, - int nextMarker, - RestApiVersion restApiVersion - ) throws IOException { + private XContentParser createParser(XContent xContent, BytesReference data, int from, int nextMarker) throws IOException { if (data.hasArray()) { - return parseBytesArray(xContent, data, from, nextMarker, restApiVersion); + return parseBytesArray(xContent, data, from, nextMarker); } else { final int length = nextMarker - from; final BytesReference slice = data.slice(from, length); if (slice.hasArray()) { - return parseBytesArray(xContent, slice, 0, length, restApiVersion); + return parseBytesArray(xContent, slice, 0, length); } else { - // EMPTY is safe here because we never call namedObject - return xContent.createParserForCompatibility( - NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, - slice.streamInput(), - restApiVersion - ); + return xContent.createParser(config, slice.streamInput()); } } } - private static XContentParser parseBytesArray( - XContent xContent, - BytesReference array, - int from, - int nextMarker, - RestApiVersion restApiVersion - ) throws IOException { + private XContentParser parseBytesArray(XContent xContent, BytesReference array, int from, int nextMarker) throws IOException { assert array.hasArray(); final int offset = array.arrayOffset(); - // EMPTY is safe here because we never call namedObject - return xContent.createParserForCompatibility( - NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, - array.array(), - offset + from, - nextMarker - from, - restApiVersion - ); + return xContent.createParser(config, array.array(), offset + from, nextMarker - from); } } diff --git a/server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java b/server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java index 9eb3f233d40b2..a34744ccf4a4a 100644 --- a/server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java +++ b/server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java @@ -19,18 +19,17 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.DeprecationLogger; -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.rest.action.search.RestMultiSearchAction; import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -170,47 +169,44 @@ public int hashCode() { } public static void readMultiLineFormat( - BytesReference data, XContent xContent, + XContentParserConfiguration parserConfig, + BytesReference data, CheckedBiConsumer consumer, String[] indices, IndicesOptions indicesOptions, String routing, String searchType, Boolean ccsMinimizeRoundtrips, - NamedXContentRegistry registry, - boolean allowExplicitIndex, - RestApiVersion restApiVersion + boolean allowExplicitIndex ) throws IOException { readMultiLineFormat( - data, xContent, + parserConfig, + data, consumer, indices, indicesOptions, routing, searchType, ccsMinimizeRoundtrips, - registry, allowExplicitIndex, - restApiVersion, (s, o, r) -> false ); } public static void readMultiLineFormat( - BytesReference data, XContent xContent, + XContentParserConfiguration parserConfig, + BytesReference data, CheckedBiConsumer consumer, String[] indices, IndicesOptions indicesOptions, String routing, String searchType, Boolean ccsMinimizeRoundtrips, - NamedXContentRegistry registry, boolean allowExplicitIndex, - RestApiVersion restApiVersion, TriFunction extraParamParser ) throws IOException { int from = 0; @@ -221,7 +217,7 @@ public static void readMultiLineFormat( break; } // support first line with \n - if (restApiVersion == RestApiVersion.V_7 && nextMarker == 0) { + if (parserConfig.restApiVersion() == RestApiVersion.V_7 && nextMarker == 0) { deprecationLogger.compatibleCritical("msearch_first_line_empty", FIRST_LINE_EMPTY_DEPRECATION_MESSAGE); from = nextMarker + 1; continue; @@ -248,12 +244,7 @@ public static void readMultiLineFormat( if (nextMarker - from > 0) { try ( InputStream stream = data.slice(from, nextMarker - from).streamInput(); - XContentParser parser = xContent.createParserForCompatibility( - registry, - LoggingDeprecationHandler.INSTANCE, - stream, - restApiVersion - ) + XContentParser parser = xContent.createParser(parserConfig, stream) ) { Map source = parser.map(); Object expandWildcards = null; @@ -287,7 +278,7 @@ public static void readMultiLineFormat( allowNoIndices = value; } else if ("ignore_throttled".equals(entry.getKey()) || "ignoreThrottled".equals(entry.getKey())) { ignoreThrottled = value; - } else if (restApiVersion == RestApiVersion.V_7 + } else if (parserConfig.restApiVersion() == RestApiVersion.V_7 && ("type".equals(entry.getKey()) || "types".equals(entry.getKey()))) { deprecationLogger.compatibleCritical("msearch_with_types", RestMultiSearchAction.TYPES_DEPRECATION_MESSAGE); } else if (extraParamParser.apply(entry.getKey(), value, searchRequest)) { @@ -315,15 +306,7 @@ public static void readMultiLineFormat( break; } BytesReference bytes = data.slice(from, nextMarker - from); - try ( - InputStream stream = bytes.streamInput(); - XContentParser parser = xContent.createParserForCompatibility( - registry, - LoggingDeprecationHandler.INSTANCE, - stream, - restApiVersion - ) - ) { + try (InputStream stream = bytes.streamInput(); XContentParser parser = xContent.createParser(parserConfig, stream)) { consumer.accept(searchRequest, parser); } // move pointers diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/IndexRouting.java b/server/src/main/java/org/elasticsearch/cluster/routing/IndexRouting.java index 07cf8a483e065..0e07b5110e94e 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/IndexRouting.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/IndexRouting.java @@ -13,12 +13,10 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.core.Nullable; import org.elasticsearch.transport.Transports; -import org.elasticsearch.xcontent.DeprecationHandler; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser.Token; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; import java.io.IOException; import java.util.ArrayList; @@ -198,12 +196,12 @@ public void collectSearchShards(String routing, IntConsumer consumer) { private static class ExtractFromSource extends IndexRouting { private final String indexName; - private final FilterPath[] include; + private final XContentParserConfiguration parserConfig; ExtractFromSource(int routingNumShards, int routingFactor, String indexName, List routingPaths) { super(routingNumShards, routingFactor); this.indexName = indexName; - this.include = FilterPath.compile(Set.copyOf(routingPaths)); + this.parserConfig = XContentParserConfiguration.EMPTY.withFiltering(Set.copyOf(routingPaths), null); } @Override @@ -214,16 +212,7 @@ public int indexShard(String id, @Nullable String routing, XContentType sourceTy assert Transports.assertNotTransportThread("parsing the _source can get slow"); try { - try ( - XContentParser parser = sourceType.xContent() - .createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, - source.streamInput(), - include, - null - ) - ) { + try (XContentParser parser = sourceType.xContent().createParser(parserConfig, source.streamInput())) { parser.nextToken(); // Move to first token if (parser.currentToken() == null) { throw new IllegalArgumentException("Error extracting routing: source didn't contain any routing fields"); diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java b/server/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java index 59ffe7ae9e1e4..1eaac03641c62 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java +++ b/server/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java @@ -27,8 +27,8 @@ import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentParseException; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; import java.io.BufferedInputStream; import java.io.IOException; @@ -39,21 +39,29 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; @SuppressWarnings("unchecked") public class XContentHelper { /** * Creates a parser based on the bytes provided - * @deprecated use {@link #createParser(NamedXContentRegistry, DeprecationHandler, BytesReference, XContentType)} + * @deprecated use {@link #createParser(XContentParserConfiguration, BytesReference, XContentType)} * to avoid content type auto-detection */ @Deprecated - public static XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, - BytesReference bytes - ) throws IOException { + public static XContentParser createParser(NamedXContentRegistry registry, DeprecationHandler deprecation, BytesReference bytes) + throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecation), bytes); + } + + /** + * Creates a parser based on the bytes provided + * @deprecated use {@link #createParser(XContentParserConfiguration, BytesReference, XContentType)} + * to avoid content type auto-detection + */ + @Deprecated + public static XContentParser createParser(XContentParserConfiguration config, BytesReference bytes) throws IOException { Compressor compressor = CompressorFactory.compressor(bytes); if (compressor != null) { InputStream compressedInput = compressor.threadLocalInputStream(bytes.streamInput()); @@ -61,21 +69,31 @@ public static XContentParser createParser( compressedInput = new BufferedInputStream(compressedInput); } final XContentType contentType = XContentFactory.xContentType(compressedInput); - return XContentFactory.xContent(contentType).createParser(xContentRegistry, deprecationHandler, compressedInput); + return XContentFactory.xContent(contentType).createParser(config, compressedInput); } else { - return XContentFactory.xContent(xContentType(bytes)).createParser(xContentRegistry, deprecationHandler, bytes.streamInput()); + return XContentFactory.xContent(xContentType(bytes)).createParser(config, bytes.streamInput()); } } /** - * Creates a parser for the bytes using the supplied content-type + * Creates a parser for the bytes provided + * @deprecated use {@link #createParser(XContentParserConfiguration, BytesReference, XContentType)} */ + @Deprecated public static XContentParser createParser( - NamedXContentRegistry xContentRegistry, - DeprecationHandler deprecationHandler, + NamedXContentRegistry registry, + DeprecationHandler deprecation, BytesReference bytes, XContentType xContentType ) throws IOException { + return createParser(XContentParserConfiguration.EMPTY.withRegistry(registry).withDeprecationHandler(deprecation), bytes); + } + + /** + * Creates a parser for the bytes using the supplied content-type + */ + public static XContentParser createParser(XContentParserConfiguration config, BytesReference bytes, XContentType xContentType) + throws IOException { Objects.requireNonNull(xContentType); Compressor compressor = CompressorFactory.compressor(bytes); if (compressor != null) { @@ -83,13 +101,13 @@ public static XContentParser createParser( if (compressedInput.markSupported() == false) { compressedInput = new BufferedInputStream(compressedInput); } - return XContentFactory.xContent(xContentType).createParser(xContentRegistry, deprecationHandler, compressedInput); + return XContentFactory.xContent(xContentType).createParser(config, compressedInput); } else { + // TODO now that we have config we make a method on bytes to do this building wihout needing this check everywhere if (bytes.hasArray()) { - return xContentType.xContent() - .createParser(xContentRegistry, deprecationHandler, bytes.array(), bytes.arrayOffset(), bytes.length()); + return xContentType.xContent().createParser(config, bytes.array(), bytes.arrayOffset(), bytes.length()); } - return xContentType.xContent().createParser(xContentRegistry, deprecationHandler, bytes.streamInput()); + return xContentType.xContent().createParser(config, bytes.streamInput()); } } @@ -111,7 +129,7 @@ public static Tuple> convertToMap(BytesReferen } /** - * Exactly the same as {@link XContentHelper#convertToMap(BytesReference, boolean, XContentType, FilterPath[], FilterPath[])} but + * Exactly the same as {@link XContentHelper#convertToMap(BytesReference, boolean, XContentType, Set, Set)} but * none of the fields are filtered */ public static Tuple> convertToMap(BytesReference bytes, boolean ordered, XContentType xContentType) { @@ -131,8 +149,8 @@ public static Tuple> convertToMap( BytesReference bytes, boolean ordered, XContentType xContentType, - @Nullable FilterPath[] include, - @Nullable FilterPath[] exclude + @Nullable Set include, + @Nullable Set exclude ) throws ElasticsearchParseException { try { final XContentType contentType; @@ -189,7 +207,7 @@ public static Map convertToMap(XContent xContent, String string, } /** - * The same as {@link XContentHelper#convertToMap(XContent, byte[], int, int, boolean, FilterPath[], FilterPath[])} but none of the + * The same as {@link XContentHelper#convertToMap(XContent, byte[], int, int, boolean, Set, Set)} but none of the * fields are filtered. */ public static Map convertToMap(XContent xContent, InputStream input, boolean ordered) @@ -207,19 +225,10 @@ public static Map convertToMap( XContent xContent, InputStream input, boolean ordered, - @Nullable FilterPath[] include, - @Nullable FilterPath[] exclude + @Nullable Set include, + @Nullable Set exclude ) throws ElasticsearchParseException { - // It is safe to use EMPTY here because this never uses namedObject - try ( - XContentParser parser = xContent.createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, - input, - include, - exclude - ) - ) { + try (XContentParser parser = xContent.createParser(XContentParserConfiguration.EMPTY.withFiltering(include, exclude), input)) { return ordered ? parser.mapOrdered() : parser.map(); } catch (IOException e) { throw new ElasticsearchParseException("Failed to parse content to map", e); @@ -248,19 +257,15 @@ public static Map convertToMap( int offset, int length, boolean ordered, - @Nullable FilterPath[] include, - @Nullable FilterPath[] exclude + @Nullable Set include, + @Nullable Set exclude ) throws ElasticsearchParseException { - // It is safe to use EMPTY here because this never uses namedObject try ( XContentParser parser = xContent.createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, + XContentParserConfiguration.EMPTY.withFiltering(include, exclude), bytes, offset, - length, - include, - exclude + length ) ) { return ordered ? parser.mapOrdered() : parser.map(); @@ -303,25 +308,17 @@ public static String convertToJson(BytesReference bytes, boolean reformatJson, b return bytes.utf8ToString(); } - // It is safe to use EMPTY here because this never uses namedObject if (bytes.hasArray()) { try ( XContentParser parser = XContentFactory.xContent(xContentType) - .createParser( - NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, - bytes.array(), - bytes.arrayOffset(), - bytes.length() - ) + .createParser(XContentParserConfiguration.EMPTY, bytes.array(), bytes.arrayOffset(), bytes.length()) ) { return toJsonString(prettyPrint, parser); } } else { try ( InputStream stream = bytes.streamInput(); - XContentParser parser = XContentFactory.xContent(xContentType) - .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, stream) + XContentParser parser = XContentFactory.xContent(xContentType).createParser(XContentParserConfiguration.EMPTY, stream) ) { return toJsonString(prettyPrint, parser); } diff --git a/server/src/main/java/org/elasticsearch/gateway/PersistedClusterStateService.java b/server/src/main/java/org/elasticsearch/gateway/PersistedClusterStateService.java index 26a82cd143d33..6423befa58c00 100644 --- a/server/src/main/java/org/elasticsearch/gateway/PersistedClusterStateService.java +++ b/server/src/main/java/org/elasticsearch/gateway/PersistedClusterStateService.java @@ -70,6 +70,7 @@ import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentFactory; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.Closeable; @@ -143,7 +144,7 @@ public class PersistedClusterStateService { private final Path[] dataPaths; private final String nodeId; - private final NamedXContentRegistry namedXContentRegistry; + private final XContentParserConfiguration parserConfig; private final BigArrays bigArrays; private final LongSupplier relativeTimeMillisSupplier; @@ -176,7 +177,8 @@ public PersistedClusterStateService( ) { this.dataPaths = dataPaths; this.nodeId = nodeId; - this.namedXContentRegistry = namedXContentRegistry; + this.parserConfig = XContentParserConfiguration.EMPTY.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE) + .withRegistry(namedXContentRegistry); this.bigArrays = bigArrays; this.relativeTimeMillisSupplier = relativeTimeMillisSupplier; this.slowWriteLoggingThreshold = clusterSettings.get(SLOW_WRITE_LOGGING_THRESHOLD); @@ -465,8 +467,7 @@ private OnDiskState loadOnDiskState(Path dataPath, DirectoryReader reader) throw final SetOnce builderReference = new SetOnce<>(); consumeFromType(searcher, GLOBAL_TYPE_NAME, bytes -> { final Metadata metadata = Metadata.Builder.fromXContent( - XContentFactory.xContent(XContentType.SMILE) - .createParser(namedXContentRegistry, LoggingDeprecationHandler.INSTANCE, bytes.bytes, bytes.offset, bytes.length) + XContentType.SMILE.xContent().createParser(parserConfig, bytes.bytes, bytes.offset, bytes.length) ); logger.trace("found global metadata with last-accepted term [{}]", metadata.coordinationMetadata().term()); if (builderReference.get() != null) { @@ -485,8 +486,7 @@ private OnDiskState loadOnDiskState(Path dataPath, DirectoryReader reader) throw final Set indexUUIDs = new HashSet<>(); consumeFromType(searcher, INDEX_TYPE_NAME, bytes -> { final IndexMetadata indexMetadata = IndexMetadata.fromXContent( - XContentFactory.xContent(XContentType.SMILE) - .createParser(namedXContentRegistry, LoggingDeprecationHandler.INSTANCE, bytes.bytes, bytes.offset, bytes.length) + XContentType.SMILE.xContent().createParser(parserConfig, bytes.bytes, bytes.offset, bytes.length) ); logger.trace("found index metadata for {}", indexMetadata.getIndex()); if (indexUUIDs.add(indexMetadata.getIndexUUID()) == false) { diff --git a/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java b/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java index bdc5c0dc1a4e2..5db7dbdf4f34c 100644 --- a/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java +++ b/server/src/main/java/org/elasticsearch/http/AbstractHttpServerTransport.java @@ -31,6 +31,7 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.core.AbstractRefCounted; import org.elasticsearch.core.RefCounted; import org.elasticsearch.rest.RestChannel; @@ -40,6 +41,7 @@ import org.elasticsearch.transport.BindTransportException; import org.elasticsearch.transport.TransportSettings; import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParserConfiguration; import java.io.IOException; import java.net.InetAddress; @@ -71,7 +73,7 @@ public abstract class AbstractHttpServerTransport extends AbstractLifecycleCompo protected final ThreadPool threadPool; protected final Dispatcher dispatcher; protected final CorsHandler corsHandler; - private final NamedXContentRegistry xContentRegistry; + private final XContentParserConfiguration parserConfig; protected final PortsRange port; protected final ByteSizeValue maxContentLength; @@ -103,7 +105,8 @@ protected AbstractHttpServerTransport( this.networkService = networkService; this.bigArrays = bigArrays; this.threadPool = threadPool; - this.xContentRegistry = xContentRegistry; + this.parserConfig = XContentParserConfiguration.EMPTY.withRegistry(xContentRegistry) + .withDeprecationHandler(LoggingDeprecationHandler.INSTANCE); this.dispatcher = dispatcher; this.handlingSettings = HttpHandlingSettings.fromSettings(settings); this.corsHandler = CorsHandler.fromSettings(settings); @@ -407,13 +410,13 @@ private void handleIncomingRequest(final HttpRequest httpRequest, final HttpChan { RestRequest innerRestRequest; try { - innerRestRequest = RestRequest.request(xContentRegistry, httpRequest, httpChannel); + innerRestRequest = RestRequest.request(parserConfig, httpRequest, httpChannel); } catch (final RestRequest.MediaTypeHeaderException e) { badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e); innerRestRequest = requestWithoutFailedHeader(httpRequest, httpChannel, badRequestCause, e.getFailedHeaderName()); } catch (final RestRequest.BadParameterException e) { badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e); - innerRestRequest = RestRequest.requestWithoutParameters(xContentRegistry, httpRequest, httpChannel); + innerRestRequest = RestRequest.requestWithoutParameters(parserConfig, httpRequest, httpChannel); } restRequest = innerRestRequest; } @@ -443,7 +446,7 @@ private void handleIncomingRequest(final HttpRequest httpRequest, final HttpChan ); } catch (final IllegalArgumentException e) { badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e); - final RestRequest innerRequest = RestRequest.requestWithoutParameters(xContentRegistry, httpRequest, httpChannel); + final RestRequest innerRequest = RestRequest.requestWithoutParameters(parserConfig, httpRequest, httpChannel); innerChannel = new DefaultRestChannel( httpChannel, httpRequest, @@ -469,10 +472,10 @@ private RestRequest requestWithoutFailedHeader( ) { HttpRequest httpRequestWithoutContentType = httpRequest.removeHeader(failedHeaderName); try { - return RestRequest.request(xContentRegistry, httpRequestWithoutContentType, httpChannel); + return RestRequest.request(parserConfig, httpRequestWithoutContentType, httpChannel); } catch (final RestRequest.BadParameterException e) { badRequestCause.addSuppressed(e); - return RestRequest.requestWithoutParameters(xContentRegistry, httpRequestWithoutContentType, httpChannel); + return RestRequest.requestWithoutParameters(parserConfig, httpRequestWithoutContentType, httpChannel); } } diff --git a/server/src/main/java/org/elasticsearch/rest/RestRequest.java b/server/src/main/java/org/elasticsearch/rest/RestRequest.java index 5842b6558b38e..a63dbd45802e9 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestRequest.java +++ b/server/src/main/java/org/elasticsearch/rest/RestRequest.java @@ -14,7 +14,6 @@ import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.unit.ByteSizeValue; -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.core.Booleans; import org.elasticsearch.core.CheckedConsumer; import org.elasticsearch.core.Nullable; @@ -23,11 +22,11 @@ import org.elasticsearch.core.Tuple; import org.elasticsearch.http.HttpChannel; import org.elasticsearch.http.HttpRequest; -import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.ParsedMediaType; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContent; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.IOException; @@ -53,7 +52,7 @@ public class RestRequest implements ToXContent.Params { private static final AtomicLong requestIdGenerator = new AtomicLong(); - private final NamedXContentRegistry xContentRegistry; + private final XContentParserConfiguration parserConfig; private final Map params; private final Map> headers; private final String rawPath; @@ -74,18 +73,18 @@ public boolean isContentConsumed() { } protected RestRequest( - NamedXContentRegistry xContentRegistry, + XContentParserConfiguration parserConfig, Map params, String path, Map> headers, HttpRequest httpRequest, HttpChannel httpChannel ) { - this(xContentRegistry, params, path, headers, httpRequest, httpChannel, requestIdGenerator.incrementAndGet()); + this(parserConfig, params, path, headers, httpRequest, httpChannel, requestIdGenerator.incrementAndGet()); } private RestRequest( - NamedXContentRegistry xContentRegistry, + XContentParserConfiguration parserConfig, Map params, String path, Map> headers, @@ -106,14 +105,30 @@ private RestRequest( } catch (IllegalArgumentException e) { throw new MediaTypeHeaderException(e, "Content-Type"); } - this.xContentRegistry = xContentRegistry; this.httpRequest = httpRequest; + this.restApiVersion = RestCompatibleVersionHelper.getCompatibleVersion(parsedAccept, parsedContentType, hasContent()); + this.parserConfig = parserConfig.restApiVersion().equals(restApiVersion) + ? parserConfig + : parserConfig.withRestApiVersion(restApiVersion); this.httpChannel = httpChannel; this.params = params; this.rawPath = path; this.headers = Collections.unmodifiableMap(headers); this.requestId = requestId; - this.restApiVersion = RestCompatibleVersionHelper.getCompatibleVersion(parsedAccept, parsedContentType, hasContent()); + } + + protected RestRequest(RestRequest other) { + assert other.parserConfig.restApiVersion().equals(other.restApiVersion); + this.parsedAccept = other.parsedAccept; + this.parsedContentType = other.parsedContentType; + this.restApiVersion = other.restApiVersion; + this.parserConfig = other.parserConfig; + this.httpRequest = other.httpRequest; + this.httpChannel = other.httpChannel; + this.params = other.params; + this.rawPath = other.rawPath; + this.headers = other.headers; + this.requestId = other.requestId; } private static @Nullable ParsedMediaType parseHeaderWithMediaType(Map> headers, String headerName) { @@ -132,18 +147,6 @@ private RestRequest( } } - protected RestRequest(RestRequest restRequest) { - this( - restRequest.getXContentRegistry(), - restRequest.params(), - restRequest.path(), - restRequest.getHeaders(), - restRequest.getHttpRequest(), - restRequest.getHttpChannel(), - restRequest.getRequestId() - ); - } - /** * Invoke {@link HttpRequest#releaseAndCopy()} on the http request in this instance and replace a pooled http request * with an unpooled copy. This is supposed to be used before passing requests to {@link RestHandler} instances that can not safely @@ -154,20 +157,16 @@ void ensureSafeBuffers() { } /** - * Creates a new REST request. This method will throw {@link BadParameterException} if the path cannot be - * decoded + * Creates a new REST request. * - * @param xContentRegistry the content registry - * @param httpRequest the http request - * @param httpChannel the http channel - * @throws BadParameterException if the parameters can not be decoded + * @throws BadParameterException if the parameters can not be decoded * @throws MediaTypeHeaderException if the Content-Type or Accept header can not be parsed */ - public static RestRequest request(NamedXContentRegistry xContentRegistry, HttpRequest httpRequest, HttpChannel httpChannel) { + public static RestRequest request(XContentParserConfiguration parserConfig, HttpRequest httpRequest, HttpChannel httpChannel) { Map params = params(httpRequest.uri()); String path = path(httpRequest.uri()); return new RestRequest( - xContentRegistry, + parserConfig, params, path, httpRequest.getHeaders(), @@ -203,19 +202,16 @@ private static String path(final String uri) { * Creates a new REST request. The path is not decoded so this constructor will not throw a * {@link BadParameterException}. * - * @param xContentRegistry the content registry - * @param httpRequest the http request - * @param httpChannel the http channel * @throws MediaTypeHeaderException if the Content-Type or Accept header can not be parsed */ public static RestRequest requestWithoutParameters( - NamedXContentRegistry xContentRegistry, + XContentParserConfiguration parserConfig, HttpRequest httpRequest, HttpChannel httpChannel ) { Map params = Collections.emptyMap(); return new RestRequest( - xContentRegistry, + parserConfig, params, httpRequest.uri(), httpRequest.getHeaders(), @@ -477,10 +473,10 @@ public String[] paramAsStringArrayOrEmptyIfAll(String key) { } /** - * Get the {@link NamedXContentRegistry} that should be used to create parsers from this request. + * Get the configuration that should be used to create {@link XContentParser} from this request. */ - public NamedXContentRegistry getXContentRegistry() { - return xContentRegistry; + public XContentParserConfiguration contentParserConfig() { + return parserConfig; } /** @@ -491,12 +487,7 @@ public NamedXContentRegistry getXContentRegistry() { public final XContentParser contentParser() throws IOException { BytesReference content = requiredContent(); // will throw exception if body or content type missing XContent xContent = xContentType.get().xContent(); - return xContent.createParserForCompatibility( - xContentRegistry, - LoggingDeprecationHandler.INSTANCE, - content.streamInput(), - restApiVersion - ); + return xContent.createParser(parserConfig, content.streamInput()); } @@ -526,9 +517,7 @@ public final boolean hasContentOrSourceParam() { */ public final XContentParser contentOrSourceParamParser() throws IOException { Tuple tuple = contentOrSourceParam(); - return tuple.v1() - .xContent() - .createParserForCompatibility(xContentRegistry, LoggingDeprecationHandler.INSTANCE, tuple.v2().streamInput(), restApiVersion); + return tuple.v1().xContent().createParser(parserConfig, tuple.v2().streamInput()); } /** @@ -543,8 +532,7 @@ public final void withContentOrSourceParamParserOrNull(CheckedConsumer header) { throw new IllegalArgumentException("empty Content-Type header"); } + /** + * The requested version of the REST API. + */ public RestApiVersion getRestApiVersion() { return restApiVersion; } diff --git a/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java b/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java index 4a4cf25b8f862..077df82a2cece 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java @@ -191,17 +191,16 @@ public static void parseMultiLineRequest( final XContent xContent = sourceTuple.v1().xContent(); final BytesReference data = sourceTuple.v2(); MultiSearchRequest.readMultiLineFormat( - data, xContent, + request.contentParserConfig(), + data, consumer, indices, indicesOptions, routing, searchType, ccsMinimizeRoundtrips, - request.getXContentRegistry(), allowExplicitIndex, - request.getRestApiVersion(), extraParamParser ); } diff --git a/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java b/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java index 8955dc550351f..03e73d9c99018 100644 --- a/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java +++ b/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java @@ -20,7 +20,6 @@ import org.elasticsearch.index.fieldvisitor.FieldsVisitor; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.filtering.FilterPath; import java.io.IOException; import java.util.Collection; @@ -173,18 +172,17 @@ public List extractRawValuesWithoutCaching(String path) { if (source != null) { return XContentMapValues.extractRawValues(path, source); } - FilterPath[] filterPaths = FilterPath.compile(Set.of(path)); if (sourceAsBytes != null) { return XContentMapValues.extractRawValues( path, - XContentHelper.convertToMap(sourceAsBytes, false, null, filterPaths, null).v2() + XContentHelper.convertToMap(sourceAsBytes, false, null, Set.of(path), null).v2() ); } try { FieldsVisitor sourceFieldVisitor = new FieldsVisitor(true); fieldReader.accept(docId, sourceFieldVisitor); BytesReference source = sourceFieldVisitor.source(); - return XContentMapValues.extractRawValues(path, XContentHelper.convertToMap(source, false, null, filterPaths, null).v2()); + return XContentMapValues.extractRawValues(path, XContentHelper.convertToMap(source, false, null, Set.of(path), null).v2()); } catch (Exception e) { throw new ElasticsearchParseException("failed to parse / load source", e); } diff --git a/server/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java b/server/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java index 2300800069715..cb5da0fb0537d 100644 --- a/server/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java @@ -297,17 +297,16 @@ public void testMultiLineSerialization() throws IOException { parsedRequest.add(r); }; MultiSearchRequest.readMultiLineFormat( - new BytesArray(originalBytes), xContentType.xContent(), + parserConfig(), + new BytesArray(originalBytes), consumer, null, null, null, null, null, - xContentRegistry(), - true, - RestApiVersion.current() + true ); assertEquals(originalRequest, parsedRequest); } diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java index 3a4004f25e3bc..2932cbabf9e94 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.json.JsonXContent; import java.io.IOException; @@ -61,14 +62,11 @@ private void runLoadStateTest(boolean hasMissingCustoms, boolean preserveUnknown Metadata.FORMAT.toXContent(builder, latestMetadata); builder.endObject(); + XContentParserConfiguration parserConfig = hasMissingCustoms + ? parserConfig().withRegistry(ElasticsearchNodeCommand.namedXContentRegistry) + : parserConfig(); Metadata loadedMetadata; - try ( - XContentParser parser = createParser( - hasMissingCustoms ? ElasticsearchNodeCommand.namedXContentRegistry : xContentRegistry(), - JsonXContent.jsonXContent, - BytesReference.bytes(builder) - ) - ) { + try (XContentParser parser = createParser(parserConfig, JsonXContent.jsonXContent, BytesReference.bytes(builder))) { loadedMetadata = Metadata.fromXContent(parser); } assertThat(loadedMetadata.clusterUUID(), not(equalTo("_na_"))); diff --git a/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java b/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java index 2703b31c0563b..265b8eba36350 100644 --- a/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java +++ b/server/src/test/java/org/elasticsearch/http/DefaultRestChannelTests.java @@ -135,7 +135,7 @@ public void testHeadersSet() { Settings settings = Settings.builder().build(); final TestHttpRequest httpRequest = new TestHttpRequest(HttpRequest.HttpVersion.HTTP_1_1, RestRequest.Method.GET, "/"); httpRequest.getHeaders().put(Task.X_OPAQUE_ID, Collections.singletonList("abc")); - final RestRequest request = RestRequest.request(xContentRegistry(), httpRequest, httpChannel); + final RestRequest request = RestRequest.request(parserConfig(), httpRequest, httpChannel); HttpHandlingSettings handlingSettings = HttpHandlingSettings.fromSettings(settings); // send a response @@ -171,7 +171,7 @@ public void testCookiesSet() { Settings settings = Settings.builder().put(HttpTransportSettings.SETTING_HTTP_RESET_COOKIES.getKey(), true).build(); final TestHttpRequest httpRequest = new TestHttpRequest(HttpRequest.HttpVersion.HTTP_1_1, RestRequest.Method.GET, "/"); httpRequest.getHeaders().put(Task.X_OPAQUE_ID, Collections.singletonList("abc")); - final RestRequest request = RestRequest.request(xContentRegistry(), httpRequest, httpChannel); + final RestRequest request = RestRequest.request(parserConfig(), httpRequest, httpChannel); HttpHandlingSettings handlingSettings = HttpHandlingSettings.fromSettings(settings); // send a response @@ -200,7 +200,7 @@ public void testCookiesSet() { public void testReleaseInListener() throws IOException { final Settings settings = Settings.builder().build(); final TestHttpRequest httpRequest = new TestHttpRequest(HttpRequest.HttpVersion.HTTP_1_1, RestRequest.Method.GET, "/"); - final RestRequest request = RestRequest.request(xContentRegistry(), httpRequest, httpChannel); + final RestRequest request = RestRequest.request(parserConfig(), httpRequest, httpChannel); HttpHandlingSettings handlingSettings = HttpHandlingSettings.fromSettings(settings); DefaultRestChannel channel = new DefaultRestChannel( @@ -266,7 +266,7 @@ public void testConnectionClose() throws Exception { httpRequest.getHeaders().put(DefaultRestChannel.CONNECTION, Collections.singletonList(DefaultRestChannel.KEEP_ALIVE)); } } - final RestRequest request = RestRequest.request(xContentRegistry(), httpRequest, httpChannel); + final RestRequest request = RestRequest.request(parserConfig(), httpRequest, httpChannel); HttpHandlingSettings handlingSettings = HttpHandlingSettings.fromSettings(settings); @@ -301,7 +301,7 @@ public void testUnsupportedHttpMethod() { final boolean close = randomBoolean(); final HttpRequest.HttpVersion httpVersion = close ? HttpRequest.HttpVersion.HTTP_1_0 : HttpRequest.HttpVersion.HTTP_1_1; final String httpConnectionHeaderValue = close ? DefaultRestChannel.CLOSE : DefaultRestChannel.KEEP_ALIVE; - final RestRequest request = RestRequest.request(xContentRegistry(), new TestHttpRequest(httpVersion, null, "/") { + final RestRequest request = RestRequest.request(parserConfig(), new TestHttpRequest(httpVersion, null, "/") { @Override public RestRequest.Method method() { throw new IllegalArgumentException("test"); @@ -347,7 +347,7 @@ public void testCloseOnException() { final boolean close = randomBoolean(); final HttpRequest.HttpVersion httpVersion = close ? HttpRequest.HttpVersion.HTTP_1_0 : HttpRequest.HttpVersion.HTTP_1_1; final String httpConnectionHeaderValue = close ? DefaultRestChannel.CLOSE : DefaultRestChannel.KEEP_ALIVE; - final RestRequest request = RestRequest.request(xContentRegistry(), new TestHttpRequest(httpVersion, null, "/") { + final RestRequest request = RestRequest.request(parserConfig(), new TestHttpRequest(httpVersion, null, "/") { @Override public HttpResponse createResponse(RestStatus status, BytesReference content) { throw new IllegalArgumentException("test"); @@ -390,7 +390,7 @@ private TestHttpResponse executeRequest(final Settings settings, final String or httpRequest.getHeaders().put(CorsHandler.ORIGIN, Collections.singletonList(originValue)); } httpRequest.getHeaders().put(CorsHandler.HOST, Collections.singletonList(host)); - final RestRequest request = RestRequest.request(xContentRegistry(), httpRequest, httpChannel); + final RestRequest request = RestRequest.request(parserConfig(), httpRequest, httpChannel); HttpHandlingSettings httpHandlingSettings = HttpHandlingSettings.fromSettings(settings); RestChannel channel = new DefaultRestChannel( diff --git a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java index 253203b00b54c..9155fbe466849 100644 --- a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java +++ b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java @@ -615,7 +615,7 @@ public void testFaviconWithWrongHttpMethod() { public void testDispatchUnsupportedHttpMethod() { final boolean hasContent = randomBoolean(); - final RestRequest request = RestRequest.request(xContentRegistry(), new HttpRequest() { + final RestRequest request = RestRequest.request(parserConfig(), new HttpRequest() { @Override public RestRequest.Method method() { throw new IllegalArgumentException("test"); diff --git a/server/src/test/java/org/elasticsearch/rest/RestRequestTests.java b/server/src/test/java/org/elasticsearch/rest/RestRequestTests.java index 238249e5a25ff..c0de1e3d47af4 100644 --- a/server/src/test/java/org/elasticsearch/rest/RestRequestTests.java +++ b/server/src/test/java/org/elasticsearch/rest/RestRequestTests.java @@ -18,6 +18,7 @@ import org.elasticsearch.test.rest.FakeRestRequest; import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.IOException; @@ -84,7 +85,7 @@ private void runConsumesContentTest(final CheckedConsumer< when(httpRequest.getHeaders()).thenReturn( Collections.singletonMap("Content-Type", Collections.singletonList(randomFrom("application/json", "application/x-ndjson"))) ); - final RestRequest request = RestRequest.request(mock(NamedXContentRegistry.class), httpRequest, mock(HttpChannel.class)); + final RestRequest request = RestRequest.request(XContentParserConfiguration.EMPTY, httpRequest, mock(HttpChannel.class)); assertFalse(request.isContentConsumed()); try { consumer.accept(request); @@ -255,7 +256,7 @@ private static final class ContentRestRequest extends RestRequest { private ContentRestRequest(RestRequest restRequest) { super( - restRequest.getXContentRegistry(), + restRequest.contentParserConfig(), restRequest.params(), restRequest.path(), restRequest.getHeaders(), diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index 8d48679ac51ef..1147efde054c3 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -1147,7 +1147,7 @@ protected void ensureClusterStateCanBeReadByNodeTool() throws IOException { final Metadata loadedMetadata; try ( XContentParser parser = createParser( - ElasticsearchNodeCommand.namedXContentRegistry, + parserConfig().withRegistry(ElasticsearchNodeCommand.namedXContentRegistry), SmileXContent.smileXContent, originalBytes ) @@ -1188,7 +1188,7 @@ protected void ensureClusterStateCanBeReadByNodeTool() throws IOException { final IndexMetadata loadedIndexMetadata; try ( XContentParser parser = createParser( - ElasticsearchNodeCommand.namedXContentRegistry, + parserConfig().withRegistry(ElasticsearchNodeCommand.namedXContentRegistry), SmileXContent.smileXContent, originalBytes ) diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java index ae7d6100f6853..c4114b1ba0dd7 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -102,6 +102,7 @@ import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser.Token; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.junit.After; import org.junit.AfterClass; @@ -111,13 +112,11 @@ import org.junit.internal.AssumptionViolatedException; import org.junit.rules.RuleChain; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.time.ZoneId; import java.util.ArrayList; @@ -1417,6 +1416,12 @@ protected static T copyInstance( } } + protected final XContentParserConfiguration parserConfig() { + XContentParserConfiguration config = XContentParserConfiguration.EMPTY.withRegistry(xContentRegistry()) + .withDeprecationHandler(LoggingDeprecationHandler.INSTANCE); + return randomBoolean() ? config : config.withRestApiVersion(RestApiVersion.minimumSupported()); + } + /** * Create a new {@link XContentParser}. */ @@ -1428,59 +1433,44 @@ protected final XContentParser createParser(XContentBuilder builder) throws IOEx * Create a new {@link XContentParser}. */ protected final XContentParser createParser(XContent xContent, String data) throws IOException { - if (randomBoolean()) { - return createParserWithCompatibilityFor(xContent, data, RestApiVersion.minimumSupported()); - } else { - return xContent.createParser(xContentRegistry(), LoggingDeprecationHandler.INSTANCE, data); - } + return xContent.createParser(parserConfig(), data); } /** * Create a new {@link XContentParser}. */ protected final XContentParser createParser(XContent xContent, InputStream data) throws IOException { - return xContent.createParser(xContentRegistry(), LoggingDeprecationHandler.INSTANCE, data); + return xContent.createParser(parserConfig(), data); } /** * Create a new {@link XContentParser}. */ protected final XContentParser createParser(XContent xContent, byte[] data) throws IOException { - return xContent.createParser(xContentRegistry(), LoggingDeprecationHandler.INSTANCE, data); + return xContent.createParser(parserConfig(), data); } /** * Create a new {@link XContentParser}. */ protected final XContentParser createParser(XContent xContent, BytesReference data) throws IOException { - return createParser(xContentRegistry(), xContent, data); + return createParser(parserConfig(), xContent, data); } /** * Create a new {@link XContentParser}. */ - protected final XContentParser createParser(NamedXContentRegistry namedXContentRegistry, XContent xContent, BytesReference data) + protected final XContentParser createParser(XContentParserConfiguration config, XContent xContent, BytesReference data) throws IOException { if (data.hasArray()) { - return xContent.createParser( - namedXContentRegistry, - LoggingDeprecationHandler.INSTANCE, - data.array(), - data.arrayOffset(), - data.length() - ); + return xContent.createParser(config, data.array(), data.arrayOffset(), data.length()); } - return xContent.createParser(namedXContentRegistry, LoggingDeprecationHandler.INSTANCE, data.streamInput()); + return xContent.createParser(config, data.streamInput()); } protected final XContentParser createParserWithCompatibilityFor(XContent xContent, String data, RestApiVersion restApiVersion) throws IOException { - return xContent.createParserForCompatibility( - xContentRegistry(), - LoggingDeprecationHandler.INSTANCE, - new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), - restApiVersion - ); + return xContent.createParser(parserConfig().withRestApiVersion(restApiVersion), data); } private static final NamedXContentRegistry DEFAULT_NAMED_X_CONTENT_REGISTRY = new NamedXContentRegistry( diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/FakeRestRequest.java b/test/framework/src/main/java/org/elasticsearch/test/rest/FakeRestRequest.java index c69856f4e1dad..66bad2fe602fd 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/FakeRestRequest.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/FakeRestRequest.java @@ -12,12 +12,14 @@ import org.elasticsearch.action.support.ListenableActionFuture; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.http.HttpChannel; import org.elasticsearch.http.HttpRequest; import org.elasticsearch.http.HttpResponse; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.net.InetSocketAddress; @@ -30,7 +32,7 @@ public class FakeRestRequest extends RestRequest { public FakeRestRequest() { this( - NamedXContentRegistry.EMPTY, + XContentParserConfiguration.EMPTY.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE), new FakeHttpRequest(Method.GET, "", BytesArray.EMPTY, new HashMap<>()), new HashMap<>(), new FakeHttpChannel(null) @@ -38,12 +40,12 @@ public FakeRestRequest() { } private FakeRestRequest( - NamedXContentRegistry xContentRegistry, + XContentParserConfiguration config, HttpRequest httpRequest, Map params, HttpChannel httpChannel ) { - super(xContentRegistry, params, httpRequest.uri(), httpRequest.getHeaders(), httpRequest, httpChannel); + super(config, params, httpRequest.uri(), httpRequest.getHeaders(), httpRequest, httpChannel); } public static class FakeHttpRequest implements HttpRequest { @@ -179,7 +181,7 @@ public void close() { } public static class Builder { - private final NamedXContentRegistry xContentRegistry; + private final XContentParserConfiguration parserConfig; private Map> headers = new HashMap<>(); @@ -195,8 +197,9 @@ public static class Builder { private Exception inboundException; - public Builder(NamedXContentRegistry xContentRegistry) { - this.xContentRegistry = xContentRegistry; + public Builder(NamedXContentRegistry registry) { + this.parserConfig = XContentParserConfiguration.EMPTY.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE) + .withRegistry(registry); } public Builder withHeaders(Map> headers) { @@ -239,7 +242,7 @@ public Builder withInboundException(Exception exception) { public FakeRestRequest build() { FakeHttpRequest fakeHttpRequest = new FakeHttpRequest(method, path, content, headers, inboundException); - return new FakeRestRequest(xContentRegistry, fakeHttpRequest, params, new FakeHttpChannel(address)); + return new FakeRestRequest(parserConfig, fakeHttpRequest, params, new FakeHttpChannel(address)); } }