Skip to content

Commit b09bd5a

Browse files
authored
Mappings get put and get mappings (#58426)
based on pgomulka:compat/delete_update #58246 CompatRestIT. test {yaml=indices.get_field_mapping/30_missing_type/Raise 404 when type doesn't exist} because of that change (custom type to _doc) a test that was expecting 404 for a type that did not exist, passes now as the logic is trying to fetch for _doc (any type that exist on that index will be good). CompatRestIT. test {yaml=indices.get_mapping/11_basic_with_types/Get /{index}/_mapping with empty mappings} this is because I can't tell if the mapping contained a type or not when fetching a mapping. CompatRestIT. test {yaml=indices.get_mapping/20_missing_type/Existent and non-existent type returns 404 and the existing type} CompatRestIT. test {yaml=indices.get_mapping/20_missing_type/Existent and non-existent types returns 404 and the existing type} CompatRestIT. test {yaml=indices.get_mapping/20_missing_type/No type matching pattern returns 404} CompatRestIT. test {yaml=indices.get_mapping/20_missing_type/Non-existent type returns 404} failing - (not returning 404) - because type is always found (defaulted to _doc) CompatRestIT. test {yaml=indices.get_mapping/20_missing_type/Type missing when no types exist} CompatRestIT. test {yaml=indices.get_mapping/61_empty_with_types/Check empty mapping when getting all mappings via /_mapping} CompatRestIT. test {yaml=indices.get_template/11_basic_with_types/Get template with no mappings} CompatRestIT. test {yaml=indices.get_template/11_basic_with_types/Get template} CompatRestIT. test {yaml=indices.put_mapping/20_mix_typeless_typeful/PUT mapping with _doc on an index that has types} CompatRestIT. test {yaml=indices.put_mapping/20_mix_typeless_typeful/PUT mapping with typeless API on an index that has types} #47364 #41676
1 parent e457a92 commit b09bd5a

File tree

15 files changed

+1130
-4
lines changed

15 files changed

+1130
-4
lines changed

modules/rest-compatibility/src/main/java/org/elasticsearch/rest/action/admin/indices/RestCreateIndexActionV7.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class RestCreateIndexActionV7 extends RestCreateIndexAction {
4242
* Parameter that controls whether certain REST apis should include type names in their requests.
4343
*/
4444
public static final String INCLUDE_TYPE_NAME_PARAMETER = "include_type_name";
45+
public static final boolean DEFAULT_INCLUDE_TYPE_NAME_POLICY = false;
4546

4647
@Override
4748
public String getName() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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.rest.action.admin.indices;
21+
22+
import org.elasticsearch.Version;
23+
import org.elasticsearch.client.node.NodeClient;
24+
import org.elasticsearch.common.logging.DeprecationLogger;
25+
import org.elasticsearch.rest.RestRequest;
26+
27+
import java.io.IOException;
28+
import java.util.List;
29+
30+
import static org.elasticsearch.rest.RestRequest.Method.GET;
31+
32+
public class RestGetFieldMappingActionV7 extends RestGetFieldMappingAction {
33+
34+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestGetFieldMappingActionV7.class);
35+
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in get "
36+
+ "field mapping requests is deprecated. The parameter will be removed in the next major version.";
37+
38+
@Override
39+
public List<Route> routes() {
40+
return List.of(
41+
new Route(GET, "/_mapping/field/{fields}"),
42+
new Route(GET, "/{index}/_mapping/field/{fields}"),
43+
44+
new Route(GET, "/_mapping/{type}/field/{fields}"),
45+
new Route(GET, "/{index}/{type}/_mapping/field/{fields}"),
46+
new Route(GET, "/{index}/_mapping/{type}/field/{fields}")
47+
);
48+
}
49+
50+
@Override
51+
public String getName() {
52+
return "get_field_mapping_action_v7";
53+
}
54+
55+
@Override
56+
public Version compatibleWithVersion() {
57+
return Version.V_7_0_0;
58+
}
59+
60+
@Override
61+
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
62+
final String[] types = request.paramAsStringArrayOrEmptyIfAll("type");
63+
64+
boolean includeTypeName = request.paramAsBoolean(
65+
RestCreateIndexActionV7.INCLUDE_TYPE_NAME_PARAMETER,
66+
RestCreateIndexActionV7.DEFAULT_INCLUDE_TYPE_NAME_POLICY
67+
);
68+
if (includeTypeName == false && types.length > 0) {
69+
throw new IllegalArgumentException("Types cannot be specified unless include_type_name" + " is set to true.");
70+
}
71+
if (request.hasParam(RestCreateIndexActionV7.INCLUDE_TYPE_NAME_PARAMETER)) {
72+
request.param(RestCreateIndexActionV7.INCLUDE_TYPE_NAME_PARAMETER);
73+
deprecationLogger.deprecate("get_field_mapping_with_types", TYPES_DEPRECATION_MESSAGE);
74+
// todo compatible log about using INCLUDE_TYPE_NAME_PARAMETER
75+
}
76+
if (types.length > 0) {
77+
// todo compatible log about using types in path
78+
}
79+
if (request.hasParam("local")) {
80+
request.param("local");
81+
deprecationLogger.deprecate(
82+
"get_field_mapping_local",
83+
"Use [local] in get field mapping requests is deprecated. " + "The parameter will be removed in the next major version"
84+
);
85+
}
86+
return super.prepareRequest(request, client);
87+
}
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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.rest.action.admin.indices;
21+
22+
import org.elasticsearch.Version;
23+
import org.elasticsearch.client.node.NodeClient;
24+
import org.elasticsearch.common.logging.DeprecationLogger;
25+
import org.elasticsearch.rest.RestRequest;
26+
27+
import java.io.IOException;
28+
import java.util.List;
29+
30+
import static org.elasticsearch.rest.RestRequest.Method.GET;
31+
import static org.elasticsearch.rest.RestRequest.Method.HEAD;
32+
import static org.elasticsearch.rest.action.admin.indices.RestCreateIndexActionV7.DEFAULT_INCLUDE_TYPE_NAME_POLICY;
33+
import static org.elasticsearch.rest.action.admin.indices.RestCreateIndexActionV7.INCLUDE_TYPE_NAME_PARAMETER;
34+
35+
public class RestGetMappingActionV7 extends RestGetMappingAction {
36+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestGetMappingActionV7.class);
37+
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in get"
38+
+ " mapping requests is deprecated. The parameter will be removed in the next major version.";
39+
40+
@Override
41+
public List<Route> routes() {
42+
return List.of(
43+
new Route(GET, "/{index}/{type}/_mapping"),
44+
new Route(GET, "/{index}/_mappings/{type}"),
45+
new Route(GET, "/{index}/_mapping/{type}"),
46+
new Route(HEAD, "/{index}/_mapping/{type}"),
47+
new Route(GET, "/_mapping/{type}"),
48+
new Route(GET, "/_mapping"),
49+
new Route(GET, "/_mappings"),
50+
new Route(GET, "/{index}/_mapping"),
51+
new Route(GET, "/{index}/_mappings")
52+
);
53+
}
54+
55+
@Override
56+
public String getName() {
57+
return "get_mapping_action_v7";
58+
}
59+
60+
@Override
61+
public Version compatibleWithVersion() {
62+
return Version.V_7_0_0;
63+
}
64+
65+
@Override
66+
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
67+
final String[] types = request.paramAsStringArrayOrEmptyIfAll("type");
68+
boolean includeTypeName = request.paramAsBoolean(INCLUDE_TYPE_NAME_PARAMETER, DEFAULT_INCLUDE_TYPE_NAME_POLICY);
69+
70+
if (request.method().equals(HEAD)) {
71+
deprecationLogger.deprecate("get_mapping_with_types", "Type exists requests are deprecated, as types have been deprecated.");
72+
} else if (includeTypeName == false && types.length > 0) {
73+
throw new IllegalArgumentException(
74+
"Types cannot be provided in get mapping requests, unless" + " include_type_name is set to true."
75+
);
76+
}
77+
if (request.hasParam(INCLUDE_TYPE_NAME_PARAMETER)) {
78+
request.paramAsBoolean(INCLUDE_TYPE_NAME_PARAMETER, DEFAULT_INCLUDE_TYPE_NAME_POLICY);
79+
deprecationLogger.deprecate("get_mapping_with_types", TYPES_DEPRECATION_MESSAGE);
80+
}
81+
if (types.length > 0) {
82+
// todo compatible log about using types in path
83+
}
84+
return super.prepareRequest(request, client);
85+
}
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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.rest.action.admin.indices;
21+
22+
import org.elasticsearch.Version;
23+
import org.elasticsearch.client.node.NodeClient;
24+
import org.elasticsearch.common.logging.DeprecationLogger;
25+
import org.elasticsearch.common.xcontent.XContentHelper;
26+
import org.elasticsearch.index.mapper.MapperService;
27+
import org.elasticsearch.rest.RestRequest;
28+
29+
import java.io.IOException;
30+
import java.util.Collections;
31+
import java.util.List;
32+
import java.util.Map;
33+
34+
import static org.elasticsearch.rest.RestRequest.Method.POST;
35+
import static org.elasticsearch.rest.RestRequest.Method.PUT;
36+
import static org.elasticsearch.rest.action.admin.indices.RestCreateIndexActionV7.DEFAULT_INCLUDE_TYPE_NAME_POLICY;
37+
import static org.elasticsearch.rest.action.admin.indices.RestCreateIndexActionV7.INCLUDE_TYPE_NAME_PARAMETER;
38+
39+
public class RestPutMappingActionV7 extends RestPutMappingAction {
40+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestPutMappingActionV7.class);
41+
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in put "
42+
+ "mapping requests is deprecated. The parameter will be removed in the next major version.";
43+
44+
@Override
45+
public List<Route> routes() {
46+
return List.of(
47+
new Route(PUT, "/{index}/{type}/_mapping"),
48+
new Route(PUT, "/{index}/_mapping/{type}"),
49+
new Route(PUT, "/_mapping/{type}"),
50+
51+
new Route(POST, "/{index}/{type}/_mapping"),
52+
new Route(POST, "/{index}/_mapping/{type}"),
53+
new Route(POST, "/_mapping/{type}"),
54+
55+
// register the same paths, but with plural form _mappings
56+
new Route(PUT, "/{index}/{type}/_mappings"),
57+
new Route(PUT, "/{index}/_mappings/{type}"),
58+
new Route(PUT, "/_mappings/{type}"),
59+
60+
new Route(POST, "/{index}/{type}/_mappings"),
61+
new Route(POST, "/{index}/_mappings/{type}"),
62+
new Route(POST, "/_mappings/{type}"),
63+
64+
// no types in path, but type can be provided in body
65+
new Route(POST, "/{index}/_mapping/"),
66+
new Route(PUT, "/{index}/_mapping/"),
67+
new Route(POST, "/{index}/_mappings/"),
68+
new Route(PUT, "/{index}/_mappings/")
69+
);
70+
}
71+
72+
@Override
73+
public String getName() {
74+
return "put_mapping_action_v7";
75+
}
76+
77+
@Override
78+
public Version compatibleWithVersion() {
79+
return Version.V_7_0_0;
80+
}
81+
82+
@Override
83+
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
84+
final boolean includeTypeName = request.paramAsBoolean(INCLUDE_TYPE_NAME_PARAMETER, DEFAULT_INCLUDE_TYPE_NAME_POLICY);
85+
86+
String type = request.param("type");
87+
Map<String, Object> sourceAsMap = XContentHelper.convertToMap(request.requiredContent(), false, request.getXContentType()).v2();
88+
if (includeTypeName == false
89+
&& (type != null || MapperService.isMappingSourceTyped(MapperService.SINGLE_MAPPING_NAME, sourceAsMap))) {
90+
throw new IllegalArgumentException(
91+
"Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true."
92+
);
93+
}
94+
if (request.hasParam(INCLUDE_TYPE_NAME_PARAMETER)) {
95+
deprecationLogger.deprecate("put_mapping_with_types", TYPES_DEPRECATION_MESSAGE);
96+
}
97+
if (includeTypeName) {
98+
sourceAsMap = prepareMappingsV7(sourceAsMap, request);
99+
}
100+
return super.sendPutMappingRequest(request, client, sourceAsMap);
101+
}
102+
103+
private Map<String, Object> prepareMappingsV7(Map<String, Object> mappings, RestRequest request) {
104+
String typeName = mappings.keySet().iterator().next();
105+
@SuppressWarnings("unchecked")
106+
Map<String, Object> typedMappings = (Map<String, Object>) mappings.get(typeName);
107+
108+
// no matter what the type was, replace it with _doc, because the internal representation still uses single type `_doc`.
109+
return Collections.singletonMap(MapperService.SINGLE_MAPPING_NAME, typedMappings);
110+
}
111+
}

