Skip to content

Commit a07accd

Browse files
committed
First pass at PUT and GET IndexTemplates.
For HLRC support PutIndexTemplateRequest now includes checks to change the toXContent format if it looks like custom doc types are used. Removed getTypedTemplate method that violated REST-api contract and added parameter to the GetIndexTemplatesRequest for the HLRC client to request typed templates Removed doc types from HLRC documentation examples PITR.toXContent() now strips type name from `mapping->_doc->properties` to make untyped REST requests with include_type_name=false Tidied PutIndexTemplateRequest inconsistencies - some public methods ran mappings through the `internalMappings` validation and some didn’t. All do now. Added new APIs to take mappings with no doc types embedded in mapping definition blobs which are apis we will document in HLRC. The legacy `source` and `mapping` apis that support type names in the blob are all marked as deprecated.
1 parent 1a41d84 commit a07accd

File tree

18 files changed

+452
-107
lines changed

18 files changed

+452
-107
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) thro
351351
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
352352
RequestConverters.Params params = new RequestConverters.Params(request);
353353
params.withMasterTimeout(putIndexTemplateRequest.masterNodeTimeout());
354+
params.putParam("include_type_name", Boolean.toString(putIndexTemplateRequest.isCustomTyped()));
354355
if (putIndexTemplateRequest.create()) {
355356
params.putParam("create", Boolean.TRUE.toString());
356357
}
@@ -395,6 +396,9 @@ static Request getTemplates(GetIndexTemplatesRequest getIndexTemplatesRequest) {
395396
final RequestConverters.Params params = new RequestConverters.Params(request);
396397
params.withLocal(getIndexTemplatesRequest.isLocal());
397398
params.withMasterTimeout(getIndexTemplatesRequest.getMasterNodeTimeout());
399+
if(getIndexTemplatesRequest.includeTypeNamesInResponse() == false) {
400+
params.putParam("include_type_name", Boolean.toString(getIndexTemplatesRequest.includeTypeNamesInResponse()));
401+
}
398402
return request;
399403
}
400404

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class GetIndexTemplatesRequest implements Validatable {
4040

4141
private TimeValue masterNodeTimeout = TimedRequest.DEFAULT_MASTER_NODE_TIMEOUT;
4242
private boolean local = false;
43+
private boolean includeTypeNamesInResponse = true;
4344

4445
/**
4546
* Create a request to read the content of one or more index templates. If no template names are provided, all templates will be read
@@ -96,4 +97,13 @@ public boolean isLocal() {
9697
public void setLocal(boolean local) {
9798
this.local = local;
9899
}
100+
101+
102+
public boolean includeTypeNamesInResponse() {
103+
return includeTypeNamesInResponse;
104+
}
105+
106+
public void includeTypeNamesInResponse(boolean includeTypeNamesInResponse) {
107+
this.includeTypeNamesInResponse = includeTypeNamesInResponse;
108+
}
99109
}

client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
8181
import org.elasticsearch.common.ValidationException;
8282
import org.elasticsearch.common.bytes.BytesArray;
83+
import org.elasticsearch.common.collect.ImmutableOpenMap;
84+
import org.elasticsearch.common.compress.CompressedXContent;
8385
import org.elasticsearch.common.settings.Setting;
8486
import org.elasticsearch.common.settings.Settings;
8587
import org.elasticsearch.common.unit.ByteSizeUnit;
@@ -1229,32 +1231,74 @@ public void testIndexPutSettingNonExistent() throws IOException {
12291231
+ "reason=unknown setting [index.no_idea_what_you_are_talking_about] please check that any required plugins are installed, "
12301232
+ "or check the breaking changes documentation for removed settings]"));
12311233
}
1234+
12321235

1233-
@SuppressWarnings("unchecked")
1236+
@SuppressWarnings("deprecation")
1237+
public void testPutCustomTypedTemplateHasWarnings() throws Exception {
1238+
PutIndexTemplateRequest putTemplateRequest = new PutIndexTemplateRequest()
1239+
.name("my-template")
1240+
.patterns(Arrays.asList("pattern-1", "name-*"))
1241+
.order(10)
1242+
.create(randomBoolean())
1243+
.mapping("custom_doc_type", "host_name", "type=keyword", "description", "type=text");
1244+
1245+
1246+
ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(putTemplateRequest,
1247+
highLevelClient().indices()::putTemplate, highLevelClient().indices()::putTemplateAsync));
1248+
assertThat(exception.getDetailedMessage(), containsString("[types removal]"));
1249+
assertThat(exception.status(), equalTo(RestStatus.OK));
1250+
}
1251+
1252+
@SuppressWarnings({"unchecked","deprecation"})
12341253
public void testPutTemplate() throws Exception {
12351254
PutIndexTemplateRequest putTemplateRequest = new PutIndexTemplateRequest()
12361255
.name("my-template")
12371256
.patterns(Arrays.asList("pattern-1", "name-*"))
12381257
.order(10)
12391258
.create(randomBoolean())
12401259
.settings(Settings.builder().put("number_of_shards", "3").put("number_of_replicas", "0"))
1241-
.mapping("doc", "host_name", "type=keyword", "description", "type=text")
1260+
.simplifiedMapping("host_name", "type=keyword", "description", "type=text")
12421261
.alias(new Alias("alias-1").indexRouting("abc")).alias(new Alias("{index}-write").searchRouting("xyz"));
12431262

1263+
IndicesClient indicesClient = highLevelClient().indices();
12441264
AcknowledgedResponse putTemplateResponse = execute(putTemplateRequest,
1245-
highLevelClient().indices()::putTemplate, highLevelClient().indices()::putTemplateAsync);
1265+
indicesClient::putTemplate, indicesClient::putTemplateAsync);
12461266
assertThat(putTemplateResponse.isAcknowledged(), equalTo(true));
12471267

1248-
Map<String, Object> templates = getAsMap("/_template/my-template");
1268+
1269+
Map<String, Object> templates = getAsMap("/_template/my-template?include_type_name=false");
12491270
assertThat(templates.keySet(), hasSize(1));
12501271
assertThat(extractValue("my-template.order", templates), equalTo(10));
12511272
assertThat(extractRawValues("my-template.index_patterns", templates), contains("pattern-1", "name-*"));
12521273
assertThat(extractValue("my-template.settings.index.number_of_shards", templates), equalTo("3"));
12531274
assertThat(extractValue("my-template.settings.index.number_of_replicas", templates), equalTo("0"));
1254-
assertThat(extractValue("my-template.mappings.doc.properties.host_name.type", templates), equalTo("keyword"));
1255-
assertThat(extractValue("my-template.mappings.doc.properties.description.type", templates), equalTo("text"));
1275+
assertThat(extractValue("my-template.mappings.properties.host_name.type", templates), equalTo("keyword"));
1276+
assertThat(extractValue("my-template.mappings.properties.description.type", templates), equalTo("text"));
12561277
assertThat((Map<String, String>) extractValue("my-template.aliases.alias-1", templates), hasEntry("index_routing", "abc"));
12571278
assertThat((Map<String, String>) extractValue("my-template.aliases.{index}-write", templates), hasEntry("search_routing", "xyz"));
1279+
1280+
// Test the typed version of the template has the default doc type name
1281+
templates = getAsMap("/_template/my-template");
1282+
assertThat(extractValue("my-template.mappings._doc.properties.host_name.type", templates), equalTo("keyword"));
1283+
assertThat(extractValue("my-template.mappings._doc.properties.description.type", templates), equalTo("text"));
1284+
1285+
// Now test with the getIndexTemplatesResponse untyped mappings
1286+
GetIndexTemplatesRequest untypedGet = new GetIndexTemplatesRequest("my-template");
1287+
untypedGet.includeTypeNamesInResponse(false);
1288+
GetIndexTemplatesResponse getTemplate1 = execute(untypedGet, indicesClient::getTemplate, indicesClient::getTemplateAsync);
1289+
IndexTemplateMetaData typelessTemplate = getTemplate1.getIndexTemplates().get(0);
1290+
ImmutableOpenMap<String, CompressedXContent> mappings = typelessTemplate.getMappings();
1291+
assertNull(mappings.get("_doc"));
1292+
assertNotNull(mappings.get("properties"));
1293+
1294+
// Now test with the getIndexTemplatesResponse typed mappings
1295+
GetIndexTemplatesRequest typedMappingRequest = new GetIndexTemplatesRequest("my-template");
1296+
typedMappingRequest.includeTypeNamesInResponse(true);
1297+
getTemplate1 = execute(typedMappingRequest, indicesClient::getTemplate, indicesClient::getTemplateAsync);
1298+
IndexTemplateMetaData typedTemplate = getTemplate1.getIndexTemplates().get(0);
1299+
mappings = typedTemplate.getMappings();
1300+
assertNotNull(mappings.get("_doc"));
1301+
assertNull(mappings.get("properties"));
12581302
}
12591303

12601304
public void testPutTemplateBadRequests() throws Exception {

client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,14 +817,16 @@ public void testPutTemplateRequest() throws Exception {
817817
if (ESTestCase.randomBoolean()) {
818818
putTemplateRequest.settings(Settings.builder().put("setting-" + ESTestCase.randomInt(), ESTestCase.randomTimeValue()));
819819
}
820+
Map<String, String> expectedParams = new HashMap<>();
821+
expectedParams.put("include_type_name", "false");
820822
if (ESTestCase.randomBoolean()) {
821823
putTemplateRequest.mapping("doc-" + ESTestCase.randomInt(),
822824
"field-" + ESTestCase.randomInt(), "type=" + ESTestCase.randomFrom("text", "keyword"));
825+
expectedParams.put("include_type_name", "true"); // Custom doc types will set the "include_type_name" = true flag
823826
}
824827
if (ESTestCase.randomBoolean()) {
825828
putTemplateRequest.alias(new Alias("alias-" + ESTestCase.randomInt()));
826829
}
827-
Map<String, String> expectedParams = new HashMap<>();
828830
if (ESTestCase.randomBoolean()) {
829831
expectedParams.put("create", Boolean.TRUE.toString());
830832
putTemplateRequest.create(true);

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,31 +2119,31 @@ public void testPutTemplate() throws Exception {
21192119

21202120
{
21212121
// tag::put-template-request-mappings-json
2122-
request.mapping("_doc", // <1>
2122+
request.mappingNoDocType(
21232123
"{\n" +
2124-
" \"_doc\": {\n" +
2125-
" \"properties\": {\n" +
2126-
" \"message\": {\n" +
2127-
" \"type\": \"text\"\n" +
2128-
" }\n" +
2124+
" \"properties\": {\n" +
2125+
" \"message\": {\n" +
2126+
" \"type\": \"text\"\n" +
21292127
" }\n" +
21302128
" }\n" +
2131-
"}", // <2>
2129+
"}", // <1>
21322130
XContentType.JSON);
21332131
// end::put-template-request-mappings-json
21342132
assertTrue(client.indices().putTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
21352133
}
21362134
{
21372135
//tag::put-template-request-mappings-map
21382136
Map<String, Object> jsonMap = new HashMap<>();
2139-
Map<String, Object> message = new HashMap<>();
2140-
message.put("type", "text");
2141-
Map<String, Object> properties = new HashMap<>();
2142-
properties.put("message", message);
2143-
Map<String, Object> mapping = new HashMap<>();
2144-
mapping.put("properties", properties);
2145-
jsonMap.put("_doc", mapping);
2146-
request.mapping("_doc", jsonMap); // <1>
2137+
{
2138+
Map<String, Object> properties = new HashMap<>();
2139+
{
2140+
Map<String, Object> message = new HashMap<>();
2141+
message.put("type", "text");
2142+
properties.put("message", message);
2143+
}
2144+
jsonMap.put("properties", properties);
2145+
}
2146+
request.mapping(jsonMap); // <1>
21472147
//end::put-template-request-mappings-map
21482148
assertTrue(client.indices().putTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
21492149
}
@@ -2152,28 +2152,24 @@ public void testPutTemplate() throws Exception {
21522152
XContentBuilder builder = XContentFactory.jsonBuilder();
21532153
builder.startObject();
21542154
{
2155-
builder.startObject("_doc");
2155+
builder.startObject("properties");
21562156
{
2157-
builder.startObject("properties");
2157+
builder.startObject("message");
21582158
{
2159-
builder.startObject("message");
2160-
{
2161-
builder.field("type", "text");
2162-
}
2163-
builder.endObject();
2159+
builder.field("type", "text");
21642160
}
21652161
builder.endObject();
21662162
}
21672163
builder.endObject();
21682164
}
21692165
builder.endObject();
2170-
request.mapping("_doc", builder); // <1>
2166+
request.mappingNoDocType(builder); // <1>
21712167
//end::put-template-request-mappings-xcontent
21722168
assertTrue(client.indices().putTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
21732169
}
21742170
{
21752171
//tag::put-template-request-mappings-shortcut
2176-
request.mapping("_doc", "message", "type=text"); // <1>
2172+
request.simplifiedMapping("message", "type=text"); // <1>
21772173
//end::put-template-request-mappings-shortcut
21782174
assertTrue(client.indices().putTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
21792175
}
@@ -2192,7 +2188,7 @@ public void testPutTemplate() throws Exception {
21922188
// end::put-template-request-version
21932189

21942190
// tag::put-template-whole-source
2195-
request.source("{\n" +
2191+
request.sourceNoDocTypes("{\n" +
21962192
" \"index_patterns\": [\n" +
21972193
" \"log-*\",\n" +
21982194
" \"pattern-1\"\n" +
@@ -2202,11 +2198,9 @@ public void testPutTemplate() throws Exception {
22022198
" \"number_of_shards\": 1\n" +
22032199
" },\n" +
22042200
" \"mappings\": {\n" +
2205-
" \"_doc\": {\n" +
2206-
" \"properties\": {\n" +
2207-
" \"message\": {\n" +
2208-
" \"type\": \"text\"\n" +
2209-
" }\n" +
2201+
" \"properties\": {\n" +
2202+
" \"message\": {\n" +
2203+
" \"type\": \"text\"\n" +
22102204
" }\n" +
22112205
" }\n" +
22122206
" },\n" +
@@ -2269,13 +2263,11 @@ public void testGetTemplates() throws Exception {
22692263
PutIndexTemplateRequest putRequest = new PutIndexTemplateRequest("my-template");
22702264
putRequest.patterns(Arrays.asList("pattern-1", "log-*"));
22712265
putRequest.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 1));
2272-
putRequest.mapping("_doc",
2266+
putRequest.mappingNoDocType(
22732267
"{\n" +
2274-
" \"_doc\": {\n" +
2275-
" \"properties\": {\n" +
2276-
" \"message\": {\n" +
2277-
" \"type\": \"text\"\n" +
2278-
" }\n" +
2268+
" \"properties\": {\n" +
2269+
" \"message\": {\n" +
2270+
" \"type\": \"text\"\n" +
22792271
" }\n" +
22802272
" }\n" +
22812273
"}", XContentType.JSON);

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public void onFailure(Exception e) {
278278
client.security().putUserAsync(request, RequestOptions.DEFAULT, listener); // <1>
279279
// end::put-user-execute-async
280280

281-
assertTrue(latch.await(30L, TimeUnit.SECONDS));
281+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
282282
}
283283
}
284284

docs/java-rest/high-level/indices/put_template.asciidoc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ template's patterns.
3939
--------------------------------------------------
4040
include-tagged::{doc-tests-file}[{api}-request-mappings-json]
4141
--------------------------------------------------
42-
<1> The type to define
43-
<2> The mapping for this type, provided as a JSON string
42+
<1> The mapping for this type, provided as a JSON string
4443

4544
The mapping source can be provided in different ways in addition to the
4645
`String` example shown above:

docs/reference/indices/templates.asciidoc

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,23 @@ For example:
1616

1717
[source,js]
1818
--------------------------------------------------
19-
PUT _template/template_1
19+
PUT _template/template_1?include_type_name=false
2020
{
2121
"index_patterns": ["te*", "bar*"],
2222
"settings": {
2323
"number_of_shards": 1
2424
},
2525
"mappings": {
26-
"_doc": {
27-
"_source": {
28-
"enabled": false
26+
"_source": {
27+
"enabled": false
28+
},
29+
"properties": {
30+
"host_name": {
31+
"type": "keyword"
2932
},
30-
"properties": {
31-
"host_name": {
32-
"type": "keyword"
33-
},
34-
"created_at": {
35-
"type": "date",
36-
"format": "EEE MMM dd HH:mm:ss Z yyyy"
37-
}
33+
"created_at": {
34+
"type": "date",
35+
"format": "EEE MMM dd HH:mm:ss Z yyyy"
3836
}
3937
}
4038
}
@@ -50,6 +48,11 @@ Defines a template named `template_1`, with a template pattern of `te*` or `bar*
5048
The settings and mappings will be applied to any index name that matches
5149
the `te*` or `bar*` pattern.
5250

51+
NOTE: This mapping example uses a "typeless" format new to 7.0.
52+
Previous versions of elasticsearch included document type names in the "mappings"section
53+
but here we have set the `include_type_name=false` parameter in the URL to use the new format.
54+
The old approach of including type names in mappings is still supported but is now deprecated.
55+
5356
It is also possible to include aliases in an index template as follows:
5457

5558
[source,js]
@@ -149,31 +152,27 @@ orders overriding them. For example:
149152

150153
[source,js]
151154
--------------------------------------------------
152-
PUT /_template/template_1
155+
PUT /_template/template_1?include_type_name=false
153156
{
154157
"index_patterns" : ["*"],
155158
"order" : 0,
156159
"settings" : {
157160
"number_of_shards" : 1
158161
},
159162
"mappings" : {
160-
"_doc" : {
161-
"_source" : { "enabled" : false }
162-
}
163+
"_source" : { "enabled" : false }
163164
}
164165
}
165166
166-
PUT /_template/template_2
167+
PUT /_template/template_2?include_type_name=false
167168
{
168169
"index_patterns" : ["te*"],
169170
"order" : 1,
170171
"settings" : {
171172
"number_of_shards" : 1
172173
},
173174
"mappings" : {
174-
"_doc" : {
175-
"_source" : { "enabled" : true }
176-
}
175+
"_source" : { "enabled" : true }
177176
}
178177
}
179178
--------------------------------------------------
@@ -189,6 +188,11 @@ order templates, with lower order templates providing the basis.
189188
NOTE: Multiple matching templates with the same order value will
190189
result in a non-deterministic merging order.
191190

191+
NOTE: This mapping example uses the "typeless" format new to 7.0.
192+
Previous versions of elasticsearch included document type names in the "mappings"section
193+
but here we have set the `include_type_name=false` parameter in the URL to use the new format.
194+
The old approach of including type names in mappings is still supported but is now deprecated.
195+
192196
[float]
193197
[[versioning-templates]]
194198
=== Template Versioning

0 commit comments

Comments
 (0)