This is an automated email from the ASF dual-hosted git repository. sergehuber pushed a commit to branch UNOMI-943-migration in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 565c78b2550ed24a7d907a01c8f2f5214f2e22d0 Author: Serge Huber <[email protected]> AuthorDate: Mon Jul 6 16:53:21 2026 +0200 UNOMI-943: Fix 3.1.0 migration idempotency and missing resource errors Hoist rollover alias configuration to a top-level migration step so resume after failure can still configure write aliases. Fail fast in getFileWithoutComments when a bundled resource is missing. --- .../shell/migration/utils/MigrationUtils.java | 3 ++ .../migrate-3.1.0-01-tenantDocumentIds.groovy | 55 +++++++++++----------- .../shell/migration/utils/MigrationUtilsTest.java | 10 ++++ 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java index 1bc480410..71755c590 100644 --- a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java +++ b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java @@ -76,6 +76,9 @@ public class MigrationUtils { public static String getFileWithoutComments(BundleContext bundleContext, final String resource) { final URL url = bundleContext.getBundle().getResource(resource); + if (url == null) { + throw new RuntimeException("Resource not found: " + resource); + } try { // Read the entire file into a string to preserve exact line endings String fileContent; diff --git a/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-3.1.0-01-tenantDocumentIds.groovy b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-3.1.0-01-tenantDocumentIds.groovy index 8a05cd1c6..a49916d83 100644 --- a/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-3.1.0-01-tenantDocumentIds.groovy +++ b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-3.1.0-01-tenantDocumentIds.groovy @@ -146,34 +146,35 @@ context.performMigrationStep("3.1.0-get-all-indices", () -> { // Execute reindex MigrationUtils.reIndex(context.getHttpClient(), bundleContext, esAddress, indexName, newIndexSettings, updateScript, params, context, "3.1.0-${indexName}-update") } - - // Configure aliases for rollover indices after all reindexing is complete - // For each rollover alias, find all indices and set the latest one as write index - context.performMigrationStep("3.1.0-configure-rollover-aliases", () -> { - String configureAliasBody = MigrationUtils.resourceAsString(bundleContext, "requestBody/2.2.0/configure_alias_body.json") - - // Process each rollover item type - indexConfigs.each { itemType, config -> - if (config.useRollover) { - String alias = config.alias(indexPrefix) - // Find all indices that match the rollover pattern (e.g., context-session-000001, context-session-000002) - Set<String> rolloverIndices = MigrationUtils.getIndexesPrefixedBy(context.getHttpClient(), esAddress, "${indexPrefix}-${itemType}-") - - if (!rolloverIndices.isEmpty()) { - // Sort indices to find the latest one (highest number) - SortedSet<String> sortedIndices = new TreeSet<>(rolloverIndices) - String writeIndex = sortedIndices.last() - - // All indices except the last one should be read-only - SortedSet<String> readIndices = Collections.emptySortedSet() - if (sortedIndices.size() > 1) { - readIndices = sortedIndices.headSet(sortedIndices.last()) - } - - context.printMessage("Configuring alias ${alias}: write index=${writeIndex}, read indices=${readIndices}") - MigrationUtils.configureAlias(context.getHttpClient(), esAddress, alias, writeIndex, readIndices, configureAliasBody, context) +}) + +// Configure aliases for rollover indices after all reindexing is complete. +// Top-level step so resume after failure can run alias configuration even when +// "3.1.0-get-all-indices" is already marked COMPLETED (UNOMI-943). +context.performMigrationStep("3.1.0-configure-rollover-aliases", () -> { + String configureAliasBody = MigrationUtils.resourceAsString(bundleContext, "requestBody/2.2.0/configure_alias_body.json") + + // Process each rollover item type + indexConfigs.each { itemType, config -> + if (config.useRollover) { + String alias = config.alias(indexPrefix) + // Find all indices that match the rollover pattern (e.g., context-session-000001, context-session-000002) + Set<String> rolloverIndices = MigrationUtils.getIndexesPrefixedBy(context.getHttpClient(), esAddress, "${indexPrefix}-${itemType}-") + + if (!rolloverIndices.isEmpty()) { + // Sort indices to find the latest one (highest number) + SortedSet<String> sortedIndices = new TreeSet<>(rolloverIndices) + String writeIndex = sortedIndices.last() + + // All indices except the last one should be read-only + SortedSet<String> readIndices = Collections.emptySortedSet() + if (sortedIndices.size() > 1) { + readIndices = sortedIndices.headSet(sortedIndices.last()) } + + context.printMessage("Configuring alias ${alias}: write index=${writeIndex}, read indices=${readIndices}") + MigrationUtils.configureAlias(context.getHttpClient(), esAddress, alias, writeIndex, readIndices, configureAliasBody, context) } } - }) + } }) diff --git a/tools/shell-commands/src/test/java/org/apache/unomi/shell/migration/utils/MigrationUtilsTest.java b/tools/shell-commands/src/test/java/org/apache/unomi/shell/migration/utils/MigrationUtilsTest.java index aa1c0cb9d..96129f47c 100644 --- a/tools/shell-commands/src/test/java/org/apache/unomi/shell/migration/utils/MigrationUtilsTest.java +++ b/tools/shell-commands/src/test/java/org/apache/unomi/shell/migration/utils/MigrationUtilsTest.java @@ -27,6 +27,7 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.*; public class MigrationUtilsTest { @@ -199,4 +200,13 @@ public class MigrationUtilsTest { String expected = "code1 code2 code3"; testCommentHandling(input, expected); } + + @Test + public void testGetFileWithoutCommentsMissingResource() { + when(bundle.getResource("missing.painless")).thenReturn(null); + + RuntimeException ex = assertThrows(RuntimeException.class, + () -> MigrationUtils.getFileWithoutComments(bundleContext, "missing.painless")); + assertEquals("Resource not found: missing.painless", ex.getMessage()); + } } \ No newline at end of file
