diff --git a/docs/changelog/134231.yaml b/docs/changelog/134231.yaml new file mode 100644 index 0000000000000..dd0e7f5f84f0d --- /dev/null +++ b/docs/changelog/134231.yaml @@ -0,0 +1,6 @@ +pr: 134231 +summary: Fix unnecessary determinization in index pattern conflict checks +area: Indices APIs +type: bug +issues: + - 133652 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 69dd4359fd764..16a7783d3265b 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java @@ -995,12 +995,16 @@ static Map> findConflictingV2Templates( boolean checkPriority, long priority ) { - Automaton v1automaton = Regex.simpleMatchToAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY)); + // No need to determinize the automaton, as it is only used to check for intersection with another automaton. + // Determinization is avoided because it can fail or become very costly due to state explosion. + Automaton v1automaton = Regex.simpleMatchToNonDeterminizedAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY)); Map> overlappingTemplates = new TreeMap<>(); for (Map.Entry entry : project.templatesV2().entrySet()) { String name = entry.getKey(); ComposableIndexTemplate template = entry.getValue(); - Automaton v2automaton = Regex.simpleMatchToAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY)); + // No need to determinize the automaton, as it is only used to check for intersection with another automaton. + // Determinization is avoided because it can fail or become very costly due to state explosion. + Automaton v2automaton = Regex.simpleMatchToNonDeterminizedAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY)); if (Operations.isEmpty(Operations.intersection(v1automaton, v2automaton)) == false) { if (checkPriority == false || priority == template.priorityOrZero()) { logger.debug( 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 9a37cd6dd85b8..64cd2ff45667a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java @@ -2495,6 +2495,23 @@ public void testV2TemplateOverlaps() throws Exception { } } + /** + * test that using complex index patterns doesn't run into a too_complex_to_determinize_exception, + * see https://github.com/elastic/elasticsearch/issues/133652 + */ + public void testFindConflictingTemplates_complex_pattern() throws Exception { + ProjectMetadata initialProject = ProjectMetadata.builder(randomProjectIdOrDefault()).build(); + List complexPattern = new ArrayList<>(); + for (int i = 1; i < 20; i++) { + complexPattern.add("cluster-somenamespace-*-app" + i + "*"); + } + ComposableIndexTemplate template = ComposableIndexTemplate.builder().indexPatterns(complexPattern).build(); + MetadataIndexTemplateService service = getMetadataIndexTemplateService(); + ProjectMetadata project = service.addIndexTemplateV2(initialProject, false, "foo", template); + assertEquals(0, MetadataIndexTemplateService.findConflictingV1Templates(project, "foo", complexPattern).size()); + assertEquals(0, MetadataIndexTemplateService.findConflictingV2Templates(project, "foo", complexPattern).size()); + } + /** * Tests to add two component templates but ignores both with is valid *