diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecks.java index 1d3d25b8828a5..5794549d95ae0 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecks.java @@ -12,6 +12,8 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.MappingMetadata; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.index.IndexSettings; @@ -167,4 +169,24 @@ static DeprecationIssue checkPollIntervalTooLow(ClusterState state) { } return null; } + + static DeprecationIssue checkTemplatesWithMultipleTypes(ClusterState state) { + Set templatesWithMultipleTypes = new HashSet<>(); + state.getMetadata().getTemplates().forEach((templateCursor) -> { + String templateName = templateCursor.key; + ImmutableOpenMap mappings = templateCursor.value.mappings(); + if (mappings != null && mappings.size() > 1) { + templatesWithMultipleTypes.add(templateName); + } + }); + if (templatesWithMultipleTypes.isEmpty()) { + return null; + } + return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, + "Some index templates contain multiple mapping types", + "https://www.elastic.co/guide/en/elasticsearch/reference/master/removal-of-types.html", + "Index templates " + templatesWithMultipleTypes + + " define multiple types and so will cause errors when used in index creation" + ); + } } diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java index 3f8593b0343c3..c1926827156ff 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java @@ -38,7 +38,8 @@ private DeprecationChecks() { ClusterDeprecationChecks::checkUserAgentPipelines, ClusterDeprecationChecks::checkTemplatesWithTooManyFields, ClusterDeprecationChecks::checkPollIntervalTooLow, - ClusterDeprecationChecks::checkTemplatesWithFieldNamesDisabled + ClusterDeprecationChecks::checkTemplatesWithFieldNamesDisabled, + ClusterDeprecationChecks::checkTemplatesWithMultipleTypes )); diff --git a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecksTests.java b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecksTests.java index 96d3164ecef9f..f32c3acd4cdd0 100644 --- a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecksTests.java +++ b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/ClusterDeprecationChecksTests.java @@ -13,6 +13,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; @@ -21,7 +22,6 @@ import org.elasticsearch.ingest.IngestService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue; -import org.hamcrest.Matchers; import java.io.IOException; import java.util.Collections; @@ -32,6 +32,8 @@ import static org.elasticsearch.xpack.core.ilm.LifecycleSettings.LIFECYCLE_POLL_INTERVAL_SETTING; import static org.elasticsearch.xpack.deprecation.DeprecationChecks.CLUSTER_SETTINGS_CHECKS; import static org.elasticsearch.xpack.deprecation.IndexDeprecationChecksTests.addRandomFields; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; public class ClusterDeprecationChecksTests extends ESTestCase { @@ -272,7 +274,41 @@ public void testPollIntervalTooLow() { .metadata(okMetadata) .build(); List noIssues = DeprecationChecks.filterChecks(CLUSTER_SETTINGS_CHECKS, c -> c.apply(okState)); - assertThat(noIssues, Matchers.hasSize(0)); + assertThat(noIssues, hasSize(0)); } } + + public void testIndexTemplatesWithMultipleTypes() throws IOException { + + IndexTemplateMetadata multipleTypes = IndexTemplateMetadata.builder("multiple-types") + .patterns(Collections.singletonList("foo")) + .putMapping("type1", "{\"type1\":{}}") + .putMapping("type2", "{\"type2\":{}}") + .build(); + IndexTemplateMetadata singleType = IndexTemplateMetadata.builder("single-type") + .patterns(Collections.singletonList("foo")) + .putMapping("type1", "{\"type1\":{}}") + .build(); + ImmutableOpenMap templates = ImmutableOpenMap.builder() + .fPut("multiple-types", multipleTypes) + .fPut("single-type", singleType) + .build(); + Metadata badMetadata = Metadata.builder() + .templates(templates) + .build(); + ClusterState badState = ClusterState.builder(new ClusterName("test")).metadata(badMetadata).build(); + List issues = DeprecationChecks.filterChecks(CLUSTER_SETTINGS_CHECKS, c -> c.apply(badState)); + assertThat(issues, hasSize(1)); + assertThat(issues.get(0).getDetails(), + equalTo("Index templates [multiple-types] define multiple types and so will cause errors when used in index creation")); + + Metadata goodMetadata = Metadata.builder() + .templates(ImmutableOpenMap.builder().fPut("single-type", singleType).build()) + .build(); + ClusterState goodState = ClusterState.builder(new ClusterName("test")).metadata(goodMetadata).build(); + assertThat( + DeprecationChecks.filterChecks(CLUSTER_SETTINGS_CHECKS, c -> c.apply(goodState)), + hasSize(0) + ); + } }