diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java index 0a2830e55fce8..6fefc3f2579a1 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java @@ -264,58 +264,64 @@ public ClusterState execute(ClusterState currentState) throws Exception { customs.put(entry.getKey(), entry.getValue()); } - // apply templates, merging the mappings into the request mapping if exists - for (IndexTemplateMetaData template : templates) { - templateNames.add(template.getName()); - for (ObjectObjectCursor cursor : template.mappings()) { - String mappingString = cursor.value.string(); - if (mappings.containsKey(cursor.key)) { - XContentHelper.mergeDefaults(mappings.get(cursor.key), + final Index shrinkFromIndex = request.shrinkFrom(); + + if (shrinkFromIndex == null) { + // apply templates, merging the mappings into the request mapping if exists + for (IndexTemplateMetaData template : templates) { + templateNames.add(template.getName()); + for (ObjectObjectCursor cursor : template.mappings()) { + String mappingString = cursor.value.string(); + if (mappings.containsKey(cursor.key)) { + XContentHelper.mergeDefaults(mappings.get(cursor.key), MapperService.parseMapping(xContentRegistry, mappingString)); - } else { - mappings.put(cursor.key, - MapperService.parseMapping(xContentRegistry, mappingString)); - } - } - // handle custom - for (ObjectObjectCursor cursor : template.customs()) { - String type = cursor.key; - IndexMetaData.Custom custom = cursor.value; - IndexMetaData.Custom existing = customs.get(type); - if (existing == null) { - customs.put(type, custom); - } else { - IndexMetaData.Custom merged = existing.mergeWith(custom); - customs.put(type, merged); - } - } - //handle aliases - for (ObjectObjectCursor cursor : template.aliases()) { - AliasMetaData aliasMetaData = cursor.value; - //if an alias with same name came with the create index request itself, - // ignore this one taken from the index template - if (request.aliases().contains(new Alias(aliasMetaData.alias()))) { - continue; + } else { + mappings.put(cursor.key, + MapperService.parseMapping(xContentRegistry, mappingString)); + } } - //if an alias with same name was already processed, ignore this one - if (templatesAliases.containsKey(cursor.key)) { - continue; + // handle custom + for (ObjectObjectCursor cursor : template.customs()) { + String type = cursor.key; + IndexMetaData.Custom custom = cursor.value; + IndexMetaData.Custom existing = customs.get(type); + if (existing == null) { + customs.put(type, custom); + } else { + IndexMetaData.Custom merged = existing.mergeWith(custom); + customs.put(type, merged); + } } - - //Allow templatesAliases to be templated by replacing a token with the name of the index that we are applying it to - if (aliasMetaData.alias().contains("{index}")) { - String templatedAlias = aliasMetaData.alias().replace("{index}", request.index()); - aliasMetaData = AliasMetaData.newAliasMetaData(aliasMetaData, templatedAlias); + //handle aliases + for (ObjectObjectCursor cursor : template.aliases()) { + AliasMetaData aliasMetaData = cursor.value; + //if an alias with same name came with the create index request itself, + // ignore this one taken from the index template + if (request.aliases().contains(new Alias(aliasMetaData.alias()))) { + continue; + } + //if an alias with same name was already processed, ignore this one + if (templatesAliases.containsKey(cursor.key)) { + continue; + } + + //Allow templatesAliases to be templated by replacing a token with the name of the index that we are applying it to + if (aliasMetaData.alias().contains("{index}")) { + String templatedAlias = aliasMetaData.alias().replace("{index}", request.index()); + aliasMetaData = AliasMetaData.newAliasMetaData(aliasMetaData, templatedAlias); + } + + aliasValidator.validateAliasMetaData(aliasMetaData, request.index(), currentState.metaData()); + templatesAliases.put(aliasMetaData.alias(), aliasMetaData); } - - aliasValidator.validateAliasMetaData(aliasMetaData, request.index(), currentState.metaData()); - templatesAliases.put(aliasMetaData.alias(), aliasMetaData); } } Settings.Builder indexSettingsBuilder = Settings.builder(); - // apply templates, here, in reverse order, since first ones are better matching - for (int i = templates.size() - 1; i >= 0; i--) { - indexSettingsBuilder.put(templates.get(i).settings()); + if (shrinkFromIndex == null) { + // apply templates, here, in reverse order, since first ones are better matching + for (int i = templates.size() - 1; i >= 0; i--) { + indexSettingsBuilder.put(templates.get(i).settings()); + } } // now, put the request settings, so they override templates indexSettingsBuilder.put(request.settings()); @@ -340,7 +346,6 @@ public ClusterState execute(ClusterState currentState) throws Exception { } indexSettingsBuilder.put(IndexMetaData.SETTING_INDEX_PROVIDED_NAME, request.getProvidedName()); indexSettingsBuilder.put(SETTING_INDEX_UUID, UUIDs.randomBase64UUID()); - final Index shrinkFromIndex = request.shrinkFrom(); final IndexMetaData.Builder tmpImdBuilder = IndexMetaData.builder(request.index()); final int routingNumShards; diff --git a/core/src/test/java/org/elasticsearch/routing/PartitionedRoutingIT.java b/core/src/test/java/org/elasticsearch/routing/PartitionedRoutingIT.java index 48b8430077fae..b23ce6a9286bb 100644 --- a/core/src/test/java/org/elasticsearch/routing/PartitionedRoutingIT.java +++ b/core/src/test/java/org/elasticsearch/routing/PartitionedRoutingIT.java @@ -67,6 +67,7 @@ public void testShrinking() throws Exception { client().admin().indices().prepareCreate(index) .setSettings(Settings.builder() .put("index.number_of_shards", currentShards) + .put("index.number_of_replicas", numberOfReplicas()) .put("index.routing_partition_size", partitionSize)) .addMapping("type", "{\"type\":{\"_routing\":{\"required\":true}}}", XContentType.JSON) .execute().actionGet(); @@ -107,6 +108,7 @@ public void testShrinking() throws Exception { client().admin().indices().prepareShrinkIndex(previousIndex, index) .setSettings(Settings.builder() .put("index.number_of_shards", currentShards) + .put("index.number_of_replicas", numberOfReplicas()) .build()).get(); ensureGreen(); } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/indices.shrink/20_source_mapping.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.shrink/20_source_mapping.yml new file mode 100644 index 0000000000000..7f6d57b1f8592 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.shrink/20_source_mapping.yml @@ -0,0 +1,77 @@ +--- +"Shrink index ignores target template mapping": + - skip: + version: " - 5.99.99" + reason: bug fixed in 6.0 + + - do: + cluster.state: {} + # Get master node id + + - set: { master_node: master } + + # create index + - do: + indices.create: + index: source + wait_for_active_shards: 1 + body: + settings: + # ensure everything is allocated on a single node + index.routing.allocation.include._id: $master + number_of_replicas: 0 + mappings: + test: + properties: + count: + type: text + + # index document + - do: + index: + index: source + type: test + id: "1" + body: { "count": "1" } + + # create template matching shrink tagret + - do: + indices.put_template: + name: tpl1 + body: + index_patterns: targ* + mappings: + test: + properties: + count: + type: integer + + # make it read-only + - do: + indices.put_settings: + index: source + body: + index.blocks.write: true + index.number_of_replicas: 0 + + - do: + cluster.health: + wait_for_status: green + index: source + + # now we do the actual shrink + - do: + indices.shrink: + index: "source" + target: "target" + wait_for_active_shards: 1 + master_timeout: 10s + body: + settings: + index.number_of_replicas: 0 + + - do: + cluster.health: + wait_for_status: green + +