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