Skip to content

Commit 7b46b5f

Browse files
author
Christoph Büscher
committed
Support 'include_type_name' in RestGetIndicesAction
This change adds support for the 'include_type_name' parameter for the indices.get API. This parameter, which defaults to `false` starting in 7.0, changes the response to not include the indices type names any longer. If the parameter is set in the request, we additionally emit a deprecation warning since using the parameter should be only temporarily necessary while adapting to the new response format and we will remove it with the next major version.
1 parent 3f7d6a9 commit 7b46b5f

File tree

10 files changed

+210
-33
lines changed

10 files changed

+210
-33
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.elasticsearch.common.xcontent.json.JsonXContent;
9090
import org.elasticsearch.common.xcontent.support.XContentMapValues;
9191
import org.elasticsearch.index.IndexSettings;
92+
import org.elasticsearch.index.mapper.MapperService;
9293
import org.elasticsearch.index.query.QueryBuilder;
9394
import org.elasticsearch.index.query.QueryBuilders;
9495
import org.elasticsearch.rest.RestStatus;
@@ -209,7 +210,7 @@ public void testCreateIndex() throws IOException {
209210
mappingBuilder.startObject().startObject("properties").startObject("field");
210211
mappingBuilder.field("type", "text");
211212
mappingBuilder.endObject().endObject().endObject();
212-
createIndexRequest.mapping("type_name", mappingBuilder);
213+
createIndexRequest.mapping(MapperService.SINGLE_MAPPING_NAME, mappingBuilder);
213214

214215
CreateIndexResponse createIndexResponse =
215216
execute(createIndexRequest, highLevelClient().indices()::create, highLevelClient().indices()::createAsync);
@@ -226,7 +227,7 @@ public void testCreateIndex() throws IOException {
226227
Map<String, Object> term = (Map) filter.get("term");
227228
assertEquals(2016, term.get("year"));
228229

229-
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.type_name.properties.field.type", getIndexResponse));
230+
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.properties.field.type", getIndexResponse));
230231
}
231232
}
232233

