Skip to content

Commit 547fe1f

Browse files
author
Christoph Büscher
committed
RankEvalRequest should implement IndicesRequest (#29188)
Change RankEvalRequest to implement IndicesRequest, so it gets treated in a similar fashion to regular search requests e.g. by security.
1 parent 10466d1 commit 547fe1f

File tree

8 files changed

+162
-37
lines changed

8 files changed

+162
-37
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ static Request existsAlias(GetAliasesRequest getAliasesRequest) {
533533
}
534534

535535
static Request rankEval(RankEvalRequest rankEvalRequest) throws IOException {
536-
String endpoint = endpoint(rankEvalRequest.getIndices(), Strings.EMPTY_ARRAY, "_rank_eval");
536+
String endpoint = endpoint(rankEvalRequest.indices(), Strings.EMPTY_ARRAY, "_rank_eval");
537537
HttpEntity entity = createEntity(rankEvalRequest.getRankEvalSpec(), REQUEST_BODY_CONTENT_TYPE);
538538
return new Request(HttpGet.METHOD_NAME, endpoint, Collections.emptyMap(), entity);
539539
}

modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RankEvalRequest.java

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,47 @@
2222
import org.elasticsearch.Version;
2323
import org.elasticsearch.action.ActionRequest;
2424
import org.elasticsearch.action.ActionRequestValidationException;
25+
import org.elasticsearch.action.IndicesRequest;
26+
import org.elasticsearch.action.search.SearchRequest;
27+
import org.elasticsearch.action.support.IndicesOptions;
2528
import org.elasticsearch.common.Strings;
2629
import org.elasticsearch.common.io.stream.StreamInput;
2730
import org.elasticsearch.common.io.stream.StreamOutput;
2831

2932
import java.io.IOException;
33+
import java.util.Arrays;
3034
import java.util.Objects;
3135

3236
/**
3337
* Request to perform a search ranking evaluation.
3438
*/
35-
public class RankEvalRequest extends ActionRequest {
39+
public class RankEvalRequest extends ActionRequest implements IndicesRequest.Replaceable {
3640

3741
private RankEvalSpec rankingEvaluationSpec;
42+
43+
private IndicesOptions indicesOptions = SearchRequest.DEFAULT_INDICES_OPTIONS;
3844
private String[] indices = Strings.EMPTY_ARRAY;
3945

4046
public RankEvalRequest(RankEvalSpec rankingEvaluationSpec, String[] indices) {
41-
this.rankingEvaluationSpec = rankingEvaluationSpec;
42-
setIndices(indices);
47+
this.rankingEvaluationSpec = Objects.requireNonNull(rankingEvaluationSpec, "ranking evaluation specification must not be null");
48+
indices(indices);
49+
}
50+
51+
RankEvalRequest(StreamInput in) throws IOException {
52+
super.readFrom(in);
53+
rankingEvaluationSpec = new RankEvalSpec(in);
54+
if (in.getVersion().onOrAfter(Version.V_6_3_0)) {
55+
indices = in.readStringArray();
56+
indicesOptions = IndicesOptions.readIndicesOptions(in);
57+
} else {
58+
// readStringArray uses readVInt for size, we used readInt in 6.2
59+
int indicesSize = in.readInt();
60+
String[] indices = new String[indicesSize];
61+
for (int i = 0; i < indicesSize; i++) {
62+
indices[i] = in.readString();
63+
}
64+
// no indices options yet
65+
}
4366
}
4467

4568
RankEvalRequest() {
@@ -72,7 +95,8 @@ public void setRankEvalSpec(RankEvalSpec task) {
7295
/**
7396
* Sets the indices the search will be executed on.
7497
*/
75-
public RankEvalRequest setIndices(String... indices) {
98+
@Override
99+
public RankEvalRequest indices(String... indices) {
76100
Objects.requireNonNull(indices, "indices must not be null");
77101
for (String index : indices) {
78102
Objects.requireNonNull(index, "index must not be null");
@@ -84,24 +108,23 @@ public RankEvalRequest setIndices(String... indices) {
84108
/**
85109
* @return the indices for this request
86110
*/
87-
public String[] getIndices() {
111+
@Override
112+
public String[] indices() {
88113
return indices;
89114
}
90115

116+
@Override
117+
public IndicesOptions indicesOptions() {
118+
return indicesOptions;
119+
}
120+
121+
public void indicesOptions(IndicesOptions indicesOptions) {
122+
this.indicesOptions = Objects.requireNonNull(indicesOptions, "indicesOptions must not be null");
123+
}
124+
91125
@Override
92126
public void readFrom(StreamInput in) throws IOException {
93-
super.readFrom(in);
94-
rankingEvaluationSpec = new RankEvalSpec(in);
95-
if (in.getVersion().onOrAfter(Version.V_6_3_0)) {
96-
indices = in.readStringArray();
97-
} else {
98-
// readStringArray uses readVInt for size, we used readInt in 6.2
99-
int indicesSize = in.readInt();
100-
String[] indices = new String[indicesSize];
101-
for (int i = 0; i < indicesSize; i++) {
102-
indices[i] = in.readString();
103-
}
104-
}
127+
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
105128
}
106129

107130
@Override
@@ -110,12 +133,33 @@ public void writeTo(StreamOutput out) throws IOException {
110133
rankingEvaluationSpec.writeTo(out);
111134
if (out.getVersion().onOrAfter(Version.V_6_3_0)) {
112135
out.writeStringArray(indices);
136+
indicesOptions.writeIndicesOptions(out);
113137
} else {
114138
// writeStringArray uses writeVInt for size, we used writeInt in 6.2
115139
out.writeInt(indices.length);
116140
for (String index : indices) {
117141
out.writeString(index);
118142
}
143+
// no indices options yet
144+
}
145+
}
146+
147+
@Override
148+
public boolean equals(Object o) {
149+
if (this == o) {
150+
return true;
151+
}
152+
if (o == null || getClass() != o.getClass()) {
153+
return false;
119154
}
155+
RankEvalRequest that = (RankEvalRequest) o;
156+
return Objects.equals(indicesOptions, that.indicesOptions) &&
157+
Arrays.equals(indices, that.indices) &&
158+
Objects.equals(rankingEvaluationSpec, that.rankingEvaluationSpec);
159+
}
160+
161+
@Override
162+
public int hashCode() {
163+
return Objects.hash(indicesOptions, Arrays.hashCode(indices), rankingEvaluationSpec);
120164
}
121165
}

modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/RestRankEvalAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
108108
}
109109

110110
private static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, XContentParser parser) {
111-
rankEvalRequest.setIndices(Strings.splitStringByCommaToArray(request.param("index")));
111+
rankEvalRequest.indices(Strings.splitStringByCommaToArray(request.param("index")));
112112
RankEvalSpec spec = RankEvalSpec.parse(parser);
113113
rankEvalRequest.setRankEvalSpec(spec);
114114
}

modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/TransportRankEvalAction.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequ
7575
public TransportRankEvalAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
7676
IndexNameExpressionResolver indexNameExpressionResolver, Client client, TransportService transportService,
7777
ScriptService scriptService, NamedXContentRegistry namedXContentRegistry) {
78-
super(settings, RankEvalAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
79-
RankEvalRequest::new);
78+
super(settings, RankEvalAction.NAME, threadPool, transportService, actionFilters, RankEvalRequest::new,
79+
indexNameExpressionResolver);
8080
this.scriptService = scriptService;
8181
this.namedXContentRegistry = namedXContentRegistry;
8282
this.client = client;
@@ -126,7 +126,7 @@ LoggingDeprecationHandler.INSTANCE, new BytesArray(resolvedRequest), XContentTyp
126126
} else {
127127
ratedSearchSource.fetchSource(summaryFields.toArray(new String[summaryFields.size()]), new String[0]);
128128
}
129-
msearchRequest.add(new SearchRequest(request.getIndices(), ratedSearchSource));
129+
msearchRequest.add(new SearchRequest(request.indices(), ratedSearchSource));
130130
}
131131
assert ratedRequestsInSearch.size() == msearchRequest.requests().size();
132132
client.multiSearch(msearchRequest, new RankEvalActionListener(listener, metric,

modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalRequestIT.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void testPrecisionAtRequest() {
8989
RankEvalAction.INSTANCE, new RankEvalRequest());
9090
builder.setRankEvalSpec(task);
9191

92-
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request().setIndices("test"))
92+
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request().indices("test"))
9393
.actionGet();
9494
// the expected Prec@ for the first query is 4/6 and the expected Prec@ for the
9595
// second is 1/6, divided by 2 to get the average
@@ -131,8 +131,7 @@ public void testPrecisionAtRequest() {
131131
metric = new PrecisionAtK(1, false, 3);
132132
task = new RankEvalSpec(specifications, metric);
133133

134-
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest().setIndices("test"));
135-
builder.setRankEvalSpec(task);
134+
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest(task, new String[] { "test" }));
136135

137136
response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
138137
// if we look only at top 3 documente, the expected P@3 for the first query is
@@ -164,8 +163,7 @@ public void testDCGRequest() {
164163
RankEvalSpec task = new RankEvalSpec(specifications, metric);
165164

166165
RankEvalRequestBuilder builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE,
167-
new RankEvalRequest().setIndices("test"));
168-
builder.setRankEvalSpec(task);
166+
new RankEvalRequest(task, new String[] { "test" }));
169167

170168
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
171169
assertEquals(DiscountedCumulativeGainTests.EXPECTED_DCG, response.getEvaluationResult(), 10E-14);
@@ -174,8 +172,7 @@ public void testDCGRequest() {
174172
metric = new DiscountedCumulativeGain(false, null, 3);
175173
task = new RankEvalSpec(specifications, metric);
176174

177-
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest().setIndices("test"));
178-
builder.setRankEvalSpec(task);
175+
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest(task, new String[] { "test" }));
179176

180177
response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
181178
assertEquals(12.39278926071437, response.getEvaluationResult(), 10E-14);
@@ -194,8 +191,7 @@ public void testMRRRequest() {
194191
RankEvalSpec task = new RankEvalSpec(specifications, metric);
195192

196193
RankEvalRequestBuilder builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE,
197-
new RankEvalRequest().setIndices("test"));
198-
builder.setRankEvalSpec(task);
194+
new RankEvalRequest(task, new String[] { "test" }));
199195

200196
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
201197
// the expected reciprocal rank for the amsterdam_query is 1/5
@@ -208,8 +204,7 @@ public void testMRRRequest() {
208204
metric = new MeanReciprocalRank(1, 3);
209205
task = new RankEvalSpec(specifications, metric);
210206

211-
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest().setIndices("test"));
212-
builder.setRankEvalSpec(task);
207+
builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest(task, new String[] { "test" }));
213208

