Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow duplicate dynamic_templates names #51817

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
import static org.elasticsearch.index.mapper.TypeParsers.parseDateTimeFormatter;
Expand Down Expand Up @@ -170,6 +172,7 @@ protected boolean processField(RootObjectMapper.Builder builder, String fieldNam
*/
List<?> tmplNodes = (List<?>) fieldNode;
List<DynamicTemplate> templates = new ArrayList<>();
Set<String> templatesAlreadyDefinded = new HashSet<>();
for (Object tmplNode : tmplNodes) {
Map<String, Object> tmpl = (Map<String, Object>) tmplNode;
if (tmpl.size() != 1) {
Expand All @@ -180,7 +183,12 @@ protected boolean processField(RootObjectMapper.Builder builder, String fieldNam
Map<String, Object> templateParams = (Map<String, Object>) entry.getValue();
DynamicTemplate template = DynamicTemplate.parse(templateName, templateParams);
if (template != null) {
if (templatesAlreadyDefinded.contains(templateName)) {
throw new MapperParsingException("A dynamic template cannot be defined twice, but a template with name ["
+ templateName + "] has already been defined.");
}
templates.add(template);
templatesAlreadyDefinded.add(template.name());
}
}
builder.dynamicTemplates(templates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ public void testDateDetectionInheritsFormat() throws Exception {
.endObject()
.endObject()
.startObject()
.startObject("dates")
.startObject("dates_with_explicit_format")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After having to change this test I'm not entirely sure anymore about the approach, in particular whether this test was lazily "missusing" a leniency in our code by using the name twice or wether this should work. In the end both templates seem to match different fields, so I'm not sure why the test used the same name?

.field("match_mapping_type", "date")
.field("match", "*3")
.startObject("mapping")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,38 @@ public void testDynamicTemplates() throws Exception {
assertEquals(mapping3, mapper.mappingSource().toString());
}

public void testDynamicTemplatesDuplicationThrows() throws Exception {
String mapping = Strings.toString(XContentFactory.jsonBuilder()
.startObject()
.startObject("type")
.startArray("dynamic_templates")
.startObject()
.startObject("my_template")
.field("match_mapping_type", "string")
.startObject("mapping")
.field("type", "keyword")
.endObject()
.endObject()
.endObject()
.startObject()
.startObject("my_template")
.field("match_mapping_type", "string")
.startObject("mapping")
.field("type", "keyword")
.endObject()
.endObject()
.endObject()
.endArray()
.endObject()
.endObject());
MapperService mapperService = createIndex("test").mapperService();
MapperParsingException ex = expectThrows(MapperParsingException.class,
() -> mapperService.merge("type", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE));
assertEquals("Failed to parse mapping: A dynamic template cannot be defined twice, but a template with name [my_template]"
+ " has already been defined.", ex.getMessage());

}

public void testIllegalFormatField() throws Exception {
String dynamicMapping = Strings.toString(XContentFactory.jsonBuilder()
.startObject()
Expand Down