@@ -340,7 +341,7 @@ public void testGetIndex() throws IOException {
340341
.put(SETTING_NUMBER_OF_SHARDS, 1)
341342
.put(SETTING_NUMBER_OF_REPLICAS, 0)
342343
.build();
343-
String mappings = "\"type-1\":{\"properties\":{\"field-1\":{\"type\":\"integer\"}}}";
344+
String mappings = "\"_doc\":{\"properties\":{\"field-1\":{\"type\":\"integer\"}}}";
344345
createIndex(indexName, basicSettings, mappings);
345346

346347
GetIndexRequest getIndexRequest = new GetIndexRequest()
@@ -353,8 +354,8 @@ public void testGetIndex() throws IOException {
353354
assertEquals("1", getIndexResponse.getSetting(indexName, SETTING_NUMBER_OF_SHARDS));
354355
assertEquals("0", getIndexResponse.getSetting(indexName, SETTING_NUMBER_OF_REPLICAS));
355356
assertNotNull(getIndexResponse.getMappings().get(indexName));
356-
assertNotNull(getIndexResponse.getMappings().get(indexName).get("type-1"));
357-
Object o = getIndexResponse.getMappings().get(indexName).get("type-1").getSourceAsMap().get("properties");
357+
assertNotNull(getIndexResponse.getMappings().get(indexName).get("_doc"));
358+
Object o = getIndexResponse.getMappings().get(indexName).get("_doc").getSourceAsMap().get("properties");
358359
assertThat(o, instanceOf(Map.class));
359360
//noinspection unchecked
360361
assertThat(((Map<String, Object>) o).get("field-1"), instanceOf(Map.class));
@@ -370,7 +371,7 @@ public void testGetIndexWithDefaults() throws IOException {
370371
.put(SETTING_NUMBER_OF_SHARDS, 1)
371372
.put(SETTING_NUMBER_OF_REPLICAS, 0)
372373
.build();
373-
String mappings = "\"type-1\":{\"properties\":{\"field-1\":{\"type\":\"integer\"}}}";
374+
String mappings = "\"_doc\":{\"properties\":{\"field-1\":{\"type\":\"integer\"}}}";
374375
createIndex(indexName, basicSettings, mappings);
375376

376377
GetIndexRequest getIndexRequest = new GetIndexRequest()
@@ -384,8 +385,8 @@ public void testGetIndexWithDefaults() throws IOException {
384385
assertEquals("1", getIndexResponse.getSetting(indexName, SETTING_NUMBER_OF_SHARDS));
385386
assertEquals("0", getIndexResponse.getSetting(indexName, SETTING_NUMBER_OF_REPLICAS));
386387
assertNotNull(getIndexResponse.getMappings().get(indexName));
387-
assertNotNull(getIndexResponse.getMappings().get(indexName).get("type-1"));
388-
Object o = getIndexResponse.getMappings().get(indexName).get("type-1").getSourceAsMap().get("properties");
388+
assertNotNull(getIndexResponse.getMappings().get(indexName).get("_doc"));
389+
Object o = getIndexResponse.getMappings().get(indexName).get("_doc").getSourceAsMap().get("properties");
389390
assertThat(o, instanceOf(Map.class));
390391
assertThat(((Map<String, Object>) o).get("field-1"), instanceOf(Map.class));
391392
Map<String, Object> fieldMapping = (Map<String, Object>) ((Map<String, Object>) o).get("field-1");
@@ -408,7 +409,7 @@ public void testPutMapping() throws IOException {
408409
createIndex(indexName, Settings.EMPTY);
409410

410411
PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
411-
putMappingRequest.type("type_name");
412+
putMappingRequest.type("_doc");
412413
XContentBuilder mappingBuilder = JsonXContent.contentBuilder();
413414
mappingBuilder.startObject().startObject("properties").startObject("field");
414415
mappingBuilder.field("type", "text");
@@ -420,7 +421,7 @@ public void testPutMapping() throws IOException {
420421
assertTrue(putMappingResponse.isAcknowledged());
421422

422423
Map<String, Object> getIndexResponse = getAsMap(indexName);
423-
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.type_name.properties.field.type", getIndexResponse));
424+
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.properties.field.type", getIndexResponse));
424425
}
425426

426427
public void testGetMapping() throws IOException {
@@ -440,7 +441,7 @@ public void testGetMapping() throws IOException {
440441
assertTrue(putMappingResponse.isAcknowledged());
441442

442443
Map<String, Object> getIndexResponse = getAsMap(indexName);
443-
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings._doc.properties.field.type", getIndexResponse));
444+
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.properties.field.type", getIndexResponse));
444445

445446
GetMappingsRequest request = new GetMappingsRequest()
446447
.indices(indexName)

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@
7070
import org.elasticsearch.action.support.IndicesOptions;
7171
import org.elasticsearch.action.support.master.AcknowledgedResponse;
7272
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
73-
import org.elasticsearch.client.indices.FreezeIndexRequest;
7473
import org.elasticsearch.client.GetAliasesResponse;
7574
import org.elasticsearch.client.RequestOptions;
7675
import org.elasticsearch.client.RestHighLevelClient;
7776
import org.elasticsearch.client.SyncedFlushResponse;
77+
import org.elasticsearch.client.core.ShardsAcknowledgedResponse;
78+
import org.elasticsearch.client.indices.FreezeIndexRequest;
7879
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
7980
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
8081
import org.elasticsearch.client.indices.UnfreezeIndexRequest;
81-
import org.elasticsearch.client.core.ShardsAcknowledgedResponse;
8282
import org.elasticsearch.cluster.metadata.AliasMetaData;
8383
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
8484
import org.elasticsearch.cluster.metadata.MappingMetaData;
@@ -1249,7 +1249,7 @@ public void testGetIndex() throws Exception {
12491249
Settings settings = Settings.builder().put("number_of_shards", 3).build();
12501250
String mappings = "{\"properties\":{\"field-1\":{\"type\":\"integer\"}}}";
12511251
CreateIndexResponse createIndexResponse = client.indices().create(
1252-
new CreateIndexRequest("index", settings).mapping("doc", mappings, XContentType.JSON),
1252+
new CreateIndexRequest("index", settings).mapping("_doc", mappings, XContentType.JSON),
12531253
RequestOptions.DEFAULT);
12541254
assertTrue(createIndexResponse.isAcknowledged());
12551255
}
@@ -1272,7 +1272,7 @@ public void testGetIndex() throws Exception {
12721272

12731273
// tag::get-index-response
12741274
ImmutableOpenMap<String, MappingMetaData> indexMappings = getIndexResponse.getMappings().get("index"); // <1>
1275-
Map<String, Object> indexTypeMappings = indexMappings.get("doc").getSourceAsMap(); // <2>
1275+
Map<String, Object> indexTypeMappings = indexMappings.get("_doc").getSourceAsMap(); // <2>
12761276
List<AliasMetaData> indexAliases = getIndexResponse.getAliases().get("index"); // <3>
12771277
String numberOfShardsString = getIndexResponse.getSetting("index", "index.number_of_shards"); // <4>
12781278
Settings indexSettings = getIndexResponse.getSettings().get("index"); // <5>

rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
}
1414
},
1515
"params":{
16+
"include_type_name": {
17+
"type" : "boolean",
18+
"description" : "Whether to add the type name to the response (default: false)"
19+
},
1620
"local":{
1721
"type":"boolean",
1822
"description":"Return local information, do not retrieve the state from master node (default: false)"

rest-api-spec/src/main/resources/rest-api-spec/test/indices.get/10_basic.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ setup:
5252
- is_true: test_index.settings
5353
- is_true: test_index.mappings
5454

55+
---
56+
"Test include_type_name":
57+
- skip:
58+
version: " - 6.99.99"
59+
reason: the include_type_name parameter is not backported to pre 7.0 versions yet
60+
61+
- do:
62+
indices.get:
63+
include_type_name: true
64+
index: test_index
65+
66+
- is_true: test_index.mappings
67+
- is_true: test_index.mappings.type_1
68+
69+
- do:
70+
indices.get:
71+
include_type_name: false
72+
index: test_index
73+
74+
- is_true: test_index.mappings
75+
- is_false: test_index.mappings.type_1
76+
77+
- do:
78+
indices.get:
79+
index: test_index
80+
81+
- is_true: test_index.mappings
82+
- is_false: test_index.mappings.type_1
83+
5584
---
5685
"Get index infos should work for wildcards":
5786

server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexResponse.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.elasticsearch.action.admin.indices.get;
2121

2222
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
23+
2324
import org.apache.lucene.util.CollectionUtil;
2425
import org.elasticsearch.Version;
2526
import org.elasticsearch.action.ActionResponse;
@@ -34,13 +35,15 @@
3435
import org.elasticsearch.common.xcontent.XContentBuilder;
3536
import org.elasticsearch.common.xcontent.XContentParser;
3637
import org.elasticsearch.common.xcontent.XContentParser.Token;
38+
import org.elasticsearch.index.mapper.MapperService;
3739

3840
import java.io.IOException;
3941
import java.util.ArrayList;
4042
import java.util.Arrays;
4143
import java.util.Collections;
4244
import java.util.Comparator;
4345
import java.util.List;
46+
import java.util.Map;
4447
import java.util.Objects;
4548

4649
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
@@ -249,15 +252,29 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
249252
}
250253
builder.endObject();
251254

252-
builder.startObject("mappings");
253255
ImmutableOpenMap<String, MappingMetaData> indexMappings = mappings.get(index);
254-
if (indexMappings != null) {
255-
for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexMappings) {
256-
builder.field(typeEntry.key);
257-
builder.map(typeEntry.value.sourceAsMap());
256+
boolean includeTypeName = params.paramAsBoolean("include_type_name", false);
257+
if (includeTypeName) {
258+
builder.startObject("mappings");
259+
if (indexMappings != null) {
260+
for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexMappings) {
261+
builder.field(typeEntry.key);
262+
builder.map(typeEntry.value.sourceAsMap());
263+
}
264+
}
265+
builder.endObject();
266+
} else {
267+
if (indexMappings != null && indexMappings.size() > 0) {
268+
builder.field("mappings");
269+
for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexMappings) {
270+
builder.map(typeEntry.value.sourceAsMap());
271+
}
272+
} else {
273+
// we always want to output a mappings object, even if empty
274+
builder.startObject("mappings");
275+
builder.endObject();
258276
}
259277
}
260-
builder.endObject();
261278

262279
builder.startObject("settings");
263280
Settings indexSettings = settings.get(index);
@@ -291,6 +308,16 @@ private static List<AliasMetaData> parseAliases(XContentParser parser) throws IO
291308
}
292309

293310
private static ImmutableOpenMap<String, MappingMetaData> parseMappings(XContentParser parser) throws IOException {
311+
ImmutableOpenMap.Builder<String, MappingMetaData> indexMappings = ImmutableOpenMap.builder();
312+
// We start at START_OBJECT since parseIndexEntry ensures that
313+
Map<String, Object> map = parser.map();
314+
if (map.isEmpty() == false) {
315+
indexMappings.put(MapperService.SINGLE_MAPPING_NAME, new MappingMetaData(MapperService.SINGLE_MAPPING_NAME, map));
316+
}
317+
return indexMappings.build();
318+
}
319+
320+
private static ImmutableOpenMap<String, MappingMetaData> parseMappingsWithTypes(XContentParser parser) throws IOException {
294321
ImmutableOpenMap.Builder<String, MappingMetaData> indexMappings = ImmutableOpenMap.builder();
295322
// We start at START_OBJECT since parseIndexEntry ensures that
296323
while (parser.nextToken() != Token.END_OBJECT) {
@@ -306,7 +333,7 @@ private static ImmutableOpenMap<String, MappingMetaData> parseMappings(XContentP
306333
return indexMappings.build();
307334
}
308335

309-
private static IndexEntry parseIndexEntry(XContentParser parser) throws IOException {
336+
private static IndexEntry parseIndexEntry(XContentParser parser, boolean legacyWithTypes) throws IOException {
310337
List<AliasMetaData> indexAliases = null;
311338
ImmutableOpenMap<String, MappingMetaData> indexMappings = null;
312339
Settings indexSettings = null;
@@ -321,7 +348,11 @@ private static IndexEntry parseIndexEntry(XContentParser parser) throws IOExcept
321348
indexAliases = parseAliases(parser);
322349
break;
323350
case "mappings":
324-
indexMappings = parseMappings(parser);
351+
if (legacyWithTypes) {
352+
indexMappings = parseMappingsWithTypes(parser);
353+
} else {
354+
indexMappings = parseMappings(parser);
355+
}
325356
break;
326357
case "settings":
327358
indexSettings = Settings.fromXContent(parser);
@@ -355,6 +386,10 @@ private static class IndexEntry {
355386
}
356387

357388
public static GetIndexResponse fromXContent(XContentParser parser) throws IOException {
389+
return fromXContent(parser, false);
390+
}
391+
392+
public static GetIndexResponse fromXContent(XContentParser parser, boolean legacyWithTypes) throws IOException {
358393
ImmutableOpenMap.Builder<String, List<AliasMetaData>> aliases = ImmutableOpenMap.builder();
359394
ImmutableOpenMap.Builder<String, ImmutableOpenMap<String, MappingMetaData>> mappings = ImmutableOpenMap.builder();
360395
ImmutableOpenMap.Builder<String, Settings> settings = ImmutableOpenMap.builder();
@@ -372,7 +407,7 @@ public static GetIndexResponse fromXContent(XContentParser parser) throws IOExce
372407
// we assume this is an index entry
373408
String indexName = parser.currentName();
374409
indices.add(indexName);
375-
IndexEntry indexEntry = parseIndexEntry(parser);
410+
IndexEntry indexEntry = parseIndexEntry(parser, legacyWithTypes);
376411
// make the order deterministic
377412
CollectionUtil.timSort(indexEntry.indexAliases, Comparator.comparing(AliasMetaData::alias));
378413
aliases.put(indexName, Collections.unmodifiableList(indexEntry.indexAliases));

server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetIndicesAction.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
package org.elasticsearch.rest.action.admin.indices;
2121

2222

23+
import org.apache.logging.log4j.LogManager;
2324
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
2425
import org.elasticsearch.action.support.IndicesOptions;
2526
import org.elasticsearch.client.node.NodeClient;
2627
import org.elasticsearch.common.Strings;
28+
import org.elasticsearch.common.logging.DeprecationLogger;
2729
import org.elasticsearch.common.settings.Settings;
2830
import org.elasticsearch.rest.BaseRestHandler;
2931
import org.elasticsearch.rest.RestController;
@@ -41,6 +43,9 @@
4143
*/
4244
public class RestGetIndicesAction extends BaseRestHandler {
4345

46+
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(RestGetIndicesAction.class));
47+
static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using `include_type_name` in get indices requests is deprecated. "
48+
+ "The parameter will be removed in the next major version.";
4449

4550
public RestGetIndicesAction(
4651
final Settings settings,
@@ -58,6 +63,10 @@ public String getName() {
5863
@Override
5964
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
6065
String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
66+
// starting with 7.0 we don't include types by default in the response
67+
if (request.hasParam("include_type_name")) {
68+
deprecationLogger.deprecatedAndMaybeLog("get_indices_with_types", TYPES_DEPRECATION_MESSAGE);
69+
}
6170
final GetIndexRequest getIndexRequest = new GetIndexRequest();
6271
getIndexRequest.indices(indices);
6372
getIndexRequest.indicesOptions(IndicesOptions.fromRequest(request, getIndexRequest.indicesOptions()));

server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetMappingAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
package org.elasticsearch.rest.action.admin.indices;
2121

2222
import com.carrotsearch.hppc.cursors.ObjectCursor;
23-
import org.apache.logging.log4j.Logger;
23+
2424
import org.apache.logging.log4j.LogManager;
25+
import org.apache.logging.log4j.Logger;
2526
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
2627
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
2728
import org.elasticsearch.action.support.IndicesOptions;

0 commit comments

Comments
 (0)