From fcc8d2ef699b7a55340a66ce245bbcb9af52f4b8 Mon Sep 17 00:00:00 2001 From: Serge Huber Date: Mon, 20 Jul 2026 23:25:44 +0200 Subject: [PATCH 1/3] UNOMI-968: Pluggable persistence IT harness for ES, OS, and other backends Extract PersistenceITBackend SPI with capability-based skips so the same CorePersistenceITs/AllITs suite runs on Elasticsearch and OpenSearch as before, while external providers (PostgreSQL, etc.) can plug in via ServiceLoader without forking Unomi IT sources. --- itests/README.md | 84 ++++- itests/pom.xml | 32 ++ .../java/org/apache/unomi/itests/AllITs.java | 4 +- .../java/org/apache/unomi/itests/BaseIT.java | 309 +++++++++--------- .../unomi/itests/CorePersistenceITs.java | 90 +++++ .../apache/unomi/itests/HealthCheckIT.java | 51 ++- .../org/apache/unomi/itests/JSONSchemaIT.java | 11 +- .../apache/unomi/itests/ProfileServiceIT.java | 6 +- .../ProfileServiceWithoutOverwriteIT.java | 3 +- .../org/apache/unomi/itests/RolloverIT.java | 42 ++- .../Migrate16xToCurrentVersionIT.java | 45 +-- .../persistence/ElasticsearchITBackend.java | 117 +++++++ .../persistence/OpenSearchITBackend.java | 130 ++++++++ .../persistence/PersistenceITBackend.java | 92 ++++++ .../PersistenceITBackendResolver.java | 110 +++++++ .../PersistenceITCapabilities.java | 204 ++++++++++++ .../itests/persistence/SearchBackendIT.java | 29 ++ ...mi.itests.persistence.PersistenceITBackend | 2 + 18 files changed, 1159 insertions(+), 202 deletions(-) create mode 100644 itests/src/test/java/org/apache/unomi/itests/CorePersistenceITs.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/ElasticsearchITBackend.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/OpenSearchITBackend.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/PersistenceITBackend.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/PersistenceITBackendResolver.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/PersistenceITCapabilities.java create mode 100644 itests/src/test/java/org/apache/unomi/itests/persistence/SearchBackendIT.java create mode 100644 itests/src/test/resources/META-INF/services/org.apache.unomi.itests.persistence.PersistenceITBackend diff --git a/itests/README.md b/itests/README.md index ebb3d97085..20a5f79eda 100644 --- a/itests/README.md +++ b/itests/README.md @@ -32,7 +32,9 @@ and data migration. `docker-maven-plugin`). - **Maven Failsafe** runs a single entry point — `AllITs` — which aggregates all test classes. Each test class extends `BaseIT`, which handles Karaf startup, OSGi service - injection, and common test utilities. + injection, and common test utilities. Persistence is selected via + `unomi.persistence.provider` (Elasticsearch / OpenSearch today; see + [Pluggable persistence providers](#pluggable-persistence-providers)). A full IT run typically takes 20–30 minutes. The Karaf instance is created fresh for each run under `itests/target/exam/` with a UUID directory name. @@ -284,6 +286,86 @@ See the [Maven Failsafe plugin docs](https://maven.apache.org/surefire/maven-fai --- +## Pluggable persistence providers + +Unomi’s runtime persistence is an OSGi capability (`unomi.persistence;provider:=…`). +The IT harness follows the same idea: `BaseIT` resolves a test-only +`PersistenceITBackend` instead of hard-coding Elasticsearch / OpenSearch. + +### Provider selection + +| Property | Role | +|----------|------| +| `unomi.persistence.provider` | Preferred provider id (`elasticsearch`, `opensearch`, or an extension id) | +| `unomi.search.engine` | **Deprecated alias** — used when `unomi.persistence.provider` is unset | +| `unomi.persistence.it.backend` | Optional FQCN of a `PersistenceITBackend` implementation | + +Default CI cells set both `unomi.persistence.provider` and the deprecated +`unomi.search.engine` so existing `--use-opensearch` / scripts keep working. + +### Built-in backends + +| Id | Class | Suite for CI | +|----|-------|--------------| +| `elasticsearch` | `ElasticsearchITBackend` | `AllITs` (default) | +| `opensearch` | `OpenSearchITBackend` | `AllITs` with `-Duse.opensearch=true` | + +### Search-only vs core behavioural tests + +`AllITs` and `CorePersistenceITs` share the **same** test membership for maximum coverage. +Tests that need HTTP admin / snapshot / rollover APIs stay in the suite and use +`Assume` + `PersistenceITCapabilities` so unsupported backends **skip** (reported as +skipped, not green false-pass): + +| Class | Gate | +|-------|------| +| `Migrate16xToCurrentVersionIT` | `snapshotRestoreMigration()` | +| `RolloverIT` | `indexRolloverApi().isPresent()` + `httpAdminApi()`; switch on `LIFECYCLE` / `STATE_MANAGEMENT` | +| `HealthCheckIT` | Always asserts `karaf` / `unomi` / `persistence`; optional `providerNamedHealthProbe` / `clusterHealthProbe` | + +`HealthCheckIT` is not search-only: it runs on every provider. + +Elasticsearch / OpenSearch CI continues to use `AllITs`. Portable / non-search cells +(PostgreSQL, …) should run `CorePersistenceITs` (identical membership, clearer name). + +```bash +mvn clean install -P integration-tests -Dit.test=org.apache.unomi.itests.CorePersistenceITs +``` + +Capability flags gate remaining special-cases +(e.g. `snapshotRestoreMigration`, `flattenedRangeQueryResult`, `indexRolloverApi`) +so providers skip what they cannot support instead of checking product names. + +### Adding a third-party backend + +1. Implement `org.apache.unomi.itests.persistence.PersistenceITBackend` + (feature options, distribution name for `unomi:setup`, ConfigAdmin PID, + capabilities, await-ready / HTTP helpers as needed). +2. Put the implementation on the Failsafe test classpath. +3. Register it either: + - in `META-INF/services/org.apache.unomi.itests.persistence.PersistenceITBackend`, or + - via `-Dunomi.persistence.it.backend=com.example.MyPersistenceITBackend` +4. Select it with `-Dunomi.persistence.provider=`. +5. Run `CorePersistenceITs` (same membership as `AllITs`). Incomplete SPI + implementations may still fail behavioural tests — unsupported HTTP-admin + features are skipped via `Assume`, not removed from the suite. + +`unomi-itests` publishes a **test-jar** (`mvn -pl itests install`) so external modules can +depend on `BaseIT`, `CorePersistenceITs`, and `PersistenceITBackend` without forking +sources. Optionally implement `prepareBeforeUnomiSetup` to patch ConfigAdmin (e.g. JDBC +DataSource) after `UnomiManagementService` is up and before `unomi:setup`. + +Example Failsafe exclude when running `AllITs` against a non-search provider: + +```xml +org.apache.unomi.itests.persistence.SearchBackendIT +``` + +(Note: JUnit 4 category filtering applies to classes Failsafe launches directly; +prefer `CorePersistenceITs` when using the suite entry point.) + +--- + ## Debugging Integration Tests ### Attaching a remote debugger to the test JVM diff --git a/itests/pom.xml b/itests/pom.xml index d28e1d2a62..026a1798f3 100644 --- a/itests/pom.xml +++ b/itests/pom.xml @@ -28,6 +28,7 @@ Apache Unomi Context Server integration tests + elasticsearch elasticsearch false itests-opensearch @@ -277,6 +278,33 @@ + + + org.apache.maven.plugins + maven-jar-plugin + + + test-jar + + test-jar + + + + + org/apache/unomi/itests/** + **/*.cfg + **/*.csv + **/*.json + **/*.groovy + migration/** + schemas/** + META-INF/** + + + + + @@ -306,6 +334,8 @@ foo + elasticsearch + elasticsearch ${elasticsearch.port} ${karaf.heap} @@ -432,6 +462,8 @@ foo + opensearch + opensearch localhost:${opensearch.port} INFO diff --git a/itests/src/test/java/org/apache/unomi/itests/AllITs.java b/itests/src/test/java/org/apache/unomi/itests/AllITs.java index 8617b1dcb9..41351e5b02 100644 --- a/itests/src/test/java/org/apache/unomi/itests/AllITs.java +++ b/itests/src/test/java/org/apache/unomi/itests/AllITs.java @@ -24,7 +24,9 @@ import org.junit.runners.Suite.SuiteClasses; /** - * Defines suite of test classes to run. + * Defines suite of test classes to run (Elasticsearch / OpenSearch CI default). + * Same membership as {@link CorePersistenceITs}; use capabilities + {@code Assume} for + * provider-specific skips rather than maintaining a smaller suite. * * @author Sergiy Shyrkov */ diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java index 8587f4f8a4..5ec6385bad 100644 --- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java @@ -22,8 +22,6 @@ import org.apache.camel.Route; import org.apache.camel.ServiceStatus; import org.apache.commons.io.IOUtils; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.HttpEntity; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.*; @@ -54,6 +52,9 @@ import org.apache.unomi.api.tenants.TenantService; import org.apache.unomi.api.utils.ConditionBuilder; import org.apache.unomi.groovy.actions.services.GroovyActionsService; +import org.apache.unomi.itests.persistence.PersistenceITBackend; +import org.apache.unomi.itests.persistence.PersistenceITBackendResolver; +import org.apache.unomi.itests.persistence.PersistenceITCapabilities; import org.apache.unomi.itests.tools.LogChecker; import org.apache.unomi.itests.tools.httpclient.HttpClientThatWaitsForUnomi; import org.apache.unomi.lifecycle.BundleWatcher; @@ -98,9 +99,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; @@ -135,16 +138,23 @@ public abstract class BaseIT extends KarafTestSupport { protected static final int DEFAULT_TRYING_TRIES = 10; protected static final int DEFAULT_SHOULDBETRUE_TRIES = 5; - protected static final String SEARCH_ENGINE_PROPERTY = "unomi.search.engine"; + /** @deprecated use {@link PersistenceITBackendResolver#PROVIDER_PROPERTY}. */ + @Deprecated + protected static final String SEARCH_ENGINE_PROPERTY = PersistenceITBackendResolver.SEARCH_ENGINE_PROPERTY; protected static final String SEARCH_ENGINE_HTTPREQUEST_LOG_LEVEL = "unomi.search.engine.httprequest.log.level"; - protected static final String SEARCH_ENGINE_ELASTICSEARCH = "elasticsearch"; - protected static final String SEARCH_ENGINE_OPENSEARCH = "opensearch"; + protected static final String SEARCH_ENGINE_ELASTICSEARCH = PersistenceITBackendResolver.PROVIDER_ELASTICSEARCH; + protected static final String SEARCH_ENGINE_OPENSEARCH = PersistenceITBackendResolver.PROVIDER_OPENSEARCH; + protected static final String PERSISTENCE_PROVIDER_PROPERTY = PersistenceITBackendResolver.PROVIDER_PROPERTY; protected static final String RESOLVER_DEBUG_PROPERTY = "it.unomi.resolver.debug"; protected static final String ENABLE_LOG_CHECKING_PROPERTY = "it.unomi.log.checking.enabled"; protected static final String CAMEL_DEBUG_PROPERTY = "it.unomi.camel.debug"; protected static boolean unomiStarted = false; + /** + * Active provider id. Kept for existing tests; prefer {@link #getPersistenceBackend()}. + */ protected static String searchEngine = SEARCH_ENGINE_ELASTICSEARCH; + private static PersistenceITBackend persistenceBackend; private static boolean searchEngineConfiguredForTesting = false; private static boolean searchEngineHealthVerifiedAfterStartup = false; @@ -239,37 +249,71 @@ protected TestUtils.RequestResponse executeContextJSONRequest(org.apache.http.cl } protected void checkSearchEngine() { - searchEngine = System.getProperty(SEARCH_ENGINE_PROPERTY, SEARCH_ENGINE_ELASTICSEARCH); + resolvePersistenceBackend(); configureSearchEngineForTesting(); } + /** + * Resolves (and caches) the active {@link PersistenceITBackend} from system properties / + * ServiceLoader. Also updates the legacy {@link #searchEngine} field. + */ + protected static PersistenceITBackend resolvePersistenceBackend() { + if (persistenceBackend == null) { + persistenceBackend = PersistenceITBackendResolver.resolve(); + searchEngine = persistenceBackend.providerId(); + } + return persistenceBackend; + } + + protected static PersistenceITBackend getPersistenceBackend() { + return resolvePersistenceBackend(); + } + + protected PersistenceITCapabilities persistenceCapabilities() { + return getPersistenceBackend().capabilities(); + } + + /** ConfigAdmin PID for the active persistence provider (e.g. throwExceptions). */ + protected String persistenceConfigPid() { + return getPersistenceBackend().persistenceConfigPid(); + } + @Before public void waitForStartup() throws InterruptedException { // disable retry retry = new KarafTestSupport.Retry(false); - // Check search engine and apply any necessary fixes (e.g., default_template deletion) + // Resolve provider and apply any necessary backend prep (e.g., zero-replica template) checkSearchEngine(); + try { + getPersistenceBackend().awaitBackendReady(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw e; + } catch (Exception e) { + throw new IllegalStateException("Persistence backend awaitBackendReady failed", e); + } // Start Unomi if not already done if (!unomiStarted) { // We must check that the Unomi Management Service is up and running before launching the // command otherwise the start configuration will not be properly populated. waitForUnomiManagementService(); - if (SEARCH_ENGINE_ELASTICSEARCH.equals(searchEngine)) { - LOGGER.info("Starting Unomi with elasticsearch search engine..."); - System.out.println("==== Starting Unomi with elasticsearch search engine..."); - executeCommand("unomi:setup -d=unomi-distribution-elasticsearch -f=true"); - executeCommand("unomi:start"); - } else if (SEARCH_ENGINE_OPENSEARCH.equals(searchEngine)){ - LOGGER.info("Starting Unomi with opensearch search engine..."); - System.out.println("==== Starting Unomi with opensearch search engine..."); - executeCommand("unomi:setup -d=unomi-distribution-opensearch -f=true"); - executeCommand("unomi:start"); - } else { - LOGGER.error("Unknown search engine: " + searchEngine); - throw new InterruptedException("Unknown search engine: " + searchEngine); + PersistenceITBackend backend = getPersistenceBackend(); + try { + backend.prepareBeforeUnomiSetup(bundleContext, configurationAdmin); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw e; + } catch (Exception e) { + throw new IllegalStateException("Persistence backend prepareBeforeUnomiSetup failed", e); } + String distribution = backend.distributionFeature(); + LOGGER.info("Starting Unomi with persistence provider {} (distribution {})...", backend.providerId(), distribution); + System.out.println("==== Starting Unomi with persistence provider " + backend.providerId() + + " (distribution " + distribution + ")..."); + executeCommand("unomi:setup -d=" + distribution + " -f=true"); + executeCommand("unomi:start"); unomiStarted = true; } @@ -542,6 +586,43 @@ protected void refreshPersistence(final Class... classes) throws Thread.sleep(1000); } + /** + * Resolves a fixture under {@code src/test/resources} for Pax Exam {@code replaceConfigurationFile}. + * Prefers the local filesystem (Unomi itests module); falls back to the classpath so out-of-tree + * consumers of the {@code unomi-itests} test-jar can reuse {@link #config()} without copying files. + */ + protected static File resolveTestResource(String pathUnderSrcTestResources) { + File local = new File(pathUnderSrcTestResources); + if (local.isFile()) { + return local; + } + String classpathName = pathUnderSrcTestResources; + final String prefix = "src/test/resources/"; + if (classpathName.startsWith(prefix)) { + classpathName = classpathName.substring(prefix.length()); + } + URL url = BaseIT.class.getClassLoader().getResource(classpathName); + if (url == null) { + throw new IllegalStateException("Missing test resource: " + pathUnderSrcTestResources + + " (not on filesystem or classpath)"); + } + try { + if ("file".equals(url.getProtocol())) { + return new File(url.toURI()); + } + String fileName = new File(classpathName).getName(); + Path tmp = Files.createTempFile("unomi-it-resource-", "-" + fileName); + try (InputStream in = url.openStream()) { + Files.copy(in, tmp, StandardCopyOption.REPLACE_EXISTING); + } + File out = tmp.toFile(); + out.deleteOnExit(); + return out; + } catch (Exception e) { + throw new IllegalStateException("Cannot resolve test resource " + pathUnderSrcTestResources, e); + } + } + @Override public MavenArtifactUrlReference getKarafDistribution() { return maven().groupId("org.apache.unomi").artifactId("unomi").versionAsInProject().type("tar.gz"); @@ -554,120 +635,41 @@ public Option[] config() { System.out.println("==== Configuring container"); } - searchEngine = System.getProperty(SEARCH_ENGINE_PROPERTY, SEARCH_ENGINE_ELASTICSEARCH); + resolvePersistenceBackend(); if (!configLogged) { - LOGGER.info("Search Engine: {}", searchEngine); - System.out.println("Search Engine: " + searchEngine); - } - - // Define features option based on search engine - Option featuresOption; - Option distributionOption; - if (SEARCH_ENGINE_ELASTICSEARCH.equals(searchEngine)) { - featuresOption = features( - maven().groupId("org.apache.unomi").artifactId("unomi-kar").versionAsInProject().type("xml").classifier("features"), - "unomi-base", - "unomi-startup", - "unomi-elasticsearch-core", - "unomi-persistence-core", - "unomi-services", - "unomi-cxs-privacy-extension-services", - "unomi-plugins-base", - "unomi-plugins-request", - "unomi-plugins-mail", - "unomi-plugins-optimization-test", - "unomi-rest-api", - "unomi-cxs-privacy-extension", - "unomi-elasticsearch-conditions", - "unomi-cxs-lists-extension", - "unomi-cxs-geonames-extension", - "unomi-shell-dev-commands", - "unomi-wab", - "unomi-web-tracker", - "unomi-healthcheck-elasticsearch", - "unomi-router-karaf-feature", - "unomi-groovy-actions", - "unomi-rest-ui", - "cdp-graphql-feature", - "unomi-startup-complete" - ); - distributionOption = features( - maven().groupId("org.apache.unomi").artifactId("unomi-distribution").versionAsInProject().type("xml").classifier("features"), - "unomi-distribution-elasticsearch-graphql" - ); - } else if (SEARCH_ENGINE_OPENSEARCH.equals(searchEngine)) { - featuresOption = features( - maven().groupId("org.apache.unomi").artifactId("unomi-kar").versionAsInProject().type("xml").classifier("features"), - "unomi-base", - "unomi-startup", - "unomi-opensearch-core", - "unomi-persistence-core", - "unomi-services", - "unomi-cxs-privacy-extension-services", - "unomi-plugins-base", - "unomi-plugins-request", - "unomi-plugins-mail", - "unomi-plugins-optimization-test", - "unomi-rest-api", - "unomi-cxs-privacy-extension", - "unomi-opensearch-conditions", - "unomi-cxs-lists-extension", - "unomi-cxs-geonames-extension", - "unomi-shell-dev-commands", - "unomi-wab", - "unomi-web-tracker", - "unomi-healthcheck-opensearch", - "unomi-router-karaf-feature", - "unomi-groovy-actions", - "unomi-rest-ui", - "cdp-graphql-feature", - "unomi-startup-complete" - ); - distributionOption = features( - maven().groupId("org.apache.unomi").artifactId("unomi-distribution").versionAsInProject().type("xml").classifier("features"), - "unomi-distribution-opensearch-graphql" - ); - } else { - throw new IllegalArgumentException("Unknown search engine: " + searchEngine); + LOGGER.info("Persistence provider: {}", searchEngine); + System.out.println("Persistence provider: " + searchEngine); } + PersistenceITBackend backend = getPersistenceBackend(); + Option[] backendFeatures = backend.featureOptions(); + Option[] backendConfig = backend.configurationOptions(); + Option[] options = new Option[]{ - replaceConfigurationFile("etc/org.apache.unomi.router.cfg", new File("src/test/resources/org.apache.unomi.router.cfg")), - replaceConfigurationFile("data/tmp/1-basic-test.csv", new File("src/test/resources/1-basic-test.csv")), - replaceConfigurationFile("data/tmp/recurrent_import/2-surfers-test.csv", new File("src/test/resources/2-surfers-test.csv")), - replaceConfigurationFile("data/tmp/recurrent_import/3-surfers-overwrite-test.csv", new File("src/test/resources/3-surfers-overwrite-test.csv")), - replaceConfigurationFile("data/tmp/recurrent_import/4-surfers-delete-test.csv", new File("src/test/resources/4-surfers-delete-test.csv")), - replaceConfigurationFile("data/tmp/recurrent_import/5-ranking-test.csv", new File("src/test/resources/5-ranking-test.csv")), - replaceConfigurationFile("data/tmp/recurrent_import/6-actors-test.csv", new File("src/test/resources/6-actors-test.csv")), - replaceConfigurationFile("data/tmp/testLogin.json", new File("src/test/resources/testLogin.json")), - replaceConfigurationFile("data/tmp/testCopyProperties.json", new File("src/test/resources/testCopyProperties.json")), - replaceConfigurationFile("data/tmp/testCopyPropertiesWithoutSystemTags.json", new File("src/test/resources/testCopyPropertiesWithoutSystemTags.json")), - replaceConfigurationFile("data/tmp/testLoginEventCondition.json", new File("src/test/resources/testLoginEventCondition.json")), - replaceConfigurationFile("data/tmp/testClickEventCondition.json", new File("src/test/resources/testClickEventCondition.json")), - replaceConfigurationFile("data/tmp/testRuleGroovyAction.json", new File("src/test/resources/testRuleGroovyAction.json")), - replaceConfigurationFile("data/tmp/conditions/testIdsConditionLegacy.json", new File("src/test/resources/conditions/testIdsConditionLegacy.json")), - replaceConfigurationFile("data/tmp/conditions/testIdsConditionNew.json", new File("src/test/resources/conditions/testIdsConditionNew.json")), - replaceConfigurationFile("data/tmp/conditions/testBooleanConditionLegacy.json", new File("src/test/resources/conditions/testBooleanConditionLegacy.json")), - replaceConfigurationFile("data/tmp/conditions/testPropertyConditionLegacy.json", new File("src/test/resources/conditions/testPropertyConditionLegacy.json")), - replaceConfigurationFile("data/tmp/groovy/UpdateAddressAction.groovy", new File("src/test/resources/groovy/UpdateAddressAction.groovy")), + replaceConfigurationFile("etc/org.apache.unomi.router.cfg", resolveTestResource("src/test/resources/org.apache.unomi.router.cfg")), + replaceConfigurationFile("data/tmp/1-basic-test.csv", resolveTestResource("src/test/resources/1-basic-test.csv")), + replaceConfigurationFile("data/tmp/recurrent_import/2-surfers-test.csv", resolveTestResource("src/test/resources/2-surfers-test.csv")), + replaceConfigurationFile("data/tmp/recurrent_import/3-surfers-overwrite-test.csv", resolveTestResource("src/test/resources/3-surfers-overwrite-test.csv")), + replaceConfigurationFile("data/tmp/recurrent_import/4-surfers-delete-test.csv", resolveTestResource("src/test/resources/4-surfers-delete-test.csv")), + replaceConfigurationFile("data/tmp/recurrent_import/5-ranking-test.csv", resolveTestResource("src/test/resources/5-ranking-test.csv")), + replaceConfigurationFile("data/tmp/recurrent_import/6-actors-test.csv", resolveTestResource("src/test/resources/6-actors-test.csv")), + replaceConfigurationFile("data/tmp/testLogin.json", resolveTestResource("src/test/resources/testLogin.json")), + replaceConfigurationFile("data/tmp/testCopyProperties.json", resolveTestResource("src/test/resources/testCopyProperties.json")), + replaceConfigurationFile("data/tmp/testCopyPropertiesWithoutSystemTags.json", resolveTestResource("src/test/resources/testCopyPropertiesWithoutSystemTags.json")), + replaceConfigurationFile("data/tmp/testLoginEventCondition.json", resolveTestResource("src/test/resources/testLoginEventCondition.json")), + replaceConfigurationFile("data/tmp/testClickEventCondition.json", resolveTestResource("src/test/resources/testClickEventCondition.json")), + replaceConfigurationFile("data/tmp/testRuleGroovyAction.json", resolveTestResource("src/test/resources/testRuleGroovyAction.json")), + replaceConfigurationFile("data/tmp/conditions/testIdsConditionLegacy.json", resolveTestResource("src/test/resources/conditions/testIdsConditionLegacy.json")), + replaceConfigurationFile("data/tmp/conditions/testIdsConditionNew.json", resolveTestResource("src/test/resources/conditions/testIdsConditionNew.json")), + replaceConfigurationFile("data/tmp/conditions/testBooleanConditionLegacy.json", resolveTestResource("src/test/resources/conditions/testBooleanConditionLegacy.json")), + replaceConfigurationFile("data/tmp/conditions/testPropertyConditionLegacy.json", resolveTestResource("src/test/resources/conditions/testPropertyConditionLegacy.json")), + replaceConfigurationFile("data/tmp/groovy/UpdateAddressAction.groovy", resolveTestResource("src/test/resources/groovy/UpdateAddressAction.groovy")), editConfigurationFilePut("etc/org.ops4j.pax.logging.cfg", "log4j2.rootLogger.level", "INFO"), editConfigurationFilePut("etc/org.apache.karaf.features.cfg", "serviceRequirements", "disable"), editConfigurationFilePut("etc/system.properties", "my.system.property", System.getProperty("my.system.property")), - editConfigurationFilePut("etc/system.properties", SEARCH_ENGINE_PROPERTY, System.getProperty(SEARCH_ENGINE_PROPERTY, SEARCH_ENGINE_ELASTICSEARCH)), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.elasticsearch.cluster.name", "contextElasticSearchITests"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.elasticsearch.addresses", "localhost:" + getSearchPort()), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.elasticsearch.taskWaitingPollingInterval", "50"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.elasticsearch.rollover.maxDocs", "300"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.elasticsearch.minimalClusterState", "YELLOW"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.cluster.name", "contextElasticSearchITests"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.addresses", "localhost:" + getSearchPort()), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.username", "admin"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.password", "Unomi.1ntegrat10n.Tests"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.sslEnable", "false"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.sslTrustAllCertificates", "true"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.rollover.maxDocs", "300"), - editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.opensearch.minimalClusterState", "YELLOW"), + editConfigurationFilePut("etc/system.properties", SEARCH_ENGINE_PROPERTY, searchEngine), + editConfigurationFilePut("etc/system.properties", PERSISTENCE_PROVIDER_PROPERTY, searchEngine), editConfigurationFilePut("etc/custom.system.properties", "org.apache.unomi.migration.tenant.id", TEST_TENANT_ID), // Default scheduler.thread.poolSize (5) is sized for the near-instant in-memory unit-test // double, not a real ES/OS backend. Under real refresh/write latency, the checker, task @@ -680,9 +682,6 @@ public Option[] config() { systemProperty("org.ops4j.pax.exam.rbc.rmi.port").value("1199"), systemProperty("org.apache.unomi.healthcheck.enabled").value("true"), - featuresOption, // Add the features option - distributionOption, // Add the distribution option - configureConsole().startRemoteShell(), logLevel(LogLevel.INFO), keepRuntimeFolder(), @@ -691,6 +690,8 @@ public Option[] config() { }; List