From 14329e8db1b893b9d9616f7cbe39c307fcd1ee69 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Thu, 13 Nov 2025 17:31:14 +1100 Subject: [PATCH 1/2] Support date math for CPS index resolution Resolves: ES-12858 --- .../CrossProjectIndexExpressionsRewriter.java | 3 -- ...sProjectIndexExpressionsRewriterTests.java | 31 +++++++++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriter.java b/server/src/main/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriter.java index 55e779c3ded0f..e3ce474c6e153 100644 --- a/server/src/main/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriter.java +++ b/server/src/main/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriter.java @@ -202,9 +202,6 @@ private static void maybeThrowOnUnsupportedResource(String resource) { if (resource.startsWith(EXCLUSION)) { throw new IllegalArgumentException("Exclusions are not currently supported but was found in the expression [" + resource + "]"); } - if (resource.startsWith(DATE_MATH)) { - throw new IllegalArgumentException("Date math are not currently supported but was found in the expression [" + resource + "]"); - } if (IndexNameExpressionResolver.hasSelectorSuffix(resource)) { throw new IllegalArgumentException("Selectors are not currently supported but was found in the expression [" + resource + "]"); } diff --git a/server/src/test/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriterTests.java b/server/src/test/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriterTests.java index 1b07b6c070c6b..86a16ae8ebfc0 100644 --- a/server/src/test/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriterTests.java +++ b/server/src/test/java/org/elasticsearch/search/crossproject/CrossProjectIndexExpressionsRewriterTests.java @@ -29,16 +29,20 @@ public void testFlatOnlyRewrite() { createRandomProjectWithAlias("P2"), createRandomProjectWithAlias("P3") ); - String[] requestedResources = new String[] { "logs*", "metrics*" }; + String[] requestedResources = new String[] { "logs*", "metrics*", "" }; var actual = CrossProjectIndexExpressionsRewriter.rewriteIndexExpressions(origin, linked, requestedResources); - assertThat(actual.keySet(), containsInAnyOrder("logs*", "metrics*")); + assertThat(actual.keySet(), containsInAnyOrder("logs*", "metrics*", "")); assertIndexRewriteResultsContains(actual.get("logs*"), containsInAnyOrder("logs*", "P1:logs*", "P2:logs*", "P3:logs*")); assertIndexRewriteResultsContains( actual.get("metrics*"), containsInAnyOrder("metrics*", "P1:metrics*", "P2:metrics*", "P3:metrics*") ); + assertIndexRewriteResultsContains( + actual.get(""), + containsInAnyOrder("", "P1:", "P2:", "P3:") + ); } public void testFlatAndQualifiedRewrite() { @@ -48,16 +52,17 @@ public void testFlatAndQualifiedRewrite() { createRandomProjectWithAlias("P2"), createRandomProjectWithAlias("P3") ); - String[] requestedResources = new String[] { "P1:logs*", "metrics*" }; + String[] requestedResources = new String[] { "P1:logs*", "metrics*", "P2:" }; var actual = CrossProjectIndexExpressionsRewriter.rewriteIndexExpressions(origin, linked, requestedResources); - assertThat(actual.keySet(), containsInAnyOrder("P1:logs*", "metrics*")); + assertThat(actual.keySet(), containsInAnyOrder("P1:logs*", "metrics*", "P2:")); assertIndexRewriteResultsContains(actual.get("P1:logs*"), containsInAnyOrder("P1:logs*")); assertIndexRewriteResultsContains( actual.get("metrics*"), containsInAnyOrder("metrics*", "P1:metrics*", "P2:metrics*", "P3:metrics*") ); + assertIndexRewriteResultsContains(actual.get("P2:"), containsInAnyOrder("P2:")); } public void testQualifiedOnlyRewrite() { @@ -67,13 +72,14 @@ public void testQualifiedOnlyRewrite() { createRandomProjectWithAlias("P2"), createRandomProjectWithAlias("P3") ); - String[] requestedResources = new String[] { "P1:logs*", "P2:metrics*" }; + String[] requestedResources = new String[] { "P1:logs*", "P2:metrics*", "P3:" }; var actual = CrossProjectIndexExpressionsRewriter.rewriteIndexExpressions(origin, linked, requestedResources); - assertThat(actual.keySet(), containsInAnyOrder("P1:logs*", "P2:metrics*")); + assertThat(actual.keySet(), containsInAnyOrder("P1:logs*", "P2:metrics*", "P3:")); assertIndexRewriteResultsContains(actual.get("P1:logs*"), containsInAnyOrder("P1:logs*")); assertIndexRewriteResultsContains(actual.get("P2:metrics*"), containsInAnyOrder("P2:metrics*")); + assertIndexRewriteResultsContains(actual.get("P3:"), containsInAnyOrder("P3:")); } public void testOriginQualifiedOnlyRewrite() { @@ -83,13 +89,14 @@ public void testOriginQualifiedOnlyRewrite() { createRandomProjectWithAlias("P2"), createRandomProjectWithAlias("P3") ); - String[] requestedResources = new String[] { "_origin:logs*", "_origin:metrics*" }; + String[] requestedResources = new String[] { "_origin:logs*", "_origin:metrics*", "_origin:" }; var actual = CrossProjectIndexExpressionsRewriter.rewriteIndexExpressions(origin, linked, requestedResources); - assertThat(actual.keySet(), containsInAnyOrder("_origin:logs*", "_origin:metrics*")); + assertThat(actual.keySet(), containsInAnyOrder("_origin:logs*", "_origin:metrics*", "_origin:")); assertIndexRewriteResultsContains(actual.get("_origin:logs*"), containsInAnyOrder("logs*")); assertIndexRewriteResultsContains(actual.get("_origin:metrics*"), containsInAnyOrder("metrics*")); + assertIndexRewriteResultsContains(actual.get("_origin:"), containsInAnyOrder("")); } public void testOriginQualifiedOnlyRewriteWithNoLikedProjects() { @@ -149,12 +156,16 @@ public void testQualifiedStartsWithProjectWildcardRewrite() { createRandomProjectWithAlias("Q1"), createRandomProjectWithAlias("Q2") ); - String[] requestedResources = new String[] { "Q*:metrics*" }; + String[] requestedResources = new String[] { "Q*:metrics*", "P*:" }; var actual = CrossProjectIndexExpressionsRewriter.rewriteIndexExpressions(origin, linked, requestedResources); - assertThat(actual.keySet(), containsInAnyOrder("Q*:metrics*")); + assertThat(actual.keySet(), containsInAnyOrder("Q*:metrics*", "P*:")); assertIndexRewriteResultsContains(actual.get("Q*:metrics*"), containsInAnyOrder("Q1:metrics*", "Q2:metrics*")); + assertIndexRewriteResultsContains( + actual.get("P*:"), + containsInAnyOrder("", "P1:", "P2:") + ); } public void testQualifiedEndsWithProjectWildcardRewrite() { From 660ec8090cbc0fcf16392bdd6ff0252fb2bc45f1 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 14 Nov 2025 14:37:13 +1100 Subject: [PATCH 2/2] helper method --- .../java/org/elasticsearch/test/rest/ESRestTestCase.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java index 3fb11cfe5e153..52f39bed3a6ad 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java @@ -1230,6 +1230,10 @@ protected static void wipeAllIndices() throws IOException { } protected static void wipeAllIndices(boolean preserveSecurityIndices) throws IOException { + wipeAllIndices(preserveSecurityIndices, cleanupClient()); + } + + protected static void wipeAllIndices(boolean preserveSecurityIndices, RestClient cleanupClient) throws IOException { try { // remove all indices except some history indices which can pop up after deleting all data streams but shouldn't interfere final List indexPatterns = new ArrayList<>( @@ -1248,7 +1252,7 @@ protected static void wipeAllIndices(boolean preserveSecurityIndices) throws IOE RequestOptions.DEFAULT.toBuilder().setWarningsHandler(ESRestTestCase::ignoreSystemIndexAccessWarnings) ); - final Response response = cleanupClient().performRequest(deleteRequest); + final Response response = cleanupClient.performRequest(deleteRequest); try (InputStream is = response.getEntity().getContent()) { assertTrue((boolean) XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true).get("acknowledged")); }