qa/rest-compat-tests/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ task copyRestTestsResources(type: Copy) {
1515
dependsOn ':distribution:bwc:minor:checkoutBwcBranch'
1616
}
1717

18+
//copyOverrides.dependsOn(copyRestTestsResources)
19+
processTestResources.dependsOn(copyRestTestsResources)
1820
integTest.dependsOn(copyRestTestsResources)
1921

2022
dependencies {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
setup:
3+
- do:
4+
indices.create:
5+
include_type_name: true
6+
index: test_index
7+
body:
8+
mappings:
9+
test_type:
10+
properties:
11+
text:
12+
type: text
13+
14+
---
15+
"Get field mapping with no index and type":
16+
17+
- do:
18+
indices.get_field_mapping:
19+
include_type_name: true
20+
fields: text
21+
#- match: {test_index.mappings.test_type.text.mapping.text.type: text}
22+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
23+
24+
---
25+
"Get field mapping by index only":
26+
- do:
27+
indices.get_field_mapping:
28+
include_type_name: true
29+
index: test_index
30+
fields: text
31+
# - match: {test_index.mappings.test_type.text.mapping.text.type: text}
32+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
33+
34+
---
35+
"Get field mapping by type & field":
36+
37+
- do:
38+
indices.get_field_mapping:
39+
include_type_name: true
40+
index: test_index
41+
type: test_type
42+
fields: text
43+
# - match: {test_index.mappings.test_type.text.mapping.text.type: text}
44+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
45+
46+
---
47+
"Get field mapping by type & field, with another field that doesn't exist":
48+
49+
- do:
50+
indices.get_field_mapping:
51+
include_type_name: true
52+
index: test_index
53+
type: test_type
54+
fields: [ text , text1 ]
55+
#- match: {test_index.mappings.test_type.text.mapping.text.type: text}
56+
# - is_false: test_index.mappings.test_type.text1
57+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
58+
- is_false: test_index.mappings._doc.text1
59+
60+
---
61+
"Get field mapping with include_defaults":
62+
63+
- do:
64+
indices.get_field_mapping:
65+
include_type_name: true
66+
index: test_index
67+
type: test_type
68+
fields: text
69+
include_defaults: true
70+
#- match: {test_index.mappings.test_type.text.mapping.text.type: text}
71+
# - match: {test_index.mappings.test_type.text.mapping.text.analyzer: default}
72+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
73+
- match: {test_index.mappings._doc.text.mapping.text.analyzer: default}
74+
75+
---
76+
"Get field mapping should work without index specifying type and fields":
77+
78+
- do:
79+
indices.get_field_mapping:
80+
include_type_name: true
81+
type: test_type
82+
fields: text
83+
# - match: {test_index.mappings.test_type.text.mapping.text.type: text}
84+
- match: {test_index.mappings._doc.text.mapping.text.type: text}
85+

0 commit comments

Comments
 (0)