From 15c59d07b325c3e72dd0e8fc90cc0811285efff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Thu, 14 Apr 2016 15:47:03 +0200 Subject: [PATCH] Remove ParseFieldMatcher from AbstractXContentParser Currently we are able to set a ParseFieldMatcher on XContentParsers, mainly to conveniently carry it around to be available where the actual parsing happens. This was just recently introduced together with ObjectParser so that ObjectParser can make use of deprecation logging and throwing errors while parsing. This however is trappy because we create parsers in so many places in the code and it is easy to forget setting the right ParseFieldMatcher. Instead we should hold the ParseFieldMatcher only in the parse contexts (e.g. QueryParseContext). This PR removes the ParseFieldMatcher from XContentParser. ObjectParser can still make use of it because we can make the otherwise unbounded `context` type to extend an interface that makes sure contexts used in ObjectParser can supply a ParseFieldMatcher. Contexts in ObjectParser are now no longer optional, but it is sufficient to pass in a small lambda expression in places where no other context is available. Relates to #17417 --- .../ClusterAllocationExplainRequest.java | 9 +- .../reroute/ClusterRerouteRequest.java | 6 +- .../cluster/routing/AllocationId.java | 7 +- .../AbstractAllocateAllocationCommand.java | 5 +- ...AllocateEmptyPrimaryAllocationCommand.java | 7 +- .../AllocateReplicaAllocationCommand.java | 7 +- ...AllocateStalePrimaryAllocationCommand.java | 7 +- .../command/AllocationCommands.java | 6 +- .../command/BasePrimaryAllocationCommand.java | 5 +- .../common/ParseFieldMatcherSupplier.java | 36 +++++++ .../common/xcontent/ObjectParser.java | 23 ++--- .../common/xcontent/ParseFieldRegistry.java | 14 +-- .../common/xcontent/XContentParser.java | 16 +-- .../support/AbstractXContentParser.java | 11 --- .../index/query/QueryParseContext.java | 12 +-- .../index/query/QueryShardContext.java | 5 +- .../FunctionScoreQueryBuilder.java | 6 +- .../elasticsearch/ingest/IngestMetadata.java | 7 +- .../ingest/PipelineConfiguration.java | 6 +- .../aggregations/AggregatorParsers.java | 18 ++-- .../CompletionSuggestionBuilder.java | 10 +- .../suggest/completion/FuzzyOptions.java | 8 +- .../suggest/completion/RegexOptions.java | 8 +- .../context/CategoryQueryContext.java | 6 +- .../completion/context/GeoQueryContext.java | 6 +- .../DirectCandidateGeneratorBuilder.java | 4 +- .../allocation/AllocationCommandsTests.java | 3 +- .../common/xcontent/ObjectParserTests.java | 99 ++++++++++--------- .../search/SearchModuleTests.java | 8 +- .../aggregations/BaseAggregationTestCase.java | 2 +- .../BasePipelineAggregationTestCase.java | 2 +- .../pipeline/moving/avg/MovAvgTests.java | 5 +- .../search/sort/SortParserTests.java | 40 ++++++-- .../index/reindex/RestReindexAction.java | 13 ++- 34 files changed, 245 insertions(+), 182 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/common/ParseFieldMatcherSupplier.java diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java index 11722821efb..4d143c437c3 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java @@ -24,14 +24,14 @@ import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.MasterNodeRequest; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.Strings; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; -import java.util.Objects; import static org.elasticsearch.action.ValidateActions.addValidationError; @@ -40,7 +40,8 @@ import static org.elasticsearch.action.ValidateActions.addValidationError; */ public class ClusterAllocationExplainRequest extends MasterNodeRequest { - private static ObjectParser PARSER = new ObjectParser("cluster/allocation/explain"); + private static ObjectParser PARSER = new ObjectParser( + "cluster/allocation/explain"); static { PARSER.declareString(ClusterAllocationExplainRequest::setIndex, new ParseField("index")); PARSER.declareInt(ClusterAllocationExplainRequest::setShard, new ParseField("shard")); @@ -148,7 +149,7 @@ public class ClusterAllocationExplainRequest extends MasterNodeRequest ParseFieldMatcher.STRICT); Exception e = req.validate(); if (e != null) { throw new ElasticsearchParseException("'index', 'shard', and 'primary' must be specified in allocation explain request", e); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java index fc371b9c1f0..a241f01ea28 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java @@ -25,17 +25,14 @@ import org.elasticsearch.action.support.master.AcknowledgedRequest; import org.elasticsearch.cluster.routing.allocation.command.AllocationCommand; import org.elasticsearch.cluster.routing.allocation.command.AllocationCommandRegistry; import org.elasticsearch.cluster.routing.allocation.command.AllocationCommands; -import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; -import java.util.List; /** * Request to submit cluster reroute allocation commands @@ -105,7 +102,6 @@ public class ClusterRerouteRequest extends AcknowledgedRequest ALLOCATION_ID_PARSER = new ObjectParser<>("allocationId"); + private static final ObjectParser ALLOCATION_ID_PARSER = new ObjectParser<>( + "allocationId"); static { ALLOCATION_ID_PARSER.declareString(AllocationId.Builder::setId, new ParseField(ID_KEY)); @@ -198,6 +201,6 @@ public class AllocationId implements ToXContent { } public static AllocationId fromXContent(XContentParser parser) throws IOException { - return ALLOCATION_ID_PARSER.parse(parser, new AllocationId.Builder()).build(); + return ALLOCATION_ID_PARSER.parse(parser, new AllocationId.Builder(), () -> ParseFieldMatcher.STRICT).build(); } } diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AbstractAllocateAllocationCommand.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AbstractAllocateAllocationCommand.java index 28a829b5af9..50e71c5094a 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AbstractAllocateAllocationCommand.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AbstractAllocateAllocationCommand.java @@ -28,6 +28,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ObjectParser; @@ -47,8 +48,8 @@ public abstract class AbstractAllocateAllocationCommand implements AllocationCom private static final String SHARD_FIELD = "shard"; private static final String NODE_FIELD = "node"; - protected static > ObjectParser createAllocateParser(String command) { - ObjectParser parser = new ObjectParser<>(command); + protected static > ObjectParser createAllocateParser(String command) { + ObjectParser parser = new ObjectParser<>(command); parser.declareString(Builder::setIndex, new ParseField(INDEX_FIELD)); parser.declareInt(Builder::setShard, new ParseField(SHARD_FIELD)); parser.declareString(Builder::setNode, new ParseField(NODE_FIELD)); diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateEmptyPrimaryAllocationCommand.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateEmptyPrimaryAllocationCommand.java index 4ee0294faaf..74e3a18efbc 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateEmptyPrimaryAllocationCommand.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateEmptyPrimaryAllocationCommand.java @@ -28,6 +28,8 @@ import org.elasticsearch.cluster.routing.allocation.RerouteExplanation; import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; @@ -45,7 +47,8 @@ public class AllocateEmptyPrimaryAllocationCommand extends BasePrimaryAllocation public static final String NAME = "allocate_empty_primary"; public static final ParseField COMMAND_NAME_FIELD = new ParseField(NAME); - private static final ObjectParser EMPTY_PRIMARY_PARSER = BasePrimaryAllocationCommand.createAllocatePrimaryParser(NAME); + private static final ObjectParser EMPTY_PRIMARY_PARSER = BasePrimaryAllocationCommand + .createAllocatePrimaryParser(NAME); /** * Creates a new {@link AllocateEmptyPrimaryAllocationCommand} @@ -78,7 +81,7 @@ public class AllocateEmptyPrimaryAllocationCommand extends BasePrimaryAllocation @Override public Builder parse(XContentParser parser) throws IOException { - return EMPTY_PRIMARY_PARSER.parse(parser, this); + return EMPTY_PRIMARY_PARSER.parse(parser, this, () -> ParseFieldMatcher.STRICT); } @Override diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateReplicaAllocationCommand.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateReplicaAllocationCommand.java index a62928fded4..b651580ea74 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateReplicaAllocationCommand.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateReplicaAllocationCommand.java @@ -28,6 +28,8 @@ import org.elasticsearch.cluster.routing.allocation.RerouteExplanation; import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; @@ -44,7 +46,8 @@ public class AllocateReplicaAllocationCommand extends AbstractAllocateAllocation public static final String NAME = "allocate_replica"; public static final ParseField COMMAND_NAME_FIELD = new ParseField(NAME); - private static final ObjectParser REPLICA_PARSER = createAllocateParser(NAME); + private static final ObjectParser REPLICA_PARSER = + createAllocateParser(NAME); /** * Creates a new {@link AllocateReplicaAllocationCommand} @@ -77,7 +80,7 @@ public class AllocateReplicaAllocationCommand extends AbstractAllocateAllocation @Override public Builder parse(XContentParser parser) throws IOException { - return REPLICA_PARSER.parse(parser, this); + return REPLICA_PARSER.parse(parser, this, () -> ParseFieldMatcher.STRICT); } @Override diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateStalePrimaryAllocationCommand.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateStalePrimaryAllocationCommand.java index 438827d004e..5fad78d0360 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateStalePrimaryAllocationCommand.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocateStalePrimaryAllocationCommand.java @@ -28,6 +28,8 @@ import org.elasticsearch.cluster.routing.allocation.RerouteExplanation; import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; @@ -44,7 +46,8 @@ public class AllocateStalePrimaryAllocationCommand extends BasePrimaryAllocation public static final String NAME = "allocate_stale_primary"; public static final ParseField COMMAND_NAME_FIELD = new ParseField(NAME); - private static final ObjectParser STALE_PRIMARY_PARSER = BasePrimaryAllocationCommand.createAllocatePrimaryParser(NAME); + private static final ObjectParser STALE_PRIMARY_PARSER = BasePrimaryAllocationCommand + .createAllocatePrimaryParser(NAME); /** * Creates a new {@link AllocateStalePrimaryAllocationCommand} @@ -78,7 +81,7 @@ public class AllocateStalePrimaryAllocationCommand extends BasePrimaryAllocation @Override public Builder parse(XContentParser parser) throws IOException { - return STALE_PRIMARY_PARSER.parse(parser, this); + return STALE_PRIMARY_PARSER.parse(parser, this, () -> ParseFieldMatcher.STRICT); } @Override diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocationCommands.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocationCommands.java index f5a06fe78a9..10c43fac7d7 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocationCommands.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/AllocationCommands.java @@ -22,6 +22,7 @@ package org.elasticsearch.cluster.routing.allocation.command; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.RoutingExplanations; +import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContent; @@ -128,7 +129,8 @@ public class AllocationCommands { * @return {@link AllocationCommands} read * @throws IOException if something bad happens while reading the stream */ - public static AllocationCommands fromXContent(XContentParser parser, AllocationCommandRegistry registry) throws IOException { + public static AllocationCommands fromXContent(XContentParser parser, ParseFieldMatcher parseFieldMatcher, + AllocationCommandRegistry registry) throws IOException { AllocationCommands commands = new AllocationCommands(); XContentParser.Token token = parser.currentToken(); @@ -157,7 +159,7 @@ public class AllocationCommands { token = parser.nextToken(); String commandName = parser.currentName(); token = parser.nextToken(); - commands.add(registry.lookup(commandName, parser).fromXContent(parser)); + commands.add(registry.lookup(commandName, parser, parseFieldMatcher).fromXContent(parser)); // move to the end object one if (parser.nextToken() != XContentParser.Token.END_OBJECT) { throw new ElasticsearchParseException("allocation command is malformed, done parsing a command, but didn't get END_OBJECT, got [{}] instead", token); diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/BasePrimaryAllocationCommand.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/BasePrimaryAllocationCommand.java index bbb911c6f01..0013061e8ea 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/BasePrimaryAllocationCommand.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/command/BasePrimaryAllocationCommand.java @@ -20,6 +20,7 @@ package org.elasticsearch.cluster.routing.allocation.command; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ObjectParser; @@ -34,8 +35,8 @@ public abstract class BasePrimaryAllocationCommand extends AbstractAllocateAlloc private static final String ACCEPT_DATA_LOSS_FIELD = "accept_data_loss"; - protected static > ObjectParser createAllocatePrimaryParser(String command) { - ObjectParser parser = AbstractAllocateAllocationCommand.createAllocateParser(command); + protected static > ObjectParser createAllocatePrimaryParser(String command) { + ObjectParser parser = AbstractAllocateAllocationCommand.createAllocateParser(command); parser.declareBoolean(Builder::setAcceptDataLoss, new ParseField(ACCEPT_DATA_LOSS_FIELD)); return parser; } diff --git a/core/src/main/java/org/elasticsearch/common/ParseFieldMatcherSupplier.java b/core/src/main/java/org/elasticsearch/common/ParseFieldMatcherSupplier.java new file mode 100644 index 00000000000..b2b7b51ffcb --- /dev/null +++ b/core/src/main/java/org/elasticsearch/common/ParseFieldMatcherSupplier.java @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common; + +import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.index.query.QueryShardContext; + +/** + * This interface should be implemented by classes like {@link QueryParseContext} or {@link QueryShardContext} that + * are able to carry a {@link ParseFieldMatcher}. + */ +@FunctionalInterface +public interface ParseFieldMatcherSupplier { + + /** + * @return the parseFieldMatcher + */ + ParseFieldMatcher parseFieldMatcher(); +} diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java b/core/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java index 311b93744ed..a9f6518211c 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java @@ -20,6 +20,7 @@ package org.elasticsearch.common.xcontent; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.ParsingException; import java.io.IOException; @@ -51,7 +52,7 @@ import static org.elasticsearch.common.xcontent.XContentParser.Token.VALUE_STRIN * use the high level declare methods like {@link #declareString(BiConsumer, ParseField)} instead of {@link #declareField} which can be used * to implement exceptional parsing operations not covered by the high level methods. */ -public final class ObjectParser implements BiFunction { +public final class ObjectParser implements BiFunction { /** * Adapts an array (or varags) setter into a list setter. */ @@ -87,32 +88,22 @@ public final class ObjectParser implements BiFunction implements BiFunction { * Lookup a value from the registry by name while checking that the name matches the ParseField. * * @param name The name of the thing to look up. - * @param parser The parser from which the name was looked up. This is used to resolve the {@link ParseFieldMatcher} and to build nice - * error messages. + * @param parser The parser from which the name was looked up. + * @param parseFieldMatcher to build nice error messages. * @return The value being looked up. Never null. * @throws ParsingException if the named thing isn't in the registry or the name was deprecated and deprecated names aren't supported. */ - public T lookup(String name, XContentParser parser) { - T value = lookupReturningNullIfNotFound(name, parser); + public T lookup(String name, XContentParser parser, ParseFieldMatcher parseFieldMatcher) { + T value = lookupReturningNullIfNotFound(name, parseFieldMatcher); if (value == null) { throw new ParsingException(parser.getTokenLocation(), "no [" + registryName + "] registered for [" + name + "]"); } @@ -85,19 +85,19 @@ public class ParseFieldRegistry { * Lookup a value from the registry by name while checking that the name matches the ParseField. * * @param name The name of the thing to look up. - * @param parser The parser from which the name was looked up. This is used to resolve the {@link ParseFieldMatcher} and to build nice + * @param parseFieldMatcher The parseFieldMatcher. This is used to resolve the {@link ParseFieldMatcher} and to build nice * error messages. * @return The value being looked up or null if it wasn't found. * @throws ParsingException if the named thing isn't in the registry or the name was deprecated and deprecated names aren't supported. */ - public T lookupReturningNullIfNotFound(String name, XContentParser parser) { + public T lookupReturningNullIfNotFound(String name, ParseFieldMatcher parseFieldMatcher) { Tuple parseFieldAndValue = registry.get(name); if (parseFieldAndValue == null) { return null; } ParseField parseField = parseFieldAndValue.v1(); T value = parseFieldAndValue.v2(); - boolean match = parser.getParseFieldMatcher().match(name, parseField); + boolean match = parseFieldMatcher.match(name, parseField); //this is always expected to match, ParseField is useful for deprecation warnings etc. here assert match : "ParseField did not match registered name [" + name + "][" + registryName + "]"; return value; diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java index d647c5f0134..54de31c3150 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java @@ -20,7 +20,6 @@ package org.elasticsearch.common.xcontent; import org.apache.lucene.util.BytesRef; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.lease.Releasable; import java.io.IOException; @@ -187,7 +186,7 @@ public interface XContentParser extends Releasable { float floatValue(boolean coerce) throws IOException; double doubleValue(boolean coerce) throws IOException; - + short shortValue() throws IOException; int intValue() throws IOException; @@ -241,21 +240,10 @@ public interface XContentParser extends Releasable { /** * Used for error reporting to highlight where syntax errors occur in * content being parsed. - * + * * @return last token's location or null if cannot be determined */ XContentLocation getTokenLocation(); boolean isClosed(); - - /** - * Returns this parsers {@link ParseFieldMatcher} - */ - ParseFieldMatcher getParseFieldMatcher(); - - - /** - * Sets this parsers {@link ParseFieldMatcher} - */ - void setParseFieldMatcher(ParseFieldMatcher matcher) ; } diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java b/core/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java index e994b81832f..39a6fca1095 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java @@ -22,7 +22,6 @@ package org.elasticsearch.common.xcontent.support; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.Booleans; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; @@ -37,8 +36,6 @@ import java.util.Map; */ public abstract class AbstractXContentParser implements XContentParser { - private ParseFieldMatcher matcher = ParseFieldMatcher.STRICT; - // Currently this is not a setting that can be changed and is a policy // that relates to how parsing of things like "boost" are done across // the whole of Elasticsearch (eg if String "1.0" is a valid float). @@ -337,12 +334,4 @@ public abstract class AbstractXContentParser implements XContentParser { @Override public abstract boolean isClosed(); - - public ParseFieldMatcher getParseFieldMatcher() { - return matcher; - } - - public void setParseFieldMatcher(ParseFieldMatcher matcher) { - this.matcher = matcher; - } } diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java index 3fe7cfd6da5..ee6c49234fd 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java @@ -21,13 +21,14 @@ package org.elasticsearch.index.query; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.indices.query.IndicesQueriesRegistry; import java.io.IOException; -public class QueryParseContext { +public class QueryParseContext implements ParseFieldMatcherSupplier { private static final ParseField CACHE = new ParseField("_cache").withAllDeprecated("Elasticsearch makes its own caching decisions"); private static final ParseField CACHE_KEY = new ParseField("_cache_key").withAllDeprecated("Filters are always used as cache keys"); @@ -44,9 +45,6 @@ public class QueryParseContext { public void reset(XContentParser jp) { this.parseFieldMatcher = ParseFieldMatcher.EMPTY; this.parser = jp; - if (parser != null) { - this.parser.setParseFieldMatcher(parseFieldMatcher); - } } public XContentParser parser() { @@ -57,9 +55,6 @@ public class QueryParseContext { if (parseFieldMatcher == null) { throw new IllegalArgumentException("parseFieldMatcher must not be null"); } - if (parser != null) { - parser.setParseFieldMatcher(parseFieldMatcher); - } this.parseFieldMatcher = parseFieldMatcher; } @@ -120,7 +115,7 @@ public class QueryParseContext { if (token != XContentParser.Token.START_OBJECT && token != XContentParser.Token.START_ARRAY) { throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object"); } - QueryBuilder result = indicesQueriesRegistry.lookup(queryName, parser).fromXContent(this); + QueryBuilder result = indicesQueriesRegistry.lookup(queryName, parser, parseFieldMatcher).fromXContent(this); if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) { // if we are at END_OBJECT, move to the next one... parser.nextToken(); @@ -128,6 +123,7 @@ public class QueryParseContext { return result; } + @Override public ParseFieldMatcher parseFieldMatcher() { return parseFieldMatcher; } diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index b516e44ea28..6420c235c2e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -29,6 +29,7 @@ import org.apache.lucene.search.similarities.Similarity; import org.elasticsearch.Version; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; @@ -49,7 +50,6 @@ import org.elasticsearch.index.mapper.core.TextFieldMapper; import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.percolator.PercolatorQueryCache; import org.elasticsearch.index.query.support.InnerHitBuilder; -import org.elasticsearch.index.query.support.InnerHitsBuilder; import org.elasticsearch.index.query.support.NestedScope; import org.elasticsearch.index.similarity.SimilarityService; import org.elasticsearch.indices.query.IndicesQueriesRegistry; @@ -69,7 +69,7 @@ import static java.util.Collections.unmodifiableMap; /** * Context object used to create lucene queries on the shard level. */ -public class QueryShardContext extends QueryRewriteContext { +public class QueryShardContext extends QueryRewriteContext implements ParseFieldMatcherSupplier { private final MapperService mapperService; private final SimilarityService similarityService; @@ -118,6 +118,7 @@ public class QueryShardContext extends QueryRewriteContext { this.parseContext.parseFieldMatcher(parseFieldMatcher); } + @Override public ParseFieldMatcher parseFieldMatcher() { return parseContext.parseFieldMatcher(); } diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java index c3d8dc976ef..a4b5fdd806c 100644 --- a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java @@ -476,7 +476,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder scoreFunction = scoreFunctionsRegistry.lookup(currentFieldName, parseContext.parser()) + ScoreFunctionBuilder scoreFunction = scoreFunctionsRegistry + .lookup(currentFieldName, parseContext.parser(), parseContext.parseFieldMatcher()) .fromXContent(parseContext); filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(scoreFunction)); } @@ -581,7 +582,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder, Void> INGEST_METADATA_PARSER = new ObjectParser<>("ingest_metadata", ArrayList::new); + private static final ObjectParser, ParseFieldMatcherSupplier> INGEST_METADATA_PARSER = new ObjectParser<>( + "ingest_metadata", ArrayList::new); static { INGEST_METADATA_PARSER.declareObjectArray(List::addAll , PipelineConfiguration.getParser(), PIPELINES_FIELD); @@ -94,7 +97,7 @@ public final class IngestMetadata implements MetaData.Custom { @Override public IngestMetadata fromXContent(XContentParser parser) throws IOException { Map pipelines = new HashMap<>(); - List configs = INGEST_METADATA_PARSER.parse(parser); + List configs = INGEST_METADATA_PARSER.parse(parser, () -> ParseFieldMatcher.STRICT); for (PipelineConfiguration pipeline : configs) { pipelines.put(pipeline.getId(), pipeline); } diff --git a/core/src/main/java/org/elasticsearch/ingest/PipelineConfiguration.java b/core/src/main/java/org/elasticsearch/ingest/PipelineConfiguration.java index d99d0e18c5c..6272eee1cbf 100644 --- a/core/src/main/java/org/elasticsearch/ingest/PipelineConfiguration.java +++ b/core/src/main/java/org/elasticsearch/ingest/PipelineConfiguration.java @@ -21,6 +21,7 @@ package org.elasticsearch.ingest; import org.elasticsearch.cluster.AbstractDiffable; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -46,7 +47,7 @@ public final class PipelineConfiguration extends AbstractDiffable PARSER = new ObjectParser<>("pipeline_config", Builder::new); + private final static ObjectParser PARSER = new ObjectParser<>("pipeline_config", Builder::new); static { PARSER.declareString(Builder::setId, new ParseField("id")); PARSER.declareField((parser, builder, aVoid) -> { @@ -56,7 +57,7 @@ public final class PipelineConfiguration extends AbstractDiffable getParser() { + public static BiFunction getParser() { return (p, c) -> PARSER.apply(p ,c).build(); } private static class Builder { @@ -110,6 +111,7 @@ public final class PipelineConfiguration extends AbstractDiffable TLP_PARSER = + private static ObjectParser TLP_PARSER = new ObjectParser<>(SUGGESTION_NAME, null); static { TLP_PARSER.declareStringArray(CompletionSuggestionBuilder.InnerBuilder::payload, PAYLOAD_FIELD); @@ -80,12 +82,12 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder - completionSuggestionContext.regexOptions = RegexOptions.parse(parser), + completionSuggestionContext.regexOptions = RegexOptions.parse(parser, context), RegexOptions.REGEX_OPTIONS, ObjectParser.ValueType.OBJECT); TLP_PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::field, SuggestUtils.Fields.FIELD); TLP_PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::analyzer, SuggestUtils.Fields.ANALYZER); @@ -263,7 +265,7 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder ParseFieldMatcher.STRICT); String field = builder.field; // now we should have field name, check and copy fields over to the suggestion builder we return if (field == null) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java index ed2efdf4562..2977e8ad9a2 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java @@ -23,6 +23,7 @@ import org.apache.lucene.search.suggest.document.FuzzyCompletionQuery; import org.apache.lucene.util.automaton.Operations; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -56,7 +57,8 @@ public class FuzzyOptions implements ToXContent, Writeable { * "max_determinized_states" : INT * } */ - private static ObjectParser PARSER = new ObjectParser<>(FUZZY_OPTIONS.getPreferredName(), Builder::new); + private static ObjectParser PARSER = new ObjectParser<>(FUZZY_OPTIONS.getPreferredName(), + Builder::new); static { PARSER.declareInt(Builder::setFuzzyMinLength, MIN_LENGTH_FIELD); PARSER.declareInt(Builder::setMaxDeterminizedStates, MAX_DETERMINIZED_STATES_FIELD); @@ -111,8 +113,8 @@ public class FuzzyOptions implements ToXContent, Writeable { out.writeVInt(maxDeterminizedStates); } - static FuzzyOptions parse(XContentParser parser) throws IOException { - return PARSER.parse(parser).build(); + static FuzzyOptions parse(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException { + return PARSER.parse(parser, context).build(); } public static Builder builder() { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java index 58464cddee2..59ca2a6da14 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java @@ -23,6 +23,7 @@ import org.apache.lucene.util.automaton.Operations; import org.apache.lucene.util.automaton.RegExp; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -48,7 +49,8 @@ public class RegexOptions implements ToXContent, Writeable { * "max_determinized_states" : INT * } */ - private static ObjectParser PARSER = new ObjectParser<>(REGEX_OPTIONS.getPreferredName(), Builder::new); + private static ObjectParser PARSER = new ObjectParser<>(REGEX_OPTIONS.getPreferredName(), + Builder::new); static { PARSER.declareInt(Builder::setMaxDeterminizedStates, MAX_DETERMINIZED_STATES); PARSER.declareField((parser, builder, aVoid) -> { @@ -105,8 +107,8 @@ public class RegexOptions implements ToXContent, Writeable { return new Builder(); } - static RegexOptions parse(XContentParser parser) throws IOException { - return PARSER.parse(parser).build(); + static RegexOptions parse(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException { + return PARSER.parse(parser, context).build(); } @Override diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java index 62892216c68..1384868f0dc 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java @@ -21,6 +21,8 @@ package org.elasticsearch.search.suggest.completion.context; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -95,7 +97,7 @@ public final class CategoryQueryContext implements ToXContent { return result; } - private static ObjectParser CATEGORY_PARSER = new ObjectParser<>(NAME, null); + private static ObjectParser CATEGORY_PARSER = new ObjectParser<>(NAME, null); static { CATEGORY_PARSER.declareString(Builder::setCategory, new ParseField(CONTEXT_VALUE)); CATEGORY_PARSER.declareInt(Builder::setBoost, new ParseField(CONTEXT_BOOST)); @@ -106,7 +108,7 @@ public final class CategoryQueryContext implements ToXContent { XContentParser.Token token = parser.currentToken(); Builder builder = builder(); if (token == XContentParser.Token.START_OBJECT) { - CATEGORY_PARSER.parse(parser, builder); + CATEGORY_PARSER.parse(parser, builder, () -> ParseFieldMatcher.STRICT); } else if (token == XContentParser.Token.VALUE_STRING) { builder.setCategory(parser.text()); } else { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java index 1d27f171594..dd625f252de 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java @@ -21,6 +21,8 @@ package org.elasticsearch.search.suggest.completion.context; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.xcontent.ObjectParser; @@ -111,7 +113,7 @@ public final class GeoQueryContext implements ToXContent { return new Builder(); } - private static ObjectParser GEO_CONTEXT_PARSER = new ObjectParser<>(NAME, null); + private static ObjectParser GEO_CONTEXT_PARSER = new ObjectParser<>(NAME, null); static { GEO_CONTEXT_PARSER.declareField((parser, geoQueryContext, geoContextMapping) -> geoQueryContext.setGeoPoint(GeoUtils.parseGeoPoint(parser)), new ParseField(CONTEXT_VALUE), ObjectParser.ValueType.OBJECT); GEO_CONTEXT_PARSER.declareInt(GeoQueryContext.Builder::setBoost, new ParseField(CONTEXT_BOOST)); @@ -127,7 +129,7 @@ public final class GeoQueryContext implements ToXContent { XContentParser.Token token = parser.currentToken(); GeoQueryContext.Builder builder = new Builder(); if (token == XContentParser.Token.START_OBJECT) { - GEO_CONTEXT_PARSER.parse(parser, builder); + GEO_CONTEXT_PARSER.parse(parser, builder, () -> ParseFieldMatcher.STRICT); } else if (token == XContentParser.Token.VALUE_STRING) { builder.setGeoPoint(GeoPoint.fromGeohash(parser.text())); } else { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java index d2fee7ccb30..0d4e269a5c4 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java @@ -375,13 +375,15 @@ public final class DirectCandidateGeneratorBuilder DirectCandidateGeneratorBuilder tempGenerator = new DirectCandidateGeneratorBuilder("_na_"); // bucket for the field name, needed as constructor arg later Set tmpFieldName = new HashSet<>(1); - PARSER.parse(parseContext.parser(), new Tuple, DirectCandidateGeneratorBuilder>(tmpFieldName, tempGenerator)); + PARSER.parse(parseContext.parser(), new Tuple, DirectCandidateGeneratorBuilder>(tmpFieldName, tempGenerator), + parseContext); if (tmpFieldName.size() != 1) { throw new IllegalArgumentException("[" + TYPE + "] expects exactly one field parameter, but found " + tmpFieldName); } return replaceField(tmpFieldName.iterator().next(), tempGenerator); } + @Override public PhraseSuggestionContext.DirectCandidateGenerator build(MapperService mapperService) throws IOException { PhraseSuggestionContext.DirectCandidateGenerator generator = new PhraseSuggestionContext.DirectCandidateGenerator(); generator.setField(this.field); diff --git a/core/src/test/java/org/elasticsearch/cluster/routing/allocation/AllocationCommandsTests.java b/core/src/test/java/org/elasticsearch/cluster/routing/allocation/AllocationCommandsTests.java index e1b55b735c0..2cd688a661c 100644 --- a/core/src/test/java/org/elasticsearch/cluster/routing/allocation/AllocationCommandsTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/routing/allocation/AllocationCommandsTests.java @@ -36,6 +36,7 @@ import org.elasticsearch.cluster.routing.allocation.command.AllocationCommands; import org.elasticsearch.cluster.routing.allocation.command.CancelAllocationCommand; import org.elasticsearch.cluster.routing.allocation.command.MoveAllocationCommand; import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider; +import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -452,7 +453,7 @@ public class AllocationCommandsTests extends ESAllocationTestCase { parser.nextToken(); AllocationCommandRegistry registry = new NetworkModule(null, Settings.EMPTY, true, new NamedWriteableRegistry()) .getAllocationCommandRegistry(); - AllocationCommands sCommands = AllocationCommands.fromXContent(parser, registry); + AllocationCommands sCommands = AllocationCommands.fromXContent(parser, ParseFieldMatcher.STRICT, registry); assertThat(sCommands.commands().size(), equalTo(5)); assertThat(((AllocateEmptyPrimaryAllocationCommand) (sCommands.commands().get(0))).shardId(), equalTo(1)); diff --git a/core/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java b/core/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java index ec4da62c2dd..abafd7e4cf3 100644 --- a/core/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java +++ b/core/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java @@ -18,22 +18,25 @@ */ package org.elasticsearch.common.xcontent; -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParseFieldMatcher; -import org.elasticsearch.common.ParsingException; -import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser; -import org.elasticsearch.common.xcontent.ObjectParser.ValueType; -import org.elasticsearch.test.ESTestCase; +import static org.hamcrest.Matchers.hasSize; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.hamcrest.Matchers.hasSize; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; +import org.elasticsearch.common.ParsingException; +import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser; +import org.elasticsearch.common.xcontent.ObjectParser.ValueType; +import org.elasticsearch.test.ESTestCase; public class ObjectParserTests extends ESTestCase { + private final static ParseFieldMatcherSupplier STRICT_PARSING = () -> ParseFieldMatcher.STRICT; + public void testBasics() throws IOException { XContentParser parser = XContentType.JSON.xContent().createParser( "{\n" @@ -53,14 +56,13 @@ public class ObjectParserTests extends ESTestCase { this.ints = ints; } } - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); TestStruct s = new TestStruct(); objectParser.declareField((i, c, x) -> c.test = i.text(), new ParseField("test"), ObjectParser.ValueType.STRING); objectParser.declareInt(TestStruct::setTestNumber, new ParseField("test_number")); objectParser.declareIntArray(TestStruct::setInts, new ParseField("test_array")); - parser.setParseFieldMatcher(ParseFieldMatcher.STRICT); - objectParser.parse(parser, s); + objectParser.parse(parser, s, STRICT_PARSING); assertEquals(s.test, "foo"); assertEquals(s.testNumber, 2); assertEquals(s.ints, Arrays.asList(1, 2, 3, 4)); @@ -74,17 +76,17 @@ public class ObjectParserTests extends ESTestCase { public void testObjectOrDefault() throws IOException { XContentParser parser = XContentType.JSON.xContent().createParser("{\"object\" : { \"test\": 2}}"); - ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); + ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); objectParser.declareInt(StaticTestStruct::setTest, new ParseField("test")); objectParser.declareObjectOrDefault(StaticTestStruct::setObject, objectParser, StaticTestStruct::new, new ParseField("object")); - StaticTestStruct s = objectParser.parse(parser); + StaticTestStruct s = objectParser.parse(parser, STRICT_PARSING); assertEquals(s.object.test, 2); parser = XContentType.JSON.xContent().createParser("{\"object\" : false }"); - s = objectParser.parse(parser); + s = objectParser.parse(parser, STRICT_PARSING); assertNull(s.object); parser = XContentType.JSON.xContent().createParser("{\"object\" : true }"); - s = objectParser.parse(parser); + s = objectParser.parse(parser, STRICT_PARSING); assertNotNull(s.object); assertEquals(s.object.test, 0); @@ -96,12 +98,12 @@ public class ObjectParserTests extends ESTestCase { public void setTest(int test) { } } - ObjectParser objectParser = new ObjectParser<>("the_parser"); + ObjectParser objectParser = new ObjectParser<>("the_parser"); TestStruct s = new TestStruct(); objectParser.declareInt(TestStruct::setTest, new ParseField("test")); try { - objectParser.parse(parser, s); + objectParser.parse(parser, s, STRICT_PARSING); fail("numeric value expected"); } catch (ParsingException ex) { assertEquals(ex.getMessage(), "[the_parser] failed to parse field [test]"); @@ -110,7 +112,7 @@ public class ObjectParserTests extends ESTestCase { parser = XContentType.JSON.xContent().createParser("{\"not_supported_field\" : \"foo\"}"); try { - objectParser.parse(parser, s); + objectParser.parse(parser, s, STRICT_PARSING); fail("field not supported"); } catch (IllegalArgumentException ex) { assertEquals(ex.getMessage(), "[the_parser] unknown field [not_supported_field], parser not found"); @@ -122,14 +124,13 @@ public class ObjectParserTests extends ESTestCase { class TestStruct { public String test; } - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); TestStruct s = new TestStruct(); objectParser.declareField((i, v, c) -> v.test = i.text(), new ParseField("test", "old_test"), ObjectParser.ValueType.STRING); - parser.setParseFieldMatcher(ParseFieldMatcher.STRICT); try { - objectParser.parse(parser, s); + objectParser.parse(parser, s, STRICT_PARSING); fail("deprecated value"); } catch (IllegalArgumentException ex) { assertEquals(ex.getMessage(), "Deprecated field [old_test] used, expected [test] instead"); @@ -137,8 +138,7 @@ public class ObjectParserTests extends ESTestCase { } assertNull(s.test); parser = XContentType.JSON.xContent().createParser("{\"old_test\" : \"foo\"}"); - parser.setParseFieldMatcher(ParseFieldMatcher.EMPTY); - objectParser.parse(parser, s); + objectParser.parse(parser, s, () -> ParseFieldMatcher.EMPTY); assertEquals("foo", s.test); } @@ -147,13 +147,12 @@ public class ObjectParserTests extends ESTestCase { class TestStruct { public String test; } - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); TestStruct s = new TestStruct(); objectParser.declareField((i, c, x) -> c.test = i.text(), new ParseField("numeric_value"), ObjectParser.ValueType.FLOAT); - parser.setParseFieldMatcher(ParseFieldMatcher.STRICT); try { - objectParser.parse(parser, s); + objectParser.parse(parser, s, STRICT_PARSING); fail("wrong type - must be number"); } catch (IllegalArgumentException ex) { assertEquals(ex.getMessage(), "[foo] numeric_value doesn't support values of type: VALUE_BOOLEAN"); @@ -166,39 +165,40 @@ public class ObjectParserTests extends ESTestCase { public int test; TestStruct object; } - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); TestStruct s = new TestStruct(); s.object = new TestStruct(); objectParser.declareField((i, c, x) -> c.test = i.intValue(), new ParseField("test"), ValueType.INT); - objectParser.declareField((i, c, x) -> objectParser.parse(parser, c.object), new ParseField("object"), ValueType.OBJECT); - objectParser.parse(parser, s); + objectParser.declareField((i, c, x) -> objectParser.parse(parser, c.object, STRICT_PARSING), new ParseField("object"), + ValueType.OBJECT); + objectParser.parse(parser, s, STRICT_PARSING); assertEquals(s.test, 1); assertEquals(s.object.test, 2); } public void testParseNestedShortcut() throws IOException { XContentParser parser = XContentType.JSON.xContent().createParser("{ \"test\" : 1, \"object\" : { \"test\": 2}}"); - ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); + ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); objectParser.declareInt(StaticTestStruct::setTest, new ParseField("test")); objectParser.declareObject(StaticTestStruct::setObject, objectParser, new ParseField("object")); - StaticTestStruct s = objectParser.parse(parser); + StaticTestStruct s = objectParser.parse(parser, STRICT_PARSING); assertEquals(s.test, 1); assertEquals(s.object.test, 2); } public void testEmptyObject() throws IOException { XContentParser parser = XContentType.JSON.xContent().createParser("{\"object\" : {}}"); - ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); + ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); objectParser.declareObject(StaticTestStruct::setObject, objectParser, new ParseField("object")); - StaticTestStruct s = objectParser.parse(parser); + StaticTestStruct s = objectParser.parse(parser, STRICT_PARSING); assertNotNull(s.object); } public void testEmptyObjectInArray() throws IOException { XContentParser parser = XContentType.JSON.xContent().createParser("{\"object_array\" : [{}]}"); - ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); + ObjectParser objectParser = new ObjectParser<>("foo", StaticTestStruct::new); objectParser.declareObjectArray(StaticTestStruct::setObjectArray, objectParser, new ParseField("object_array")); - StaticTestStruct s = objectParser.parse(parser); + StaticTestStruct s = objectParser.parse(parser, STRICT_PARSING); assertNotNull(s.objectArray); } @@ -233,9 +233,9 @@ public class ObjectParserTests extends ESTestCase { } } XContentParser parser = XContentType.JSON.xContent().createParser("{ \"test\" : \"FOO\" }"); - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); objectParser.declareString((struct, value) -> struct.set(TestEnum.valueOf(value)), new ParseField("test")); - TestStruct s = objectParser.parse(parser, new TestStruct()); + TestStruct s = objectParser.parse(parser, new TestStruct(), STRICT_PARSING); assertEquals(s.test, TestEnum.FOO); } @@ -329,7 +329,7 @@ public class ObjectParserTests extends ESTestCase { this.string_or_null = string_or_null; } } - ObjectParser objectParser = new ObjectParser<>("foo"); + ObjectParser objectParser = new ObjectParser<>("foo"); objectParser.declareInt(TestStruct::setInt_field, new ParseField("int_field")); objectParser.declareIntArray(TestStruct::setInt_array_field, new ParseField("int_array_field")); objectParser.declareLong(TestStruct::setLong_field, new ParseField("long_field")); @@ -343,7 +343,7 @@ public class ObjectParserTests extends ESTestCase { objectParser.declareStringOrNull(TestStruct::setString_or_null, new ParseField("string_or_null")); objectParser.declareBoolean(TestStruct::setNull_value, new ParseField("boolean_field")); - TestStruct parse = objectParser.parse(parser, new TestStruct()); + TestStruct parse = objectParser.parse(parser, new TestStruct(), STRICT_PARSING); assertArrayEquals(parse.double_array_field.toArray(), Arrays.asList(2.1d).toArray()); assertEquals(parse.double_field, 2.1d, 0.0d); @@ -372,7 +372,7 @@ public class ObjectParserTests extends ESTestCase { "{\"named\": {\n" + " \"a\": {}" + "}}"); - NamedObjectHolder h = NamedObjectHolder.PARSER.apply(parser, null); + NamedObjectHolder h = NamedObjectHolder.PARSER.apply(parser, STRICT_PARSING); assertThat(h.named, hasSize(1)); assertEquals("a", h.named.get(0).name); assertFalse(h.namedSuppliedInOrder); @@ -383,7 +383,7 @@ public class ObjectParserTests extends ESTestCase { "{\"named\": [\n" + " {\"a\": {}}" + "]}"); - NamedObjectHolder h = NamedObjectHolder.PARSER.apply(parser, null); + NamedObjectHolder h = NamedObjectHolder.PARSER.apply(parser, STRICT_PARSING); assertThat(h.named, hasSize(1)); assertEquals("a", h.named.get(0).name); assertTrue(h.namedSuppliedInOrder); @@ -394,7 +394,7 @@ public class ObjectParserTests extends ESTestCase { "{\"named\": [\n" + " {\"a\": {}, \"b\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, STRICT_PARSING)); assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); assertEquals( "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", @@ -406,7 +406,7 @@ public class ObjectParserTests extends ESTestCase { "{\"named\": [\n" + " {}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, STRICT_PARSING)); assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); assertEquals( "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", @@ -418,7 +418,7 @@ public class ObjectParserTests extends ESTestCase { "{\"named\": [\n" + " \"junk\"" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, STRICT_PARSING)); assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); assertEquals( "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", @@ -432,17 +432,18 @@ public class ObjectParserTests extends ESTestCase { + "]}"); // Create our own parser for this test so we can disable support for the "ordered" mode specified by the array above - ObjectParser objectParser = new ObjectParser<>("named_object_holder", NamedObjectHolder::new); + ObjectParser objectParser = new ObjectParser<>("named_object_holder", + NamedObjectHolder::new); objectParser.declareNamedObjects(NamedObjectHolder::setNamed, NamedObject.PARSER, new ParseField("named")); // Now firing the xml through it fails - ParsingException e = expectThrows(ParsingException.class, () -> objectParser.apply(parser, null)); + ParsingException e = expectThrows(ParsingException.class, () -> objectParser.apply(parser, STRICT_PARSING)); assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); assertEquals("[named] doesn't support arrays. Use a single object with multiple fields.", e.getCause().getMessage()); } static class NamedObjectHolder { - public static final ObjectParser PARSER = new ObjectParser<>("named_object_holder", + public static final ObjectParser PARSER = new ObjectParser<>("named_object_holder", NamedObjectHolder::new); static { PARSER.declareNamedObjects(NamedObjectHolder::setNamed, NamedObject.PARSER, NamedObjectHolder::keepNamedInOrder, @@ -462,11 +463,11 @@ public class ObjectParserTests extends ESTestCase { } public static class NamedObject { - public static final NamedObjectParser PARSER; + public static final NamedObjectParser PARSER; static { - ObjectParser parser = new ObjectParser<>("named"); + ObjectParser parser = new ObjectParser<>("named"); parser.declareInt(NamedObject::setFoo, new ParseField("foo")); - PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new NamedObject(name)); + PARSER = (XContentParser p, ParseFieldMatcherSupplier v, String name) -> parser.parse(p, new NamedObject(name), STRICT_PARSING); } final String name; diff --git a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java index 31d9722eced..393321e8e06 100644 --- a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java +++ b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java @@ -98,19 +98,17 @@ public class SearchModuleTests extends ModuleTestCase { IndicesQueriesRegistry indicesQueriesRegistry = module.getQueryParserRegistry(); XContentParser dummyParser = XContentHelper.createParser(new BytesArray("{}")); - dummyParser.setParseFieldMatcher(ParseFieldMatcher.EMPTY); for (String queryName : supportedQueries) { - indicesQueriesRegistry.lookup(queryName, dummyParser); + indicesQueriesRegistry.lookup(queryName, dummyParser, ParseFieldMatcher.EMPTY); } - dummyParser.setParseFieldMatcher(ParseFieldMatcher.STRICT); for (String queryName : NON_DEPRECATED_QUERIES) { - QueryParser queryParser = indicesQueriesRegistry.lookup(queryName, dummyParser); + QueryParser queryParser = indicesQueriesRegistry.lookup(queryName, dummyParser, ParseFieldMatcher.STRICT); assertThat(queryParser, notNullValue()); } for (String queryName : DEPRECATED_QUERIES) { try { - indicesQueriesRegistry.lookup(queryName, dummyParser); + indicesQueriesRegistry.lookup(queryName, dummyParser, ParseFieldMatcher.STRICT); fail("query is deprecated, getQueryParser should have failed in strict mode"); } catch(IllegalArgumentException e) { assertThat(e.getMessage(), containsString("Deprecated field [" + queryName + "] used")); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java index 4603326e3a8..3833d59ef34 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java @@ -235,7 +235,7 @@ public abstract class BaseAggregationTestCase> assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken()); assertEquals(testAgg.type.name(), parser.currentName()); assertSame(XContentParser.Token.START_OBJECT, parser.nextToken()); - AggregatorBuilder newAgg = aggParsers.parser(testAgg.getType(), parser).parse(testAgg.name, parseContext); + AggregatorBuilder newAgg = aggParsers.parser(testAgg.getType(), ParseFieldMatcher.STRICT).parse(testAgg.name, parseContext); assertSame(XContentParser.Token.END_OBJECT, parser.currentToken()); assertSame(XContentParser.Token.END_OBJECT, parser.nextToken()); assertSame(XContentParser.Token.END_OBJECT, parser.nextToken()); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java index a3d4ff46e42..4c9311bb110 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java @@ -237,7 +237,7 @@ public abstract class BasePipelineAggregationTestCase newAgg = aggParsers.pipelineParser(testAgg.getWriteableName(), parser) + PipelineAggregatorBuilder newAgg = aggParsers.pipelineParser(testAgg.getWriteableName(), ParseFieldMatcher.STRICT) .parse(testAgg.name(), parseContext); assertSame(XContentParser.Token.END_OBJECT, parser.currentToken()); assertSame(XContentParser.Token.END_OBJECT, parser.nextToken()); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java index 04499e2fcde..e4d134b8e38 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.aggregations.pipeline.moving.avg; +import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryParseContext; @@ -116,8 +117,8 @@ public class MovAvgTests extends BasePipelineAggregationTestCase newAgg = aggParsers.pipelineParser(expected.getWriteableName(), parser).parse(expected.name(), - parseContext); + PipelineAggregatorBuilder newAgg = aggParsers.pipelineParser(expected.getWriteableName(), ParseFieldMatcher.STRICT) + .parse(expected.name(), parseContext); assertSame(XContentParser.Token.END_OBJECT, parser.currentToken()); assertSame(XContentParser.Token.END_OBJECT, parser.nextToken()); assertSame(XContentParser.Token.END_OBJECT, parser.nextToken()); diff --git a/core/src/test/java/org/elasticsearch/search/sort/SortParserTests.java b/core/src/test/java/org/elasticsearch/search/sort/SortParserTests.java index c3dc8eab745..a5ef892bf17 100644 --- a/core/src/test/java/org/elasticsearch/search/sort/SortParserTests.java +++ b/core/src/test/java/org/elasticsearch/search/sort/SortParserTests.java @@ -47,7 +47,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -58,7 +58,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -69,7 +69,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -80,7 +80,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -91,7 +91,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -100,7 +100,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.field("location", new GeoPoint(1, 2)); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -109,7 +109,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.field("location", "1,2"); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -118,7 +118,7 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.field("location", "s3y0zh7w1z0g"); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); @@ -129,16 +129,36 @@ public class SortParserTests extends ESSingleNodeTestCase { sortBuilder.endArray(); sortBuilder.field("order", "desc"); sortBuilder.field("unit", "km"); - sortBuilder.field("sort_mode", "max"); + sortBuilder.field("mode", "max"); sortBuilder.endObject(); parse(context, sortBuilder); } + public void testGeoDistanceSortDeprecatedSortModeException() throws Exception { + XContentBuilder mapping = jsonBuilder(); + mapping.startObject().startObject("type").startObject("properties").startObject("location").field("type", "geo_point").endObject().endObject().endObject().endObject(); + IndexService indexService = createIndex("testidx", Settings.builder().build(), "type", mapping); + TestSearchContext context = (TestSearchContext) createSearchContext(indexService); + context.getQueryShardContext().setTypes("type"); + + XContentBuilder sortBuilder = jsonBuilder(); + sortBuilder.startObject(); + sortBuilder.startArray("location"); + sortBuilder.startArray().value(1.2).value(3).endArray().startArray().value(5).value(6).endArray(); + sortBuilder.endArray(); + sortBuilder.field("order", "desc"); + sortBuilder.field("unit", "km"); + sortBuilder.field("sort_mode", "max"); + sortBuilder.endObject(); + IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> parse(context, sortBuilder)); + assertEquals("Deprecated field [sort_mode] used, expected [mode] instead", ex.getMessage()); + } + protected void parse(TestSearchContext context, XContentBuilder sortBuilder) throws Exception { QueryParseContext parseContext = context.getQueryShardContext().parseContext(); XContentParser parser = XContentHelper.createParser(sortBuilder.bytes()); - parser.setParseFieldMatcher(ParseFieldMatcher.STRICT); parseContext.reset(parser); + parseContext.parseFieldMatcher(ParseFieldMatcher.STRICT); parser.nextToken(); GeoDistanceSortBuilder.fromXContent(parseContext, null); } diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java index 8f6fe71d46e..fc5f1c69ecd 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java @@ -33,6 +33,8 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; @@ -80,7 +82,7 @@ public class RestReindexAction extends AbstractBaseReindexRestHandler destParser = new ObjectParser<>("dest"); + ObjectParser destParser = new ObjectParser<>("dest"); destParser.declareString(IndexRequest::index, new ParseField("index")); destParser.declareString(IndexRequest::type, new ParseField("type")); destParser.declareString(IndexRequest::routing, new ParseField("routing")); @@ -94,7 +96,7 @@ public class RestReindexAction extends AbstractBaseReindexRestHandler sourceParser.parse(p, v.getSearchRequest(), c), new ParseField("source"), ValueType.OBJECT); - PARSER.declareField((p, v, c) -> destParser.parse(p, v.getDestination(), null), new ParseField("dest"), ValueType.OBJECT); + PARSER.declareField((p, v, c) -> destParser.parse(p, v.getDestination(), c), new ParseField("dest"), ValueType.OBJECT); PARSER.declareInt(ReindexRequest::setSize, new ParseField("size")); PARSER.declareField((p, v, c) -> v.setScript(Script.parse(p, c.queryParseContext.parseFieldMatcher())), new ParseField("script"), ValueType.OBJECT); @@ -169,7 +171,7 @@ public class RestReindexAction extends AbstractBaseReindexRestHandler