Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rest Api Compatibility] Typed endpoints for explain api #73901

Merged
merged 4 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions rest-api-spec/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,14 @@ tasks.named("yamlRestCompatTest").configure {
// This mean test cases where there is assertion on not finging by type won't work
'mget/11_default_index_type/Default index/type',
'mget/16_basic_with_types/Basic multi-get',
// 88 - 14 = 74 tests won't be fixed
// asserting about type not found won't work as we ignore the type information
'explain/40_mix_typeless_typeful/Explain with typeless API on an index that has types',
// 89 - 15 = 74 tests won't be fixed
'cluster.voting_config_exclusions/10_basic/Throw exception when adding voting config exclusion and specifying both node_ids and node_names',
'cluster.voting_config_exclusions/10_basic/Throw exception when adding voting config exclusion without specifying nodes',
'count/11_basic_with_types/count body without query element',
'count/11_basic_with_types/count with body',
'count/11_basic_with_types/count with empty body',
'explain/10_basic/Basic explain',
'explain/10_basic/Basic explain with alias',
'explain/11_basic_with_types/Basic explain',
'explain/11_basic_with_types/Basic explain with alias',
'explain/20_source_filtering/Source filtering',
'explain/21_source_filtering_with_types/Source filtering',
'explain/31_query_string_with_types/explain with query_string parameters',
'explain/40_mix_typeless_typeful/Explain with typeless API on an index that has types',
'field_caps/30_filter/Field caps with index filter',
'get_source/11_basic_with_types/Basic with types',
'get_source/16_default_values_with_types/Default values',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.xcontent.ParseField;
import org.elasticsearch.core.RestApiVersion;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
Expand Down Expand Up @@ -172,6 +173,10 @@ public static ExplainResponse fromXContent(XContentParser parser, boolean exists
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(_INDEX.getPreferredName(), index);
if (builder.getRestApiVersion() == RestApiVersion.V_7) {
builder.field(MapperService.TYPE_FIELD_NAME, MapperService.SINGLE_MAPPING_NAME);
}

builder.field(_ID.getPreferredName(), id);
builder.field(MATCHED.getPreferredName(), isMatch());
if (hasExplanation()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.elasticsearch.action.explain.ExplainRequest;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.core.RestApiVersion;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.rest.BaseRestHandler;
Expand All @@ -28,12 +29,20 @@
* Rest action for computing a score explanation for specific documents.
*/
public class RestExplainAction extends BaseRestHandler {
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] " +
"Specifying a type in explain requests is deprecated.";

@Override
public List<Route> routes() {
return List.of(
new Route(GET, "/{index}/_explain/{id}"),
new Route(POST, "/{index}/_explain/{id}"));
new Route(POST, "/{index}/_explain/{id}"),
Route.builder(GET, "/{index}/{type}/{id}/_explain")
.deprecated(TYPES_DEPRECATION_MESSAGE, RestApiVersion.V_7)
.build(),
Route.builder(POST, "/{index}/{type}/{id}/_explain")
.deprecated(TYPES_DEPRECATION_MESSAGE, RestApiVersion.V_7)
.build());
}

@Override
Expand All @@ -43,6 +52,9 @@ public String getName() {

@Override
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
if(request.getRestApiVersion() == RestApiVersion.V_7 && request.hasParam("type")) {
request.param("type");
}
ExplainRequest explainRequest = new ExplainRequest(request.param("index"), request.param("id"));

explainRequest.parent(request.param("parent"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.rest.action.search;

import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.core.RestApiVersion;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.test.rest.FakeRestRequest;
import org.elasticsearch.test.rest.RestActionTestCase;
import org.junit.Before;
import org.mockito.Mockito;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class RestExplainActionTests extends RestActionTestCase {
final List<String> contentTypeHeader = Collections.singletonList(compatibleMediaType(XContentType.VND_JSON, RestApiVersion.V_7));

@Before
public void setUpAction() {
RestExplainAction action = new RestExplainAction();
controller().registerHandler(action);
verifyingClient.setExecuteVerifier((actionType, request) -> Mockito.mock(ExplainResponse.class));
verifyingClient.setExecuteLocallyVerifier((actionType, request) -> Mockito.mock(ExplainResponse.class));
}

public void testTypeInPath() {
RestRequest deprecatedRequest = new FakeRestRequest.Builder(xContentRegistry())
.withHeaders(Map.of("Accept", contentTypeHeader))
.withMethod(RestRequest.Method.GET)
.withPath("/some_index/some_type/some_id/_explain")
.build();
dispatchRequest(deprecatedRequest);
assertWarnings(RestExplainAction.TYPES_DEPRECATION_MESSAGE);

RestRequest validRequest = new FakeRestRequest.Builder(xContentRegistry())
.withHeaders(Map.of("Accept", contentTypeHeader))
.withMethod(RestRequest.Method.GET)
.withPath("/some_index/_explain/some_id")
.build();
dispatchRequest(validRequest);
}

}