diff --git a/docs/changelog/124784.yaml b/docs/changelog/124784.yaml new file mode 100644 index 0000000000000..e0b49834f56e1 --- /dev/null +++ b/docs/changelog/124784.yaml @@ -0,0 +1,6 @@ +pr: 124784 +summary: Merge template mappings properly during validation +area: Mapping +type: bug +issues: + - 123372 diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java index e58f766a9781b..c6a24a3711b51 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java @@ -1905,7 +1905,7 @@ private static void validateTemplate(Settings validateSettings, CompressedXConte createdIndex = dummyIndexService.index(); if (mappings != null) { - dummyIndexService.mapperService().merge(MapperService.SINGLE_MAPPING_NAME, mappings, MergeReason.MAPPING_UPDATE); + dummyIndexService.mapperService().merge(MapperService.SINGLE_MAPPING_NAME, mappings, MergeReason.INDEX_TEMPLATE); } } finally { diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java index 1c60a9ff7cea3..6402088aeb326 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java @@ -2596,6 +2596,59 @@ public void testComposableTemplateWithSubobjectsFalse() throws Exception { ); } + public void testComposableTemplateWithSubobjectsFalseObjectAndSubfield() throws Exception { + MetadataIndexTemplateService service = getMetadataIndexTemplateService(); + ProjectMetadata project = ProjectMetadata.builder(randomProjectIdOrDefault()).build(); + + ComponentTemplate subobjects = new ComponentTemplate(new Template(null, new CompressedXContent(""" + { + "properties": { + "foo": { + "type": "object", + "subobjects": false + }, + "foo.bar": { + "type": "keyword" + } + } + } + """), null), null, null); + + project = service.addComponentTemplate(project, true, "subobjects", subobjects); + ComposableIndexTemplate it = ComposableIndexTemplate.builder() + .indexPatterns(List.of("test-*")) + .template(new Template(null, null, null)) + .componentTemplates(List.of("subobjects", "field_mapping")) + .priority(0L) + .version(1L) + .build(); + project = service.addIndexTemplateV2(project, true, "composable-template", it); + + List mappings = MetadataIndexTemplateService.collectMappings(project, "composable-template", "test-index"); + + assertNotNull(mappings); + assertThat(mappings.size(), equalTo(1)); + List> parsedMappings = mappings.stream().map(m -> { + try { + return MapperService.parseMapping(NamedXContentRegistry.EMPTY, m); + } catch (Exception e) { + logger.error(e); + fail("failed to parse mappings: " + m.string()); + return null; + } + }).toList(); + + assertThat( + parsedMappings.get(0), + equalTo( + Map.of( + "_doc", + Map.of("properties", Map.of("foo.bar", Map.of("type", "keyword"), "foo", Map.of("type", "object", "subobjects", false))) + ) + ) + ); + } + public void testAddIndexTemplateWithDeprecatedComponentTemplate() throws Exception { ProjectMetadata project = ProjectMetadata.builder(randomProjectIdOrDefault()).build(); MetadataIndexTemplateService service = getMetadataIndexTemplateService();