From dde2a09ba5a20d493533d4b96d55418119e470b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Fri, 3 Feb 2017 20:53:30 +0100 Subject: [PATCH] Updating rank-eval module after major changes on master --- .../rankeval/DiscountedCumulativeGain.java | 7 +- .../index/rankeval/Precision.java | 7 +- .../index/rankeval/RankEvalContext.java | 80 ----------- .../index/rankeval/RankEvalPlugin.java | 15 +- .../index/rankeval/RankEvalResponse.java | 8 +- .../index/rankeval/RankEvalSpec.java | 34 ++--- .../rankeval/RankedListQualityMetric.java | 9 +- .../index/rankeval/RatedDocument.java | 7 +- .../index/rankeval/RatedRequest.java | 21 ++- .../index/rankeval/ReciprocalRank.java | 7 +- .../index/rankeval/RestRankEvalAction.java | 26 +--- .../rankeval/TransportRankEvalAction.java | 35 ++--- .../DiscountedCumulativeGainTests.java | 33 +++-- .../index/rankeval/PrecisionTests.java | 31 +++-- .../index/rankeval/RankEvalResponseTests.java | 2 - .../index/rankeval/RankEvalSpecTests.java | 86 ++++-------- .../index/rankeval/RankEvalTestHelper.java | 18 --- .../index/rankeval/RankEvalYamlIT.java | 3 +- .../index/rankeval/RatedDocumentTests.java | 20 ++- .../index/rankeval/RatedRequestsTests.java | 130 +++++++++--------- .../index/rankeval/ReciprocalRankTests.java | 24 ++-- .../build.gradle | 1 + ...stRankEvalWithMustacheYAMLTestSuiteIT.java | 3 +- 23 files changed, 236 insertions(+), 371 deletions(-) delete mode 100644 modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalContext.java diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGain.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGain.java index 65af4ec193a..27b4fc5fda1 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGain.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGain.java @@ -20,7 +20,6 @@ package org.elasticsearch.index.rankeval; 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; @@ -141,7 +140,7 @@ public class DiscountedCumulativeGain implements RankedListQualityMetric { private static final ParseField NORMALIZE_FIELD = new ParseField("normalize"); private static final ParseField UNKNOWN_DOC_RATING_FIELD = new ParseField("unknown_doc_rating"); - private static final ObjectParser PARSER = + private static final ObjectParser PARSER = new ObjectParser<>("dcg_at", () -> new DiscountedCumulativeGain()); static { @@ -149,8 +148,8 @@ public class DiscountedCumulativeGain implements RankedListQualityMetric { PARSER.declareInt(DiscountedCumulativeGain::setUnknownDocRating, UNKNOWN_DOC_RATING_FIELD); } - public static DiscountedCumulativeGain fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) { - return PARSER.apply(parser, matcher); + public static DiscountedCumulativeGain fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } @Override diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/Precision.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/Precision.java index 1536388391b..40923fe1a0a 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/Precision.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/Precision.java @@ -20,7 +20,6 @@ package org.elasticsearch.index.rankeval; 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; @@ -49,7 +48,7 @@ public class Precision implements RankedListQualityMetric { private static final ParseField RELEVANT_RATING_FIELD = new ParseField("relevant_rating_threshold"); private static final ParseField IGNORE_UNLABELED_FIELD = new ParseField("ignore_unlabeled"); - private static final ObjectParser PARSER = new ObjectParser<>(NAME, Precision::new); + private static final ObjectParser PARSER = new ObjectParser<>(NAME, Precision::new); /** * This setting controls how unlabeled documents in the search hits are @@ -118,8 +117,8 @@ public class Precision implements RankedListQualityMetric { return ignoreUnlabeled; } - public static Precision fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) { - return PARSER.apply(parser, matcher); + public static Precision fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } /** Compute precisionAtN based on provided relevant document IDs. diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalContext.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalContext.java deleted file mode 100644 index 0e9a617bb59..00000000000 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalContext.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.index.rankeval; - -import org.elasticsearch.common.ParseFieldMatcher; -import org.elasticsearch.common.ParseFieldMatcherSupplier; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.search.SearchExtRegistry; -import org.elasticsearch.search.SearchRequestParsers; -import org.elasticsearch.search.aggregations.AggregatorParsers; -import org.elasticsearch.search.suggest.Suggesters; - -public class RankEvalContext implements ParseFieldMatcherSupplier { - - private final SearchRequestParsers searchRequestParsers; - private final ParseFieldMatcher parseFieldMatcher; - private final QueryParseContext parseContext; - private final ScriptService scriptService; - - public RankEvalContext(ParseFieldMatcher parseFieldMatcher, QueryParseContext parseContext, SearchRequestParsers searchRequestParsers, - ScriptService scriptService) { - this.parseFieldMatcher = parseFieldMatcher; - this.searchRequestParsers = searchRequestParsers; - this.parseContext = parseContext; - this.scriptService = scriptService; - } - - public Suggesters getSuggesters() { - return searchRequestParsers.suggesters; - } - - public AggregatorParsers getAggs() { - return searchRequestParsers.aggParsers; - } - - public SearchRequestParsers getSearchRequestParsers() { - return searchRequestParsers; - } - - public ScriptService getScriptService() { - return scriptService; - } - - public SearchExtRegistry getSearchExtParsers() { - return searchRequestParsers.searchExtParsers; - } - - @Override - public ParseFieldMatcher getParseFieldMatcher() { - return this.parseFieldMatcher; - } - - public XContentParser parser() { - return this.parseContext.parser(); - } - - public QueryParseContext getParseContext() { - return this.parseContext; - } - -} diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java index 32e1dbb8486..ca2654fb943 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalPlugin.java @@ -21,15 +21,23 @@ package org.elasticsearch.index.rankeval; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.IndexScopedSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestHandler; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Supplier; public class RankEvalPlugin extends Plugin implements ActionPlugin { @@ -38,9 +46,12 @@ public class RankEvalPlugin extends Plugin implements ActionPlugin { return Arrays.asList(new ActionHandler<>(RankEvalAction.INSTANCE, TransportRankEvalAction.class)); } + @Override - public List> getRestHandlers() { - return Arrays.asList(RestRankEvalAction.class); + public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster) { + return Arrays.asList(new RestRankEvalAction(settings, restController)); } /** diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalResponse.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalResponse.java index 23c4e27fb8c..5364fb87cdc 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalResponse.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalResponse.java @@ -23,7 +23,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; @@ -42,7 +42,7 @@ import java.util.Map; * **/ //TODO instead of just returning averages over complete results, think of other statistics, micro avg, macro avg, partial results -public class RankEvalResponse extends ActionResponse implements ToXContent { +public class RankEvalResponse extends ActionResponse implements ToXContentObject { /**Average precision observed when issuing query intents with this specification.*/ private double qualityLevel; /**Mapping from intent id to all documents seen for this intent that were not annotated.*/ @@ -113,6 +113,7 @@ public class RankEvalResponse extends ActionResponse implements ToXContent { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); builder.startObject("rank_eval"); builder.field("quality_level", qualityLevel); builder.startObject("details"); @@ -123,11 +124,12 @@ public class RankEvalResponse extends ActionResponse implements ToXContent { builder.startObject("failures"); for (String key : failures.keySet()) { builder.startObject(key); - ElasticsearchException.renderException(builder, params, failures.get(key)); + ElasticsearchException.generateFailureXContent(builder, params, failures.get(key), true); builder.endObject(); } builder.endObject(); builder.endObject(); + builder.endObject(); return builder; } } diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalSpec.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalSpec.java index 81919c87a01..e45ba14eda6 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalSpec.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalSpec.java @@ -133,7 +133,7 @@ public class RankEvalSpec extends ToXContentToBytes implements Writeable { public Map getTemplates() { return this.templates; } - + /** Returns the max concurrent searches allowed. */ public int getMaxConcurrentSearches() { return this.maxConcurrentSearches; @@ -149,43 +149,35 @@ public class RankEvalSpec extends ToXContentToBytes implements Writeable { private static final ParseField REQUESTS_FIELD = new ParseField("requests"); private static final ParseField MAX_CONCURRENT_SEARCHES_FIELD = new ParseField("max_concurrent_searches"); @SuppressWarnings("unchecked") - private static final ConstructingObjectParser PARSER = + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("rank_eval", a -> new RankEvalSpec((Collection) a[0], (RankedListQualityMetric) a[1], (Collection) a[2])); static { PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> { - try { - return RatedRequest.fromXContent(p, c); - } catch (IOException ex) { - throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex); - } + return RatedRequest.fromXContent(p); } , REQUESTS_FIELD); PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> { try { - return RankedListQualityMetric.fromXContent(p, c); + return RankedListQualityMetric.fromXContent(p); } catch (IOException ex) { throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex); } } , METRIC_FIELD); PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> { - try { - return ScriptWithId.fromXContent(p, c); - } catch (IOException ex) { - throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex); - } + return ScriptWithId.fromXContent(p); }, TEMPLATES_FIELD); PARSER.declareInt(RankEvalSpec::setMaxConcurrentSearches, MAX_CONCURRENT_SEARCHES_FIELD); } - public static RankEvalSpec parse(XContentParser parser, RankEvalContext context) throws IOException { - return PARSER.apply(parser, context); + public static RankEvalSpec parse(XContentParser parser) { + return PARSER.apply(parser, null); } - + public static class ScriptWithId { private Script script; private String id; - + private static final ParseField TEMPLATE_FIELD = new ParseField("template"); private static final ParseField TEMPLATE_ID_FIELD = new ParseField("id"); @@ -194,18 +186,18 @@ public class RankEvalSpec extends ToXContentToBytes implements Writeable { this.script = script; } - private static final ConstructingObjectParser PARSER = + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("script_with_id", a -> new ScriptWithId((String) a[0], (Script) a[1])); - public static ScriptWithId fromXContent(XContentParser parser, RankEvalContext context) throws IOException { - return PARSER.apply(parser, context); + public static ScriptWithId fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } static { PARSER.declareString(ConstructingObjectParser.constructorArg(), TEMPLATE_ID_FIELD); PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> { try { - return Script.parse(p, c.getParseFieldMatcher(), "mustache"); + return Script.parse(p, "mustache"); } catch (IOException ex) { throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex); } diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankedListQualityMetric.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankedListQualityMetric.java index cd1f6cb0e85..ea42f32ff07 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankedListQualityMetric.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankedListQualityMetric.java @@ -19,7 +19,6 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.xcontent.ToXContent; @@ -54,7 +53,7 @@ public interface RankedListQualityMetric extends ToXContent, NamedWriteable { * */ EvalQueryQuality evaluate(String taskId, SearchHit[] hits, List ratedDocs); - static RankedListQualityMetric fromXContent(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException { + static RankedListQualityMetric fromXContent(XContentParser parser) throws IOException { RankedListQualityMetric rc; Token token = parser.nextToken(); if (token != XContentParser.Token.FIELD_NAME) { @@ -65,13 +64,13 @@ public interface RankedListQualityMetric extends ToXContent, NamedWriteable { // TODO maybe switch to using a plugable registry later? switch (metricName) { case Precision.NAME: - rc = Precision.fromXContent(parser, context); + rc = Precision.fromXContent(parser); break; case ReciprocalRank.NAME: - rc = ReciprocalRank.fromXContent(parser, context); + rc = ReciprocalRank.fromXContent(parser); break; case DiscountedCumulativeGain.NAME: - rc = DiscountedCumulativeGain.fromXContent(parser, context); + rc = DiscountedCumulativeGain.fromXContent(parser); break; default: throw new ParsingException(parser.getTokenLocation(), "[_na] unknown query metric name [{}]", metricName); diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedDocument.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedDocument.java index c6639619cac..0102de14436 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedDocument.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedDocument.java @@ -21,7 +21,6 @@ package org.elasticsearch.index.rankeval; import org.elasticsearch.action.support.ToXContentToBytes; 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; @@ -42,7 +41,7 @@ public class RatedDocument extends ToXContentToBytes implements Writeable { public static final ParseField TYPE_FIELD = new ParseField("_type"); public static final ParseField INDEX_FIELD = new ParseField("_index"); - private static final ConstructingObjectParser PARSER = + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("rated_document", a -> new RatedDocument((String) a[0], (String) a[1], (String) a[2], (Integer) a[3])); @@ -96,8 +95,8 @@ public class RatedDocument extends ToXContentToBytes implements Writeable { out.writeVInt(rating); } - public static RatedDocument fromXContent(XContentParser parser, ParseFieldMatcherSupplier supplier) throws IOException { - return PARSER.apply(parser, supplier); + public static RatedDocument fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } @Override diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedRequest.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedRequest.java index acc963ebe23..395b77ef801 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedRequest.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RatedRequest.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; @@ -99,7 +100,7 @@ public class RatedRequest extends ToXContentToBytes implements Writeable { } this.templateId = templateId; } - + public RatedRequest(String id, List ratedDocs, Map params, String templateId) { this(id, ratedDocs, null, params, templateId); } @@ -203,7 +204,7 @@ public class RatedRequest extends ToXContentToBytes implements Writeable { public List getSummaryFields() { return summaryFields; } - + public void setSummaryFields(List summaryFields) { if (summaryFields == null) { throw new IllegalArgumentException("Setting summaryFields to null not allowed."); @@ -218,22 +219,18 @@ public class RatedRequest extends ToXContentToBytes implements Writeable { private static final ParseField FIELDS_FIELD = new ParseField("summary_fields"); private static final ParseField TEMPLATE_ID_FIELD = new ParseField("template_id"); - private static final ConstructingObjectParser PARSER = + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("requests", a -> new RatedRequest( (String) a[0], (List) a[1], (SearchSourceBuilder) a[2], (Map) a[3], (String) a[4])); static { PARSER.declareString(ConstructingObjectParser.constructorArg(), ID_FIELD); PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> { - try { - return RatedDocument.fromXContent(p, c); - } catch (IOException ex) { - throw new ParsingException(p.getTokenLocation(), "error parsing ratings", ex); - } + return RatedDocument.fromXContent(p); }, RATINGS_FIELD); PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> { try { - return SearchSourceBuilder.fromXContent(c.getParseContext(), c.getAggs(), c.getSuggesters(), c.getSearchExtParsers()); + return SearchSourceBuilder.fromXContent(c); } catch (IOException ex) { throw new ParsingException(p.getTokenLocation(), "error parsing request", ex); } @@ -270,8 +267,8 @@ public class RatedRequest extends ToXContentToBytes implements Writeable { * "ratings": [{ "1": 1 }, { "2": 0 }, { "3": 1 } ] * } */ - public static RatedRequest fromXContent(XContentParser parser, RankEvalContext context) throws IOException { - return PARSER.apply(parser, context); + public static RatedRequest fromXContent(XContentParser parser) { + return PARSER.apply(parser, new QueryParseContext(parser)); } @Override @@ -315,7 +312,7 @@ public class RatedRequest extends ToXContentToBytes implements Writeable { } RatedRequest other = (RatedRequest) obj; - + return Objects.equals(id, other.id) && Objects.equals(testRequest, other.testRequest) && Objects.equals(indices, other.indices) && diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/ReciprocalRank.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/ReciprocalRank.java index a0238717169..2c4021ce2fc 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/ReciprocalRank.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/ReciprocalRank.java @@ -20,7 +20,6 @@ package org.elasticsearch.index.rankeval; 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; @@ -117,15 +116,15 @@ public class ReciprocalRank implements RankedListQualityMetric { } private static final ParseField RELEVANT_RATING_FIELD = new ParseField("relevant_rating_threshold"); - private static final ObjectParser PARSER = new ObjectParser<>( + private static final ObjectParser PARSER = new ObjectParser<>( "reciprocal_rank", () -> new ReciprocalRank()); static { PARSER.declareInt(ReciprocalRank::setRelevantRatingThreshhold, RELEVANT_RATING_FIELD); } - public static ReciprocalRank fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) { - return PARSER.apply(parser, matcher); + public static ReciprocalRank fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } @Override diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RestRankEvalAction.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RestRankEvalAction.java index 275e15b1dda..3acba41e54f 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RestRankEvalAction.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RestRankEvalAction.java @@ -21,16 +21,12 @@ package org.elasticsearch.index.rankeval; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.RestToXContentListener; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.search.SearchRequestParsers; import java.io.IOException; import java.util.Arrays; @@ -154,18 +150,10 @@ import static org.elasticsearch.rest.RestRequest.Method.POST; * */ public class RestRankEvalAction extends BaseRestHandler { - private SearchRequestParsers searchRequestParsers; - private ScriptService scriptService; + //private ScriptService scriptService; - @Inject - public RestRankEvalAction( - Settings settings, - RestController controller, - SearchRequestParsers searchRequestParsers, - ScriptService scriptService) { + public RestRankEvalAction(Settings settings, RestController controller) { super(settings); - this.searchRequestParsers = searchRequestParsers; - this.scriptService = scriptService; controller.registerHandler(GET, "/_rank_eval", this); controller.registerHandler(POST, "/_rank_eval", this); controller.registerHandler(GET, "/{index}/_rank_eval", this); @@ -178,21 +166,17 @@ public class RestRankEvalAction extends BaseRestHandler { protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { RankEvalRequest rankEvalRequest = new RankEvalRequest(); try (XContentParser parser = request.contentOrSourceParamParser()) { - QueryParseContext parseContext = new QueryParseContext(searchRequestParsers.queryParsers, parser, parseFieldMatcher); - // TODO can we get rid of aggregators parsers and suggesters? - parseRankEvalRequest(rankEvalRequest, request, - new RankEvalContext(parseFieldMatcher, parseContext, searchRequestParsers, scriptService)); + parseRankEvalRequest(rankEvalRequest, request, parser); } return channel -> client.executeLocally(RankEvalAction.INSTANCE, rankEvalRequest, new RestToXContentListener(channel)); } - public static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, RankEvalContext context) - throws IOException { + private static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, XContentParser parser) { List indices = Arrays.asList(Strings.splitStringByCommaToArray(request.param("index"))); List types = Arrays.asList(Strings.splitStringByCommaToArray(request.param("type"))); RankEvalSpec spec = null; - spec = RankEvalSpec.parse(context.parser(), context); + spec = RankEvalSpec.parse(parser); for (RatedRequest specification : spec.getRatedRequests()) { specification.setIndices(indices); specification.setTypes(types); diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/TransportRankEvalAction.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/TransportRankEvalAction.java index 10e84e68d58..fafda7bb704 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/TransportRankEvalAction.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/TransportRankEvalAction.java @@ -29,15 +29,15 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.script.CompiledScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptService; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.SearchRequestParsers; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; @@ -47,12 +47,14 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.Map.Entry; +import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; +import static org.elasticsearch.common.xcontent.XContentHelper.createParser; + /** * Instances of this class execute a collection of search intents (read: user supplied query parameters) against a set of * possible search requests (read: search specifications, expressed as query/search request templates) and compares the result @@ -66,17 +68,17 @@ import java.util.concurrent.atomic.AtomicInteger; public class TransportRankEvalAction extends HandledTransportAction { private Client client; private ScriptService scriptService; - private SearchRequestParsers searchRequestParsers; Queue taskQueue = new ConcurrentLinkedQueue<>(); - + private NamedXContentRegistry namedXContentRegistry; + @Inject public TransportRankEvalAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, Client client, TransportService transportService, - SearchRequestParsers searchRequestParsers, ScriptService scriptService) { + ScriptService scriptService, NamedXContentRegistry namedXContentRegistry) { super(settings, RankEvalAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, RankEvalRequest::new); - this.searchRequestParsers = searchRequestParsers; this.scriptService = scriptService; + this.namedXContentRegistry = namedXContentRegistry; this.client = client; } @@ -92,8 +94,8 @@ public class TransportRankEvalAction extends HandledTransportAction scriptsWithoutParams = new HashMap<>(); for (Entry entry : qualityTask.getTemplates().entrySet()) { scriptsWithoutParams.put( - entry.getKey(), - scriptService.compile(entry.getValue(), ScriptContext.Standard.SEARCH, new HashMap<>())); + entry.getKey(), + scriptService.compile(entry.getValue(), ScriptContext.Standard.SEARCH)); } for (RatedRequest ratedRequest : ratedRequests) { @@ -104,11 +106,10 @@ public class TransportRankEvalAction extends HandledTransportAction params = ratedRequest.getParams(); String templateId = ratedRequest.getTemplateId(); CompiledScript compiled = scriptsWithoutParams.get(templateId); - String resolvedRequest = ((BytesReference) (scriptService.executable(compiled, params).run())).utf8ToString(); - try (XContentParser subParser = XContentFactory.xContent(resolvedRequest).createParser(resolvedRequest)) { - QueryParseContext parseContext = new QueryParseContext(searchRequestParsers.queryParsers, subParser, parseFieldMatcher); - ratedSearchSource = SearchSourceBuilder.fromXContent(parseContext, searchRequestParsers.aggParsers, - searchRequestParsers.suggesters, searchRequestParsers.searchExtParsers); + BytesReference resolvedRequest = (BytesReference) (scriptService.executable(compiled, params).run()); + try (XContentParser subParser = createParser(namedXContentRegistry, resolvedRequest, XContentType.JSON)) { + QueryParseContext parseContext = new QueryParseContext(subParser); + ratedSearchSource = SearchSourceBuilder.fromXContent(parseContext); } catch (IOException e) { listener.onFailure(e); } @@ -142,13 +143,13 @@ public class TransportRankEvalAction extends HandledTransportAction { private ActionListener listener; diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java index 80f954f3914..209b8ca8fe3 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java @@ -19,10 +19,13 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.search.SearchShardTarget; import org.elasticsearch.search.internal.InternalSearchHit; @@ -192,10 +195,11 @@ public class DiscountedCumulativeGainTests extends ESTestCase { + " \"unknown_doc_rating\": 2,\n" + " \"normalize\": true\n" + "}"; - XContentParser parser = XContentFactory.xContent(xContent).createParser(xContent); - DiscountedCumulativeGain dcgAt = DiscountedCumulativeGain.fromXContent(parser, () -> ParseFieldMatcher.STRICT); - assertEquals(2, dcgAt.getUnknownDocRating().intValue()); - assertEquals(true, dcgAt.getNormalize()); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + DiscountedCumulativeGain dcgAt = DiscountedCumulativeGain.fromXContent(parser); + assertEquals(2, dcgAt.getUnknownDocRating().intValue()); + assertEquals(true, dcgAt.getNormalize()); + } } public static DiscountedCumulativeGain createTestItem() { @@ -206,15 +210,18 @@ public class DiscountedCumulativeGainTests extends ESTestCase { } public void testXContentRoundtrip() throws IOException { DiscountedCumulativeGain testItem = createTestItem(); - XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem); - itemParser.nextToken(); - itemParser.nextToken(); - DiscountedCumulativeGain parsedItem = DiscountedCumulativeGain.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT); - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS)); + try (XContentParser itemParser = createParser(shuffled)) { + itemParser.nextToken(); + itemParser.nextToken(); + DiscountedCumulativeGain parsedItem = DiscountedCumulativeGain.fromXContent(itemParser); + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } - + public void testSerialization() throws IOException { DiscountedCumulativeGain original = createTestItem(); DiscountedCumulativeGain deserialized = RankEvalTestHelper.copy(original, DiscountedCumulativeGain::new); diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionTests.java index eec41ea2fec..77e6cfaff34 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionTests.java @@ -19,10 +19,13 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.Index; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchShardTarget; @@ -153,9 +156,10 @@ public class PrecisionTests extends ESTestCase { String xContent = " {\n" + " \"relevant_rating_threshold\" : 2" + "}"; - XContentParser parser = XContentFactory.xContent(xContent).createParser(xContent); - Precision precicionAt = Precision.fromXContent(parser, () -> ParseFieldMatcher.STRICT); - assertEquals(2, precicionAt.getRelevantRatingThreshold()); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + Precision precicionAt = Precision.fromXContent(parser); + assertEquals(2, precicionAt.getRelevantRatingThreshold()); + } } public void testCombine() { @@ -183,15 +187,18 @@ public class PrecisionTests extends ESTestCase { public void testXContentRoundtrip() throws IOException { Precision testItem = createTestItem(); - XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem); - itemParser.nextToken(); - itemParser.nextToken(); - Precision parsedItem = Precision.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT); - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS)); + try (XContentParser itemParser = createParser(shuffled)) { + itemParser.nextToken(); + itemParser.nextToken(); + Precision parsedItem = Precision.fromXContent(itemParser); + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } - + public void testSerialization() throws IOException { Precision original = createTestItem(); Precision deserialized = RankEvalTestHelper.copy(original, Precision::new); diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java index fb24043dca1..fa1a512c54b 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java @@ -78,9 +78,7 @@ public class RankEvalResponseTests extends ESTestCase { if (ESTestCase.randomBoolean()) { builder.prettyPrint(); } - builder.startObject(); randomResponse.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); // TODO check the correctness of the output } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java index 3386caa38ee..b1ab9d9134a 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java @@ -19,30 +19,19 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.ParseFieldRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.rankeval.RankEvalSpec.ScriptWithId; -import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; -import org.elasticsearch.search.SearchModule; -import org.elasticsearch.search.SearchRequestParsers; -import org.elasticsearch.search.aggregations.AggregatorParsers; import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.suggest.Suggesters; import org.elasticsearch.test.ESTestCase; -import org.junit.AfterClass; -import org.junit.BeforeClass; import java.io.IOException; import java.util.ArrayList; @@ -56,30 +45,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.function.Supplier; -import static java.util.Collections.emptyList; - public class RankEvalSpecTests extends ESTestCase { - private static SearchModule searchModule; - private static SearchRequestParsers searchRequestParsers; - - /** - * setup for the whole base test class - */ - @BeforeClass - public static void init() { - AggregatorParsers aggsParsers = new AggregatorParsers(new ParseFieldRegistry<>("aggregation"), - new ParseFieldRegistry<>("aggregation_pipes")); - searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); - IndicesQueriesRegistry queriesRegistry = searchModule.getQueryParserRegistry(); - Suggesters suggesters = searchModule.getSuggesters(); - searchRequestParsers = new SearchRequestParsers(queriesRegistry, aggsParsers, suggesters, null); - } - - @AfterClass - public static void afterClass() throws Exception { - searchModule = null; - searchRequestParsers = null; - } private static List randomList(Supplier randomSupplier) { List result = new ArrayList<>(); @@ -90,7 +56,7 @@ public class RankEvalSpecTests extends ESTestCase { return result; } - private RankEvalSpec createTestItem() throws IOException { + private static RankEvalSpec createTestItem() throws IOException { RankedListQualityMetric metric; if (randomBoolean()) { metric = PrecisionTests.createTestItem(); @@ -118,7 +84,7 @@ public class RankEvalSpecTests extends ESTestCase { templates = new HashSet<>(); templates.add( - new ScriptWithId("templateId", new Script(scriptType, randomFrom("_lang1", "_lang2"), script, params))); + new ScriptWithId("templateId", new Script(scriptType, Script.DEFAULT_TEMPLATE_LANG, script, params))); Map templateParams = new HashMap<>(); templateParams.put("key", "value"); @@ -130,7 +96,7 @@ public class RankEvalSpecTests extends ESTestCase { "id", Arrays.asList(RatedDocumentTests.createRatedDocument()), new SearchSourceBuilder()); ratedRequests = Arrays.asList(ratedRequest); } - RankEvalSpec spec = new RankEvalSpec(ratedRequests, metric, templates); + RankEvalSpec spec = new RankEvalSpec(ratedRequests, metric, templates); maybeSet(spec::setMaxConcurrentSearches, randomInt(100)); return spec; } @@ -138,19 +104,18 @@ public class RankEvalSpecTests extends ESTestCase { public void testXContentRoundtrip() throws IOException { RankEvalSpec testItem = createTestItem(); - XContentBuilder shuffled = ESTestCase.shuffleXContent(testItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)); - XContentParser itemParser = XContentHelper.createParser(shuffled.bytes()); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, shuffled.bytes())) { - QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, itemParser, ParseFieldMatcher.STRICT); - RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext, - searchRequestParsers, null); - - RankEvalSpec parsedItem = RankEvalSpec.parse(itemParser, rankContext); - // IRL these come from URL parameters - see RestRankEvalAction - // TODO Do we still need this? parsedItem.getRatedRequests().stream().forEach(e -> {e.setIndices(indices); e.setTypes(types);}); - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + RankEvalSpec parsedItem = RankEvalSpec.parse(parser); + // IRL these come from URL parameters - see RestRankEvalAction + // TODO Do we still need this? + // parsedItem.getRatedRequests().stream().forEach(e -> + // {e.setIndices(indices); e.setTypes(types);}); + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } public void testSerialization() throws IOException { @@ -185,7 +150,7 @@ public class RankEvalSpecTests extends ESTestCase { RankEvalTestHelper.copy(testItem, RankEvalSpec::new, new NamedWriteableRegistry(namedWriteables))); } - private RankEvalSpec mutateTestItem(RankEvalSpec mutant) { + private static RankEvalSpec mutateTestItem(RankEvalSpec mutant) { Collection ratedRequests = mutant.getRatedRequests(); RankedListQualityMetric metric = mutant.getMetric(); Map templates = mutant.getTemplates(); @@ -193,7 +158,7 @@ public class RankEvalSpecTests extends ESTestCase { int mutate = randomIntBetween(0, 2); switch (mutate) { case 0: - RatedRequest request = RatedRequestsTests.createTestItem(new ArrayList<>(), new ArrayList<>()); + RatedRequest request = RatedRequestsTests.createTestItem(new ArrayList<>(), new ArrayList<>(), true); ratedRequests.add(request); break; case 1: @@ -205,13 +170,8 @@ public class RankEvalSpecTests extends ESTestCase { break; case 2: if (templates.size() > 0) { - if (randomBoolean()) { - templates = null; - } else { - String mutatedTemplate = randomAsciiOfLength(10); - templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>())); - - } + String mutatedTemplate = randomAsciiOfLength(10); + templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>())); } else { String mutatedTemplate = randomValueOtherThanMany(templates::containsValue, () -> randomAsciiOfLength(10)); templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>())); @@ -225,7 +185,7 @@ public class RankEvalSpecTests extends ESTestCase { for (Entry entry : templates.entrySet()) { scripts.add(new ScriptWithId(entry.getKey(), entry.getValue())); } - + RankEvalSpec result = new RankEvalSpec(ratedRequests, metric, scripts); return result; } @@ -235,10 +195,10 @@ public class RankEvalSpecTests extends ESTestCase { expectThrows(IllegalStateException.class, () -> new RankEvalSpec(new ArrayList<>(), metric)); expectThrows(IllegalStateException.class, () -> new RankEvalSpec(null, metric)); } - + public void testMissingMetricFailsParsing() { List strings = Arrays.asList("value"); - List ratedRequests = randomList(() -> RatedRequestsTests.createTestItem(strings, strings)); + List ratedRequests = randomList(() -> RatedRequestsTests.createTestItem(strings, strings, randomBoolean())); expectThrows(IllegalStateException.class, () -> new RankEvalSpec(ratedRequests, null)); } @@ -249,7 +209,7 @@ public class RankEvalSpecTests extends ESTestCase { RatedRequest request = new RatedRequest("id", ratedDocs, params, "templateId"); List ratedRequests = Arrays.asList(request); - + expectThrows(IllegalStateException.class, () -> new RankEvalSpec(ratedRequests, new Precision())); } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalTestHelper.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalTestHelper.java index 8be80707e06..be97ad8ff06 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalTestHelper.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalTestHelper.java @@ -25,13 +25,6 @@ import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.Collections; @@ -45,17 +38,6 @@ import static org.junit.Assert.assertTrue; public class RankEvalTestHelper { - public static XContentParser roundtrip(ToXContent testItem) throws IOException { - XContentBuilder builder = XContentFactory.contentBuilder(ESTestCase.randomFrom(XContentType.values())); - if (ESTestCase.randomBoolean()) { - builder.prettyPrint(); - } - testItem.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = ESTestCase.shuffleXContent(builder); - XContentParser itemParser = XContentHelper.createParser(shuffled.bytes()); - return itemParser; - } - public static void testHashCodeAndEquals(T testItem, T mutation, T secondCopy) { assertFalse("testItem is equal to null", testItem.equals(null)); assertFalse("testItem is equal to incompatible type", testItem.equals("")); diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalYamlIT.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalYamlIT.java index 09e1a906044..90c07bb244d 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalYamlIT.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalYamlIT.java @@ -24,7 +24,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate; import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase; -import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException; import java.io.IOException; @@ -34,7 +33,7 @@ public class RankEvalYamlIT extends ESClientYamlSuiteTestCase { } @ParametersFactory - public static Iterable parameters() throws IOException, ClientYamlTestParseException { + public static Iterable parameters() throws IOException { return ESClientYamlSuiteTestCase.createParameters(); } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java index f42c6e3e542..b100a21b38b 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java @@ -19,8 +19,11 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.test.ESTestCase; import java.io.IOException; @@ -38,13 +41,16 @@ public class RatedDocumentTests extends ESTestCase { public void testXContentParsing() throws IOException { RatedDocument testItem = createRatedDocument(); - XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem); - RatedDocument parsedItem = RatedDocument.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT); - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS)); + try (XContentParser itemParser = createParser(shuffled)) { + RatedDocument parsedItem = RatedDocument.fromXContent(itemParser); + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } - + public void testSerialization() throws IOException { RatedDocument original = createRatedDocument(); RatedDocument deserialized = RankEvalTestHelper.copy(original, RatedDocument::new); diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java index 4844c21c299..99035504785 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java @@ -19,21 +19,19 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.ParseFieldRegistry; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryParseContext; -import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.search.SearchModule; -import org.elasticsearch.search.SearchRequestParsers; -import org.elasticsearch.search.aggregations.AggregatorParsers; import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.suggest.Suggesters; import org.elasticsearch.test.ESTestCase; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -44,36 +42,38 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; public class RatedRequestsTests extends ESTestCase { - private static SearchModule searchModule; - private static SearchRequestParsers searchRequestParsers; + private static NamedXContentRegistry xContentRegistry; /** * setup for the whole base test class */ @BeforeClass - public static void init() throws IOException { - AggregatorParsers aggsParsers = new AggregatorParsers(new ParseFieldRegistry<>("aggregation"), - new ParseFieldRegistry<>("aggregation_pipes")); - searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); - IndicesQueriesRegistry queriesRegistry = searchModule.getQueryParserRegistry(); - Suggesters suggesters = searchModule.getSuggesters(); - searchRequestParsers = new SearchRequestParsers(queriesRegistry, aggsParsers, suggesters, null); + public static void init() { + xContentRegistry = new NamedXContentRegistry(Stream.of( + new SearchModule(Settings.EMPTY, false, emptyList()).getNamedXContents().stream() + ).flatMap(Function.identity()).collect(toList())); } @AfterClass public static void afterClass() throws Exception { - searchModule = null; - searchRequestParsers = null; + xContentRegistry = null; } - public static RatedRequest createTestItem(List indices, List types) { - String requestId = randomAsciiOfLength(50); + @Override + protected NamedXContentRegistry xContentRegistry() { + return xContentRegistry; + } + public static RatedRequest createTestItem(List indices, List types, boolean forceRequest) { + String requestId = randomAsciiOfLength(50); List ratedDocs = new ArrayList<>(); int size = randomIntBetween(0, 2); @@ -83,15 +83,15 @@ public class RatedRequestsTests extends ESTestCase { Map params = new HashMap<>(); SearchSourceBuilder testRequest = null; - if (randomBoolean()) { + if (randomBoolean() || forceRequest) { + testRequest = new SearchSourceBuilder(); + testRequest.size(randomInt()); + testRequest.query(new MatchAllQueryBuilder()); + } else { int randomSize = randomIntBetween(1, 10); for (int i = 0; i < randomSize; i++) { params.put(randomAsciiOfLengthBetween(1, 10), randomAsciiOfLengthBetween(1, 10)); } - } else { - testRequest = new SearchSourceBuilder(); - testRequest.size(randomInt()); - testRequest.query(new MatchAllQueryBuilder()); } List summaryFields = new ArrayList<>(); @@ -100,7 +100,7 @@ public class RatedRequestsTests extends ESTestCase { summaryFields.add(randomAsciiOfLength(5)); } - RatedRequest ratedRequest = null; + RatedRequest ratedRequest = null; if (params.size() == 0) { ratedRequest = new RatedRequest(requestId, ratedDocs, testRequest); ratedRequest.setIndices(indices); @@ -112,8 +112,6 @@ public class RatedRequestsTests extends ESTestCase { ratedRequest.setTypes(types); ratedRequest.setSummaryFields(summaryFields); } - - return ratedRequest; } @@ -130,22 +128,24 @@ public class RatedRequestsTests extends ESTestCase { types.add(randomAsciiOfLengthBetween(0, 50)); } - RatedRequest testItem = createTestItem(indices, types); - XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem); - itemParser.nextToken(); + RatedRequest testItem = createTestItem(indices, types, randomBoolean()); + XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS)); + try (XContentParser itemParser = createParser(shuffled)) { + itemParser.nextToken(); - QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, itemParser, ParseFieldMatcher.STRICT); - RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext, - searchRequestParsers, null); - - RatedRequest parsedItem = RatedRequest.fromXContent(itemParser, rankContext); - parsedItem.setIndices(indices); // IRL these come from URL parameters - see RestRankEvalAction - parsedItem.setTypes(types); // IRL these come from URL parameters - see RestRankEvalAction - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + RatedRequest parsedItem = RatedRequest.fromXContent(itemParser); + parsedItem.setIndices(indices); // IRL these come from URL + // parameters - see + // RestRankEvalAction + parsedItem.setTypes(types); // IRL these come from URL parameters - + // see RestRankEvalAction + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } - + public void testSerialization() throws IOException { List indices = new ArrayList<>(); int size = randomIntBetween(0, 20); @@ -159,7 +159,7 @@ public class RatedRequestsTests extends ESTestCase { types.add(randomAsciiOfLengthBetween(0, 50)); } - RatedRequest original = createTestItem(indices, types); + RatedRequest original = createTestItem(indices, types, randomBoolean()); List namedWriteables = new ArrayList<>(); namedWriteables.add(new NamedWriteableRegistry.Entry(QueryBuilder.class, MatchAllQueryBuilder.NAME, MatchAllQueryBuilder::new)); @@ -183,7 +183,7 @@ public class RatedRequestsTests extends ESTestCase { types.add(randomAsciiOfLengthBetween(0, 50)); } - RatedRequest testItem = createTestItem(indices, types); + RatedRequest testItem = createTestItem(indices, types, randomBoolean()); List namedWriteables = new ArrayList<>(); namedWriteables.add(new NamedWriteableRegistry.Entry(QueryBuilder.class, MatchAllQueryBuilder.NAME, MatchAllQueryBuilder::new)); @@ -270,19 +270,19 @@ public class RatedRequestsTests extends ESTestCase { "Found duplicate rated document key [{ \"_index\" : \"index1\", \"_type\" : \"type1\", \"_id\" : \"id1\"}]", ex.getMessage()); } - + public void testNullSummaryFieldsTreatment() { List ratedDocs = Arrays.asList(new RatedDocument(new DocumentKey("index1", "type1", "id1"), 1)); RatedRequest request = new RatedRequest("id", ratedDocs, new SearchSourceBuilder()); expectThrows(IllegalArgumentException.class, () -> request.setSummaryFields(null)); } - + public void testNullParamsTreatment() { List ratedDocs = Arrays.asList(new RatedDocument(new DocumentKey("index1", "type1", "id1"), 1)); RatedRequest request = new RatedRequest("id", ratedDocs, new SearchSourceBuilder(), null, null); assertNotNull(request.getParams()); } - + public void testSettingParamsAndRequestThrows() { List ratedDocs = Arrays.asList(new RatedDocument(new DocumentKey("index1", "type1", "id1"), 1)); Map params = new HashMap<>(); @@ -290,7 +290,7 @@ public class RatedRequestsTests extends ESTestCase { expectThrows(IllegalArgumentException.class, () -> new RatedRequest("id", ratedDocs, new SearchSourceBuilder(), params, null)); } - + public void testSettingNeitherParamsNorRequestThrows() { List ratedDocs = Arrays.asList(new RatedDocument(new DocumentKey("index1", "type1", "id1"), 1)); expectThrows(IllegalArgumentException.class, () -> new RatedRequest("id", ratedDocs, null, null)); @@ -304,7 +304,7 @@ public class RatedRequestsTests extends ESTestCase { expectThrows(IllegalArgumentException.class, () -> new RatedRequest("id", ratedDocs, null, params, null)); } - + public void testSettingTemplateIdAndRequestThrows() { List ratedDocs = Arrays.asList(new RatedDocument(new DocumentKey("index1", "type1", "id1"), 1)); expectThrows(IllegalArgumentException.class, @@ -338,23 +338,21 @@ public class RatedRequestsTests extends ESTestCase { + " {\"_type\": \"testtype\", \"_index\": \"test\", \"_id\": \"2\", \"rating\" : 0 }, " + " {\"_id\": \"3\", \"_index\": \"test\", \"_type\": \"testtype\", \"rating\" : 1 }]\n" + "}"; - XContentParser parser = XContentFactory.xContent(querySpecString).createParser(querySpecString); - QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, parser, ParseFieldMatcher.STRICT); - RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext, - searchRequestParsers, null); - RatedRequest specification = RatedRequest.fromXContent(parser, rankContext); - assertEquals("my_qa_query", specification.getId()); - assertNotNull(specification.getTestRequest()); - List ratedDocs = specification.getRatedDocs(); - assertEquals(3, ratedDocs.size()); - for (int i = 0; i < 3; i++) { - assertEquals("" + (i + 1), ratedDocs.get(i).getDocID()); - assertEquals("test", ratedDocs.get(i).getIndex()); - assertEquals("testtype", ratedDocs.get(i).getType()); - if (i == 1) { - assertEquals(0, ratedDocs.get(i).getRating()); - } else { - assertEquals(1, ratedDocs.get(i).getRating()); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, querySpecString)) { + RatedRequest specification = RatedRequest.fromXContent(parser); + assertEquals("my_qa_query", specification.getId()); + assertNotNull(specification.getTestRequest()); + List ratedDocs = specification.getRatedDocs(); + assertEquals(3, ratedDocs.size()); + for (int i = 0; i < 3; i++) { + assertEquals("" + (i + 1), ratedDocs.get(i).getDocID()); + assertEquals("test", ratedDocs.get(i).getIndex()); + assertEquals("testtype", ratedDocs.get(i).getType()); + if (i == 1) { + assertEquals(0, ratedDocs.get(i).getRating()); + } else { + assertEquals(1, ratedDocs.get(i).getRating()); + } } } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/ReciprocalRankTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/ReciprocalRankTests.java index b3c2e0d7cdc..c66f7ba45aa 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/ReciprocalRankTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/ReciprocalRankTests.java @@ -19,9 +19,12 @@ package org.elasticsearch.index.rankeval; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.Index; import org.elasticsearch.index.rankeval.PrecisionTests.Rating; import org.elasticsearch.search.SearchHit; @@ -124,13 +127,16 @@ public class ReciprocalRankTests extends ESTestCase { public void testXContentRoundtrip() throws IOException { ReciprocalRank testItem = createTestItem(); - XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem); - itemParser.nextToken(); - itemParser.nextToken(); - ReciprocalRank parsedItem = ReciprocalRank.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT); - assertNotSame(testItem, parsedItem); - assertEquals(testItem, parsedItem); - assertEquals(testItem.hashCode(), parsedItem.hashCode()); + XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); + XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS)); + try (XContentParser itemParser = createParser(shuffled)) { + itemParser.nextToken(); + itemParser.nextToken(); + ReciprocalRank parsedItem = ReciprocalRank.fromXContent(itemParser); + assertNotSame(testItem, parsedItem); + assertEquals(testItem, parsedItem); + assertEquals(testItem.hashCode(), parsedItem.hashCode()); + } } /** @@ -145,7 +151,7 @@ public class ReciprocalRankTests extends ESTestCase { } return hits; } - + private ReciprocalRank createTestItem() { ReciprocalRank testItem = new ReciprocalRank(); testItem.setRelevantRatingThreshhold(randomIntBetween(0, 20)); diff --git a/qa/smoke-test-rank-eval-with-mustache/build.gradle b/qa/smoke-test-rank-eval-with-mustache/build.gradle index 4fdbaa04502..7274e65f4e1 100644 --- a/qa/smoke-test-rank-eval-with-mustache/build.gradle +++ b/qa/smoke-test-rank-eval-with-mustache/build.gradle @@ -17,6 +17,7 @@ * under the License. */ +apply plugin: 'elasticsearch.standalone-rest-test' apply plugin: 'elasticsearch.rest-test' diff --git a/qa/smoke-test-rank-eval-with-mustache/src/test/java/org/elasticsearch/smoketest/SmokeTestRankEvalWithMustacheYAMLTestSuiteIT.java b/qa/smoke-test-rank-eval-with-mustache/src/test/java/org/elasticsearch/smoketest/SmokeTestRankEvalWithMustacheYAMLTestSuiteIT.java index 92c60b6f090..401bddd3439 100644 --- a/qa/smoke-test-rank-eval-with-mustache/src/test/java/org/elasticsearch/smoketest/SmokeTestRankEvalWithMustacheYAMLTestSuiteIT.java +++ b/qa/smoke-test-rank-eval-with-mustache/src/test/java/org/elasticsearch/smoketest/SmokeTestRankEvalWithMustacheYAMLTestSuiteIT.java @@ -24,7 +24,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate; import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase; -import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException; import java.io.IOException; @@ -35,7 +34,7 @@ public class SmokeTestRankEvalWithMustacheYAMLTestSuiteIT extends ESClientYamlSu } @ParametersFactory - public static Iterable parameters() throws IOException, ClientYamlTestParseException { + public static Iterable parameters() throws IOException { return ESClientYamlSuiteTestCase.createParameters(); }