214209
response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
215210
// limiting to top 3 results, the amsterdam_query has no relevant document in it
@@ -240,7 +235,7 @@ public void testBadQuery() {
240235
RankEvalSpec task = new RankEvalSpec(specifications, new PrecisionAtK());
241236

242237
RankEvalRequestBuilder builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE,
243-
new RankEvalRequest().setIndices("test"));
238+
new RankEvalRequest(task, new String[] { "test" }));
244239
builder.setRankEvalSpec(task);
245240

246241
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request()).actionGet();
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.rankeval;
21+
22+
import org.elasticsearch.action.support.IndicesOptions;
23+
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
24+
import org.elasticsearch.common.io.stream.Writeable.Reader;
25+
import org.elasticsearch.common.util.ArrayUtils;
26+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
27+
import org.elasticsearch.test.AbstractWireSerializingTestCase;
28+
import org.junit.AfterClass;
29+
30+
import java.io.IOException;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
public class RankEvalRequestTests extends AbstractWireSerializingTestCase<RankEvalRequest> {
35+
36+
private static RankEvalPlugin rankEvalPlugin = new RankEvalPlugin();
37+
38+
@AfterClass
39+
public static void releasePluginResources() throws IOException {
40+
rankEvalPlugin.close();
41+
}
42+
43+
@Override
44+
protected NamedXContentRegistry xContentRegistry() {
45+
return new NamedXContentRegistry(rankEvalPlugin.getNamedXContent());
46+
}
47+
48+
@Override
49+
protected NamedWriteableRegistry getNamedWriteableRegistry() {
50+
return new NamedWriteableRegistry(rankEvalPlugin.getNamedWriteables());
51+
}
52+
53+
@Override
54+
protected RankEvalRequest createTestInstance() {
55+
int numberOfIndices = randomInt(3);
56+
String[] indices = new String[numberOfIndices];
57+
for (int i=0; i < numberOfIndices; i++) {
58+
indices[i] = randomAlphaOfLengthBetween(5, 10);
59+
}
60+
RankEvalRequest rankEvalRequest = new RankEvalRequest(RankEvalSpecTests.createTestItem(), indices);
61+
IndicesOptions indicesOptions = IndicesOptions.fromOptions(
62+
randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
63+
rankEvalRequest.indicesOptions(indicesOptions);
64+
return rankEvalRequest;
65+
}
66+
67+
@Override
68+
protected Reader<RankEvalRequest> instanceReader() {
69+
return RankEvalRequest::new;
70+
}
71+
72+
@Override
73+
protected RankEvalRequest mutateInstance(RankEvalRequest instance) throws IOException {
74+
RankEvalRequest mutation = copyInstance(instance);
75+
List<Runnable> mutators = new ArrayList<>();
76+
mutators.add(() -> mutation.indices(ArrayUtils.concat(instance.indices(), new String[] { randomAlphaOfLength(10) })));
77+
mutators.add(() -> mutation.indicesOptions(randomValueOtherThan(instance.indicesOptions(),
78+
() -> IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()))));
79+
mutators.add(() -> mutation.setRankEvalSpec(RankEvalSpecTests.mutateTestItem(instance.getRankEvalSpec())));
80+
randomFrom(mutators).run();
81+
return mutation;
82+
}
83+
}

modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private static <T> List<T> randomList(Supplier<T> randomSupplier) {
7070
return result;
7171
}
7272

73-
private static RankEvalSpec createTestItem() throws IOException {
73+
static RankEvalSpec createTestItem() {
7474
Supplier<EvaluationMetric> metric = randomFrom(Arrays.asList(
7575
() -> PrecisionAtKTests.createTestItem(),
7676
() -> MeanReciprocalRankTests.createTestItem(),
@@ -87,6 +87,9 @@ private static RankEvalSpec createTestItem() throws IOException {
8787
builder.field("field", randomAlphaOfLengthBetween(1, 5));
8888
builder.endObject();
8989
script = Strings.toString(builder);
90+
} catch (IOException e) {
91+
// this shouldn't happen in tests, re-throw just not to swallow it
92+
throw new RuntimeException(e);
9093
}
9194

9295
templates = new HashSet<>();
@@ -156,7 +159,7 @@ public void testEqualsAndHash() throws IOException {
156159
checkEqualsAndHashCode(createTestItem(), RankEvalSpecTests::copy, RankEvalSpecTests::mutateTestItem);
157160
}
158161

159-
private static RankEvalSpec mutateTestItem(RankEvalSpec original) {
162+
static RankEvalSpec mutateTestItem(RankEvalSpec original) {
160163
List<RatedRequest> ratedRequests = new ArrayList<>(original.getRatedRequests());
161164
EvaluationMetric metric = original.getMetric();
162165
Map<String, Script> templates = new HashMap<>(original.getTemplates());

qa/smoke-test-rank-eval-with-mustache/src/test/java/org/elasticsearch/index/rankeval/SmokeMultipleTemplatesIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public void testPrecisionAtRequest() throws IOException {
102102
RankEvalRequestBuilder builder = new RankEvalRequestBuilder(client(), RankEvalAction.INSTANCE, new RankEvalRequest());
103103
builder.setRankEvalSpec(task);
104104

105-
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request().setIndices("test")).actionGet();
105+
RankEvalResponse response = client().execute(RankEvalAction.INSTANCE, builder.request().indices("test")).actionGet();
106106
assertEquals(0.9, response.getEvaluationResult(), Double.MIN_VALUE);
107107
}
108108

0 commit comments

Comments
 (0)