)]}'
{
  "log": [
    {
      "commit": "c85fb8856aee58b4b755d170bca79eb2f08f3501",
      "tree": "b58c1865b22fcb694c75cee5b1e004c5236bd2f8",
      "parents": [
        "e9a3300526e29bd9870fa7b2d7d98bf92192ef4f"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Mon Apr 20 07:08:45 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 20 07:08:45 2026 +0200"
      },
      "message": "UNOMI-882: Enable AsciiDoctor diagrams (PlantUML/GraphViz) and expand manual (#753)\n\nCo-authored-by: Jerome Blanchard \u003cjblanchard@jahia.com\u003e"
    },
    {
      "commit": "e9a3300526e29bd9870fa7b2d7d98bf92192ef4f",
      "tree": "fd1c4169fbc79a7ad4b1f8a36ce8f26c1313fcf0",
      "parents": [
        "9fd07d622910d638cd7c0532ddc0b6300d24003e"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Apr 15 14:09:05 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 15 14:09:05 2026 +0200"
      },
      "message": "UNOMI-936: Update log format (#752)\n\nIncludes coloration for log level and reduce the diff with the original Karaf configuration."
    },
    {
      "commit": "9fd07d622910d638cd7c0532ddc0b6300d24003e",
      "tree": "ec612ecd97281058476fd728d0d720f7846618db",
      "parents": [
        "959299ba81d80e31efc93c45f82ca17300872d22"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Fri Mar 06 16:20:39 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 06 16:20:39 2026 +0100"
      },
      "message": "UNOMI-930: sync startup log display to avoid to see it twice (#749)"
    },
    {
      "commit": "959299ba81d80e31efc93c45f82ca17300872d22",
      "tree": "f82247f13dc528dabbcc7d73b8ba9bd83793321e",
      "parents": [
        "c2185035a67d38249b4b1fa2e0a5a0756653d748"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Feb 19 13:33:57 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Feb 19 13:33:57 2026 +0100"
      },
      "message": "fix: Fix unexisting bundle maven type for artefact httpclient-osgi (#751)\n\n"
    },
    {
      "commit": "c2185035a67d38249b4b1fa2e0a5a0756653d748",
      "tree": "43d2bbc1534a4093ac8ee198598b7565e5d279b2",
      "parents": [
        "15ae3eaca8c640a00df255bb0da781fa55f19fa8"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Tue Feb 10 18:08:18 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Feb 10 18:08:18 2026 +0100"
      },
      "message": "Upgrade CodeQL Action from v2 to v3 in JavaScript workflow (#750)\n\nWe need this fixed so that tests can complete successfully"
    },
    {
      "commit": "15ae3eaca8c640a00df255bb0da781fa55f19fa8",
      "tree": "dfa833e624ccc1f8f4d2bab6a481db8717680816",
      "parents": [
        "28772582f65efb95e719ec2b4c9a69b1bf5bf986"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Jan 09 08:31:24 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jan 09 08:31:24 2026 +0100"
      },
      "message": "[UNOMI-924] Add healthcheck activated by default (#748)\n\n"
    },
    {
      "commit": "28772582f65efb95e719ec2b4c9a69b1bf5bf986",
      "tree": "63a28092bfd05551d7f58a392844aa9a768a9431",
      "parents": [
        "c0f145bb030a718e7782578c939099c626fb8b69"
      ],
      "author": {
        "name": "Francois G.",
        "email": "fgerthoffert@jahia.com",
        "time": "Fri Jan 09 08:27:58 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jan 09 08:27:58 2026 +0100"
      },
      "message": "chore: github settings to only enable squash commits (#747)\n\n"
    },
    {
      "commit": "c0f145bb030a718e7782578c939099c626fb8b69",
      "tree": "f823275a5c91faa55df47903e37c658016f45164",
      "parents": [
        "5cc5543c38b3f8bb880abed63c63286d83dd944e"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Jan 07 14:09:59 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jan 07 14:09:59 2026 +0100"
      },
      "message": "[UNOMI-922] Inconsistency between value for nbOfVisits in Profile and number of Sessions (#744)\n\n* UNOMI-922: Incoherency between value for nbOfVisits in Profile and number of Sessions\n* UNOMI-922: Add new ES snapshot to test migration\n* UNOMI-922: Upgrade ES version to ensure snapshot can be restored\n* UNOMI-922: Fix migration test\n* feat: improve batch size for profile migration from 100 to 1000"
    },
    {
      "commit": "5cc5543c38b3f8bb880abed63c63286d83dd944e",
      "tree": "2bef9d53630513ebe84b782dc016fd92f1aa0cce",
      "parents": [
        "1fa563a3d3c00efd9a704109c04dfeb6b8351d62"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Jan 05 15:52:17 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jan 05 15:52:17 2026 +0100"
      },
      "message": "[UNOMI-919] Remove unwanted file"
    },
    {
      "commit": "1fa563a3d3c00efd9a704109c04dfeb6b8351d62",
      "tree": "09994d51057d561d03f3c21250f656d0d2fca41e",
      "parents": [
        "f9e9877fc6136373f13bf4ccc69494a7d1aafef3",
        "f2938484750c7890ae73fdabf5c46294cd86880d"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Jan 05 15:10:02 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jan 05 15:10:02 2026 +0100"
      },
      "message": "[UNOMI-923] Avoid install already installed features and start already started features\n\n"
    },
    {
      "commit": "f2938484750c7890ae73fdabf5c46294cd86880d",
      "tree": "09994d51057d561d03f3c21250f656d0d2fca41e",
      "parents": [
        "f9e9877fc6136373f13bf4ccc69494a7d1aafef3"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Dec 19 09:10:40 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Jan 05 11:23:43 2026 +0100"
      },
      "message": "Avoid install already installed features and start already started features. This avoid duplicate installation in tests.\n\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\nindex 8d4ecae21..5c94eef60 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n@@ -101,16 +101,14 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n     private BundleWatcher bundleWatcher;\n\n     private final ExecutorService executor \u003d Executors.newSingleThreadExecutor();\n-    private final List\u003cString\u003e installedDistributionDependencies \u003d new ArrayList\u003c\u003e();\n-    private final List\u003cString\u003e startedDistributionDependencies \u003d new ArrayList\u003c\u003e();\n-\n-    private BundleContext bundleContext;\n+    private final List\u003cString\u003e trackedInstalledDistributionDependencies \u003d new ArrayList\u003c\u003e();\n+    private final List\u003cString\u003e trackedStartedDistributionDependencies \u003d new ArrayList\u003c\u003e();\n\n     @Activate\n     public void init(ComponentContext componentContext) throws Exception {\n         LOGGER.info(\"Initializing Unomi management service\");\n         try {\n-            this.bundleContext \u003d componentContext.getBundleContext();\n+            BundleContext bundleContext \u003d componentContext.getBundleContext();\n\n             UnomiSetup setup \u003d getUnomiSetup();\n             if (setup \u003d\u003d null) {\n@@ -201,10 +199,28 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n                 return;\n             }\n             for (Dependency dependency : feature.getDependencies()) {\n-                if (!installedDistributionDependencies.contains(dependency.getName())) {\n-                    LOGGER.info(\"Installing distribution feature\u0027s dependency: {}\", dependency.getName());\n-                    featuresService.installFeature(dependency.getName(), dependency.getVersion(), EnumSet.of(FeaturesService.Option.NoAutoStartBundles));\n-                    installedDistributionDependencies.add(dependency.getName());\n+                try {\n+                    Feature depFeature \u003d featuresService.getFeature(dependency.getName(), dependency.getVersion());\n+                    if (depFeature !\u003d null) {\n+                        List\u003cFeature\u003e karafInstalledFeatures \u003d Arrays.stream(featuresService.listInstalledFeatures()).toList();\n+                        if (!trackedInstalledDistributionDependencies.contains(dependency.getName())) {\n+                            Optional\u003cFeature\u003e karafInstalledFeature \u003d karafInstalledFeatures.stream()\n+                                    .filter(f -\u003e f.getName().equals(depFeature.getName()) \u0026\u0026 f.getVersion().equals(depFeature.getVersion())).findFirst();\n+                            if (karafInstalledFeature.isEmpty()) {\n+                                LOGGER.info(\"Installing distribution\u0027s dependency feature: {}\", depFeature);\n+                                featuresService.installFeature(depFeature, EnumSet.of(FeaturesService.Option.NoAutoStartBundles));\n+                            } else {\n+                                LOGGER.info(\"Feature {} is already installed, skipping installation.\", karafInstalledFeature.get());\n+                            }\n+                            LOGGER.info(\"Installing distribution feature\u0027s dependency: {}\", dependency.getName());\n+                            featuresService.installFeature(dependency.getName(), dependency.getVersion(), EnumSet.of(FeaturesService.Option.NoAutoStartBundles));\n+                            trackedInstalledDistributionDependencies.add(dependency.getName());\n+                        }\n+                    } else {\n+                        LOGGER.error(\"Distribution\u0027s dependency feature not found: {}\", dependency);\n+                    }\n+                } catch (Exception e) {\n+                    LOGGER.error(\"Error installing distribution\u0027s dependency feature: {}\", dependency, e);\n                 }\n             }\n         } catch (Exception e) {\n@@ -213,18 +229,18 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n\n         if (mustStartDistribution) {\n             LOGGER.info(\"Starting distribution: {}\", distribution);\n-            for (String featureName : installedDistributionDependencies) {\n+            for (String featureName : trackedInstalledDistributionDependencies) {\n                 try {\n                     Feature feature \u003d featuresService.getFeature(featureName);\n                     if (feature \u003d\u003d null) {\n                         LOGGER.error(\"Distribution feature\u0027s dependency not found: {}\", featureName);\n                         continue;\n                     }\n-                    LOGGER.info(\"Starting dependency: {}\", featureName);\n-                    startFeature(featureName);\n-                    startedDistributionDependencies.add(featureName); // Keep track of started distribution dependencies\n+                    LOGGER.info(\"Starting distribution\u0027s dependency feature: {}\", featureName);\n+                    startFeature(feature.getName(), feature.getVersion());\n+                    trackedStartedDistributionDependencies.add(featureName); // Keep track of started distribution dependencies\n                 } catch (Exception e) {\n-                    LOGGER.error(\"Error starting feature: {}\", featureName, e);\n+                    LOGGER.error(\"Error starting distribution\u0027s dependency feature: {}\", featureName, e);\n                 }\n             }\n         }\n@@ -258,57 +274,63 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n     }\n\n     private void doStopUnomi() throws Exception {\n-        if (startedDistributionDependencies.isEmpty()) {\n-            LOGGER.info(\"No features to stop.\");\n+        if (trackedStartedDistributionDependencies.isEmpty()) {\n+            LOGGER.info(\"No distribution\u0027s dependency features to stop.\");\n         } else {\n-            LOGGER.info(\"Stopping features in reverse order...\");\n-            ListIterator\u003cString\u003e iterator \u003d startedDistributionDependencies.listIterator(startedDistributionDependencies.size());\n+            LOGGER.info(\"Stopping distribution\u0027s dependency features in reverse order...\");\n+            ListIterator\u003cString\u003e iterator \u003d trackedStartedDistributionDependencies.listIterator(trackedStartedDistributionDependencies.size());\n             while (iterator.hasPrevious()) {\n                 String featureName \u003d iterator.previous();\n                 try {\n-                    LOGGER.info(\"Stopping feature: {}\", featureName);\n+                    LOGGER.info(\"Stopping distribution\u0027s dependency feature: {}\", featureName);\n                     stopFeature(featureName);\n                 } catch (Exception e) {\n-                    LOGGER.error(\"Error stopping feature: {}\", featureName, e);\n+                    LOGGER.error(\"Error stopping distribution\u0027s dependency feature: {}\", featureName, e);\n                 }\n             }\n\n-            startedDistributionDependencies.clear(); // Clear the list after stopping all features\n+            trackedStartedDistributionDependencies.clear(); // Clear the list after stopping all features\n         }\n-        if (installedDistributionDependencies.isEmpty()) {\n-            LOGGER.info(\"No features to uninstall.\");\n+        if (trackedInstalledDistributionDependencies.isEmpty()) {\n+            LOGGER.info(\"No distribution\u0027s dependency features to uninstall.\");\n         } else {\n-            LOGGER.info(\"Stopping features in reverse order...\");\n-            ListIterator\u003cString\u003e iterator \u003d installedDistributionDependencies.listIterator(installedDistributionDependencies.size());\n+            LOGGER.info(\"Stopping distribution\u0027s dependency features in reverse order...\");\n+            ListIterator\u003cString\u003e iterator \u003d trackedInstalledDistributionDependencies.listIterator(trackedInstalledDistributionDependencies.size());\n             while (iterator.hasPrevious()) {\n                 String featureName \u003d iterator.previous();\n                 try {\n-                    LOGGER.info(\"Uninstalling feature: {}\", featureName);\n+                    LOGGER.info(\"Uninstalling distribution\u0027s dependency feature: {}\", featureName);\n                     featuresService.uninstallFeature(featureName);\n                 } catch (Exception e) {\n-                    LOGGER.error(\"Error uninstalling feature: {}\", featureName, e);\n+                    LOGGER.error(\"Error uninstalling distribution\u0027s dependency feature: {}\", featureName, e);\n                 }\n             }\n-            installedDistributionDependencies.clear(); // Clear the list after stopping all features\n+            trackedInstalledDistributionDependencies.clear(); // Clear the list after stopping all features\n         }\n     }\n\n-    private void startFeature(String featureName) throws Exception {\n-        Feature feature \u003d featuresService.getFeature(featureName);\n+    private void startFeature(String featureName, String version) throws Exception {\n+        Feature feature \u003d featuresService.getFeature(featureName, version);\n         Map\u003cString, Map\u003cString, FeatureState\u003e\u003e stateChanges \u003d new HashMap\u003c\u003e();\n         Map\u003cString, FeatureState\u003e regionChanges \u003d new HashMap\u003c\u003e();\n-        regionChanges.put(feature.getId(), FeatureState.Started);\n-        stateChanges.put(FeaturesService.ROOT_REGION, regionChanges);\n-        featuresService.updateFeaturesState(stateChanges, EnumSet.of(FeaturesService.Option.Verbose));\n+        FeatureState state \u003d featuresService.getState(feature.getId());\n+        if (state !\u003d FeatureState.Started) {\n+            regionChanges.put(feature.getId(), FeatureState.Started);\n+            stateChanges.put(FeaturesService.ROOT_REGION, regionChanges);\n+            featuresService.updateFeaturesState(stateChanges, EnumSet.of(FeaturesService.Option.Verbose));\n+        }\n     }\n\n     private void stopFeature(String featureName) throws Exception {\n         Feature feature \u003d featuresService.getFeature(featureName);\n         Map\u003cString, Map\u003cString, FeatureState\u003e\u003e stateChanges \u003d new HashMap\u003c\u003e();\n         Map\u003cString, FeatureState\u003e regionChanges \u003d new HashMap\u003c\u003e();\n-        regionChanges.put(feature.getId(), FeatureState.Resolved);\n-        stateChanges.put(FeaturesService.ROOT_REGION, regionChanges);\n-        featuresService.updateFeaturesState(stateChanges, EnumSet.of(FeaturesService.Option.Verbose));\n+        FeatureState state \u003d featuresService.getState(feature.getId());\n+        if (state \u003d\u003d FeatureState.Started) {\n+            regionChanges.put(feature.getId(), FeatureState.Resolved);\n+            stateChanges.put(FeaturesService.ROOT_REGION, regionChanges);\n+            featuresService.updateFeaturesState(stateChanges, EnumSet.of(FeaturesService.Option.Verbose));\n+        }\n     }\n\n     @Deactivate\n"
    },
    {
      "commit": "f9e9877fc6136373f13bf4ccc69494a7d1aafef3",
      "tree": "95fba0c00384d254e22f921da2d72c8fde862482",
      "parents": [
        "0c44c9bd20bcbb38971a0100911978d80b2f1533",
        "4b95b49f9ef23e89b58aa7ccabd76bb138b1e6e3"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Jan 05 09:34:48 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jan 05 09:34:48 2026 +0100"
      },
      "message": "UNOMI-919: Refactor the UNOMI startFeatures configuration to use a Karaf feature\n\n"
    },
    {
      "commit": "4b95b49f9ef23e89b58aa7ccabd76bb138b1e6e3",
      "tree": "95fba0c00384d254e22f921da2d72c8fde862482",
      "parents": [
        "2b7aa2738a560aad327b26fc650d4a0cbf1afacc"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Jan 02 08:10:21 2026 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Jan 02 08:10:21 2026 +0100"
      },
      "message": "fix: fix test missed in merge\n"
    },
    {
      "commit": "2b7aa2738a560aad327b26fc650d4a0cbf1afacc",
      "tree": "c233291812edc94d32af9509db652f7b7849e6d7",
      "parents": [
        "3dc54983c6720e933f27e98c8564faf60a3ea3f1"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 14:59:37 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:29:14 2025 +0100"
      },
      "message": "doc: update documentation for distribution\n\ndiff --git c/manual/src/main/asciidoc/configuration.adoc i/manual/src/main/asciidoc/configuration.adoc\nindex b3d97a936..4d923ad88 100644\n--- c/manual/src/main/asciidoc/configuration.adoc\n+++ i/manual/src/main/asciidoc/configuration.adoc\n@@ -876,60 +876,143 @@ The following permissions are required by Unomi:\n  - required cluster privileges: `manage` OR `all`\n  - required index privileges on unomi indices: `write, manage, read` OR `all`\n\n-\u003d\u003d\u003d Customizing Start Features Configuration\n+\u003d\u003d\u003d Unomi Distribution (features configuration)\n\n-Apache Unomi allows you to customize which features and bundles are installed and started when using the `unomi:start` command. This is controlled through the `org.apache.unomi.start.cfg` configuration file.\n+You can define a specific distribution for Apache Unomi to configure desired features when the server boots up. Is it a classic Karaf feature that defines desired features for Unomi.\n+Be aware that, even if a distribution is a classic Karaf feature XML file, it must only be composed feature\u0027s dependencies as this file is interpreted by the Unomi ManagementService.\n+No bundle nor config file will be processed from this file.\n\n-\u003d\u003d\u003d\u003d Default Configuration\n+To set the desired distribution, set the `unomi.distribution` system property or `UNOMI_DISTRIBUTION` environment variable to the name of your desired distribution.\n+You can also use the dedicated `unomi:setup` command to set the distribution interactively.\n\n-By default, Apache Unomi comes with two predefined start features configurations:\n+Apache Unomi comes with some predefined distributions that you can use directly.\n\n-[source]\n-----\n-startFeatures \u003d [\n-    \"elasticsearch\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\",\n-    \"opensearch\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\"\n-]\n-----\n+\u003d\u003d\u003d\u003d Default Distributions\n\n-**Key Differences Between Configurations:**\n+By default, Apache Unomi comes with four predefined distributions:\n+\n+unomi-distribution-elasticsearch, unomi-distribution-elasticsearch-graphql, unomi-distribution-opensearch, unomi-distribution-opensearch-graphql\n+\n+**Key Differences Between Distributions:**\n\n The only difference between the Elasticsearch and OpenSearch configurations is the persistence layer:\n\n * **Elasticsearch**: Uses `unomi-elasticsearch-core` and `unomi-elasticsearch-conditions`\n * **OpenSearch**: Uses `unomi-opensearch-core` and `unomi-opensearch-conditions`\n\n-All other features remain identical between both configurations.\n+All other features remain identical between both configurations. Each one is derived with or without GraphQL support.\n\n-\u003d\u003d\u003d\u003d Environment-Specific Configurations\n+\u003d\u003d\u003d\u003d Environment-Specific Distributions\n\n-You can create different configurations for different deployment environments by including or excluding certain features:\n+You can create different distributions for different deployment environments by creating a dedicated distribution feature.\n+\n+Be aware that in distribution\u0027s feature, you should only reference other features, not bundles or configuration directly.\n\n **Development Environment** (includes development tools and debugging features):\n-[source]\n+[source,xml]\n ----\n-startFeatures \u003d [\n-    \"elasticsearch-dev\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\",\n-    \"opensearch-dev\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\"\n-]\n+\u003cfeatures name\u003d\"unomi-distributions\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n+\n+    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.unomi/unomi-kar/${project.version}/xml/features\u003c/repository\u003e\n+\n+    \u003cfeature name\u003d\"unomi-distribution-elasticsearch-dev\" description\u003d\"Apache Unomi :: ElasticSearch Development Distribution\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-optimization-test\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-shell-dev-commands\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\u003c/features\u003e\n ----\n\n **Staging Environment** (production-like but with some development features):\n-[source]\n+[source,xml]\n ----\n-startFeatures \u003d [\n-    \"elasticsearch-staging\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\",\n-    \"opensearch-staging\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\"\n-]\n+\u003cfeatures name\u003d\"unomi-distributions\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n+\n+    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.unomi/unomi-kar/${project.version}/xml/features\u003c/repository\u003e\n+\n+    \u003cfeature name\u003d\"unomi-distribution-elasticsearch-staging\" description\u003d\"Apache Unomi :: ElasticSearch Staging Distribution\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-optimization-test\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-shell-dev-commands\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\u003c/features\u003e\n ----\n\n **Production Environment** (minimal, secure configuration):\n-[source]\n+[source,xml]\n ----\n-startFeatures \u003d [\n-    \"elasticsearch-prod\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\",\n-    \"opensearch-prod\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\"\n-]\n+\u003cfeatures name\u003d\"unomi-distributions\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n+\n+    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.unomi/unomi-kar/${project.version}/xml/features\u003c/repository\u003e\n+\n+    \u003cfeature name\u003d\"unomi-distribution-elasticsearch-prod\" description\u003d\"Apache Unomi :: ElasticSearch Production Distribution\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-optimization-test\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\u003c/features\u003e\n ----\n\n **Environment Differences Summary:**\n@@ -949,37 +1032,32 @@ startFeatures \u003d [\n |✗ (excluded)\n |\u003d\u003d\u003d\n\n-\u003d\u003d\u003d\u003d Configuration Format\n+\u003d\u003d\u003d\u003d Distribution Feature Format\n\n-Each start features configuration follows this format:\n+Each start features configuration follows the classic Karaf features XML format, but you must only reference other features in your distribution feature.\n+If you reference bundles or configuration files directly, they will be ignored by Unomi.\n+\n+To use a custom distribution, the corresponding feature must be accessible by Karaf. It can be done by publishing the feature maven artefact and adding it as a feature repository in Karaf os for any other feature. Of course you can also add your distribution feature in the existing source code and repackage Unomi making it available directly.\n+\n+\u003d\u003d\u003d\u003d Using Custom Distributions\n+\n+You can use your custom distribution with:\n\n [source]\n ----\n-\"configuration-name\u003dfeature1,feature2,feature3,...\"\n+# Using system property\n+-Dunomi.distribution\u003dunomi-distribution-elasticsearch\n+\n+# Using environment variable\n+UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n+\n+# Using the setup command\n+unomi:setup unomi-distribution-elasticsearch-staging\n ----\n\n-Where:\n-* `configuration-name` is the identifier you\u0027ll use with the `unomi:start` command\n-* The comma-separated list contains the Karaf features to install and start\n-\n-\u003d\u003d\u003d\u003d Using Custom Configurations\n-\n-You can use your custom configurations with:\n-\n-[source]\n-----\n-# Development environment\n-unomi:start elasticsearch-dev\n-unomi:start opensearch-dev\n-\n-# Staging environment\n-unomi:start elasticsearch-staging\n-unomi:start opensearch-staging\n-\n-# Production environment\n-unomi:start elasticsearch-prod\n-unomi:start opensearch-prod\n-----\n+Once you have called the `unomi:setup` command with your desired distribution, you can start Apache Unomi using the `unomi:start` command.\n+The setup command only needs to be called once unless you want to change the distribution ; it creates a marker file to remember the chosen distribution.\n+In case you want to change it, you can use the `unomi:setup --force` command again with the desired distribution name (using the --force option will override the existing distribution).\n\n \u003d\u003d\u003d\u003d Auto-Start\n\n@@ -989,27 +1067,17 @@ To enable auto-start, set the `unomi.autoStart` system property or `UNOMI_AUTO_S\n\n Note: Auto-start only works when Apache Unomi is not already running. If the server is already started, the auto-start setting will be ignored.\n\n-\u003d\u003d\u003d\u003d Unomi Distribution\n+\u003d\u003d\u003d Customizing Apache Unomi Distribution\n\n-You can define a specific distribution for Apache Unomi to configure desired features when the server boots up. Is it a classic Karaf feature that defines desired features for Unomi.\n-Be aware that, even if a distribution is a classic Karaf feature XML file, it must only be composed feature\u0027s dependencies as this file is interpreted by the Unomi ManagementService.\n-No bundle nor config file will be processed from this file.\n+Apache Unomi allows you to create custom distributions by repackaging the standard distribution with your own configuration files and customizations. This is useful for creating deployment-specific packages that include your custom configurations, plugins, and settings.\n\n-To set the desired distribution, set the `unomi.distribution` system property or `UNOMI_DISTRIBUTION` environment variable to the name of your desired distribution:\n+\u003d\u003d\u003d\u003d Note on Custom Distributions (Advanced)\n\n-[source]\n-----\n-# Using system property\n--Dunomi.distribution\u003dunomi-distribution-elasticsearch\n+You can build custom distributions of Unomi using the Karaf Maven Plugin to assemble features and overlay configuration. This is an advanced path and not required for most users. We recommend Docker-based packaging and configuration overrides as documented above.\n\n-# Using environment variable (Docker)\n-UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n+For details about custom distributions, see the Karaf documentation (Karaf Maven Plugin):\n\n-# Using custom distribution\n-UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch-staging\n-----\n-\n-To use a custom distribution, the corresponding feature must be accessible by Karaf. It can be done by publishing the feature maven artefact and adding it as a feature repository in Karaf os for any other feature. Of course you can also add your distribution feature in the existing source code and repackage Unomi making it available directly.\n+`https://karaf.apache.org/manual/latest/#_karaf_maven_plugin`\n\n \u003d\u003d\u003d\u003d Important Notes\n\n@@ -1059,18 +1127,6 @@ services:\n - Declare the feature repository in Karaf using KARAF_FEATURES_REPOSITORIES environment variable pointing to your mounted file or a online maven artifact (mvn:com.example/custom-unomi-distribs/1.0.0/xml/features)\n - Use the `UNOMI_DISTRIBUTION` environment variable to specify which distribution (using the feature name) to use from that feature\u0027s repository\n\n-\u003d\u003d\u003d Customizing Apache Unomi Distribution\n-\n-Apache Unomi allows you to create custom distributions by repackaging the standard distribution with your own configuration files and customizations. This is useful for creating deployment-specific packages that include your custom configurations, plugins, and settings.\n-\n-\u003d\u003d\u003d\u003d Note on Custom Distributions (Advanced)\n-\n-You can build custom distributions of Unomi using the Karaf Maven Plugin to assemble features and overlay configuration. This is an advanced path and not required for most users. We recommend Docker-based packaging and configuration overrides as documented above.\n-\n-For details about custom distributions, see the Karaf documentation (Karaf Maven Plugin):\n-\n-`https://karaf.apache.org/manual/latest/#_karaf_maven_plugin`\n-\n \u003d\u003d\u003d\u003d Configuration Override Priority\n\n Apache Unomi follows this priority order for configuration files (highest to lowest priority):\ndiff --git c/manual/src/main/asciidoc/shell-commands.adoc i/manual/src/main/asciidoc/shell-commands.adoc\nindex 5bcb32ddc..515d63cf9 100644\n--- c/manual/src/main/asciidoc/shell-commands.adoc\n+++ i/manual/src/main/asciidoc/shell-commands.adoc\n@@ -65,6 +65,11 @@ The commands control the lifecycle of the Apache Unomi server and are used to mi\n |\u003d\u003d\u003d\n |Command|Arguments|Description\n\n+|setup\n+|distribution-feature-name,--force\n+|This command must be used only when the Apache Unomi application is NOT STARTED. It will perform initial setup of the application\n+using the specified distribution feature name (unomi-distribution-elasticsearch for example).\n+\n |migrate\n |fromVersion\n |This command must be used only when the Apache Unomi application is NOT STARTED. It will perform migration of the data stored in search engine using the argument fromVersion as a starting point.\n@@ -74,8 +79,8 @@ The commands control the lifecycle of the Apache Unomi server and are used to mi\n |Shutsdown the Apache Unomi application\n\n |start\n-|startFeatures\n-|Starts the Apache Unomi application with the specified start features configuration (elasticsearch or opensearch). Note that this state will be remembered between Apache Karaf launches, so in general it is only needed after a first installation or after a `migrate` command\n+|n/a\n+|Starts the Apache Unomi application with the specified distribution (or by default unomi-distribution-elasticsearch). Note that this state will be remembered between Apache Karaf launches, so in general it is only needed after a first installation\n\n |version\n |n/a\n@@ -195,4 +200,4 @@ and interactive mode except that it undeploys definitions instead of deploying t\n working on a plugin. For example to remove all the definitions deployed by a plugin you can simply use the following\n command: `undeploy-definition BUNDLE_ID * *` when `BUNDLE_ID` is the identifier of the bundle that contains your plugin.\n\n-|\u003d\u003d\u003d\n\\ No newline at end of file\n+|\u003d\u003d\u003d\ndiff --git c/manual/src/main/asciidoc/writing-plugins.adoc i/manual/src/main/asciidoc/writing-plugins.adoc\nindex c2b49fee1..b485f0cea 100644\n--- c/manual/src/main/asciidoc/writing-plugins.adoc\n+++ i/manual/src/main/asciidoc/writing-plugins.adoc\n@@ -162,14 +162,40 @@ OpenSearch Bundle (my-plugin-opensearch):\n\n \u003d\u003d\u003d\u003d Configuration and Deployment\n\n-Administrators can control which search engine implementation to use through the `org.apache.unomi.start.cfg` configuration file. This file determines which features (including your plugin\u0027s bundles) are deployed based on the chosen search engine:\n+Administrators can control which search engine implementation to use by setting up a distribution. This distribution \u0027macro\u0027 feature determines which features (including your plugin\u0027s bundles) are deployed based on the chosen search engine:\n\n-[source]\n+[source,xml]\n ----\n-startFeatures \u003d [\n-    \"elasticsearch\u003dunomi-persistence-elasticsearch,my-plugin-elasticsearch,unomi-services,...\",\n-    \"opensearch\u003dunomi-persistence-opensearch,my-plugin-opensearch,unomi-services,...\"\n-]\n+\u003cfeatures\u003e\n+    \u003cfeature name\u003d\"my-plugin-feature\" version\u003d\"${project.version}\"\u003e\n+        \u003cbundle\u003emvn:my.group.id/my-plugin-common/${project.version}\u003c/bundle\u003e\n+        \u003cbundle\u003emvn:my.group.id/my-plugin-${search.engine}/${project.version}\u003c/bundle\u003e\n+    \u003c/feature\u003e\n+\n+    \u003cfeature name\u003d\"my-unomi-distribution-with-my-plugin\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003emy-plugin-feature\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\u003c/features\u003e\n ----\n\n \u003d\u003d\u003d\u003d Custom Plugins\n@@ -680,14 +706,14 @@ import org.apache.unomi.persistence.elasticsearch.ConditionESQueryBuilderDispatc\n import java.util.Map;\n\n public class MyCustomQueryBuilder implements ConditionESQueryBuilder {\n-\n+\n     @Override\n-    public Query buildQuery(Condition condition, Map\u003cString, Object\u003e context,\n+    public Query buildQuery(Condition condition, Map\u003cString, Object\u003e context,\n                            ConditionESQueryBuilderDispatcher dispatcher) {\n         // Get parameters from the condition\n         String fieldName \u003d (String) condition.getParameter(\"fieldName\");\n         String fieldValue \u003d (String) condition.getParameter(\"fieldValue\");\n-\n+\n         // Build Elasticsearch-specific query using the new client\n         return Query.of(q -\u003e q\n             .bool(b -\u003e b\n@@ -700,9 +726,9 @@ public class MyCustomQueryBuilder implements ConditionESQueryBuilder {\n             )\n         );\n     }\n-\n+\n     @Override\n-    public long count(Condition condition, Map\u003cString, Object\u003e context,\n+    public long count(Condition condition, Map\u003cString, Object\u003e context,\n                      ConditionESQueryBuilderDispatcher dispatcher) {\n         // Implement count logic if needed\n         return 0;\n@@ -723,14 +749,14 @@ import org.apache.unomi.persistence.opensearch.ConditionOSQueryBuilderDispatcher\n import java.util.Map;\n\n public class MyCustomQueryBuilder implements ConditionOSQueryBuilder {\n-\n+\n     @Override\n-    public Query buildQuery(Condition condition, Map\u003cString, Object\u003e context,\n+    public Query buildQuery(Condition condition, Map\u003cString, Object\u003e context,\n                            ConditionOSQueryBuilderDispatcher dispatcher) {\n         // Get parameters from the condition\n         String fieldName \u003d (String) condition.getParameter(\"fieldName\");\n         String fieldValue \u003d (String) condition.getParameter(\"fieldValue\");\n-\n+\n         // Build OpenSearch-specific query\n         return Query.of(q -\u003e q\n             .bool(b -\u003e b\n@@ -743,9 +769,9 @@ public class MyCustomQueryBuilder implements ConditionOSQueryBuilder {\n             )\n         );\n     }\n-\n+\n     @Override\n-    public long count(Condition condition, Map\u003cString, Object\u003e context,\n+    public long count(Condition condition, Map\u003cString, Object\u003e context,\n                      ConditionOSQueryBuilderDispatcher dispatcher) {\n         // Implement count logic if needed\n         return 0;\n@@ -800,7 +826,7 @@ public class MyCustomQueryBuilder implements ConditionOSQueryBuilder {\n       \"multivalued\": false\n     },\n     {\n-      \"id\": \"fieldValue\",\n+      \"id\": \"fieldValue\",\n       \"type\": \"string\",\n       \"multivalued\": false\n     }\n@@ -854,14 +880,14 @@ my-custom-plugin/\n     \u003cartifactId\u003emy-custom-plugin\u003c/artifactId\u003e\n     \u003cversion\u003e1.0.0\u003c/version\u003e\n     \u003cpackaging\u003epom\u003c/packaging\u003e\n-\n+\n     \u003cmodules\u003e\n         \u003cmodule\u003emy-custom-plugin-common\u003c/module\u003e\n         \u003cmodule\u003emy-custom-plugin-elasticsearch\u003c/module\u003e\n         \u003cmodule\u003emy-custom-plugin-opensearch\u003c/module\u003e\n         \u003cmodule\u003emy-custom-plugin-features\u003c/module\u003e\n     \u003c/modules\u003e\n-\n+\n     \u003cproperties\u003e\n         \u003cunomi.version\u003e3.0.0\u003c/unomi.version\u003e\n     \u003c/properties\u003e\n@@ -877,10 +903,10 @@ my-custom-plugin/\n         \u003cartifactId\u003emy-custom-plugin\u003c/artifactId\u003e\n         \u003cversion\u003e1.0.0\u003c/version\u003e\n     \u003c/parent\u003e\n-\n+\n     \u003cartifactId\u003emy-custom-plugin-elasticsearch\u003c/artifactId\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n-\n+\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n@@ -898,7 +924,7 @@ my-custom-plugin/\n             \u003cversion\u003e1.0.0\u003c/version\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n-\n+\n     \u003cbuild\u003e\n         \u003cplugins\u003e\n             \u003cplugin\u003e\n@@ -926,14 +952,14 @@ my-custom-plugin/\n ----\n \u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\"?\u003e\n \u003cfeatures name\u003d\"my-custom-plugin\" version\u003d\"1.0.0\"\u003e\n-\n+\n     \u003c!-- Elasticsearch feature --\u003e\n     \u003cfeature name\u003d\"my-custom-plugin-elasticsearch\" version\u003d\"1.0.0\"\u003e\n         \u003cbundle\u003emvn:org.apache.unomi.plugins/my-custom-plugin-common/1.0.0\u003c/bundle\u003e\n         \u003cbundle\u003emvn:org.apache.unomi.plugins/my-custom-plugin-elasticsearch/1.0.0\u003c/bundle\u003e\n         \u003cfeature\u003eunomi-elasticsearch\u003c/feature\u003e\n     \u003c/feature\u003e\n-\n+\n     \u003c!-- OpenSearch feature --\u003e\n     \u003cfeature name\u003d\"my-custom-plugin-opensearch\" version\u003d\"1.0.0\"\u003e\n         \u003cbundle\u003emvn:org.apache.unomi.plugins/my-custom-plugin-common/1.0.0\u003c/bundle\u003e\n@@ -981,24 +1007,43 @@ my-custom-plugin/\n      - For OpenSearch: `feature:install my-custom-plugin-opensearch`\n    - Document dependencies and requirements clearly\n\n-\u003d\u003d\u003d\u003d Custom Start Configuration\n+\u003d\u003d\u003d\u003d Custom Distribution Feature\n\n-For production deployments, you can create a custom `org.apache.unomi.start.cfg` file to automatically include your plugin features in the startup configuration. This approach ensures your plugin is automatically deployed when Apache Unomi starts.\n+For production deployments, you can create a custom distribution\u0027s feature file to automatically include your plugin features in the startup configuration. This approach ensures your plugin is automatically deployed when Apache Unomi starts.\n\n-**Creating a Custom Start Configuration:**\n+**Creating a Custom Distribution Feature:**\n\n-1. **Create the configuration file** in your deployment directory:\n-   ```\n-   etc/org.apache.unomi.start.cfg\n-   ```\n+1. **Create the feature file** in a dedicated maven module. You can use the unomi-distribution module as a reference.\n\n-2. **Define your custom configurations** by extending the default ones:\n+2. **Define your custom distribution** by extending the default ones:\n\n-[source,properties]\n+[source,xml]\n ----\n-# Custom start configurations that include your plugin features\n-startFeatures \u003d [ \"elasticsearch\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete,my-custom-plugin-elasticsearch\", \\\n-                  \"opensearch\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete,my-custom-plugin-opensearch\" ]\n+\u003cfeatures name\u003d\"unomi-distributions\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n+    \u003cfeature name\u003d\"unomi-distribution-custom\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003ecustom-feature\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\u003c/features\u003e\n ----\n\n **Key Points:**\n@@ -1008,14 +1053,14 @@ startFeatures \u003d [ \"elasticsearch\u003dunomi-base,unomi-startup,unomi-elasticsearch-co\n - **Dependency management**: Ensure your plugin features are listed after their dependencies (e.g., after `unomi-elasticsearch-core` or `unomi-opensearch-core`)\n\n-**Benefits of Custom Start Configuration:**\n+**Benefits of Custom Distribution Feature:**\n\n - **Automatic deployment**: Your plugin is automatically installed when Apache Unomi starts\n - **Consistent environments**: Ensures the same features are deployed across all environments\n - **Production ready**: No manual feature installation required\n - **Version control**: Configuration can be versioned and managed with your deployment\n\n-**Note**: For more detailed information about customizing start features configurations, including environment-specific examples, see the \u003c\u003cCustomizing Start Features Configuration,Configuration\u003e\u003e section of the documentation.\n+**Note**: For more detailed information about custom distributions, including environment-specific examples, see the \u003c\u003cCustom Distribution Feature,Configuration\u003e\u003e section of the documentation.\n\n 6. **Migration from Legacy Implementations**\n    - **DO NOT** use legacy mappings for custom query builders\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\nindex 607f08729..de7635153 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\n@@ -36,7 +36,7 @@ public interface UnomiManagementService {\n     /**\n      * This method will start Apache Unomi\n      * @param mustStartFeatures true if features should be started, false if they should not\n-     * @throws Exception if there was an error starting Unomi\u0027s bundles\n+     * @throws Exception if there was an error starting Unomi\u0027s features\n      */\n     void startUnomi(boolean mustStartFeatures) throws Exception;\n\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\nindex 5ae349930..8d4ecae21 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n@@ -43,28 +43,24 @@ import java.util.concurrent.*;\n  *\n  * \u003cp\u003eThis service handles the following responsibilities:\u003c/p\u003e\n  * \u003cul\u003e\n- *   \u003cli\u003eLoading configuration from the OSGi Configuration Admin service, including start features configuration and feature lists.\u003c/li\u003e\n- *   \u003cli\u003eStarting Apache Unomi by installing and starting the configured features for a selected start features configuration.\u003c/li\u003e\n+ *   \u003cli\u003eLoading distribution\u0027s feature from an environment variable, a java option or by calling the setupUnomiDistribution method.\u003c/li\u003e\n+ *   \u003cli\u003eStarting Apache Unomi by installing and starting the configured features for a selected distribution.\u003c/li\u003e\n  *   \u003cli\u003eStopping Apache Unomi by uninstalling features in reverse order to ensure proper teardown.\u003c/li\u003e\n  *   \u003cli\u003eInterfacing with the {@link org.apache.unomi.shell.migration.MigrationService} for migration tasks during startup.\u003c/li\u003e\n  * \u003c/ul\u003e\n  *\n- * \u003cp\u003eThe class is designed to be used within an OSGi environment and integrates with the Configuration Admin service\n- * to dynamically adjust its behavior based on external configurations. It leverages the {@link FeaturesService} to\n+ * \u003cp\u003eThe class is designed to be used within an OSGi environment. It leverages the {@link FeaturesService} to\n  * manage Karaf features dynamically.\u003c/p\u003e\n  *\n  * \u003cp\u003e\u003cb\u003eConfiguration\u003c/b\u003e\u003c/p\u003e\n- * \u003cp\u003eThe service reads its configuration from the OSGi Configuration Admin under the PID \u003ccode\u003eorg.apache.unomi.start\u003c/code\u003e.\n- * The configuration includes:\u003c/p\u003e\n- * \u003cul\u003e\n- *   \u003cli\u003e\u003cb\u003estartFeatures\u003c/b\u003e: A semicolon-separated list of features mapped to persistence implementations\n- *       in the format \u003ccode\u003epersistenceImplementation:feature1,feature2\u003c/code\u003e.\u003c/li\u003e\n- * \u003c/ul\u003e\n+ * \u003cp\u003eThe service stores its distribution\u0027s name using the OSGi Configuration Admin under the PID \u003ccode\u003eorg.apache.unomi.setup\u003c/code\u003e.\n+ * This allows the service to persist the selected distribution across restarts. The default distribution is unomi-distribution-elasticsearch\u003c/p\u003e\n  *\n  * \u003cp\u003e\u003cb\u003eUsage\u003c/b\u003e\u003c/p\u003e\n  * \u003cp\u003eThis service can be controlled programmatically through its methods:\u003c/p\u003e\n  * \u003cul\u003e\n- *   \u003cli\u003e{@link #startUnomi(String, boolean)}: Installs and starts features for the specified start features configuration.\u003c/li\u003e\n+ *   \u003cli\u003e{@link #setupUnomiDistribution(String, boolean)}: Sets up the Unomi distribution\u0027s feature name.\u003c/li\u003e\n+ *   \u003cli\u003e{@link #startUnomi(boolean)}: Installs and starts features for the configured distribution.\u003c/li\u003e\n  *   \u003cli\u003e{@link #stopUnomi()}: Stops and uninstalls the previously started features.\u003c/li\u003e\n  * \u003c/ul\u003e\n  *\n"
    },
    {
      "commit": "3dc54983c6720e933f27e98c8564faf60a3ea3f1",
      "tree": "704b1297bbf935831c6f623502dffb80f420362b",
      "parents": [
        "77883f35ac543378a009826cd69f6029be009e74"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 10:42:07 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:28:03 2025 +0100"
      },
      "message": "chore: remove unused variable\n"
    },
    {
      "commit": "77883f35ac543378a009826cd69f6029be009e74",
      "tree": "a0e6234f2a40e32552a5a2d4fb35f58154959307",
      "parents": [
        "cef067f2d5642cf378d9464fb66de6e5917b83fd"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Dec 29 13:03:37 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:28:03 2025 +0100"
      },
      "message": "feat: remove the additional features option to use the distribution\u0027s one.\n"
    },
    {
      "commit": "cef067f2d5642cf378d9464fb66de6e5917b83fd",
      "tree": "55342045a040600a771dfca5b70388e436d3c4ba",
      "parents": [
        "a9e498ce3a43750f8e1b350df2f86a589c79e563"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 09 11:45:35 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:28:02 2025 +0100"
      },
      "message": "UNOMI-919: Remove healthcheck config from karaf/etc package to let the bundle propose it\u0027s own cfg file.\n"
    },
    {
      "commit": "a9e498ce3a43750f8e1b350df2f86a589c79e563",
      "tree": "986c0037187fb7493ec723fe8412ce2ee090c3ea",
      "parents": [
        "bbad05d11bb6bd09f5e3d23688d413a997a2f9b1"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Dec 08 23:13:26 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:28:01 2025 +0100"
      },
      "message": "UNOMI-919: fix tests\n"
    },
    {
      "commit": "bbad05d11bb6bd09f5e3d23688d413a997a2f9b1",
      "tree": "69b647b9cec1468afabca2f457d70d5e7cf60205",
      "parents": [
        "b93fbf46697b6fdedf7970bf8af0c4b77833aa9e"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Dec 08 14:41:50 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:28:00 2025 +0100"
      },
      "message": "UNOMI-919: Include dedicated healthcheck config for each persistence type.\n"
    },
    {
      "commit": "b93fbf46697b6fdedf7970bf8af0c4b77833aa9e",
      "tree": "5e7cf1079aff1a83309bb0cb35755e2f296ec1be",
      "parents": [
        "383c7ac4dbd01c61770da9f44af99d35035e5535"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Dec 08 12:04:27 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:59 2025 +0100"
      },
      "message": "UNOMI-919: Remove unused healthcheck config file\n"
    },
    {
      "commit": "383c7ac4dbd01c61770da9f44af99d35035e5535",
      "tree": "ec92ee325b8fcae36a7f3dfe6bfeee914effb09c",
      "parents": [
        "dc95f77432511b4429c0d23eb9c8fabfd2ae887f"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Dec 05 17:47:07 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:58 2025 +0100"
      },
      "message": "UNOMI-919: Restore additional feature config into unomi startup\n"
    },
    {
      "commit": "dc95f77432511b4429c0d23eb9c8fabfd2ae887f",
      "tree": "c68d8dae95d21f9a988c21ad7c947dee36d84374",
      "parents": [
        "d0ca690e1b4b59860fa4d2f7f367deed7b51c7a9"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Dec 04 17:01:14 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:57 2025 +0100"
      },
      "message": "UNOMI-919: Fix bad command syntax in tests\n"
    },
    {
      "commit": "d0ca690e1b4b59860fa4d2f7f367deed7b51c7a9",
      "tree": "83d61705372ce6a09e80042a350e40edc6627492",
      "parents": [
        "92369e3cf35f8e50e8b9aaf0a927171be055748c"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Dec 04 15:31:19 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:56 2025 +0100"
      },
      "message": "UNOMI-919: Restore missing feature in merged branch.\n"
    },
    {
      "commit": "92369e3cf35f8e50e8b9aaf0a927171be055748c",
      "tree": "bd92005ef4f34a7f2dcc4044e3d18a7baa4b8ddd",
      "parents": [
        "a0a08e4ad4000f5e72f50cae1c2f5ea0cd4c92aa"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Dec 04 15:03:57 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:55 2025 +0100"
      },
      "message": "UNOMI-919: Avoid applying setup in test mode as packaging is already done.\n"
    },
    {
      "commit": "a0a08e4ad4000f5e72f50cae1c2f5ea0cd4c92aa",
      "tree": "69929346d0f0dd3ded2f51aa6922654053d45664",
      "parents": [
        "0c44c9bd20bcbb38971a0100911978d80b2f1533"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Nov 28 18:03:35 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 16:27:46 2025 +0100"
      },
      "message": "UNOMI-919: Refactor the UNOMI startFeatures configuration to use a Karaf\n\ndiff --git c/bom/artifacts/pom.xml i/bom/artifacts/pom.xml\nindex b0c0ec5b2..ecc78948d 100644\n--- c/bom/artifacts/pom.xml\n+++ i/bom/artifacts/pom.xml\n@@ -60,6 +60,21 @@\n                 \u003cartifactId\u003eunomi-persistence-elasticsearch-core\u003c/artifactId\u003e\n                 \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-persistence-elasticsearch-conditions\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-persistence-opensearch-core\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-persistence-opensearch-conditions\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n             \u003cdependency\u003e\n                 \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                 \u003cartifactId\u003eunomi-json-schema-services\u003c/artifactId\u003e\n@@ -243,6 +258,13 @@\n                 \u003cclassifier\u003efeatures\u003c/classifier\u003e\n                 \u003ctype\u003exml\u003c/type\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-distribution\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+                \u003cclassifier\u003efeatures\u003c/classifier\u003e\n+                \u003ctype\u003exml\u003c/type\u003e\n+            \u003c/dependency\u003e\n         \u003c/dependencies\u003e\n     \u003c/dependencyManagement\u003e\n\ndiff --git c/distribution/pom.xml i/distribution/pom.xml\nnew file mode 100644\nindex 000000000..0c469361a\n--- /dev/null\n+++ i/distribution/pom.xml\n@@ -0,0 +1,229 @@\n+\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\"?\u003e\n+\u003c!--\n+  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n+  ~ contributor license agreements.  See the NOTICE file distributed with\n+  ~ this work for additional information regarding copyright ownership.\n+  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n+  ~ (the \"License\"); you may not use this file except in compliance with\n+  ~ the License.  You may obtain a copy of the License at\n+  ~\n+  ~      http://www.apache.org/licenses/LICENSE-2.0\n+  ~\n+  ~ Unless required by applicable law or agreed to in writing, software\n+  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+  ~ See the License for the specific language governing permissions and\n+  ~ limitations under the License.\n+  --\u003e\n+\n+\u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n+    \u003cparent\u003e\n+        \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+        \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n+        \u003cversion\u003e3.1.0-SNAPSHOT\u003c/version\u003e\n+    \u003c/parent\u003e\n+    \u003cartifactId\u003eunomi-distribution\u003c/artifactId\u003e\n+    \u003cname\u003eApache Unomi :: Distribution\u003c/name\u003e\n+    \u003cdescription\u003eApache Unomi Distribution\u0027s Karaf features assemblies for the Apache Unomi Context Server\u003c/description\u003e\n+    \u003cpackaging\u003ekar\u003c/packaging\u003e\n+\n+    \u003cdependencyManagement\u003e\n+        \u003cdependencies\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-bom\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+                \u003ctype\u003epom\u003c/type\u003e\n+                \u003cscope\u003eimport\u003c/scope\u003e\n+            \u003c/dependency\u003e\n+        \u003c/dependencies\u003e\n+    \u003c/dependencyManagement\u003e\n+\n+    \u003cdependencies\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-common\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-wab\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-metrics\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-scripting\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-elasticsearch-core\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-elasticsearch-conditions\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-opensearch-core\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-opensearch-conditions\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003c!-- plugins --\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-plugins-base\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-plugins-request\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-plugins-mail\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-plugins-optimization-test\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003c!-- extensions --\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-lists-extension-services\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-lists-extension-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-lists-extension-actions\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-geonames-services\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-geonames-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-privacy-extension-services\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-privacy-extension-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-json-schema-services\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-json-schema-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eshell-dev-commands\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-web-tracker-wab\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ejoda-time\u003c/groupId\u003e\n+            \u003cartifactId\u003ejoda-time\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003c!-- Apache HTTP Client --\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n+            \u003cartifactId\u003ehttpcore-osgi\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n+            \u003cartifactId\u003ehttpclient-osgi\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+    \u003c/dependencies\u003e\n+    \u003cbuild\u003e\n+        \u003cpluginManagement\u003e\n+            \u003cplugins\u003e\n+                \u003cplugin\u003e\n+                    \u003cgroupId\u003eorg.apache.karaf.tooling\u003c/groupId\u003e\n+                    \u003cartifactId\u003ekaraf-maven-plugin\u003c/artifactId\u003e\n+                    \u003cextensions\u003etrue\u003c/extensions\u003e\n+                    \u003cconfiguration\u003e\n+                        \u003cincludeTransitiveDependency\u003efalse\u003c/includeTransitiveDependency\u003e\n+                    \u003c/configuration\u003e\n+                \u003c/plugin\u003e\n+            \u003c/plugins\u003e\n+        \u003c/pluginManagement\u003e\n+\n+        \u003cplugins\u003e\n+            \u003cplugin\u003e\n+                \u003cgroupId\u003eorg.apache.karaf.tooling\u003c/groupId\u003e\n+                \u003cartifactId\u003ekaraf-maven-plugin\u003c/artifactId\u003e\n+                \u003cconfiguration\u003e\n+                    \u003cstartLevel\u003e85\u003c/startLevel\u003e\n+                \u003c/configuration\u003e\n+                \u003cexecutions\u003e\n+                    \u003cexecution\u003e\n+                        \u003cid\u003egenerate-features\u003c/id\u003e\n+                        \u003cphase\u003egenerate-resources\u003c/phase\u003e\n+                        \u003cgoals\u003e\n+                            \u003cgoal\u003efeatures-generate-descriptor\u003c/goal\u003e\n+                        \u003c/goals\u003e\n+                        \u003cconfiguration\u003e\n+                            \u003cenableGeneration\u003etrue\u003c/enableGeneration\u003e\n+                        \u003c/configuration\u003e\n+                    \u003c/execution\u003e\n+                    \u003cexecution\u003e\n+                        \u003cid\u003everify\u003c/id\u003e\n+                        \u003cphase\u003eprocess-resources\u003c/phase\u003e\n+                        \u003cgoals\u003e\n+                            \u003cgoal\u003everify\u003c/goal\u003e\n+                        \u003c/goals\u003e\n+                        \u003cconfiguration\u003e\n+                            \u003cdescriptors\u003e\n+                                \u003cdescriptor\u003emvn:org.apache.karaf.features/standard/${karaf.version}/xml/features\u003c/descriptor\u003e\n+                                \u003cdescriptor\u003emvn:org.apache.karaf.features/enterprise/${karaf.version}/xml/features\u003c/descriptor\u003e\n+                                \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n+                            \u003c/descriptors\u003e\n+                            \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n+                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cframework\u003e\n+                                \u003cfeature\u003eframework\u003c/feature\u003e\n+                            \u003c/framework\u003e\n+\n+                            \u003cfeatures\u003e\n+                                \u003cfeature\u003eunomi-distribution-opensearch\u003c/feature\u003e\n+                                \u003cfeature\u003eunomi-distribution-elasticsearch\u003c/feature\u003e\n+                            \u003c/features\u003e\n+\n+                            \u003cignoreMissingConditions\u003efalse\u003c/ignoreMissingConditions\u003e\n+                        \u003c/configuration\u003e\n+                    \u003c/execution\u003e\n+                \u003c/executions\u003e\n+            \u003c/plugin\u003e\n+        \u003c/plugins\u003e\n+    \u003c/build\u003e\n+\u003c/project\u003e\ndiff --git c/docker/README.md i/docker/README.md\nindex 83cce28a2..ae1e4f93b 100644\n--- c/docker/README.md\n+++ i/docker/README.md\n@@ -45,55 +45,75 @@ If you want to run it without docker-compose you should then make sure you setup\n\n For ElasticSearch:\n\n-    docker pull docker.elastic.co/elasticsearch/elasticsearch:7.4.2\n-    docker network create unomi\n-    docker run --name elasticsearch --net unomi -p 9200:9200 -p 9300:9300 -e \"discovery.type\u003dsingle-node\" -e cluster.name\u003dcontextElasticSearch docker.elastic.co/elasticsearch/elasticsearch:7.4.2\n+```bash\n+docker pull docker.elastic.co/elasticsearch/elasticsearch:9.2.1\n+docker network create unomi\n+docker run -d --name elasticsearch --net unomi -p 9200:9200 -p 9300:9300 \\\n+    -e \"discovery.type\u003dsingle-node\" \\\n+    -e \"xpack.security.enabled\u003dfalse\" \\\n+    -e cluster.name\u003dcontextElasticSearch \\\n+    docker.elastic.co/elasticsearch/elasticsearch:9.2.1\n+```\n\n For OpenSearch:\n\n-    docker pull opensearchproject/opensearch:3.0.0\n-    docker network create unomi\n-    export OPENSEARCH_ADMIN_PASSWORD\u003denter_your_custom_admin_password_here\n-    docker run --name opensearch --net unomi -p 9200:9200 -p 9300:9300 -e \"discovery.type\u003dsingle-node\" -e OPENSEARCH_INITIAL_ADMIN_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD} opensearchproject/opensearch:3.0.0\n+```bash\n+docker pull opensearchproject/opensearch:3.0.0\n+docker network create unomi\n+export OPENSEARCH_ADMIN_PASSWORD\u003denter_your_custom_admin_password_here\n+docker run -d --name opensearch --net unomi -p 9200:9200 -p 9300:9300 \\\n+    -e \"discovery.type\u003dsingle-node\" \\\n+    -e OPENSEARCH_INITIAL_ADMIN_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD} \\\n+    opensearchproject/opensearch:3.0.0\n+```\n\n For Unomi (with ElasticSearch):\n\n-    docker pull apache/unomi:3.0.0-SNAPSHOT\n-    docker run --name unomi --net unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n-        -e UNOMI_ELASTICSEARCH_ADDRESSES\u003delasticsearch:9200 \\\n-        apache/unomi:3.0.0-SNAPSHOT\n+```bash\n+docker pull apache/unomi:3.1.0-SNAPSHOT\n+docker run -d --name unomi --net unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n+    -e UNOMI_ELASTICSEARCH_ADDRESSES\u003delasticsearch:9200 \\\n+    apache/unomi:3.1.0-SNAPSHOT\n+```\n\n For Unomi (with OpenSearch):\n\n-    docker pull apache/unomi:3.0.0-SNAPSHOT\n-    docker run --name unomi --net unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n-        -e UNOMI_AUTO_START\u003dopensearch \\\n-        -e UNOMI_OPENSEARCH_ADDRESSES\u003dopensearch:9200 \\\n-        -e UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD} \\\n-        apache/unomi:3.0.0-SNAPSHOT\n+```bash\n+docker pull apache/unomi:3.1.0-SNAPSHOT\n+docker run -d --name unomi --net unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n+    -e UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch \\\n+    -e UNOMI_OPENSEARCH_ADDRESSES\u003dopensearch:9200 \\\n+    -e UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD}\n+    apache/unomi:3.1.0-SNAPSHOT\n+```\n\n ## Using a host OS Search Engine installation (only supported on macOS \u0026 Windows)\n\n For ElasticSearch:\n\n-    docker run --name unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n-        -e UNOMI_ELASTICSEARCH_ADDRESSES\u003dhost.docker.internal:9200 \\\n-        apache/unomi:3.0.0-SNAPSHOT\n+```bash\n+docker run -d --name unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n+    -e UNOMI_ELASTICSEARCH_ADDRESSES\u003dhost.docker.internal:9200 \\\n+    apache/unomi:3.1.0-SNAPSHOT\n+```\n\n For OpenSearch:\n\n-    docker run --name unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n-        -e UNOMI_AUTO_START\u003dopensearch \\\n-        -e UNOMI_OPENSEARCH_ADDRESSES\u003dhost.docker.internal:9200 \\\n-        -e UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD} \\\n-        apache/unomi:3.0.0-SNAPSHOT\n+```bash\n+docker run -d --name unomi -p 8181:8181 -p 9443:9443 -p 8102:8102 \\\n+    -e UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n+    -e UNOMI_OPENSEARCH_ADDRESSES\u003dhost.docker.internal:9200 \\\n+    -e UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_ADMIN_PASSWORD} \\\n+    apache/unomi:3.1.0-SNAPSHOT\n+```\n\n Note: Linux doesn\u0027t support the host.docker.internal DNS lookup method yet, it should be available in an upcoming version of Docker. See https://github.com/docker/for-linux/issues/264\n\n ## Environment Variables\n\n ### Common Variables\n-- `UNOMI_AUTO_START`: Specifies the search engine type (`elasticsearch` or `opensearch`, defaults to `elasticsearch`)\n+- `UNOMI_AUTO_START`: Boolean to specify if unomi auto start with karaf (defaults to `true`)\n+- `UNOMI_DISTRIBUTION`: Specifies the Unomi Distribution Feature to use (`unomi-distribution-elasticsearch` or `unomi-distribution-opensearch`, defaults to `unomi-distribution-elasticsearch`)\n\n ### ElasticSearch-specific Variables\n - `UNOMI_ELASTICSEARCH_ADDRESSES`: ElasticSearch host:port (default: localhost:9200)\ndiff --git c/docker/src/main/docker/docker-compose-build-es.yml i/docker/src/main/docker/docker-compose-build-es.yml\nindex af71f7717..454e10364 100644\n--- c/docker/src/main/docker/docker-compose-build-es.yml\n+++ i/docker/src/main/docker/docker-compose-build-es.yml\n@@ -17,7 +17,7 @@\n version: \u00272.4\u0027\n services:\n   elasticsearch:\n-    image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3\n+    image: docker.elastic.co/elasticsearch/elasticsearch:9.2.1\n     volumes:\n       - unomi-3-elasticsearch-data:/usr/share/elasticsearch/data\n     environment:\n@@ -35,7 +35,8 @@ services:\n     build: .\n     image: apache/unomi:${project.version}\n     environment:\n-      - UNOMI_AUTO_START\u003delasticsearch\n+      - UNOMI_AUTO_START\u003dtrue\n+      - UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch\n       - UNOMI_ELASTICSEARCH_ADDRESSES\u003delasticsearch:9200\n       # Debug settings\n       - KARAF_DEBUG\u003d${DEBUG:-false}\ndiff --git c/docker/src/main/docker/docker-compose-build-os.yml i/docker/src/main/docker/docker-compose-build-os.yml\nindex 0f736e004..fb2d27d27 100644\n--- c/docker/src/main/docker/docker-compose-build-os.yml\n+++ i/docker/src/main/docker/docker-compose-build-os.yml\n@@ -95,7 +95,8 @@ services:\n     image: apache/unomi:${project.version}\n     container_name: unomi\n     environment:\n-      - UNOMI_AUTO_START\u003dopensearch\n+      - UNOMI_AUTO_START\u003dtrue\n+      - UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n       - UNOMI_OPENSEARCH_ADDRESSES\u003dopensearch-node1:9200\n       - UNOMI_OPENSEARCH_USERNAME\u003dadmin\n       - UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_INITIAL_ADMIN_PASSWORD}\ndiff --git c/docker/src/main/docker/docker-compose-es.yml i/docker/src/main/docker/docker-compose-es.yml\nindex 28e800b4b..43f3bbba5 100644\n--- c/docker/src/main/docker/docker-compose-es.yml\n+++ i/docker/src/main/docker/docker-compose-es.yml\n@@ -23,7 +23,7 @@ networks:\n\n services:\n   elasticsearch:\n-    image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3\n+    image: docker.elastic.co/elasticsearch/elasticsearch:9.2.1\n     container_name: elasticsearch\n     volumes:\n       - unomi-3-elasticsearch-data:/usr/share/elasticsearch/data\n@@ -41,7 +41,8 @@ services:\n   node-1:\n     image: apache/unomi:${project.version}\n     environment:\n-      - UNOMI_AUTO_START\u003delasticsearch\n+      - UNOMI_AUTO_START\u003dtrue\n+      - UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch\n       - UNOMI_ELASTICSEARCH_ADDRESSES\u003delasticsearch:9200\n       # Debug settings\n       - KARAF_DEBUG\u003d${DEBUG:-false}\ndiff --git c/docker/src/main/docker/docker-compose-os.yml i/docker/src/main/docker/docker-compose-os.yml\nindex cf229dedf..03abe5263 100644\n--- c/docker/src/main/docker/docker-compose-os.yml\n+++ i/docker/src/main/docker/docker-compose-os.yml\n@@ -79,7 +79,8 @@ services:\n     image: apache/unomi:${project.version}\n     container_name: unomi\n     environment:\n-      - UNOMI_AUTO_START\u003dopensearch\n+      - UNOMI_AUTO_START\u003dtrue\n+      - UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n       - UNOMI_OPENSEARCH_ADDRESSES\u003dopensearch-node1:9200\n       - UNOMI_OPENSEARCH_USERNAME\u003dadmin\n       - UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_INITIAL_ADMIN_PASSWORD}\ndiff --git c/docker/src/main/docker/entrypoint.sh i/docker/src/main/docker/entrypoint.sh\nindex 275f0edb0..1cfc68456 100755\n--- c/docker/src/main/docker/entrypoint.sh\n+++ i/docker/src/main/docker/entrypoint.sh\n@@ -29,14 +29,9 @@ if [ \"$KARAF_DEBUG\" \u003d \"true\" ]; then\n     export KARAF_DEBUG\u003dtrue\n fi\n\n-# Determine search engine type from UNOMI_AUTO_START\n-SEARCH_ENGINE\u003d\"${UNOMI_AUTO_START:-elasticsearch}\"\n-export KARAF_OPTS\u003d\"-Dunomi.autoStart\u003d${UNOMI_AUTO_START}\"\n+UNOMI_DISTRIBUTION\u003d\"${UNOMI_DISTRIBUTION:-unomi-distribution-elasticsearch}\"\n+export KARAF_OPTS\u003d\"-Dunomi.autoStart\u003d${UNOMI_AUTO_START} -Dunomi.distribution\u003d${UNOMI_DISTRIBUTION}\"\n\n-if [ \"$SEARCH_ENGINE\" \u003d \"true\" ]; then\n-    SEARCH_ENGINE\u003d\"elasticsearch\"\n-fi\n-echo \"SEARCH_ENGINE: $SEARCH_ENGINE\"\n echo \"KARAF_OPTS: $KARAF_OPTS\"\n\n # Function to check cluster health for a specific node\n@@ -51,9 +46,11 @@ check_node_health() {\n     fi\n }\n\n-# Configure connection parameters based on search engine type\n-if [ \"$SEARCH_ENGINE\" \u003d \"opensearch\" ]; then\n+# Configure connection parameters based on distribution name\n+WAIT_SEARCH_ENGINE\u003dtrue\n+if [[ \"$UNOMI_DISTRIBUTION\" \u003d\u003d *opensearch* ]]; then\n     # OpenSearch configuration\n+    SEARCH_ENGINE\u003d\"opensearch\"\n     if [ -z \"$UNOMI_OPENSEARCH_PASSWORD\" ]; then\n         echo \"Error: UNOMI_OPENSEARCH_PASSWORD must be set when using OpenSearch\"\n         exit 1\n@@ -65,8 +62,9 @@ if [ \"$SEARCH_ENGINE\" \u003d \"opensearch\" ]; then\n     curl_opts\u003d\"-k -H \\\"${auth_header}\\\" -H \\\"Content-Type: application/json\\\"\"\n     # Build array of node URLs\n     IFS\u003d\u0027,\u0027 read -ra NODES \u003c\u003c\u003c \"${UNOMI_OPENSEARCH_ADDRESSES}\"\n-else\n+elif [[ \"$UNOMI_DISTRIBUTION\" \u003d\u003d *elasticsearch* ]]; then\n     # Elasticsearch configuration\n+    SEARCH_ENGINE\u003d\"elasticsearch\"\n     if [ \"$UNOMI_ELASTICSEARCH_SSL_ENABLE\" \u003d \u0027true\u0027 ]; then\n         schema\u003d\u0027https\u0027\n     else\n@@ -80,43 +78,49 @@ else\n     health_endpoint\u003d\"_cluster/health\"\n     # Build array of node URLs\n     IFS\u003d\u0027,\u0027 read -ra NODES \u003c\u003c\u003c \"${UNOMI_ELASTICSEARCH_ADDRESSES}\"\n+else\n+    WAIT_SEARCH_ENGINE\u003dfalse\n+    echo \"WARNING: unable to determine search engine from distribution name: $UNOMI_DISTRIBUTION\"\n+    echo \"         Skipping waiting for engine to startup before starting Karaf, ensure it is expected\"\n fi\n\n-# Wait for search engine to be ready\n-echo \"Waiting for ${SEARCH_ENGINE} to be ready...\"\n-echo \"Checking nodes: ${NODES[@]}\"\n-health_check\u003d\"\"\n+# Wait for search engine to be ready (only if enabled)\n+if [ \"$WAIT_SEARCH_ENGINE\" \u003d true ]; then\n+    echo \"Waiting for ${SEARCH_ENGINE} to be ready...\"\n+    echo \"Checking nodes: ${NODES[@]}\"\n+    health_check\u003d\"\"\n\n-while ([ -z \"$health_check\" ] || ([ \"$health_check\" !\u003d \u0027yellow\u0027 ] \u0026\u0026 [ \"$health_check\" !\u003d \u0027green\u0027 ])); do\n-    # Try each node until we get a successful response\n-    for node in \"${NODES[@]}\"; do\n-        node_url\u003d\"${schema}://${node}/${health_endpoint}\"\n-        echo \"Checking health at: ${node_url}\"\n-        health_check\u003d$(check_node_health \"$node_url\" \"$curl_opts\")\n+    while ([ -z \"$health_check\" ] || ([ \"$health_check\" !\u003d \u0027yellow\u0027 ] \u0026\u0026 [ \"$health_check\" !\u003d \u0027green\u0027 ])); do\n+        # Try each node until we get a successful response\n+        for node in \"${NODES[@]}\"; do\n+            node_url\u003d\"${schema}://${node}/${health_endpoint}\"\n+            echo \"Checking health at: ${node_url}\"\n+            health_check\u003d$(check_node_health \"$node_url\" \"$curl_opts\")\n\n-        if [ ! -z \"$health_check\" ]; then\n-            echo \"Successfully connected to node: $node (status: ${health_check})\"\n-            break\n+            if [ ! -z \"$health_check\" ]; then\n+                echo \"Successfully connected to node: $node (status: ${health_check})\"\n+                break\n+            else\n+                \u003e\u00262 echo \"Connection failed to node: $node\"\n+            fi\n+        done\n+\n+        if [ -z \"$health_check\" ]; then\n+            \u003e\u00262 echo \"${SEARCH_ENGINE^} is not yet available - all nodes unreachable\"\n+            sleep 3\n+            continue\n+        fi\n+\n+        if [ \"$health_check\" !\u003d \u0027yellow\u0027 ] \u0026\u0026 [ \"$health_check\" !\u003d \u0027green\u0027 ]; then\n+            \u003e\u00262 echo \"${SEARCH_ENGINE^} health status: ${health_check} (waiting for yellow or green)\"\n+            sleep 3\n         else\n-            \u003e\u00262 echo \"Connection failed to node: $node\"\n+            \u003e\u00262 echo \"${SEARCH_ENGINE^} health status: ${health_check}\"\n         fi\n     done\n\n-    if [ -z \"$health_check\" ]; then\n-        \u003e\u00262 echo \"${SEARCH_ENGINE^} is not yet available - all nodes unreachable\"\n-        sleep 3\n-        continue\n-    fi\n-\n-    if [ \"$health_check\" !\u003d \u0027yellow\u0027 ] \u0026\u0026 [ \"$health_check\" !\u003d \u0027green\u0027 ]; then\n-        \u003e\u00262 echo \"${SEARCH_ENGINE^} health status: ${health_check} (waiting for yellow or green)\"\n-        sleep 3\n-    else\n-        \u003e\u00262 echo \"${SEARCH_ENGINE^} health status: ${health_check}\"\n-    fi\n-done\n-\n-echo \"${SEARCH_ENGINE^} is ready with health status: ${health_check}\"\n+    echo \"${SEARCH_ENGINE^} is ready with health status: ${health_check}\"\n+fi\n\n # Run Unomi in current bash session\n exec \"$UNOMI_HOME/bin/karaf\" run\ndiff --git c/extensions/healthcheck/pom.xml i/extensions/healthcheck/pom.xml\nindex e16bd9ac7..e1fca175d 100644\n--- c/extensions/healthcheck/pom.xml\n+++ i/extensions/healthcheck/pom.xml\n@@ -150,10 +150,17 @@\n                             \u003cartifacts\u003e\n                                 \u003cartifact\u003e\n                                     \u003cfile\u003e\n-                                        src/main/resources/org.apache.unomi.healthcheck.cfg\n+                                        src/main/resources/org.apache.unomi.healthcheck-elasticsearch.cfg\n                                     \u003c/file\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n-                                    \u003cclassifier\u003ehealthcheck\u003c/classifier\u003e\n+                                    \u003cclassifier\u003ehealthcheck-elasticsearch\u003c/classifier\u003e\n+                                \u003c/artifact\u003e\n+                                \u003cartifact\u003e\n+                                    \u003cfile\u003e\n+                                        src/main/resources/org.apache.unomi.healthcheck-opensearch.cfg\n+                                    \u003c/file\u003e\n+                                    \u003ctype\u003ecfg\u003c/type\u003e\n+                                    \u003cclassifier\u003ehealthcheck-opensearch\u003c/classifier\u003e\n                                 \u003c/artifact\u003e\n                             \u003c/artifacts\u003e\n                         \u003c/configuration\u003e\ndiff --git c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\nindex 278eb8a1e..b07f279e7 100644\n--- c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\n+++ i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\n@@ -30,9 +30,14 @@ import org.apache.http.impl.client.BasicCredentialsProvider;\n import org.apache.http.impl.client.CloseableHttpClient;\n import org.apache.http.util.EntityUtils;\n import org.apache.unomi.healthcheck.HealthCheckConfig;\n+import org.apache.unomi.healthcheck.HealthCheckProvider;\n import org.apache.unomi.healthcheck.HealthCheckResponse;\n import org.apache.unomi.healthcheck.util.CachedValue;\n import org.apache.unomi.shell.migration.utils.HttpUtils;\n+import org.osgi.service.component.annotations.Activate;\n+import org.osgi.service.component.annotations.Component;\n+import org.osgi.service.component.annotations.Reference;\n+import org.osgi.service.component.annotations.ReferenceCardinality;\n import org.slf4j.Logger;\n import org.slf4j.LoggerFactory;\n\n@@ -43,13 +48,17 @@ import java.util.concurrent.TimeUnit;\n  * A Health Check that checks the status of the ElasticSearch connectivity according to the provided configuration.\n  * This connectivity should be LIVE before any try to start Unomi.\n  */\n-public class ElasticSearchHealthCheckProvider implements PersistenceEngineHealthProvider {\n+@Component(service \u003d HealthCheckProvider.class, immediate \u003d true)\n+public class ElasticSearchHealthCheckProvider implements HealthCheckProvider {\n\n     public static final String NAME \u003d \"elasticsearch\";\n\n     private static final Logger LOGGER \u003d LoggerFactory.getLogger(ElasticSearchHealthCheckProvider.class.getName());\n     private final CachedValue\u003cHealthCheckResponse\u003e cache \u003d new CachedValue\u003c\u003e(10, TimeUnit.SECONDS);\n+    private final ObjectMapper mapper \u003d new ObjectMapper();\n+    private boolean isActive \u003d false;\n\n+    @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n     private HealthCheckConfig config;\n\n     private CloseableHttpClient httpClient;\n@@ -58,21 +67,25 @@ public class ElasticSearchHealthCheckProvider implements PersistenceEngineHealth\n         LOGGER.info(\"Building elasticsearch health provider service...\");\n     }\n\n+    @Activate\n     public void activate() {\n-        LOGGER.info(\"Activating elasticsearch health provider service...\");\n-        CredentialsProvider credentialsProvider \u003d null;\n-        String login \u003d config.get(HealthCheckConfig.CONFIG_ES_LOGIN);\n-        if (StringUtils.isNotEmpty(login)) {\n-            credentialsProvider \u003d new BasicCredentialsProvider();\n-            UsernamePasswordCredentials credentials\n-                    \u003d new UsernamePasswordCredentials(login, config.get(HealthCheckConfig.CONFIG_ES_PASSWORD));\n-            credentialsProvider.setCredentials(AuthScope.ANY, credentials);\n-        }\n-        try {\n-            httpClient \u003d HttpUtils.initHttpClient(\n-                    Boolean.parseBoolean(config.get(HealthCheckConfig.CONFIG_ES_TRUST_ALL_CERTIFICATES)), credentialsProvider);\n-        } catch (IOException e) {\n-            LOGGER.error(\"Unable to initialize http client\", e);\n+        if (config.isEnabled() \u0026\u0026 config.getEnabledProviders().stream().anyMatch(NAME::equals)) {\n+            LOGGER.info(\"Activating elasticsearch health provider service...\");\n+            this.isActive \u003d true;\n+            CredentialsProvider credentialsProvider \u003d null;\n+            String login \u003d config.get(HealthCheckConfig.CONFIG_ES_LOGIN);\n+            if (StringUtils.isNotEmpty(login)) {\n+                credentialsProvider \u003d new BasicCredentialsProvider();\n+                UsernamePasswordCredentials credentials \u003d new UsernamePasswordCredentials(login,\n+                        config.get(HealthCheckConfig.CONFIG_ES_PASSWORD));\n+                credentialsProvider.setCredentials(AuthScope.ANY, credentials);\n+            }\n+            try {\n+                httpClient \u003d HttpUtils.initHttpClient(Boolean.parseBoolean(config.get(HealthCheckConfig.CONFIG_ES_TRUST_ALL_CERTIFICATES)),\n+                        credentialsProvider);\n+            } catch (IOException e) {\n+                LOGGER.error(\"Unable to initialize http client\", e);\n+            }\n         }\n     }\n\n@@ -92,56 +105,64 @@ public class ElasticSearchHealthCheckProvider implements PersistenceEngineHealth\n         return cache.getValue();\n     }\n\n-    @Override public HealthCheckResponse detailed() {\n-        return execute();\n-    }\n-\n     private HealthCheckResponse refresh() {\n         LOGGER.debug(\"Refresh\");\n         HealthCheckResponse.Builder builder \u003d new HealthCheckResponse.Builder();\n         builder.name(NAME).down();\n-        String url \u003d (config.get(HealthCheckConfig.CONFIG_ES_SSL_ENABLED).equals(\"true\") ? \"https://\" : \"http://\")\n-                        .concat(config.get(HealthCheckConfig.CONFIG_ES_ADDRESSES).split(\",\")[0].trim())\n-                        .concat(\"/_cluster/health\");\n-        CloseableHttpResponse response \u003d null;\n-        try {\n-            response \u003d httpClient.execute(new HttpGet(url));\n-            if (response !\u003d null \u0026\u0026 response.getStatusLine().getStatusCode() \u003d\u003d 200) {\n-                builder.up();\n-                HttpEntity entity \u003d response.getEntity();\n-                if (entity !\u003d null) {\n-                    String content \u003d EntityUtils.toString(entity);\n-                    try {\n-                        ObjectMapper mapper \u003d new ObjectMapper();\n-                        JsonNode root \u003d mapper.readTree(content);\n-                        if (root.has(\"status\") \u0026\u0026 \"green\".equals(root.get(\"status\").asText())) {\n-                            builder.live();\n-                        }\n-                        if (root.has(\"cluster_name\")) builder.withData(\"cluster_name\", root.get(\"cluster_name\").asText());\n-                        if (root.has(\"status\")) builder.withData(\"status\", root.get(\"status\").asText());\n-                        if (root.has(\"timed_out\")) builder.withData(\"timed_out\", root.get(\"timed_out\").asBoolean());\n-                        if (root.has(\"number_of_nodes\")) builder.withData(\"number_of_nodes\", root.get(\"number_of_nodes\").asLong());\n-                        if (root.has(\"number_of_data_nodes\")) builder.withData(\"number_of_data_nodes\", root.get(\"number_of_data_nodes\").asLong());\n-                        if (root.has(\"active_primary_shards\")) builder.withData(\"active_primary_shards\", root.get(\"active_primary_shards\").asLong());\n-                        if (root.has(\"active_shards\")) builder.withData(\"active_shards\", root.get(\"active_shards\").asLong());\n-                        if (root.has(\"relocating_shards\")) builder.withData(\"relocating_shards\", root.get(\"relocating_shards\").asLong());\n-                        if (root.has(\"initializing_shards\")) builder.withData(\"initializing_shards\", root.get(\"initializing_shards\").asLong());\n-                        if (root.has(\"unassigned_shards\")) builder.withData(\"unassigned_shards\", root.get(\"unassigned_shards\").asLong());\n-                    } catch (Exception parseEx) {\n-                        // Fallback to simple LIVE detection\n-                        if (content.contains(\"\\\"status\\\":\\\"green\\\"\")) {\n-                            builder.live();\n+        if (isActive) {\n+            String url \u003d (config.get(HealthCheckConfig.CONFIG_ES_SSL_ENABLED).equals(\"true\") ? \"https://\" : \"http://\").concat(\n+                    config.get(HealthCheckConfig.CONFIG_ES_ADDRESSES).split(\",\")[0].trim()).concat(\"/_cluster/health\");\n+            CloseableHttpResponse response \u003d null;\n+            try {\n+                response \u003d httpClient.execute(new HttpGet(url));\n+                if (response !\u003d null \u0026\u0026 response.getStatusLine().getStatusCode() \u003d\u003d 200) {\n+                    builder.up();\n+                    HttpEntity entity \u003d response.getEntity();\n+                    if (entity !\u003d null) {\n+                        String content \u003d EntityUtils.toString(entity);\n+                        try {\n+                            JsonNode root \u003d mapper.readTree(content);\n+                            if (root.has(\"status\") \u0026\u0026 \"green\".equals(root.get(\"status\").asText())) {\n+                                builder.live();\n+                            }\n+                            if (root.has(\"cluster_name\"))\n+                                builder.withData(\"cluster_name\", root.get(\"cluster_name\").asText());\n+                            if (root.has(\"status\"))\n+                                builder.withData(\"status\", root.get(\"status\").asText());\n+                            if (root.has(\"timed_out\"))\n+                                builder.withData(\"timed_out\", root.get(\"timed_out\").asBoolean());\n+                            if (root.has(\"number_of_nodes\"))\n+                                builder.withData(\"number_of_nodes\", root.get(\"number_of_nodes\").asLong());\n+                            if (root.has(\"number_of_data_nodes\"))\n+                                builder.withData(\"number_of_data_nodes\", root.get(\"number_of_data_nodes\").asLong());\n+                            if (root.has(\"active_primary_shards\"))\n+                                builder.withData(\"active_primary_shards\", root.get(\"active_primary_shards\").asLong());\n+                            if (root.has(\"active_shards\"))\n+                                builder.withData(\"active_shards\", root.get(\"active_shards\").asLong());\n+                            if (root.has(\"relocating_shards\"))\n+                                builder.withData(\"relocating_shards\", root.get(\"relocating_shards\").asLong());\n+                            if (root.has(\"initializing_shards\"))\n+                                builder.withData(\"initializing_shards\", root.get(\"initializing_shards\").asLong());\n+                            if (root.has(\"unassigned_shards\"))\n+                                builder.withData(\"unassigned_shards\", root.get(\"unassigned_shards\").asLong());\n+                        } catch (Exception parseEx) {\n+                            // Fallback to simple LIVE detection\n+                            if (content.contains(\"\\\"status\\\":\\\"green\\\"\")) {\n+                                builder.live();\n+                            }\n                         }\n                     }\n                 }\n+            } catch (IOException e) {\n+                builder.error().withData(\"error\", e.getMessage());\n+                LOGGER.error(\"Error while checking elasticsearch health\", e);\n+            } finally {\n+                if (response !\u003d null) {\n+                    EntityUtils.consumeQuietly(response.getEntity());\n+                }\n             }\n-        } catch (IOException e) {\n-            builder.error().withData(\"error\", e.getMessage());\n-            LOGGER.error(\"Error while checking elasticsearch health\", e);\n-        } finally {\n-            if (response !\u003d null) {\n-                EntityUtils.consumeQuietly(response.getEntity());\n-            }\n+        } else {\n+            builder.error().withData(\"error\", \"Elasticsearch health check provider is not active\");\n         }\n         return builder.build();\n     }\ndiff --git c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/OpenSearchHealthCheckProvider.java i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/OpenSearchHealthCheckProvider.java\nindex 7b97cfa12..f64f0df84 100644\n--- c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/OpenSearchHealthCheckProvider.java\n+++ i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/OpenSearchHealthCheckProvider.java\n@@ -30,9 +30,14 @@ import org.apache.http.impl.client.BasicCredentialsProvider;\n import org.apache.http.impl.client.CloseableHttpClient;\n import org.apache.http.util.EntityUtils;\n import org.apache.unomi.healthcheck.HealthCheckConfig;\n+import org.apache.unomi.healthcheck.HealthCheckProvider;\n import org.apache.unomi.healthcheck.HealthCheckResponse;\n import org.apache.unomi.healthcheck.util.CachedValue;\n import org.apache.unomi.shell.migration.utils.HttpUtils;\n+import org.osgi.service.component.annotations.Activate;\n+import org.osgi.service.component.annotations.Component;\n+import org.osgi.service.component.annotations.Reference;\n+import org.osgi.service.component.annotations.ReferenceCardinality;\n import org.slf4j.Logger;\n import org.slf4j.LoggerFactory;\n\n@@ -43,13 +48,17 @@ import java.util.concurrent.TimeUnit;\n  * A Health Check that checks the status of the OpenSearch connectivity according to the provided configuration.\n  * This connectivity should be LIVE before any try to start Unomi.\n  */\n-public class OpenSearchHealthCheckProvider implements PersistenceEngineHealthProvider {\n+@Component(service \u003d HealthCheckProvider.class, immediate \u003d true)\n+public class OpenSearchHealthCheckProvider implements HealthCheckProvider {\n\n     public static final String NAME \u003d \"opensearch\";\n\n     private static final Logger LOGGER \u003d LoggerFactory.getLogger(OpenSearchHealthCheckProvider.class.getName());\n     private final CachedValue\u003cHealthCheckResponse\u003e cache \u003d new CachedValue\u003c\u003e(10, TimeUnit.SECONDS);\n+    private final ObjectMapper mapper \u003d new ObjectMapper();\n+    private boolean isActive \u003d false;\n\n+    @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n     private HealthCheckConfig config;\n\n     private CloseableHttpClient httpClient;\n@@ -58,21 +67,25 @@ public class OpenSearchHealthCheckProvider implements PersistenceEngineHealthPro\n         LOGGER.info(\"Building OpenSearch health provider service...\");\n     }\n\n+    @Activate\n     public void activate() {\n-        LOGGER.info(\"Activating OpenSearch health provider service...\");\n-        CredentialsProvider credentialsProvider \u003d null;\n-        String login \u003d config.get(HealthCheckConfig.CONFIG_OS_LOGIN); // Reuse ElasticSearch credentials key\n-        if (StringUtils.isNotEmpty(login)) {\n-            credentialsProvider \u003d new BasicCredentialsProvider();\n-            UsernamePasswordCredentials credentials\n-                    \u003d new UsernamePasswordCredentials(login, config.get(HealthCheckConfig.CONFIG_OS_PASSWORD));\n-            credentialsProvider.setCredentials(AuthScope.ANY, credentials);\n-        }\n-        try {\n-            httpClient \u003d HttpUtils.initHttpClient(\n-                    Boolean.parseBoolean(config.get(HealthCheckConfig.CONFIG_OS_TRUST_ALL_CERTIFICATES)), credentialsProvider);\n-        } catch (IOException e) {\n-            LOGGER.error(\"Unable to initialize http client\", e);\n+        if (config.isEnabled() \u0026\u0026 config.getEnabledProviders().stream().anyMatch(NAME::equals)) {\n+            LOGGER.info(\"Activating OpenSearch health provider service...\");\n+            this.isActive \u003d true;\n+            CredentialsProvider credentialsProvider \u003d null;\n+            String login \u003d config.get(HealthCheckConfig.CONFIG_OS_LOGIN); // Reuse ElasticSearch credentials key\n+            if (StringUtils.isNotEmpty(login)) {\n+                credentialsProvider \u003d new BasicCredentialsProvider();\n+                UsernamePasswordCredentials credentials \u003d new UsernamePasswordCredentials(login,\n+                        config.get(HealthCheckConfig.CONFIG_OS_PASSWORD));\n+                credentialsProvider.setCredentials(AuthScope.ANY, credentials);\n+            }\n+            try {\n+                httpClient \u003d HttpUtils.initHttpClient(Boolean.parseBoolean(config.get(HealthCheckConfig.CONFIG_OS_TRUST_ALL_CERTIFICATES)),\n+                        credentialsProvider);\n+            } catch (IOException e) {\n+                LOGGER.error(\"Unable to initialize http client\", e);\n+            }\n         }\n     }\n\n@@ -92,63 +105,72 @@ public class OpenSearchHealthCheckProvider implements PersistenceEngineHealthPro\n         return cache.getValue();\n     }\n\n-    @Override public HealthCheckResponse detailed() {\n-        return execute();\n-    }\n-\n     private HealthCheckResponse refresh() {\n         LOGGER.debug(\"Refresh\");\n         HealthCheckResponse.Builder builder \u003d new HealthCheckResponse.Builder();\n         builder.name(NAME).down();\n-        String minimalClusterState \u003d config.get(HealthCheckConfig.CONFIG_OS_MINIMAL_CLUSTER_STATE);\n-        if (StringUtils.isEmpty(minimalClusterState)) {\n-            minimalClusterState \u003d \"green\";\n-        } else {\n-            minimalClusterState \u003d minimalClusterState.toLowerCase();\n-        }\n-        String url \u003d (config.get(HealthCheckConfig.CONFIG_OS_SSL_ENABLED).equals(\"true\") ? \"https://\" : \"http://\")\n-                .concat(config.get(HealthCheckConfig.CONFIG_OS_ADDRESSES).split(\",\")[0].trim())\n-                .concat(\"/_cluster/health\");\n-        CloseableHttpResponse response \u003d null;\n-        try {\n-            response \u003d httpClient.execute(new HttpGet(url));\n-            if (response !\u003d null \u0026\u0026 response.getStatusLine().getStatusCode() \u003d\u003d 200) {\n-                builder.up();\n-                HttpEntity entity \u003d response.getEntity();\n-                if (entity !\u003d null) {\n-                    String content \u003d EntityUtils.toString(entity);\n-                    try {\n-                        ObjectMapper mapper \u003d new ObjectMapper();\n-                        JsonNode root \u003d mapper.readTree(content);\n-                        String status \u003d root.has(\"status\") ? root.get(\"status\").asText() : null;\n-                        if (\"green\".equals(status) || (\"yellow\".equals(status) \u0026\u0026 \"yellow\".equals(minimalClusterState))) {\n-                            builder.live();\n-                        }\n-                        if (root.has(\"cluster_name\")) builder.withData(\"cluster_name\", root.get(\"cluster_name\").asText());\n-                        if (root.has(\"status\")) builder.withData(\"status\", root.get(\"status\").asText());\n-                        if (root.has(\"timed_out\")) builder.withData(\"timed_out\", root.get(\"timed_out\").asBoolean());\n-                        if (root.has(\"number_of_nodes\")) builder.withData(\"number_of_nodes\", root.get(\"number_of_nodes\").asLong());\n-                        if (root.has(\"number_of_data_nodes\")) builder.withData(\"number_of_data_nodes\", root.get(\"number_of_data_nodes\").asLong());\n-                        if (root.has(\"active_primary_shards\")) builder.withData(\"active_primary_shards\", root.get(\"active_primary_shards\").asLong());\n-                        if (root.has(\"active_shards\")) builder.withData(\"active_shards\", root.get(\"active_shards\").asLong());\n-                        if (root.has(\"relocating_shards\")) builder.withData(\"relocating_shards\", root.get(\"relocating_shards\").asLong());\n-                        if (root.has(\"initializing_shards\")) builder.withData(\"initializing_shards\", root.get(\"initializing_shards\").asLong());\n-                        if (root.has(\"unassigned_shards\")) builder.withData(\"unassigned_shards\", root.get(\"unassigned_shards\").asLong());\n-                    } catch (Exception parseEx) {\n-                        if (content.contains(\"\\\"status\\\":\\\"green\\\"\") ||\n-                                (content.contains(\"\\\"status\\\":\\\"yellow\\\"\") \u0026\u0026 \"yellow\".equals(minimalClusterState))) {\n-                            builder.live();\n+        if (isActive) {\n+            String minimalClusterState \u003d config.get(HealthCheckConfig.CONFIG_OS_MINIMAL_CLUSTER_STATE);\n+            if (StringUtils.isEmpty(minimalClusterState)) {\n+                minimalClusterState \u003d \"green\";\n+            } else {\n+                minimalClusterState \u003d minimalClusterState.toLowerCase();\n+            }\n+            String url \u003d (config.get(HealthCheckConfig.CONFIG_OS_SSL_ENABLED).equals(\"true\") ? \"https://\" : \"http://\").concat(\n+                    config.get(HealthCheckConfig.CONFIG_OS_ADDRESSES).split(\",\")[0].trim()).concat(\"/_cluster/health\");\n+            CloseableHttpResponse response \u003d null;\n+            try {\n+                response \u003d httpClient.execute(new HttpGet(url));\n+                if (response !\u003d null \u0026\u0026 response.getStatusLine().getStatusCode() \u003d\u003d 200) {\n+                    builder.up();\n+                    HttpEntity entity \u003d response.getEntity();\n+                    if (entity !\u003d null) {\n+                        String content \u003d EntityUtils.toString(entity);\n+                        try {\n+                            ObjectMapper mapper \u003d new ObjectMapper();\n+                            JsonNode root \u003d mapper.readTree(content);\n+                            String status \u003d root.has(\"status\") ? root.get(\"status\").asText() : null;\n+                            if (\"green\".equals(status) || (\"yellow\".equals(status) \u0026\u0026 \"yellow\".equals(minimalClusterState))) {\n+                                builder.live();\n+                            }\n+                            if (root.has(\"cluster_name\"))\n+                                builder.withData(\"cluster_name\", root.get(\"cluster_name\").asText());\n+                            if (root.has(\"status\"))\n+                                builder.withData(\"status\", root.get(\"status\").asText());\n+                            if (root.has(\"timed_out\"))\n+                                builder.withData(\"timed_out\", root.get(\"timed_out\").asBoolean());\n+                            if (root.has(\"number_of_nodes\"))\n+                                builder.withData(\"number_of_nodes\", root.get(\"number_of_nodes\").asLong());\n+                            if (root.has(\"number_of_data_nodes\"))\n+                                builder.withData(\"number_of_data_nodes\", root.get(\"number_of_data_nodes\").asLong());\n+                            if (root.has(\"active_primary_shards\"))\n+                                builder.withData(\"active_primary_shards\", root.get(\"active_primary_shards\").asLong());\n+                            if (root.has(\"active_shards\"))\n+                                builder.withData(\"active_shards\", root.get(\"active_shards\").asLong());\n+                            if (root.has(\"relocating_shards\"))\n+                                builder.withData(\"relocating_shards\", root.get(\"relocating_shards\").asLong());\n+                            if (root.has(\"initializing_shards\"))\n+                                builder.withData(\"initializing_shards\", root.get(\"initializing_shards\").asLong());\n+                            if (root.has(\"unassigned_shards\"))\n+                                builder.withData(\"unassigned_shards\", root.get(\"unassigned_shards\").asLong());\n+                        } catch (Exception parseEx) {\n+                            if (content.contains(\"\\\"status\\\":\\\"green\\\"\") || (content.contains(\"\\\"status\\\":\\\"yellow\\\"\") \u0026\u0026 \"yellow\".equals(\n+                                    minimalClusterState))) {\n+                                builder.live();\n+                            }\n                         }\n                     }\n                 }\n+            } catch (IOException e) {\n+                builder.error().withData(\"error\", e.getMessage());\n+                LOGGER.error(\"Error while checking OpenSearch health\", e);\n+            } finally {\n+                if (response !\u003d null) {\n+                    EntityUtils.consumeQuietly(response.getEntity());\n+                }\n             }\n-        } catch (IOException e) {\n-            builder.error().withData(\"error\", e.getMessage());\n-            LOGGER.error(\"Error while checking OpenSearch health\", e);\n-        } finally {\n-            if (response !\u003d null) {\n-                EntityUtils.consumeQuietly(response.getEntity());\n-            }\n+        } else {\n+            builder.error().withData(\"error\", \"Elasticsearch health check provider is not active\");\n         }\n         return builder.build();\n     }\ndiff --git c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceEngineHealthProvider.java i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceEngineHealthProvider.java\ndeleted file mode 100644\nindex 276ba2272..000000000\n--- c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceEngineHealthProvider.java\n+++ /dev/null\n@@ -1,37 +0,0 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *      http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-package org.apache.unomi.healthcheck.provider;\n-\n-import org.apache.unomi.healthcheck.HealthCheckProvider;\n-import org.apache.unomi.healthcheck.HealthCheckResponse;\n-\n-/**\n- * Common contract for persistence engine health providers to expose\n- * richer, implementation-specific health details.\n- */\n-public interface PersistenceEngineHealthProvider extends HealthCheckProvider {\n-\n-    /**\n-     * Build a detailed response that may include implementation-specific data.\n-     *\n-     * @return a detailed {@link HealthCheckResponse}\n-     */\n-    HealthCheckResponse detailed();\n-}\n-\n-\ndiff --git c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceHealthCheckProvider.java i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceHealthCheckProvider.java\nindex ec136fa33..b0d2725dc 100644\n--- c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceHealthCheckProvider.java\n+++ i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/PersistenceHealthCheckProvider.java\n@@ -20,7 +20,6 @@ package org.apache.unomi.healthcheck.provider;\n import org.apache.unomi.api.PropertyType;\n import org.apache.unomi.healthcheck.HealthCheckResponse;\n import org.apache.unomi.healthcheck.HealthCheckProvider;\n-import org.apache.unomi.healthcheck.HealthCheckConfig;\n import org.apache.unomi.healthcheck.util.CachedValue;\n import org.apache.unomi.persistence.spi.PersistenceService;\n import org.osgi.service.component.annotations.Component;\n@@ -47,25 +46,16 @@ public class PersistenceHealthCheckProvider implements HealthCheckProvider {\n     @Reference(service \u003d PersistenceService.class, cardinality \u003d ReferenceCardinality.OPTIONAL, policy \u003d ReferencePolicy.DYNAMIC, bind \u003d \"bind\", unbind \u003d \"unbind\")\n     private volatile PersistenceService service;\n\n-    @Reference(cardinality \u003d ReferenceCardinality.OPTIONAL)\n-    private volatile HealthCheckConfig healthCheckConfig;\n-\n-    // Lazily created delegate depending on the current persistence implementation\n-    private volatile HealthCheckProvider delegate;\n-\n     public PersistenceHealthCheckProvider() {\n         LOGGER.info(\"Building persistence health provider service...\");\n     }\n\n     public void bind(PersistenceService service) {\n         this.service \u003d service;\n-        // Reset delegate when persistence changes\n-        this.delegate \u003d null;\n     }\n\n     public void unbind(PersistenceService service) {\n         this.service \u003d null;\n-        this.delegate \u003d null;\n     }\n\n     @Override public String name() {\n@@ -74,17 +64,6 @@ public class PersistenceHealthCheckProvider implements HealthCheckProvider {\n\n     @Override public HealthCheckResponse execute() {\n         LOGGER.debug(\"Health check persistence\");\n-\n-        // If we can detect the underlying persistence, delegate to the appropriate provider\n-        HealthCheckProvider resolved \u003d resolveDelegate();\n-        if (resolved !\u003d null) {\n-            if (resolved instanceof PersistenceEngineHealthProvider) {\n-                return ((PersistenceEngineHealthProvider) resolved).detailed();\n-            }\n-            return resolved.execute();\n-        }\n-\n-        // Fallback to legacy behavior if no delegate is available yet\n         if (cache.isStaled() || cache.getValue().isDown() || cache.getValue().isError()) {\n             cache.setValue(refresh());\n         }\n@@ -109,49 +88,4 @@ public class PersistenceHealthCheckProvider implements HealthCheckProvider {\n         }\n         return builder.build();\n     }\n-\n-    private HealthCheckProvider resolveDelegate() {\n-        try {\n-            if (delegate !\u003d null) {\n-                return delegate;\n-            }\n-            if (service \u003d\u003d null) {\n-                return null;\n-            }\n-            String persistenceName;\n-            try {\n-                persistenceName \u003d service.getName();\n-            } catch (Throwable t) {\n-                // Older SPI might not expose getName(); fallback to class inspection\n-                persistenceName \u003d service.getClass().getName().toLowerCase();\n-            }\n-\n-            if (persistenceName \u003d\u003d null) {\n-                return null;\n-            }\n-\n-            if (persistenceName.contains(\"opensearch\")) {\n-                OpenSearchHealthCheckProvider provider \u003d new OpenSearchHealthCheckProvider();\n-                if (healthCheckConfig !\u003d null) {\n-                    provider.setConfig(healthCheckConfig);\n-                }\n-                provider.activate();\n-                delegate \u003d provider;\n-            } else if (persistenceName.contains(\"elasticsearch\")) {\n-                ElasticSearchHealthCheckProvider provider \u003d new ElasticSearchHealthCheckProvider();\n-                if (healthCheckConfig !\u003d null) {\n-                    provider.setConfig(healthCheckConfig);\n-                }\n-                provider.activate();\n-                delegate \u003d provider;\n-            } else {\n-                // Unknown persistence implementation, no delegate\n-                return null;\n-            }\n-            return delegate;\n-        } catch (Exception e) {\n-            LOGGER.warn(\"Unable to resolve delegated health check provider\", e);\n-            return null;\n-        }\n-    }\n }\ndiff --git c/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-elasticsearch.cfg i/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-elasticsearch.cfg\nnew file mode 100644\nindex 000000000..20a8c2a6b\n--- /dev/null\n+++ i/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-elasticsearch.cfg\n@@ -0,0 +1,31 @@\n+#\n+# Licensed to the Apache Software Foundation (ASF) under one or more\n+# contributor license agreements.  See the NOTICE file distributed with\n+# this work for additional information regarding copyright ownership.\n+# The ASF licenses this file to You under the Apache License, Version 2.0\n+# (the \"License\"); you may not use this file except in compliance with\n+# the License.  You may obtain a copy of the License at\n+#\n+#      http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+#\n+\n+# Elasticsearch configuration\n+esAddresses \u003d ${org.apache.unomi.elasticsearch.addresses:-localhost:9200}\n+esSSLEnabled \u003d ${org.apache.unomi.elasticsearch.sslEnable:-false}\n+esLogin \u003d ${org.apache.unomi.elasticsearch.username:-}\n+esPassword \u003d ${org.apache.unomi.elasticsearch.password:-}\n+esHttpClient.trustAllCertificates \u003d ${org.apache.unomi.elasticsearch.sslTrustAllCertificates:-false}\n+\n+# Security configuration\n+authentication.realm \u003d ${org.apache.unomi.security.realm:-karaf}\n+\n+# Health check configuration\n+healthcheck.enabled \u003d ${org.apache.unomi.healthcheck.enabled:-false}\n+healthcheck.providers \u003d ${org.apache.unomi.healthcheck.providers:-cluster,elasticsearch,unomi,persistence}\n+healthcheck.timeout \u003d ${org.apache.unomi.healthcheck.timeout:-400}\ndiff --git c/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck.cfg i/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-opensearch.cfg\nsimilarity index 78%\nrename from extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck.cfg\nrename to extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-opensearch.cfg\nindex 9c6083ab9..98fef8fdf 100644\n--- c/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck.cfg\n+++ i/extensions/healthcheck/src/main/resources/org.apache.unomi.healthcheck-opensearch.cfg\n@@ -15,13 +15,6 @@\n # limitations under the License.\n #\n\n-# Elasticsearch configuration\n-esAddresses \u003d ${org.apache.unomi.elasticsearch.addresses:-localhost:9200}\n-esSSLEnabled \u003d ${org.apache.unomi.elasticsearch.sslEnable:-false}\n-esLogin \u003d ${org.apache.unomi.elasticsearch.username:-}\n-esPassword \u003d ${org.apache.unomi.elasticsearch.password:-}\n-esHttpClient.trustAllCertificates \u003d ${org.apache.unomi.elasticsearch.sslTrustAllCertificates:-false}\n-\n # OpenSearch configuration\n osAddresses \u003d ${org.apache.unomi.opensearch.addresses:-localhost:9200}\n osSSLEnabled \u003d ${org.apache.unomi.opensearch.sslEnable:-true}\n@@ -35,5 +28,5 @@ authentication.realm \u003d ${org.apache.unomi.security.realm:-karaf}\n\n # Health check configuration\n healthcheck.enabled \u003d ${org.apache.unomi.healthcheck.enabled:-false}\n-healthcheck.providers \u003d ${org.apache.unomi.healthcheck.providers:-cluster,elasticsearch,opensearch,unomi,persistence}\n+healthcheck.providers \u003d ${org.apache.unomi.healthcheck.providers:-cluster,opensearch,unomi,persistence}\n healthcheck.timeout \u003d ${org.apache.unomi.healthcheck.timeout:-400}\ndiff --git c/itests/src/test/java/org/apache/unomi/itests/BaseIT.java i/itests/src/test/java/org/apache/unomi/itests/BaseIT.java\nindex d7b6de159..9bb734c91 100644\n--- c/itests/src/test/java/org/apache/unomi/itests/BaseIT.java\n+++ i/itests/src/test/java/org/apache/unomi/itests/BaseIT.java\n@@ -182,7 +182,8 @@ public abstract class BaseIT extends KarafTestSupport {\n             } else if (SEARCH_ENGINE_OPENSEARCH.equals(searchEngine)){\n                 LOGGER.info(\"Starting Unomi with opensearch search engine...\");\n                 System.out.println(\"\u003d\u003d\u003d\u003d Starting Unomi with opensearch search engine...\");\n-                executeCommand(\"unomi:start \" + SEARCH_ENGINE_OPENSEARCH);\n+                executeCommand(\"unomi:setup -d unomi-distribution-opensearch --force true\");\n+                executeCommand(\"unomi:start\");\n             } else {\n                 LOGGER.error(\"Unknown search engine: \" + searchEngine);\n                 throw new InterruptedException(\"Unknown search engine: \" + searchEngine);\n@@ -306,7 +307,7 @@ public abstract class BaseIT extends KarafTestSupport {\n                     \"unomi-shell-dev-commands\",\n                     \"unomi-wab\",\n                     \"unomi-web-tracker\",\n-                    \"unomi-healthcheck\",\n+                    \"unomi-healthcheck-elasticsearch\",\n                     \"unomi-router-karaf-feature\",\n                     \"unomi-groovy-actions\",\n                     \"unomi-rest-ui\",\n@@ -332,7 +333,7 @@ public abstract class BaseIT extends KarafTestSupport {\n                     \"unomi-shell-dev-commands\",\n                     \"unomi-wab\",\n                     \"unomi-web-tracker\",\n-                    \"unomi-healthcheck\",\n+                    \"unomi-healthcheck-opensearch\",\n                     \"unomi-router-karaf-feature\",\n                     \"unomi-groovy-actions\",\n                     \"unomi-rest-ui\",\ndiff --git c/itests/src/test/java/org/apache/unomi/itests/HealthCheckIT.java i/itests/src/test/java/org/apache/unomi/itests/HealthCheckIT.java\nindex 882259525..d68bcd6f1 100644\n--- c/itests/src/test/java/org/apache/unomi/itests/HealthCheckIT.java\n+++ i/itests/src/test/java/org/apache/unomi/itests/HealthCheckIT.java\n@@ -59,10 +59,11 @@ public class HealthCheckIT extends BaseIT {\n             List\u003cHealthCheckResponse\u003e response \u003d get(HEALTHCHECK_ENDPOINT, new TypeReference\u003c\u003e() {});\n             LOGGER.info(\"health check response: {}\", response);\n             Assert.assertNotNull(response);\n-            Assert.assertEquals(4, response.size());\n+            Assert.assertEquals(5, response.size());\n             Assert.assertTrue(response.stream().anyMatch(r -\u003e r.getName().equals(\"karaf\") \u0026\u0026 r.getStatus() \u003d\u003d HealthCheckResponse.Status.LIVE));\n             Assert.assertTrue(response.stream().anyMatch(r -\u003e r.getName().equals(searchEngine) \u0026\u0026 r.getStatus() \u003d\u003d HealthCheckResponse.Status.LIVE));\n             Assert.assertTrue(response.stream().anyMatch(r -\u003e r.getName().equals(\"unomi\") \u0026\u0026 r.getStatus() \u003d\u003d HealthCheckResponse.Status.LIVE));\n+            Assert.assertTrue(response.stream().anyMatch(r -\u003e r.getName().equals(\"persistence\") \u0026\u0026 r.getStatus() \u003d\u003d HealthCheckResponse.Status.LIVE));\n             Assert.assertTrue(response.stream().anyMatch(r -\u003e r.getName().equals(\"cluster\") \u0026\u0026 r.getStatus() \u003d\u003d HealthCheckResponse.Status.LIVE));\n         } catch (Exception e) {\n             LOGGER.error(\"Error while executing health check\", e);\ndiff --git c/itests/src/test/resources/org.apache.unomi.healthcheck.cfg i/itests/src/test/resources/org.apache.unomi.healthcheck.cfg\nindex 9de18615b..4f5e824ea 100644\n--- c/itests/src/test/resources/org.apache.unomi.healthcheck.cfg\n+++ i/itests/src/test/resources/org.apache.unomi.healthcheck.cfg\n@@ -35,5 +35,5 @@ authentication.realm \u003d ${org.apache.unomi.security.realm:-karaf}\n\n # Health check configuration\n healthcheck.enabled \u003d ${org.apache.unomi.healthcheck.enabled:-true}\n-healthcheck.providers \u003d ${org.apache.unomi.healthcheck.providers:-cluster,elasticsearch,opensearch,unomi,persistence}\n+healthcheck.providers \u003d ${org.apache.unomi.healthcheck.providers:-cluster,unomi,persistence}\n healthcheck.timeout \u003d ${org.apache.unomi.healthcheck.timeout:-400}\ndiff --git c/kar/src/main/feature/feature.xml i/kar/src/main/feature/feature.xml\nindex d4f83fe94..ed3d3a483 100644\n--- c/kar/src/main/feature/feature.xml\n+++ i/kar/src/main/feature/feature.xml\n@@ -75,7 +75,6 @@\n     \u003cfeature name\u003d\"unomi-startup\" description\u003d\"Apache Unomi :: Startup Tools\" version\u003d\"${project.version}\"\u003e\n         \u003cfeature\u003eunomi-base\u003c/feature\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.migration.cfg\"\u003emvn:org.apache.unomi/shell-commands/${project.version}/cfg/migration\u003c/configfile\u003e\n-        \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.start.cfg\"\u003emvn:org.apache.unomi/shell-commands/${project.version}/cfg/start\u003c/configfile\u003e\n         \u003cbundle\u003emvn:org.apache.unomi/shell-commands/${project.version}\u003c/bundle\u003e\n     \u003c/feature\u003e\n\n@@ -184,9 +183,15 @@\n         \u003cbundle start\u003d\"false\"\u003emvn:org.apache.unomi/unomi-web-tracker-wab/${project.version}\u003c/bundle\u003e\n     \u003c/feature\u003e\n\n-    \u003cfeature name\u003d\"unomi-healthcheck\" description\u003d\"Apache Unomi :: Healthcheck\" version\u003d\"${project.version}\"\u003e\n+    \u003cfeature name\u003d\"unomi-healthcheck-elasticsearch\" description\u003d\"Apache Unomi :: Healthcheck ElasticSearch\" version\u003d\"${project.version}\"\u003e\n         \u003cfeature\u003eunomi-web-tracker\u003c/feature\u003e\n-        \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.healthcheck.cfg\"\u003emvn:org.apache.unomi/healthcheck/${project.version}/cfg/healthcheck\u003c/configfile\u003e\n+        \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.healthcheck.cfg\"\u003emvn:org.apache.unomi/healthcheck/${project.version}/cfg/healthcheck-elasticsearch\u003c/configfile\u003e\n+        \u003cbundle start\u003d\"false\"\u003emvn:org.apache.unomi/healthcheck/${project.version}\u003c/bundle\u003e\n+    \u003c/feature\u003e\n+\n+    \u003cfeature name\u003d\"unomi-healthcheck-opensearch\" description\u003d\"Apache Unomi :: Healthcheck OpenSearch\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.healthcheck.cfg\"\u003emvn:org.apache.unomi/healthcheck/${project.version}/cfg/healthcheck-opensearch\u003c/configfile\u003e\n         \u003cbundle start\u003d\"false\"\u003emvn:org.apache.unomi/healthcheck/${project.version}\u003c/bundle\u003e\n     \u003c/feature\u003e\n\ndiff --git c/manual/src/main/asciidoc/5-min-quickstart.adoc i/manual/src/main/asciidoc/5-min-quickstart.adoc\nindex c92fd683e..c53cbf979 100644\n--- c/manual/src/main/asciidoc/5-min-quickstart.adoc\n+++ i/manual/src/main/asciidoc/5-min-quickstart.adoc\n@@ -23,7 +23,7 @@ Begin by creating a `docker-compose.yml` file. You can choose between ElasticSea\n version: \u00273.8\u0027\n services:\n     elasticsearch:\n-        image: docker.elastic.co/elasticsearch/elasticsearch:7.17.5\n+        image: docker.elastic.co/elasticsearch/elasticsearch:9.2.1\n         environment:\n             - discovery.type\u003dsingle-node\n         ports:\n@@ -75,10 +75,11 @@ services:\n     unomi:\n         image: apache/unomi:3.0.0\n         environment:\n-            - UNOMI_AUTO_START\u003dopensearch\n+            - UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n             - UNOMI_OPENSEARCH_ADDRESSES\u003dopensearch-node1:9200\n             - UNOMI_OPENSEARCH_USERNAME\u003dadmin\n             - UNOMI_OPENSEARCH_PASSWORD\u003d${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-admin}\n+            - UNOMI_HEALTHCHECK_PROVIDERS\u003dcluster,opensearch,unomi,persistence\n         ports:\n             - 8181:8181\n             - 9443:9443\n@@ -100,7 +101,7 @@ Try accessing https://localhost:9443/cxs/cluster with username/password: karaf/k\n\n 1) Install JDK 17 and make sure you set the JAVA_HOME variable (see our \u003c\u003cJDK compatibility,Getting Started\u003e\u003e guide for more information on JDK compatibility)\n\n-2) Download ElasticSearch here : https://www.elastic.co/downloads/past-releases/elasticsearch-7-17-5 (please *make sure* you use the proper version : 7.17.5)\n+2) Download ElasticSearch here : https://www.elastic.co/downloads/past-releases/elasticsearch-9-2-1 (please *make sure* you use the proper version : 9.2.1)\n\n 3) Uncompress it and change the `config/elasticsearch.yml` to include the following config :\n\n@@ -134,10 +135,14 @@ discovery.type: single-node\n 6) Start it using : `./bin/karaf`\n\n 7) Start the Apache Unomi packages using:\n-- For ElasticSearch: `unomi:start elasticsearch`\n-- For OpenSearch: `unomi:start opensearch`\n+- `unomi:start`\n\n-The parameter specifies which start features configuration to use (elasticsearch or opensearch), which determines which set of features and bundles are installed and started.\n+Note that you could change or set the distribution (if not defined using environment variable) using:\n+- `unomi:setup unomi-distribution-opensearch --force true`\n+- `unomi:start`\n+\n+The unomi:setup parameter specifies which distribution to use (unomi-distribution-elasticsearch or unomi-distribution-opensearch),\n+which determines which set of features and bundles are installed and started. A custom distribution can also be used if available in Karaf (by adding the relevant feature repository)\n\n 8) Wait for startup to complete\n\ndiff --git c/manual/src/main/asciidoc/configuration.adoc i/manual/src/main/asciidoc/configuration.adoc\nindex 6cacb05e2..b3d97a936 100644\n--- c/manual/src/main/asciidoc/configuration.adoc\n+++ i/manual/src/main/asciidoc/configuration.adoc\n@@ -107,11 +107,11 @@ To select which search engine to use, you can:\n    * For OpenSearch: add `-Duse.opensearch\u003dtrue` to your Maven command\n    (this will only impact the integration tests if they are activated using the -Pintegration-tests profile)\n 3. When using Docker:\n-   * For ElasticSearch: use `UNOMI_AUTO_START\u003delasticsearch`\n-   * For OpenSearch: use `UNOMI_AUTO_START\u003dopensearch`\n-   * For custom configurations: use `UNOMI_AUTO_START\u003dyour-custom-config-name`\n+   * For ElasticSearch: use `UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch`\n+   * For OpenSearch: use `UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch`\n+   * For custom configurations: use `UNOMI_DISTRIBUTION\u003dyour-custom-distribution-name`\n\n-Note: The `UNOMI_AUTO_START` environment variable accepts any start features configuration name defined in the `org.apache.unomi.start.cfg` file. You can use the predefined \"elasticsearch\" or \"opensearch\" configurations, or specify a custom configuration name if you have created one.\n+Note: The `UNOMI_DISTRIBUTION` environment variable accepts any karaf feature that is available form Karaf. Two built-in distributions (unomi-distribution-elasticsearch, unomi-distribution-opensearch) are packaged with UNOMI archive but any other can be added, either in the package  or by adding a feature repository that contains the desired one in Karaf.\n\n Note: When using OpenSearch 3.x:\n  - Security is enabled by default and requires SSL/TLS\n@@ -972,7 +972,7 @@ You can use your custom configurations with:\n unomi:start elasticsearch-dev\n unomi:start opensearch-dev\n\n-# Staging environment\n+# Staging environment\n unomi:start elasticsearch-staging\n unomi:start opensearch-staging\n\n@@ -981,34 +981,42 @@ unomi:start elasticsearch-prod\n unomi:start opensearch-prod\n ----\n\n-\u003d\u003d\u003d\u003d Auto-Start Configuration\n+\u003d\u003d\u003d\u003d Auto-Start\n\n-You can configure Apache Unomi to automatically start with a specific start features configuration when the server boots up. This is useful for production deployments where you want the server to start automatically without manual intervention.\n+You can configure Apache Unomi to automatically start when the server boots up. See the next section for details. This is useful for production deployments where you want the server to start automatically without manual intervention.\n\n-To enable auto-start, set the `unomi.autoStart` system property or `UNOMI_AUTO_START` environment variable to the name of your desired start features configuration:\n+To enable auto-start, set the `unomi.autoStart` system property or `UNOMI_AUTO_START` environment variable to \u0027true\u0027\n+\n+Note: Auto-start only works when Apache Unomi is not already running. If the server is already started, the auto-start setting will be ignored.\n+\n+\u003d\u003d\u003d\u003d Unomi Distribution\n+\n+You can define a specific distribution for Apache Unomi to configure desired features when the server boots up. Is it a classic Karaf feature that defines desired features for Unomi.\n+Be aware that, even if a distribution is a classic Karaf feature XML file, it must only be composed feature\u0027s dependencies as this file is interpreted by the Unomi ManagementService.\n+No bundle nor config file will be processed from this file.\n+\n+To set the desired distribution, set the `unomi.distribution` system property or `UNOMI_DISTRIBUTION` environment variable to the name of your desired distribution:\n\n [source]\n ----\n # Using system property\n--Dunomi.autoStart\u003delasticsearch-prod\n+-Dunomi.distribution\u003dunomi-distribution-elasticsearch\n\n # Using environment variable (Docker)\n-UNOMI_AUTO_START\u003dopensearch-prod\n+UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch\n\n-# Using custom configuration\n-UNOMI_AUTO_START\u003delasticsearch-staging\n+# Using custom distribution\n+UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch-staging\n ----\n\n-The auto-start feature accepts any start features configuration name defined in your `org.apache.unomi.start.cfg` file. If you set it to `true`, it will default to the \"elasticsearch\" configuration for backward compatibility.\n-\n-Note: Auto-start only works when Apache Unomi is not already running. If the server is already started, the auto-start setting will be ignored.\n+To use a custom distribution, the corresponding feature must be accessible by Karaf. It can be done by publishing the feature maven artefact and adding it as a feature repository in Karaf os for any other feature. Of course you can also add your distribution feature in the existing source code and repackage Unomi making it available directly.\n\n \u003d\u003d\u003d\u003d Important Notes\n\n-* **Configuration changes require restart**: After modifying the start features configuration, you must restart Apache Unomi for the changes to take effect\n+* **Distribution changes require restart**: After forcing a modification of the distribution, you must restart Apache Unomi for the changes to take effect (be aware that in production it can have unpredictable side effects)\n * **Feature dependencies**: When adding custom features, ensure they have all required dependencies and are compatible with your chosen persistence implementation\n-* **Backup your configuration**: Always backup your custom configuration before upgrading Apache Unomi, as upgrades may overwrite the default configuration file\n-* **Feature availability**: Only features that are available in your Apache Unomi installation can be included in the configuration\n+* **Backup your distribution**: As a distribution is a maven artifact, use the versionning to ensure you can rollback to a previous version.\n+* **Feature availability**: According to Karaf maven repository access, you can add any feature repository that holds a Unomi distribution\u0027s feature and use it into an existing Unomi instance.\n\n \u003d\u003d\u003d\u003d Available Features\n\n@@ -1019,11 +1027,12 @@ To see all available features in your Apache Unomi installation, you can use the\n feature:list\n ----\n\n-This will show you all available features that can be included in your start features configuration.\n+This will show you all available features that can be included in your distribution.\n\n-\u003d\u003d\u003d\u003d Docker Deployment with Custom Configuration\n+\u003d\u003d\u003d\u003d Docker Deployment with Custom Distribution\n\n-For Docker deployments, you can mount your custom start configuration file to override the default settings:\n+For Docker deployments, you can declare a custom distribution feature repository (online) or a local one and mount the corresonding XML file accordingly:\n+-e KARAF_FEATURES_REPOSITORIES\u003dmvn:com.example/myfeatures/1.0.0/xml/features\n\n [source,yaml]\n ----\n@@ -1032,9 +1041,10 @@ services:\n   unomi:\n     image: apache/unomi:3.0.0\n     volumes:\n-      - ./custom-start.cfg:/opt/apache-unomi/etc/org.apache.unomi.start.cfg\n+      - ./unomi-custom-distribution-features.xml:/opt/apache-unomi/features/unomi-custom-distribution-features.xml\n     environment:\n-      - UNOMI_AUTO_START\u003delasticsearch-prod  # or opensearch-prod\n+      - KARAF_FEATURES_REPOSITORIES\u003dfile:/opt/apache-unomi/features/unomi-custom-distribution-features.xml\n+      - UNOMI_DISTRIBUTION\u003dunomi-distribution-custom\n     depends_on:\n       - elasticsearch\n   elasticsearch:\n@@ -1045,9 +1055,9 @@ services:\n ----\n\n **Key Points:**\n-- Mount your custom configuration file to `/opt/apache-unomi/etc/org.apache.unomi.start.cfg`\n-- Use the `UNOMI_AUTO_START` environment variable to specify which configuration to use\n-- The configuration file will override the default settings when the container starts\n+- Mount your custom distribution feature repository file to `/opt/apache-unomi/etc/features/your-features-files.xml` (not necessary if the feature file is available in a online maven repository)\n+- Declare the feature repository in Karaf using KARAF_FEATURES_REPOSITORIES environment variable pointing to your mounted file or a online maven artifact (mvn:com.example/custom-unomi-distribs/1.0.0/xml/features)\n+- Use the `UNOMI_DISTRIBUTION` environment variable to specify which distribution (using the feature name) to use from that feature\u0027s repository\n\n \u003d\u003d\u003d Customizing Apache Unomi Distribution\n\n@@ -1101,7 +1111,7 @@ export UNOMI_PUBLIC_ADDRESS\u003dhttps://production.unomi.example.com\n\n \u003d\u003d\u003d\u003d Deployment with Custom Distribution\n\n-Once you have created your custom distribution, you can deploy it using the same methods as the standard distribution:\n+Once you have created and published your custom distribution, you can deploy it using the same methods as the standard distribution:\n\n **Docker Deployment:**\n [source,yaml]\n@@ -1113,7 +1123,8 @@ services:\n       context: .\n       dockerfile: Dockerfile\n     environment:\n-      - UNOMI_AUTO_START\u003delasticsearch-prod\n+      - KARAF_FEATURES_REPOSITORIES\u003dmvn:com.example/your-custom-unomi-distributions/1.0.0/xml/features\n+      - UNOMI_DISTRIBUTION\u003delasticsearch-prod\n     depends_on:\n       - elasticsearch\n   elasticsearch:\n@@ -1126,7 +1137,7 @@ services:\n **Dockerfile:**\n [source,dockerfile]\n ----\n-FROM apache/unomi:3.0.0\n+FROM apache/unomi:3.1.0\n COPY apache-unomi-custom-*.tar.gz /tmp/\n RUN cd /opt/apache-unomi \u0026\u0026 tar -xzf /tmp/apache-unomi-custom-*.tar.gz\n ----\ndiff --git c/manual/src/main/asciidoc/migrations/migrate-2.x-to-3.0.adoc i/manual/src/main/asciidoc/migrations/migrate-2.x-to-3.0.adoc\nindex a42523239..8747d18ed 100644\n--- c/manual/src/main/asciidoc/migrations/migrate-2.x-to-3.0.adoc\n+++ i/manual/src/main/asciidoc/migrations/migrate-2.x-to-3.0.adoc\n@@ -222,8 +222,8 @@ When legacy queryBuilder IDs are used, Apache Unomi will log warning messages th\n **Example Warning Log:**\n [source]\n ----\n-WARN - DEPRECATED: Using legacy queryBuilderId \u0027idsConditionESQueryBuilder\u0027 for condition type \u0027customIdsCondition\u0027.\n-Please update your condition definition to use the new queryBuilderId \u0027idsConditionQueryBuilder\u0027.\n+WARN - DEPRECATED: Using legacy queryBuilderId \u0027idsConditionESQueryBuilder\u0027 for condition type \u0027customIdsCondition\u0027.\n+Please update your condition definition to use the new queryBuilderId \u0027idsConditionQueryBuilder\u0027.\n Legacy mappings are deprecated and may be removed in future versions.\n ----\n\n@@ -253,11 +253,11 @@ org.apache.unomi.opensearch.sslTrustAllCertificates\u003dtrue\n\n \u003d\u003d\u003d\u003d\u003d Docker Configuration Changes\n\n-When using Docker, you can specify the search engine backend:\n+When using Docker, you can specify the search engine backend using the distribution environment variable `UNOMI_DISTRIBUTION`.:\n\n-- **For Elasticsearch**: `UNOMI_AUTO_START\u003delasticsearch`\n-- **For OpenSearch**: `UNOMI_AUTO_START\u003dopensearch`\n-- **For custom configurations**: `UNOMI_AUTO_START\u003dyour-custom-config-name`\n+- **For Elasticsearch**: `UNOMI_DISTRIBUTION\u003dunomi-distribution-elasticsearch`\n+- **For OpenSearch**: `UNOMI_DISTRIBUTION\u003dunomi-distribution-opensearch`\n+- **For custom configurations**: `UNOMI_DISTRIBUTION\u003dyour-custom-distribution-name`\n\n \u003d\u003d\u003d\u003d Migrating from Elasticsearch to OpenSearch\n\ndiff --git c/package/pom.xml i/package/pom.xml\nindex 2021983aa..02d045d84 100644\n--- c/package/pom.xml\n+++ i/package/pom.xml\n@@ -117,6 +117,13 @@\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-distribution\u003c/artifactId\u003e\n+            \u003cclassifier\u003efeatures\u003c/classifier\u003e\n+            \u003ctype\u003exml\u003c/type\u003e\n+            \u003cscope\u003eruntime\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\n@@ -367,6 +374,8 @@\n                         \u003cfeature\u003eunomi-groovy-actions\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-web-applications\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-rest-ui\u003c/feature\u003e\n+                        \u003cfeature\u003eunomi-distribution-elasticsearch\u003c/feature\u003e\n+                        \u003cfeature\u003eunomi-distribution-opensearch\u003c/feature\u003e\n                     \u003c/installedFeatures\u003e\n                     \u003cjavase\u003e17\u003c/javase\u003e\n                 \u003c/configuration\u003e\ndiff --git c/package/src/main/resources/etc/custom.system.properties i/package/src/main/resources/etc/custom.system.properties\nindex 7ca2c55bc..dd6e1f911 100644\n--- c/package/src/main/resources/etc/custom.system.properties\n+++ i/package/src/main/resources/etc/custom.system.properties\n@@ -508,7 +508,7 @@ org.apache.unomi.healthcheck.password\u003d${env:UNOMI_HEALTHCHECK_PASSWORD:-health}\n # Specify the list of health check providers (name) to use. The list is comma separated. Other providers will be ignored.\n # As Karaf provider is the one needed by healthcheck (always LIVE), it cannot be ignored.\n #\n-org.apache.unomi.healthcheck.providers:${env:UNOMI_HEALTHCHECK_PROVIDERS:-cluster,elasticsearch,opensearch,unomi,persistence}\n+org.apache.unomi.healthcheck.providers:${env:UNOMI_HEALTHCHECK_PROVIDERS:-cluster,elasticsearch,unomi,persistence}\n #\n # Specify the timeout in milliseconds for each healthcheck provider call. The default value is 400ms.\n # If timeout is raised, the provider is marked in ERROR.\ndiff --git c/pom.xml i/pom.xml\nindex 54ce7cd0a..109ec9335 100644\n--- c/pom.xml\n+++ i/pom.xml\n@@ -419,6 +419,7 @@\n         \u003cmodule\u003eextensions/weather-update\u003c/module\u003e\n         \u003cmodule\u003egraphql\u003c/module\u003e\n         \u003cmodule\u003esamples\u003c/module\u003e\n+        \u003cmodule\u003edistribution\u003c/module\u003e\n         \u003cmodule\u003epackage\u003c/module\u003e\n     \u003c/modules\u003e\n\ndiff --git c/src/main/feature/feature.xml i/src/main/feature/feature.xml\nnew file mode 100644\nindex 000000000..3ad62251f\n--- /dev/null\n+++ i/src/main/feature/feature.xml\n@@ -0,0 +1,75 @@\n+\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\" standalone\u003d\"yes\"?\u003e\n+\u003c!--\n+  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n+  ~ contributor license agreements.  See the NOTICE file distributed with\n+  ~ this work for additional information regarding copyright ownership.\n+  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n+  ~ (the \"License\"); you may not use this file except in compliance with\n+  ~ the License.  You may obtain a copy of the License at\n+  ~\n+  ~      http://www.apache.org/licenses/LICENSE-2.0\n+  ~\n+  ~ Unless required by applicable law or agreed to in writing, software\n+  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+  ~ See the License for the specific language governing permissions and\n+  ~ limitations under the License.\n+  --\u003e\n+\n+\u003cfeatures name\u003d\"unomi-distributions\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n+\n+    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features\u003c/repository\u003e\n+    \u003crepository\u003emvn:org.apache.unomi/unomi-kar/${project.version}/xml/features\u003c/repository\u003e\n+\n+    \u003cfeature name\u003d\"unomi-distribution-elasticsearch\" description\u003d\"Apache Unomi :: ElasticSearch Distribution\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-elasticsearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-optimization-test\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-shell-dev-commands\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-elasticsearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\n+    \u003cfeature name\u003d\"unomi-distribution-opensearch\" description\u003d\"Apache Unomi :: OpenSearch Distribution\" version\u003d\"${project.version}\"\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-opensearch-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-persistence-core\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-services\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-api\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-lists-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-geonames-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-cxs-privacy-extension\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-opensearch-conditions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-base\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-request\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-mail\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-plugins-optimization-test\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-shell-dev-commands\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-wab\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-web-tracker\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-healthcheck-opensearch\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-router-karaf-feature\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-groovy-actions\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-rest-ui\u003c/feature\u003e\n+        \u003cfeature dependency\u003d\"true\" version\u003d\"${project.version}\"\u003eunomi-startup-complete\u003c/feature\u003e\n+    \u003c/feature\u003e\n+\n+\u003c/features\u003e\ndiff --git c/tools/shell-commands/pom.xml i/tools/shell-commands/pom.xml\nindex fcd3a1584..ed2cf406b 100644\n--- c/tools/shell-commands/pom.xml\n+++ i/tools/shell-commands/pom.xml\n@@ -90,6 +90,11 @@\n             \u003cartifactId\u003eorg.osgi.service.metatype.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.felix\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.apache.felix.configadmin\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n@@ -178,13 +183,6 @@\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003cclassifier\u003emigration\u003c/classifier\u003e\n                                 \u003c/artifact\u003e\n-                                \u003cartifact\u003e\n-                                    \u003cfile\u003e\n-                                        src/main/resources/org.apache.unomi.start.cfg\n-                                    \u003c/file\u003e\n-                                    \u003ctype\u003ecfg\u003c/type\u003e\n-                                    \u003cclassifier\u003estart\u003c/classifier\u003e\n-                                \u003c/artifact\u003e\n                             \u003c/artifacts\u003e\n                         \u003c/configuration\u003e\n                     \u003c/execution\u003e\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Setup.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Setup.java\nnew file mode 100644\nindex 000000000..9d4c3acd8\n--- /dev/null\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Setup.java\n@@ -0,0 +1,45 @@\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\n+ * contributor license agreements.  See the NOTICE file distributed with\n+ * this work for additional information regarding copyright ownership.\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\n+ * (the \"License\"); you may not use this file except in compliance with\n+ * the License.  You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+package org.apache.unomi.shell.actions;\n+\n+import org.apache.karaf.shell.api.action.Action;\n+import org.apache.karaf.shell.api.action.Command;\n+import org.apache.karaf.shell.api.action.Option;\n+import org.apache.karaf.shell.api.action.lifecycle.Reference;\n+import org.apache.karaf.shell.api.action.lifecycle.Service;\n+import org.apache.unomi.shell.services.UnomiManagementService;\n+\n+@Command(scope \u003d \"unomi\", name \u003d \"setup\", description \u003d \"This will setup some Apache Unomi runtime options\")\n+@Service\n+public class Setup implements Action {\n+\n+    @Reference\n+    UnomiManagementService unomiManagementService;\n+\n+    @Option(name \u003d \"-d\", aliases \u003d \"--distribution\", description \u003d \"Unomi Distribution feature to configure\", required \u003d true, multiValued \u003d false)\n+    String distribution \u003d \"unomi-distribution-elasticsearch\";\n+\n+    @Option(name \u003d \"-f\", aliases \u003d \"--force\", description \u003d \"Force setting up distribution feature name even if already exists (use with caution)\", required \u003d false, multiValued \u003d false)\n+    boolean force \u003d false;\n+\n+    public Object execute() throws Exception {\n+        System.out.println(\"Setting up Apache Unomi distribution: \" + distribution);\n+        unomiManagementService.setupUnomiDistribution(distribution, force);\n+        return null;\n+    }\n+\n+}\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Start.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Start.java\nindex 3e1c3e89e..98c5b85a9 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Start.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Start.java\n@@ -31,20 +31,12 @@ public class Start implements Action {\n     @Reference\n     UnomiManagementService unomiManagementService;\n\n-    @Argument(name \u003d \"startFeatures\", description \u003d \"Start features configuration to use (elasticsearch/opensearch)\", valueToShowInHelp \u003d \"elasticsearch\")\n-    private String selectedStartFeatures \u003d \"elasticsearch\";\n-\n-    @Option(name \u003d \"-i\", aliases \u003d \"--install-only\", description \u003d \"Only install features, don\u0027t start them\", required \u003d false, multiValued \u003d false)\n+    @Option(name \u003d \"-i\", aliases \u003d \"--install-only\", description \u003d \"Only install distribution feature\u0027s dependencies, don\u0027t start them\", required \u003d false, multiValued \u003d false)\n     boolean installOnly \u003d false;\n\n     public Object execute() throws Exception {\n-        if (!selectedStartFeatures.equals(\"elasticsearch\") \u0026\u0026\n-                !selectedStartFeatures.equals(\"opensearch\")) {\n-            System.err.println(\"Invalid value \u0027\"+selectedStartFeatures+\"\u0027 specified for start features configuration, will default to elasticsearch\");\n-            selectedStartFeatures \u003d \"elasticsearch\";\n-        }\n-        System.out.println(\"Starting Apache Unomi with start features configuration: \" + selectedStartFeatures);\n-        unomiManagementService.startUnomi(selectedStartFeatures, !installOnly);\n+        System.out.println(\"Starting Apache Unomi\");\n+        unomiManagementService.startUnomi(!installOnly);\n         return null;\n     }\n\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Stop.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Stop.java\nindex 8b8cad5e6..ca87002e5 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Stop.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/actions/Stop.java\n@@ -31,7 +31,6 @@ public class Stop implements Action {\n\n     public Object execute() throws Exception {\n         unomiManagementService.stopUnomi();\n-\n         return null;\n     }\n\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\nindex a92bf2bd2..607f08729 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/UnomiManagementService.java\n@@ -16,6 +16,7 @@\n  */\n package org.apache.unomi.shell.services;\n\n+import org.apache.unomi.shell.services.internal.UnomiSetup;\n import org.osgi.framework.BundleException;\n\n /**\n@@ -25,32 +26,38 @@ import org.osgi.framework.BundleException;\n public interface UnomiManagementService {\n\n     /**\n-     * This method will start Apache Unomi with the specified start features configuration\n-     * @param selectedStartFeatures the start features configuration to use\n-     * @param mustStartFeatures true if features should be started, false if they should not\n-     * @throws BundleException if there was an error starting Unomi\u0027s bundles\n+     * This method will set up Unomi distribution\u0027s feature name\n+     * @param distribution the distribution feature name to set up\n+     * @param overwrite to force setup even if already exists\n+     * @throws BundleException if the setup already exists and overwrite is false\n      */\n-    void startUnomi(String selectedStartFeatures, boolean mustStartFeatures) throws Exception;\n+    void setupUnomiDistribution(String distribution, boolean overwrite) throws Exception;\n\n     /**\n-     * This method will start Apache Unomi with the specified start features configuration\n-     * @param selectedStartFeatures the start features configuration to use\n+     * This method will start Apache Unomi\n+     * @param mustStartFeatures true if features should be started, false if they should not\n+     * @throws Exception if there was an error starting Unomi\u0027s bundles\n+     */\n+    void startUnomi(boolean mustStartFeatures) throws Exception;\n+\n+    /**\n+     * This method will start Apache Unomi\n      * @param mustStartFeatures true if features should be started, false if they should not\n      * @param waitForCompletion true if the method should wait for completion, false if it should not\n-     * @throws BundleException if there was an error starting Unomi\u0027s bundles\n+     * @throws Exception if there was an error starting Unomi\u0027s bundles\n      */\n-    void startUnomi(String selectedStartFeatures, boolean mustStartFeatures, boolean waitForCompletion) throws Exception;\n+    void startUnomi(boolean mustStartFeatures, boolean waitForCompletion) throws Exception;\n\n     /**\n      * This method will stop Apache Unomi\n-     * @throws BundleException if there was an error stopping Unomi\u0027s bundles\n+     * @throws Exception if there was an error stopping Unomi\u0027s bundles\n      */\n     void stopUnomi() throws Exception;\n\n     /**\n      * This method will stop Apache Unomi\n      * @param waitForCompletion true if the method should wait for completion, false if it should not\n-     * @throws BundleException if there was an error stopping Unomi\u0027s bundles\n+     * @throws Exception if there was an error stopping Unomi\u0027s bundles\n      */\n     void stopUnomi(boolean waitForCompletion) throws Exception;\n }\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceConfiguration.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceConfiguration.java\ndeleted file mode 100644\nindex fc6152985..000000000\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceConfiguration.java\n+++ /dev/null\n@@ -1,52 +0,0 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *      http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.unomi.shell.services.internal;\n-\n-import org.osgi.service.metatype.annotations.AttributeDefinition;\n-import org.osgi.service.metatype.annotations.ObjectClassDefinition;\n-\n-/**\n- * OSGi metatype configuration for the Unomi Management service.\n- * \u003cp\u003e\n- * Allows specifying a list of feature sets to start when the management\n- * service initializes. Each entry is a string that maps a logical key to\n- * one or more features.\n- */\n-@ObjectClassDefinition(\n-        name \u003d \"Unomi Management Configuration\",\n-        description \u003d \"Configuration for Unomi Management Service\"\n-)\n-public @interface UnomiManagementServiceConfiguration {\n-\n-    @AttributeDefinition(\n-            name \u003d \"Start Features\",\n-            description \u003d \"An array of strings representing start features in the format \u0027[\\\"key\u003dfeature1,feature2\\\", \\\"key2:feature3\\\"]\u0027.\"\n-    )\n-    /**\n-     * Defines one or more feature sets to start.\n-     * \u003cp\u003e\n-     * Each element is a string using one of these forms:\n-     * - key\u003dfeatureA,featureB (comma-separated list assigned to a key)\n-     * - key:featureC (single feature assigned to a key)\n-     * \u003cp\u003e\n-     * Example: [\"ui\u003dfeature1,feature2\", \"backend:feature3\"].\n-     *\n-     * @return an array of feature-set descriptors; empty by default\n-     */\n-    String[] startFeatures() default \"\";\n-\n-}\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\nindex a5881c37e..c41187c90 100644\n--- c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiManagementServiceImpl.java\n@@ -17,6 +17,7 @@\n package org.apache.unomi.shell.services.internal;\n\n import org.apache.commons.lang3.StringUtils;\n+import org.apache.karaf.features.Dependency;\n import org.apache.karaf.features.Feature;\n import org.apache.karaf.features.FeatureState;\n import org.apache.karaf.features.FeaturesService;\n@@ -24,12 +25,14 @@ import org.apache.unomi.lifecycle.BundleWatcher;\n import org.apache.unomi.shell.migration.MigrationService;\n import org.apache.unomi.shell.services.UnomiManagementService;\n import org.osgi.framework.BundleContext;\n+import org.osgi.service.cm.Configuration;\n+import org.osgi.service.cm.ConfigurationAdmin;\n import org.osgi.service.component.ComponentContext;\n import org.osgi.service.component.annotations.*;\n-import org.osgi.service.metatype.annotations.Designate;\n import org.slf4j.Logger;\n import org.slf4j.LoggerFactory;\n\n+import java.io.IOException;\n import java.util.*;\n import java.util.concurrent.*;\n\n@@ -81,56 +84,58 @@ import java.util.concurrent.*;\n  * @see org.apache.karaf.features.FeaturesService\n  * @see org.apache.karaf.features.Feature\n  */\n-@Component(service \u003d UnomiManagementService.class, immediate \u003d true, configurationPid \u003d \"org.apache.unomi.start\", configurationPolicy \u003d ConfigurationPolicy.REQUIRE)\n-@Designate(ocd \u003d UnomiManagementServiceConfiguration.class)\n+@Component(service \u003d UnomiManagementService.class, immediate \u003d true)\n public class UnomiManagementServiceImpl implements UnomiManagementService {\n\n     private static final Logger LOGGER \u003d LoggerFactory.getLogger(UnomiManagementServiceImpl.class.getName());\n     private static final int DEFAULT_TIMEOUT \u003d 300; // 5 minutes timeout\n\n-    private final ExecutorService executor \u003d Executors.newSingleThreadExecutor();\n-\n+    private static final String UNOMI_SETUP_PID \u003d \"org.apache.unomi.setup\";\n     private static final String CDP_GRAPHQL_FEATURE \u003d \"cdp-graphql-feature\";\n\n-    private BundleContext bundleContext;\n-\n     @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n     private MigrationService migrationService;\n\n+    @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n+    private ConfigurationAdmin configurationAdmin;\n+\n     @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n     private FeaturesService featuresService;\n\n     @Reference(cardinality \u003d ReferenceCardinality.MANDATORY)\n     private BundleWatcher bundleWatcher;\n\n-    private Map\u003cString, List\u003cString\u003e\u003e startFeatures \u003d new HashMap\u003cString, List\u003cString\u003e\u003e();\n-    private final List\u003cString\u003e installedFeatures \u003d new ArrayList\u003c\u003e();\n-    private final List\u003cString\u003e startedFeatures \u003d new ArrayList\u003c\u003e();\n+    private final ExecutorService executor \u003d Executors.newSingleThreadExecutor();\n+    private final List\u003cString\u003e installedDistributionDependencies \u003d new ArrayList\u003c\u003e();\n+    private final List\u003cString\u003e startedDistributionDependencies \u003d new ArrayList\u003c\u003e();\n\n     @Activate\n-    public void init(ComponentContext componentContext, UnomiManagementServiceConfiguration config) throws Exception {\n-        LOGGER.info(\"Initializing Unomi management service with configuration {}\", config);\n+    public void init(ComponentContext componentContext) throws Exception {\n+        LOGGER.info(\"Initializing Unomi management service\");\n         try {\n-            this.bundleContext \u003d componentContext.getBundleContext();\n-            this.startFeatures \u003d parseStartFeatures(config.startFeatures());\n+            BundleContext bundleContext \u003d componentContext.getBundleContext();\n+\n+            UnomiSetup setup \u003d getUnomiSetup();\n+            if (setup \u003d\u003d null) {\n+                LOGGER.info(\"No previously setup distribution found\");\n+                //We are setting a default distribution if none is set to avoid the need of calling setup manually after installation\n+                if (StringUtils.isNotBlank(bundleContext.getProperty(\"unomi.distribution\"))) {\n+                    setup \u003d createUnomiSetup(bundleContext.getProperty(\"unomi.distribution\"));\n+                    LOGGER.info(\"UnomiSetup created for distribution provided from context: {}\", setup.getDistribution());\n+                } else {\n+                    setup \u003d createUnomiSetup(\"unomi-distribution-elasticsearch\");\n+                    LOGGER.info(\"UnomiSetup created for default distribution: {}\", setup.getDistribution());\n+                }\n+            }\n\n             if (StringUtils.isNotBlank(bundleContext.getProperty(\"unomi.autoMigrate\"))) {\n                 migrationService.migrateUnomi(bundleContext.getProperty(\"unomi.autoMigrate\"), true, null);\n             }\n\n-            String autoStart \u003d bundleContext.getProperty(\"unomi.autoStart\");\n-            if (StringUtils.isNotBlank(autoStart)) {\n-                String resolvedAutoStart \u003d autoStart;\n-                if (\"true\".equals(autoStart)) {\n-                    resolvedAutoStart \u003d \"elasticsearch\";\n-                } if (\"elasticsearch\".equals(autoStart)) {\n-                    resolvedAutoStart \u003d \"elasticsearch\";\n-                } if (\"opensearch\".equals(autoStart)) {\n-                    resolvedAutoStart \u003d \"opensearch\";\n-                }\n-                LOGGER.info(\"Auto-starting unomi management service with start features configuration: {}\", resolvedAutoStart);\n+            if (StringUtils.isNotBlank(bundleContext.getProperty(\"unomi.autoStart\")) \u0026\u0026 bundleContext.getProperty(\"unomi.autoStart\").equals(\"true\")) {\n+                LOGGER.info(\"Auto-starting unomi management service for unomi distribution: {}\", setup.getDistribution());\n                 // Don\u0027t wait for completion during initialization\n-                startUnomi(resolvedAutoStart, true, false);\n+                startUnomi(true, false);\n             }\n         } catch (Exception e) {\n             LOGGER.error(\"Error during Unomi startup:\", e);\n@@ -138,46 +143,39 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n         }\n     }\n\n-    private List\u003cString\u003e getAdditionalFeaturesToInstall() {\n-        List\u003cString\u003e featuresToInstall \u003d new ArrayList\u003c\u003e();\n-        if (Boolean.parseBoolean(bundleContext.getProperty(\"org.apache.unomi.graphql.feature.activated\"))) {\n-            featuresToInstall.add(CDP_GRAPHQL_FEATURE);\n-            bundleWatcher.addRequiredBundle(\"org.apache.unomi.cdp-graphql-api-impl\");\n-            bundleWatcher.addRequiredBundle(\"org.apache.unomi.graphql-ui\");\n-        }\n-        return featuresToInstall;\n+    private UnomiSetup getUnomiSetup() throws IOException {\n+        Configuration configuration \u003d configurationAdmin.getConfiguration(UNOMI_SETUP_PID, \"?\");\n+        return UnomiSetup.fromDictionary(configuration.getProperties());\n     }\n\n-    private Map\u003cString, List\u003cString\u003e\u003e parseStartFeatures(String[] startFeaturesConfig) {\n-        Map\u003cString, List\u003cString\u003e\u003e startFeatures \u003d new HashMap\u003c\u003e();\n-        if (startFeaturesConfig \u003d\u003d null) {\n-            return startFeatures;\n-        }\n-\n-        for (String entry : startFeaturesConfig) {\n-            String[] parts \u003d entry.split(\"\u003d\");\n-            if (parts.length \u003d\u003d 2) {\n-                String key \u003d parts[0].trim();\n-                List\u003cString\u003e features \u003d new ArrayList\u003c\u003e(Arrays.asList(parts[1].split(\",\")));\n-                startFeatures.put(key, features);\n-            } else {\n-                LOGGER.warn(\"Invalid start feature entry: {}\", entry);\n-            }\n-        }\n-        return startFeatures;\n+    private UnomiSetup createUnomiSetup(String distribution) throws IOException {\n+        Configuration configuration \u003d configurationAdmin.getConfiguration(UNOMI_SETUP_PID, \"?\");\n+        UnomiSetup setup \u003d UnomiSetup.init().withDistribution(distribution);\n+        configuration.update(setup.toProperties());\n+        return setup;\n     }\n\n     @Override\n-    public void startUnomi(String selectedStartFeatures, boolean mustStartFeatures) throws Exception {\n+    public void setupUnomiDistribution(String distribution, boolean overwrite) throws Exception {\n+        UnomiSetup existingSetup \u003d getUnomiSetup();\n+        if (existingSetup !\u003d null \u0026\u0026 !overwrite) {\n+            throw new IllegalStateException(\"Unomi distribution is already set up with distribution: \" + existingSetup.getDistribution());\n+        }\n+        createUnomiSetup(distribution);\n+    }\n+\n+    @Override\n+    public void startUnomi(boolean mustStartFeatures) throws Exception {\n         // Default to waiting for completion\n-        startUnomi(selectedStartFeatures, mustStartFeatures, true);\n+        startUnomi(mustStartFeatures, true);\n     }\n\n     @Override\n-    public void startUnomi(String selectedStartFeatures, boolean mustStartFeatures, boolean waitForCompletion) throws Exception {\n+    public void startUnomi(boolean mustStartFeatures, boolean waitForCompletion) throws Exception {\n+        UnomiSetup setup \u003d getUnomiSetup();\n         Future\u003c?\u003e future \u003d executor.submit(() -\u003e {\n             try {\n-                doStartUnomi(selectedStartFeatures, mustStartFeatures);\n+                doStartUnomi(setup.getDistribution(), mustStartFeatures);\n             } catch (Exception e) {\n                 LOGGER.error(\"Error starting Unomi:\", e);\n                 throw new RuntimeException(e);\n@@ -194,47 +192,40 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n         }\n     }\n\n-    private void doStartUnomi(String selectedStartFeatures, boolean mustStartFeatures) throws Exception {\n-        List\u003cString\u003e features \u003d startFeatures.get(selectedStartFeatures);\n-        if (features \u003d\u003d null || features.isEmpty()) {\n-            LOGGER.warn(\"No features configured for start features configuration: {}\", selectedStartFeatures);\n+    private void doStartUnomi(String distribution, boolean mustStartDistribution) throws Exception {\n+        if (distribution \u003d\u003d null || distribution.isEmpty()) {\n+            LOGGER.warn(\"No distribution provided, unable to start Unomi.\");\n             return;\n         }\n-        features.addAll(getAdditionalFeaturesToInstall());\n-\n-        LOGGER.info(\"Installing features for start features configuration: {}\", selectedStartFeatures);\n-        for (String featureName : features) {\n-            try {\n-                Feature feature \u003d featuresService.getFeature(featureName);\n-                if (feature \u003d\u003d null) {\n-                    LOGGER.error(\"Feature not found: {}\", featureName);\n-                    continue;\n-                }\n-\n-                if (!installedFeatures.contains(featureName)) {\n-                    LOGGER.info(\"Installing feature: {}\", featureName);\n-                    featuresService.installFeature(featureName, EnumSet.of(FeaturesService.Option.NoAutoStartBundles));\n-                    installedFeatures.add(featureName);\n-                }\n-            } catch (Exception e) {\n-                LOGGER.error(\"Error installing feature: {}\", featureName, e);\n+        try {\n+            Feature feature \u003d featuresService.getFeature(distribution);\n+            if (feature \u003d\u003d null) {\n+                LOGGER.error(\"Distribution feature not found: {}\", distribution);\n+                return;\n             }\n+            for (Dependency dependency : feature.getDependencies()) {\n+                if (!installedDistributionDependencies.contains(dependency.getName())) {\n+                    LOGGER.info(\"Installing distribution feature\u0027s dependency: {}\", dependency.getName());\n+                    featuresService.installFeature(dependency.getName(), dependency.getVersion(), EnumSet.of(FeaturesService.Option.NoAutoStartBundles));\n+                    installedDistributionDependencies.add(dependency.getName());\n+                }\n+            }\n+        } catch (Exception e) {\n+            LOGGER.error(\"Error installing distribution: {}\", distribution, e);\n         }\n\n-        if (mustStartFeatures) {\n-            LOGGER.info(\"Starting features for start features configuration: {}\", selectedStartFeatures);\n-            for (String featureName : features) {\n+        if (mustStartDistribution) {\n+            LOGGER.info(\"Starting distribution: {}\", distribution);\n+            for (String featureName : installedDistributionDependencies) {\n                 try {\n                     Feature feature \u003d featuresService.getFeature(featureName);\n                     if (feature \u003d\u003d null) {\n-                        LOGGER.error(\"Feature not found: {}\", featureName);\n+                        LOGGER.error(\"Distribution feature\u0027s dependency not found: {}\", featureName);\n                         continue;\n                     }\n-                    if (mustStartFeatures) {\n-                        LOGGER.info(\"Starting feature: {}\", featureName);\n-                        startFeature(featureName);\n-                        startedFeatures.add(featureName); // Keep track of started features\n-                    }\n+                    LOGGER.info(\"Starting dependency: {}\", featureName);\n+                    startFeature(featureName);\n+                    startedDistributionDependencies.add(featureName); // Keep track of started distribution dependencies\n                 } catch (Exception e) {\n                     LOGGER.error(\"Error starting feature: {}\", featureName, e);\n                 }\n@@ -270,11 +261,11 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n     }\n\n     private void doStopUnomi() throws Exception {\n-        if (startedFeatures.isEmpty()) {\n+        if (startedDistributionDependencies.isEmpty()) {\n             LOGGER.info(\"No features to stop.\");\n         } else {\n             LOGGER.info(\"Stopping features in reverse order...\");\n-            ListIterator\u003cString\u003e iterator \u003d startedFeatures.listIterator(startedFeatures.size());\n+            ListIterator\u003cString\u003e iterator \u003d startedDistributionDependencies.listIterator(startedDistributionDependencies.size());\n             while (iterator.hasPrevious()) {\n                 String featureName \u003d iterator.previous();\n                 try {\n@@ -285,13 +276,13 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n                 }\n             }\n\n-            startedFeatures.clear(); // Clear the list after stopping all features\n+            startedDistributionDependencies.clear(); // Clear the list after stopping all features\n         }\n-        if (installedFeatures.isEmpty()) {\n+        if (installedDistributionDependencies.isEmpty()) {\n             LOGGER.info(\"No features to uninstall.\");\n         } else {\n             LOGGER.info(\"Stopping features in reverse order...\");\n-            ListIterator\u003cString\u003e iterator \u003d installedFeatures.listIterator(installedFeatures.size());\n+            ListIterator\u003cString\u003e iterator \u003d installedDistributionDependencies.listIterator(installedDistributionDependencies.size());\n             while (iterator.hasPrevious()) {\n                 String featureName \u003d iterator.previous();\n                 try {\n@@ -301,7 +292,7 @@ public class UnomiManagementServiceImpl implements UnomiManagementService {\n                     LOGGER.error(\"Error uninstalling feature: {}\", featureName, e);\n                 }\n             }\n-            installedFeatures.clear(); // Clear the list after stopping all features\n+            installedDistributionDependencies.clear(); // Clear the list after stopping all features\n         }\n     }\n\ndiff --git c/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiSetup.java i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiSetup.java\nnew file mode 100644\nindex 000000000..d00d4361d\n--- /dev/null\n+++ i/tools/shell-commands/src/main/java/org/apache/unomi/shell/services/internal/UnomiSetup.java\n@@ -0,0 +1,77 @@\n+/*\n+ * Copyright (C) 2002-2025 Jahia Solutions Group SA. All rights reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *   http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+package org.apache.unomi.shell.services.internal;\n+\n+import java.util.Date;\n+import java.util.Dictionary;\n+import java.util.Objects;\n+\n+/**\n+ * @author Jerome Blanchard\n+ */\n+public class UnomiSetup {\n+\n+    private String date;\n+    private String distribution;\n+\n+    public UnomiSetup() {\n+    }\n+\n+    public String getDate() {\n+        return date;\n+    }\n+\n+    private void setDate(String date) {\n+        this.date \u003d date;\n+    }\n+\n+    public String getDistribution() {\n+        return distribution;\n+    }\n+\n+    public void setDistribution(String distribution) {\n+        this.distribution \u003d distribution;\n+    }\n+\n+    public UnomiSetup withDistribution(String distribution) {\n+        this.distribution \u003d distribution;\n+        return this;\n+    }\n+\n+    public Dictionary\u003cString, Object\u003e toProperties() {\n+        Dictionary\u003cString, Object\u003e properties \u003d new java.util.Hashtable\u003c\u003e();\n+        properties.put(\"unomi.setup.date\", date);\n+        properties.put(\"unomi.setup.distribution\", distribution);\n+        return properties;\n+    }\n+\n+    public static UnomiSetup init() {\n+        UnomiSetup setup \u003d new UnomiSetup();\n+        setup.setDate(new Date().toString());\n+        return setup;\n+    }\n+\n+    public static UnomiSetup fromDictionary(Dictionary\u003cString, Object\u003e properties) {\n+        UnomiSetup setup \u003d new UnomiSetup();\n+        if (properties \u003d\u003d null) {\n+            return null;\n+        }\n+        setup.setDate(Objects.toString(properties.get(\"unomi.setup.date\"), null));\n+        setup.setDistribution(Objects.toString(properties.get(\"unomi.setup.distribution\"), null));\n+        return setup;\n+    }\n+\n+}\ndiff --git c/tools/shell-commands/src/main/resources/org.apache.unomi.start.cfg i/tools/shell-commands/src/main/resources/org.apache.unomi.start.cfg\ndeleted file mode 100644\nindex c9158a9d6..000000000\n--- c/tools/shell-commands/src/main/resources/org.apache.unomi.start.cfg\n+++ /dev/null\n@@ -1,18 +0,0 @@\n-#\n-# Licensed to the Apache Software Foundation (ASF) under one or more\n-# contributor license agreements.  See the NOTICE file distributed with\n-# this work for additional information regarding copyright ownership.\n-# The ASF licenses this file to You under the Apache License, Version 2.0\n-# (the \"License\"); you may not use this file except in compliance with\n-# the License.  You may obtain a copy of the License at\n-#\n-#      http://www.apache.org/licenses/LICENSE-2.0\n-#\n-# Unless required by applicable law or agreed to in writing, software\n-# distributed under the License is distributed on an \"AS IS\" BASIS,\n-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n-# See the License for the specific language governing permissions and\n-# limitations under the License.\n-#\n-startFeatures \u003d [ \"elasticsearch\u003dunomi-base,unomi-startup,unomi-elasticsearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-elasticsearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\", \\\n-                  \"opensearch\u003dunomi-base,unomi-startup,unomi-opensearch-core,unomi-persistence-core,unomi-services,unomi-rest-api,unomi-cxs-lists-extension,unomi-cxs-geonames-extension,unomi-cxs-privacy-extension,unomi-opensearch-conditions,unomi-plugins-base,unomi-plugins-request,unomi-plugins-mail,unomi-plugins-optimization-test,unomi-shell-dev-commands,unomi-wab,unomi-web-tracker,unomi-healthcheck,unomi-router-karaf-feature,unomi-groovy-actions,unomi-rest-ui,unomi-startup-complete\" ]\n"
    },
    {
      "commit": "0c44c9bd20bcbb38971a0100911978d80b2f1533",
      "tree": "adf046a20d548500d197b5fae7ebf2b34a8ab9f4",
      "parents": [
        "4153575c491b06e4b8bebab0f13e175d15775599",
        "31223f320da99999689fe22eb53e4fc6b2370d12"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 15:21:23 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 31 15:21:23 2025 +0100"
      },
      "message": "[UNOMI-924] Make healthcheck concurrent\n\n[UNOMI-924] Make healthcheck concurrent"
    },
    {
      "commit": "31223f320da99999689fe22eb53e4fc6b2370d12",
      "tree": "afc7670f9e124fdb609114734981d80c1d3fac30",
      "parents": [
        "3f88986c6e810ea5a9574f474d502070018548b2"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 11:42:48 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 11:42:48 2025 +0100"
      },
      "message": "test: improve log for test in send Event\n"
    },
    {
      "commit": "3f88986c6e810ea5a9574f474d502070018548b2",
      "tree": "bcf31fa1a1ca7b99ea64cb49d1de17a080577661",
      "parents": [
        "8cdb73e73b5f103a98e29e05cfde46cdbfe3cbc4"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 09:51:00 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Dec 31 09:51:00 2025 +0100"
      },
      "message": "doc: fix forbidden html tag h3 in javadoc\n"
    },
    {
      "commit": "8cdb73e73b5f103a98e29e05cfde46cdbfe3cbc4",
      "tree": "cce61fd2d34f0794e7217c06b795e2ccbc66620a",
      "parents": [
        "94336a34cd3c96a1bc689180a48b03b1beb6c1cc"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 17:19:23 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 17:19:23 2025 +0100"
      },
      "message": "test: fix list sort to avoid concurrent modification exception\n"
    },
    {
      "commit": "4153575c491b06e4b8bebab0f13e175d15775599",
      "tree": "e4c7fc891e5a11ba4b4421365be65478e367fb84",
      "parents": [
        "078ebceda2207ae276c747f4e0833cc97d8afead",
        "a9cbcb05ffddcdbc6eb51266afeb1dbf2f87d347"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 15:07:48 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 30 15:07:48 2025 +0100"
      },
      "message": "[UNOMI-890] Updated health check even for insecure elastic deployments\n\n[UNOMI-890] Updated health check even for insecure elastic deployments"
    },
    {
      "commit": "a9cbcb05ffddcdbc6eb51266afeb1dbf2f87d347",
      "tree": "e4c7fc891e5a11ba4b4421365be65478e367fb84",
      "parents": [
        "02f819dbf48daa2d5b7d8aa6c651865ea32b7dae",
        "078ebceda2207ae276c747f4e0833cc97d8afead"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 11:41:33 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 30 11:41:33 2025 +0100"
      },
      "message": "Merge branch \u0027master\u0027 into patch-1"
    },
    {
      "commit": "94336a34cd3c96a1bc689180a48b03b1beb6c1cc",
      "tree": "aad4886a187310f20b290641d303e0757f9ea18c",
      "parents": [
        "d50fa685296aba3e7842768a8fabd5ddfd84176b"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 11:31:22 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 11:31:22 2025 +0100"
      },
      "message": "test: add healthcheck test for concurrency.\n"
    },
    {
      "commit": "d50fa685296aba3e7842768a8fabd5ddfd84176b",
      "tree": "60ce31eb34246730513c1a4715dbc4ed4e1e33ca",
      "parents": [
        "7f828d8534bef69f4b8316e500be0d3fa26a2ef3"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 11:16:11 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 30 11:16:11 2025 +0100"
      },
      "message": "test: add healthcheck test for concurrency.\n"
    },
    {
      "commit": "7f828d8534bef69f4b8316e500be0d3fa26a2ef3",
      "tree": "78ff2c9e0e5649ab1ebc6c612dea39a1b344cb33",
      "parents": [
        "087aeaf14cb90aa1b05d3c938145dc5eab8b566a"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 23 17:56:03 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 23 17:56:03 2025 +0100"
      },
      "message": "feat: improve refresh conditions\n"
    },
    {
      "commit": "087aeaf14cb90aa1b05d3c938145dc5eab8b566a",
      "tree": "a1d5a6c22d142a11c059ab84a7128dce39585861",
      "parents": [
        "078ebceda2207ae276c747f4e0833cc97d8afead"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 23 17:48:47 2025 +0100"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Dec 23 17:48:47 2025 +0100"
      },
      "message": "feat: ensure that healthchecks calls can be performed concurrently and add a 1s cache for performance or DoS issues.\n"
    },
    {
      "commit": "078ebceda2207ae276c747f4e0833cc97d8afead",
      "tree": "62e370d4960ef55ff0f77c57dc9de63203f41d57",
      "parents": [
        "b617d5c25d19fe0c2740935c958751394c101e1b"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Fri Nov 28 14:04:02 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 28 14:04:02 2025 +0100"
      },
      "message": "[UNOMI-828] Support for OpenSearch persistence (#715)\n\n* Minor Quickstart refactoring\n\n* Merge changes from master branch\n\n* Additional remove commands for actions, conditions, sessions, rules to be able to fix problems with deployments\n\n* Initial working OpenSearch implementation. Basic functionality is working, work on automated tests is still in progress.\n\n* Merges from master\n\n* Bump all versions to 2.7\n\n* Fix interface in blueprint descriptor\n\n* Fix interface in blueprint descriptor\n\n* Fix interface in blueprint descriptor\n\n* - Fix issues with integration tests, ES tests now work 100%\n- Changed Unomi startup to use features instead of bundles\n- Added new build script that integrates all the functionality of the other build scripts\n- Fix IPv6 address parsing\n- Merge latest changes from master branch\n-\n\n* - Remove old build scripts\n- Add option to new build script to be able to use opensearch with integration tests\n\n* - Add new conditions bundle for ElasticSearch-specific conditions\n- Replace hardcoded past event ES query builder in pasteventconditionbuilder to use a generic interface\n- Replace GeoDistance and DistanceUnit used directly from ElasticSearch with clean-room implementation that are validated through unit tests. Also added unit tests on the ElasticSearch implementation to be able to test any differences\n- Also added clean-room implementation of the DateMathParser so that it can be used with ElasticSearch or OpenSearch\n- Modified Unomi startup mechanism to use features instead of bundles. Unfortunately due to complex interdependencies between bundles the features could not be split as wanted, so there is some duplication in the list of bundles.\n- Removed last of inter-dependencies in the base plugin and the persistence-spi to try to resolve bundle inter-dependencies but that wasn\u0027t enough.\n- ElasticSearch integration tests are now execute without any errors !\n\n* Work on making integration tests work with OpenSearch:\n- Removed elasticsearch-core from bundle watch requirements\n- Fix issues with date parsing due to case sensitivity\n- Improved test units for date parsing and date math handling\n- Modified HealthChecks to provide an OpenSearch check provider (not yet fully working)\n- Deactivate 1.x to 2.x migration integration test for OpenSearch (No OpenSearch users will be coming from 1.x)\n- Update OpenSearch past event query builder to latest changes done in ElasticSearch past event query builder\n- Various fixes in the integration tests to make them compatible with OpenSearch (removed hardcoded elasticsearch configuration and references)\n- Added new shell script in itests directory to make it easier to handle the dynamically generated Pax Exam Karaf test container directory. Documentation is also included in the README file inside the itests directory.\n\n* Work on making integration tests work with OpenSearch:\n- Removed elasticsearch-core from bundle watch requirements\n- Fix issues with date parsing due to case sensitivity\n- Improved test units for date parsing and date math handling\n- Modified HealthChecks to provide an OpenSearch check provider (not yet fully working)\n- Deactivate 1.x to 2.x migration integration test for OpenSearch (No OpenSearch users will be coming from 1.x)\n- Update OpenSearch past event query builder to latest changes done in ElasticSearch past event query builder\n- Various fixes in the integration tests to make them compatible with OpenSearch (removed hardcoded elasticsearch configuration and references)\n- Added new shell script in itests directory to make it easier to handle the dynamically generated Pax Exam Karaf test container directory. Documentation is also included in the README file inside the itests directory.\n\n* Add missing ASL header\n\n* - Introduce new ProgressListener system to indicate the current progress status in the integration tests\n- Make sure the Unomi Management Service is started in IT tests before starting the unomi:start command\n- Add support for minimal cluster state to allow to start an OpenSearch cluster with yellow status in IT tests\n- Fix OpenSearch configuration prefix\n- Modify HealthCheck providers to only be available depending on the availability of the persistence implementation.\n- Fix integration tests to work properly with OpenSearch.\n- Fix OpenSearch persistence initial startup\n- Restructure startFeatures configuration to use arrays instead of complex parsing\n- Modify OpenSearch custom object mapping to serialize map entries that have null values (which is the default for the ElasticSearch implementation).\n-\n\n* - Introduce new ProgressListener system to indicate the current progress status in the integration tests\n- Make sure the Unomi Management Service is started in IT tests before starting the unomi:start command\n- Add support for minimal cluster state to allow to start an OpenSearch cluster with yellow status in IT tests\n- Fix OpenSearch configuration prefix\n- Modify HealthCheck providers to only be available depending on the availability of the persistence implementation.\n- Fix integration tests to work properly with OpenSearch.\n- Fix OpenSearch persistence initial startup\n- Restructure startFeatures configuration to use arrays instead of complex parsing\n- Modify OpenSearch custom object mapping to serialize map entries that have null values (which is the default for the ElasticSearch implementation).\n- Make sure the OpenSearch docker container used for the IT tests is replaced when tests are restarted.\n- Fix the handling of the OffsetDateTime in the OpenSearch Property condition query builder\n- Fix the rule service IT to generate rules with proper conditions and actions\n\n* - Small cosmetic changes to the progress listener\u0027s top 10 slowest tests output to be CSV compatible\n- Added a known issue in the itests README to reference the log issue on OpenSearch 2.18.\n\n* - Add auto-start and no-karaf options to build script\n\n* - Fix NO_COLOR handling\n\n* - Add support for OpenSearch in docker images\n- Add docker compose support for OpenSearch\n- Fix startup issues with updates to UnomiManagementService\n- Documentation updates to add OpenSearch information (still to be completed)\n\n* - Improve plugin documentation to explain how to implement plugins for both OpenSearch and ElasticSearch\n- Update Health check README to explain how it now works with both ElasticSearch and OpenSearch engines\n\n* - Add support for OpenSearch in docker images\n- Add docker compose support for OpenSearch\n- Fix startup issues with updates to UnomiManagementService\n- Documentation updates to add OpenSearch information (still to be completed)\n\n* Change max parallel stragegy to 1 to avoid port conflicts\n\n* - Make the search port configurable so that we can avoid conflicts between the ElasticSearch and OpenSearch integration tests\n- Add documentation on how to migrate from ElasticSearch to OpenSearch (not tested yet)\n\n* Update persistence-opensearch/conditions/src/main/java/org/apache/unomi/persistence/opensearch/conditions/PropertyConditionOSQueryBuilder.java\n\n* Update persistence-opensearch/conditions/src/main/java/org/apache/unomi/persistence/opensearch/conditions/PropertyConditionOSQueryBuilder.java\n\n* Update persistence-opensearch/conditions/src/main/java/org/apache/unomi/persistence/opensearch/conditions/PropertyConditionOSQueryBuilder.java\n\n* Update persistence-opensearch/core/src/main/java/org/apache/unomi/persistence/opensearch/OpenSearchPersistenceServiceImpl.java\n\n* - Remove Claude config file\n- Update documentation to indicate support for OpenSearch 3 instead of 2\n\n* Fix some minor dependencies\n\n* Make sure all OpenSearch documentation points to v3\n\n* Fix Unomi version in documentation\n\n* Refactor entrypoint.sh to build node URLs array for both OpenSearch and Elasticsearch configurations\n\n* Added a maximum number of retries to address issued raised during code review.\n\n* To address issue in code review, made sure we output to both the logger and the System.out systematically\n\n* Enhance ProgressListener with detailed JUnit test run reporting features. Added visual elements, timing information, motivational quotes, and CSV output for performance data. Improved ANSI color support and structured documentation for better usability.\n\n* Enhance ProgressSuite with detailed documentation and improved test method counting. Added support for nested test classes, real-time progress reporting, and thread-safe tracking of completed tests. Updated class structure to facilitate better integration with ProgressListener.\n\n* Update RuleServiceIT to clarify default condition and action settings in rule creation\n\n* Update healthcheck configuration to correct HTTP client settings for OpenSearch and Elasticsearch, including trust certificate options and minimal cluster state defaults.\n\n* Update Unomi version in quickstart and migration documentation from 2.0.0 to 3.0.0\n\n* Clarify integration test impact of Maven profile selection for OpenSearch in configuration documentation\n\n* Update setenv.sh to modify KARAF_OPTS for OpenSearch integration and remove auto-start option\n\n* Refactor PropertyConditionEvaluator to use foldToASCII for string comparison, aligning with analyzer configuration behavior\n\n* Revert IPv6 fix\n\n* Refactor monthly index properties to rollover properties in configuration files and update related test cases. Rename test method for clarity and adjust logging messages to reflect changes in index template creation.\n\n* Quick fix on description\n\n* Refactor error handling in HealthCheckIT and OpenSearchPersistenceServiceImpl to use logging instead of printStackTrace.\nUpdate exception messages in IdsConditionESQueryBuilder and IdsConditionOSQueryBuilder to include maximum IDs query count for better clarity.\nOther general naming cleanup.\n\n* Revert test unit runner to default one, will introduce new ProgressListener in a separate PR\n\n* - Rename all query builder IDs to no longer use a reference to ElasticSearch\n- Remove hover event query builder that is replaced with a condition definition with a parent condition\n- Add a JSON schema for the hover event type\n- Add missing JavaDocs\n\n* Add detailed Javadoc comments to aggregation and condition interfaces for improved documentation\n\n* - Removed non OpenSearch specific changes\n- Added missing Javadoc comments\n- Minor whitespace cleanups\n\n* Update CI workflow to use actions/setup-java@v4 and improve OpenSearch integration test instructions in documentation\n\n* Implement legacy query builder ID mapping for backward compatibility in Elasticsearch and OpenSearch. Add integration tests for legacy query builder functionality, including new condition definitions and JSON files for legacy conditions. Update documentation to reflect changes in query builder ID conventions and migration steps from previous versions.\n\n* Refactor ConditionESQueryBuilderDispatcher and ConditionOSQueryBuilderDispatcher to utilize ConditionQueryBuilderDispatcherSupport for legacy ID resolution and contextualization. Remove hardcoded legacy ID mappings and improve documentation regarding legacy query builder handling.\n\n* Run the build serially to avoid parallel interference\n\n* Update new poms to version 3.1.0\n\n* Refactor condition query builder dispatchers to extend a new base class. Update legacy query builder references to use the new centralized mapping and logging mechanism. This change enhances code maintainability and prepares for future improvements."
    },
    {
      "commit": "b617d5c25d19fe0c2740935c958751394c101e1b",
      "tree": "514a2d2be65e8468917630048b5ddbdc3ef1c483",
      "parents": [
        "205f5815d1f46b533c678c799db9bf5c64f9964a"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Fri Nov 28 12:17:58 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 28 12:17:58 2025 +0100"
      },
      "message": "UNOMI-892-maven-cache: Adopt Maven Build Cache, consolidate BUILDING into manual, update website docs (#736)\n\n* UNOMI-892-maven-cache: Adopt Maven Build Cache, consolidate BUILDING into manual, update website docs\n- Enable Maven Build Cache (extensions.xml, maven-build-cache-config.xml); document usage, parameters, purge options; add official links\n- Update BUILDING to deprecate content and point to online manual and local Asciidoc source\n- Expand manual (manual/src/main/asciidoc/building-and-deploying.adoc):\n- Add Maven Build Cache section with detailed parameter differences and performance times (1m59s vs 3.176s)\n- Replace old site scripts with generate-manual.sh usage (publish/simulate), requirements, destinations\n- Align Maven requirement to 3.9.8\n- Minor doc cleanups and consistency across build instructions\n\n* Adressed feedback from jayblanc."
    },
    {
      "commit": "205f5815d1f46b533c678c799db9bf5c64f9964a",
      "tree": "dfbf922ee38753f329e613697950673742eb7cee",
      "parents": [
        "c59708e988a347f9675bb153652ee1e9cf818ffc"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Fri Nov 28 09:04:37 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 28 09:04:37 2025 +0100"
      },
      "message": "UNOMI-887: Introduce consolidated build.sh; remove legacy build scripts (#737)\n\n* UNOMI-887: Introduce consolidated build.sh; remove legacy build scripts\nAdd build.sh: unified build/deploy/run script with robust error handling, colorized/structured output, and preflight checks (tools, system resources, Maven settings, ports).\nSupport rich CLI options: tests/integration, OpenSearch, debug/ports/suspend, offline/cache control, migration-test skip, single-test, deploy to Karaf.\nReplace legacy scripts: remove buildAndRun.sh, buildAndRunNoTests.sh, compileDeploy.sh, generate-package.sh.\nImprove DX: clearer failures, consistent workflows across environments, NO_COLOR adherence, macOS/Linux friendly (incl. Apple Silicon hints).\nNotes: deployment expects UNOMI_VERSION for KAR/package paths; optional Geo databases copied when present.\nNo code changes to modules; build behavior is unchanged unless new flags are used.\n\n* Address PR review comments for build.sh script\n\n- Fix color readability in build.sh examples section: replace GRAY with NC\n  (no color) for better terminal readability. Use NC once at the start\n  instead of wrapping each line with color codes.\n\n- Add comprehensive documentation for build.sh script in Building section:\n  * Add brief mention at the start of Building section with cross-reference\n  * Add new \"Using the build.sh script\" subsection with:\n    - Overview of script features and benefits\n    - Step-by-step usage instructions\n    - Complete set of examples matching build.sh --help output\n    - All examples use plain commands without prompt markers\n\n- Minor formatting: align help output option descriptions for consistency\n\nThe documentation examples now exactly match those displayed by build.sh --help,\nensuring consistency between the script and its documentation."
    },
    {
      "commit": "c59708e988a347f9675bb153652ee1e9cf818ffc",
      "tree": "9487346c6a3faa6f2b98707a156e4ef44a750210",
      "parents": [
        "d6b4dfb871ef4865d5f9ec375f92f76cc22c5ef8"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Wed Nov 26 14:16:17 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 26 14:16:17 2025 +0100"
      },
      "message": "UNOMI-912 Add new progress information to integration tests run. (#735)\n\n- Start banner for integration tests\n- Progress bar during test execution is now displayed with ETA, number of successful and failed tests\n- At the end of the execution a CSV compatible output of the slowest tests is generated"
    },
    {
      "commit": "d6b4dfb871ef4865d5f9ec375f92f76cc22c5ef8",
      "tree": "44897575821f4289fe181534c9cba639fb69410b",
      "parents": [
        "bd0799c865ca63378234187f748dea490ac8eade"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 10 11:58:11 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 10 11:58:11 2025 +0100"
      },
      "message": "update doc config\n"
    },
    {
      "commit": "bd0799c865ca63378234187f748dea490ac8eade",
      "tree": "cbd9c7168752950d395a8622f0f2ac8d1c85f891",
      "parents": [
        "845869ec2a07cfb7255b8cb7e0fdcd0e2ac4ca8e"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:50:38 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:50:38 2025 +0100"
      },
      "message": "[maven-release-plugin] prepare for next development iteration\n"
    },
    {
      "commit": "845869ec2a07cfb7255b8cb7e0fdcd0e2ac4ca8e",
      "tree": "1f4b2be9408bcea8a7bb1859f0c4f16eea236910",
      "parents": [
        "1dc5705c4c6b6f6004aa95beda4fe0e1549af334"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:50:16 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:50:16 2025 +0100"
      },
      "message": "[maven-release-plugin] prepare release unomi-root-3.0.0\n"
    },
    {
      "commit": "1dc5705c4c6b6f6004aa95beda4fe0e1549af334",
      "tree": "738ebfb25b22788d108af7c52508786283deb413",
      "parents": [
        "adcbb0b1d4d92474dafe2f05e30e0e9bd1e2be3c"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:36:07 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Nov 04 10:36:07 2025 +0100"
      },
      "message": "revert version to 3.0.0-SNAPSHOT\n"
    },
    {
      "commit": "adcbb0b1d4d92474dafe2f05e30e0e9bd1e2be3c",
      "tree": "cbd9c7168752950d395a8622f0f2ac8d1c85f891",
      "parents": [
        "0e8547d811aeb5acad870cdf3feb24067836a347"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Tue Nov 04 10:22:13 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 04 10:22:13 2025 +0100"
      },
      "message": "- Fix failure to build from source ZIP (#740)\n\n- Update copyright and other minor NOTICE file adjustments"
    },
    {
      "commit": "0e8547d811aeb5acad870cdf3feb24067836a347",
      "tree": "81765095b48e447d2241b1f5901711059ae7edf1",
      "parents": [
        "812e0fb818f20c68d663998c66bc5b446da975f8"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 03 14:33:35 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 03 14:33:35 2025 +0100"
      },
      "message": "[maven-release-plugin] prepare for next development iteration\n"
    },
    {
      "commit": "812e0fb818f20c68d663998c66bc5b446da975f8",
      "tree": "abc76657e47a29eff35efe3e2056e500781181b1",
      "parents": [
        "4966e6c276c66e7b15d350d407c2ea4777ce30d2"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 03 14:32:10 2025 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Mon Nov 03 14:32:10 2025 +0100"
      },
      "message": "[maven-release-plugin] prepare release unomi-root-3.0.0\n"
    },
    {
      "commit": "4966e6c276c66e7b15d350d407c2ea4777ce30d2",
      "tree": "587e8785c0cf171491ee6e42fc024c8720868811",
      "parents": [
        "1335911f60f2ae2abb66dc8458bae87be0ae4f0b"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Nov 03 11:14:33 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 03 11:14:33 2025 +0100"
      },
      "message": "UNOMI-915: remove useless usage on maven-source.plugin.version (#739)\n\n"
    },
    {
      "commit": "1335911f60f2ae2abb66dc8458bae87be0ae4f0b",
      "tree": "07a7cc8fff19f6c4e0b297cb7962445fe29121fe",
      "parents": [
        "dfe64eb8bf3771f06e8e73944f77a216905360f5"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Fri Oct 31 15:37:41 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 31 15:37:41 2025 +0100"
      },
      "message": "Update PGP public key for Jonathan Sinovassin-naik\n\nAdded a new PGP public key for Jonathan Sinovassin-naik and updated the existing key details."
    },
    {
      "commit": "dfe64eb8bf3771f06e8e73944f77a216905360f5",
      "tree": "42b728dd17504c6ef3f0ac2e1d83a5e9f884903f",
      "parents": [
        "089443efefe3ab599b9e996ef20b647eacd77969"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Thu Oct 30 16:27:02 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 30 16:27:02 2025 +0100"
      },
      "message": "UNOMI-913: add documentation and script to migrate elasticsearch datas (#738)\n\n* UNOMI-913: add documentation and script to migrate elasticsearch datas"
    },
    {
      "commit": "089443efefe3ab599b9e996ef20b647eacd77969",
      "tree": "de17314ab5d92bf76e4fe87975d2bbbb31e3188c",
      "parents": [
        "ade3563163be3479a3e5f236d5f56e305bedeb95"
      ],
      "author": {
        "name": "Tyler Bertrand",
        "email": "121591679+tylerbertrand@users.noreply.github.com",
        "time": "Thu Oct 30 09:00:20 2025 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 30 15:00:20 2025 +0100"
      },
      "message": "Benefit from enhanced build insights and troubleshooting ability by publishing Build Scans to https://develocity.apache.org (#731)\n\n"
    },
    {
      "commit": "ade3563163be3479a3e5f236d5f56e305bedeb95",
      "tree": "613e9adeb08e4e07e6954c883aa80a9229a916ab",
      "parents": [
        "a52602d4287127497b3c28a4c2f867374820e708",
        "a72cd1a49250e844ac1d5bd4124f2ae09785cf0b"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Oct 27 10:38:03 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 27 10:38:03 2025 +0100"
      },
      "message": "[UNOMI-909] Fix places for web-tracker javascript resource in the wab\n\n[UNOMI-909] Fix places for web-tracker javascript resource in the wab"
    },
    {
      "commit": "a52602d4287127497b3c28a4c2f867374820e708",
      "tree": "5a01dc7ca5190285ca56cb1fa20e9e923e4ec911",
      "parents": [
        "1a2d899ac871624dc602faf97fc615fa30f3d9e5"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Oct 16 12:22:56 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 16 12:22:56 2025 +0200"
      },
      "message": "UNOMI-903: Fix documentation about REST privacy routes (delete and anonymize profile) (#721)\n\n"
    },
    {
      "commit": "1a2d899ac871624dc602faf97fc615fa30f3d9e5",
      "tree": "8b53d045a8e30dbcf6ec46820ea49135d0872d39",
      "parents": [
        "6d4525e1ae208ef7be63f67511853e13c8ac5f14"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Oct 13 14:35:10 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 13 14:35:10 2025 +0200"
      },
      "message": "UNOMI-911: fix sslcontext initialization (#734)\n\n"
    },
    {
      "commit": "6d4525e1ae208ef7be63f67511853e13c8ac5f14",
      "tree": "5f9f35a1f75049f15fe78e8b76d99409bb53b82a",
      "parents": [
        "8cff171ef81ad13e602be91a9bd624cc26ae4142"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@jahia.com",
        "time": "Thu Sep 25 11:45:02 2025 +0200"
      },
      "committer": {
        "name": "Serge Huber",
        "email": "shuber@jahia.com",
        "time": "Thu Sep 25 11:45:02 2025 +0200"
      },
      "message": "Update documentation scripts to streamline generation and publishing process\n\n- Consolidated `generate-site.sh` and `generate-site-and-upload.sh` into a single unified script `generate-manual.sh`.\n- Improved readability, added enhanced options (e.g., simulation mode), and better error handling.\n- Updated to support multi-version documentation generation and automatic publishing to Apache SVN, including manual and Javadoc uploads.\n"
    },
    {
      "commit": "8cff171ef81ad13e602be91a9bd624cc26ae4142",
      "tree": "bc197741266a327fe255f225e3c0a98ff443dd9e",
      "parents": [
        "73c9ea9a3742ed0069f7158242628a5935c06f84"
      ],
      "author": {
        "name": "Jerome Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Sep 23 09:44:28 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 23 09:44:28 2025 +0200"
      },
      "message": "[UNOMI-899] Replace jaxrs-analyzer-maven-plugin with an alternative for Swagger documentation generation (#732)\n\n* UNOMI-906: Add build info file at root of tar.gz\n\n* UNOMI-899: Remove jaxrs-analyzer and fix swagger-ui openapi doc.\n\n* UNOMI-899: Use karaf features for jackson."
    },
    {
      "commit": "a72cd1a49250e844ac1d5bd4124f2ae09785cf0b",
      "tree": "c74b54c42e99211b6c628ecbb3cde26529c07fbf",
      "parents": [
        "73c9ea9a3742ed0069f7158242628a5935c06f84"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Sep 19 16:40:19 2025 +0200"
      },
      "committer": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Sep 19 16:40:19 2025 +0200"
      },
      "message": "UNOMI-909: Fix places for web-tracker javascript resource in the wab\n"
    },
    {
      "commit": "73c9ea9a3742ed0069f7158242628a5935c06f84",
      "tree": "7e82436567f40c244bd7a72023d22a58366e132f",
      "parents": [
        "d3d2d16c49993669c5004167fa3362013eaad0ca"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Tue Sep 16 14:30:57 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 16 14:30:57 2025 +0200"
      },
      "message": "UNOMI-901: change condition evaluator injection to avoid reference issue on stop\" (#730)\n\n"
    },
    {
      "commit": "d3d2d16c49993669c5004167fa3362013eaad0ca",
      "tree": "166d9ce286b7086e3a6d18b8e3a39d10c0377483",
      "parents": [
        "4c182831fe0ebf80fbf67246f4f20a4acce65513"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Sep 15 13:57:02 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 15 13:57:02 2025 +0200"
      },
      "message": "UNOMI-901: Upgrade elasticsearch client (#729)\n\n* feat: upgrade elasticsearch client to version 9\n"
    },
    {
      "commit": "4c182831fe0ebf80fbf67246f4f20a4acce65513",
      "tree": "97e1ba6939dfc0fb3b3e753f0e8ca154e19c77bc",
      "parents": [
        "da9c57fd24ac8ffd9c3332f41998d4fb940c4ee6"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Tue Sep 02 14:07:52 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 02 14:07:52 2025 +0200"
      },
      "message": "UNOMI-906: Fix javadoc tags and new lines. (#728)\n\n* UNOMI-906: Fix javadoc tags and new lines.\n\n* UNOMI-906: Restore missed commit content."
    },
    {
      "commit": "da9c57fd24ac8ffd9c3332f41998d4fb940c4ee6",
      "tree": "54fa9921dba963fd17d50536866cf9e43a0ba133",
      "parents": [
        "e7be881e535ab10819c28ed850f5b1bccc3d6c05"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Sep 01 15:16:48 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 01 15:16:48 2025 +0200"
      },
      "message": "UNOMI-876: Upgrade to Karaf 4.4.8 and JDK 17 (#722)\n\n* UNOMI-876: Migrate Unomi for running on Karaf 4.4.7\n\ndiff --git c/api/pom.xml i/api/pom.xml\nindex 3ed267975..cfe1c8636 100644\n--- c/api/pom.xml\n+++ i/api/pom.xml\n@@ -22,7 +22,7 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n@@ -34,12 +34,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejakarta.xml.bind\u003c/groupId\u003e\n             \u003cartifactId\u003ejakarta.xml.bind-api\u003c/artifactId\u003e\n-            \u003cversion\u003e2.3.2\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejavax.validation\u003c/groupId\u003e\n@@ -48,6 +48,11 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-beanutils\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-beanutils\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\ndiff --git c/common/pom.xml i/common/pom.xml\nindex e202af18d..f470d48d2 100644\n--- c/common/pom.xml\n+++ i/common/pom.xml\n@@ -22,7 +22,7 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cartifactId\u003eunomi-common\u003c/artifactId\u003e\n@@ -34,7 +34,6 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-csv\u003c/artifactId\u003e\n-            \u003cversion\u003e1.5\u003c/version\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejunit\u003c/groupId\u003e\n@@ -44,28 +43,22 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.karaf.shell\u003c/groupId\u003e\n             \u003cartifactId\u003eorg.apache.karaf.shell.console\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.karaf}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.karaf.shell\u003c/groupId\u003e\n             \u003cartifactId\u003eorg.apache.karaf.shell.table\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.karaf}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n             \u003cscope\u003etest\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n             \u003cartifactId\u003eslf4j-simple\u003c/artifactId\u003e\n-            \u003cversion\u003e1.7.36\u003c/version\u003e\n             \u003cscope\u003etest\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/common/src/main/java/org/apache/unomi/common/DataTable.java i/common/src/main/java/org/apache/unomi/common/DataTable.java\nindex 06839fccd..21862d299 100644\n--- c/common/src/main/java/org/apache/unomi/common/DataTable.java\n+++ i/common/src/main/java/org/apache/unomi/common/DataTable.java\n@@ -20,7 +20,6 @@ import org.apache.commons.csv.CSVFormat;\n import org.apache.commons.csv.CSVPrinter;\n\n import java.io.IOException;\n-import java.io.StringWriter;\n import java.util.ArrayList;\n import java.util.Comparator;\n import java.util.List;\ndiff --git c/docker/pom.xml i/docker/pom.xml\nindex 57502de25..2d63324da 100644\n--- c/docker/pom.xml\n+++ i/docker/pom.xml\n@@ -22,7 +22,7 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cartifactId\u003eunomi-docker\u003c/artifactId\u003e\n@@ -43,7 +43,6 @@\n             \u003cplugin\u003e\n                 \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n                 \u003cartifactId\u003emaven-dependency-plugin\u003c/artifactId\u003e\n-                \u003cversion\u003e3.1.2\u003c/version\u003e\n                 \u003cexecutions\u003e\n                     \u003cexecution\u003e\n                         \u003cid\u003ecopy\u003c/id\u003e\n@@ -105,7 +104,7 @@\n             \u003cplugin\u003e\n                 \u003cgroupId\u003eio.fabric8\u003c/groupId\u003e\n                 \u003cartifactId\u003edocker-maven-plugin\u003c/artifactId\u003e\n-                \u003cversion\u003e0.40.2\u003c/version\u003e\n+                \u003cversion\u003e0.46.0\u003c/version\u003e\n                 \u003cconfiguration\u003e\n                     \u003cimages\u003e\n                         \u003cimage\u003e\ndiff --git c/docker/src/main/docker/Dockerfile i/docker/src/main/docker/Dockerfile\nindex 6734689fc..30d8db250 100644\n--- c/docker/src/main/docker/Dockerfile\n+++ i/docker/src/main/docker/Dockerfile\n@@ -15,7 +15,7 @@\n # limitations under the License.\n ################################################################################\n\n-FROM library/eclipse-temurin:11\n+FROM library/eclipse-temurin:17\n\n # Unomi environment variables\n ENV UNOMI_HOME /opt/apache-unomi\ndiff --git c/extensions/geonames/pom.xml i/extensions/geonames/pom.xml\nindex f83aaccbb..e337f3b33 100644\n--- c/extensions/geonames/pom.xml\n+++ i/extensions/geonames/pom.xml\n@@ -18,20 +18,18 @@\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n+    \u003cparent\u003e\n+        \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+        \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n+    \u003c/parent\u003e\n+    \u003cartifactId\u003ecxs-geonames\u003c/artifactId\u003e\n+    \u003cname\u003eApache Unomi :: Extensions :: Geonames Database\u003c/name\u003e\n+    \u003cdescription\u003eApache Unomi Context Server extension that integrates with the Geonames database\u003c/description\u003e\n+    \u003cpackaging\u003epom\u003c/packaging\u003e\n\n     \u003cmodules\u003e\n         \u003cmodule\u003eservices\u003c/module\u003e\n         \u003cmodule\u003erest\u003c/module\u003e\n     \u003c/modules\u003e\n-\n-    \u003cparent\u003e\n-        \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n-    \u003c/parent\u003e\n-\n-    \u003cartifactId\u003ecxs-geonames\u003c/artifactId\u003e\n-    \u003cname\u003eApache Unomi :: Extensions :: Geonames Database\u003c/name\u003e\n-    \u003cdescription\u003eApache Unomi Context Server extension that integrates with the Geonames database\u003c/description\u003e\n-    \u003cpackaging\u003epom\u003c/packaging\u003e\n \u003c/project\u003e\ndiff --git c/extensions/geonames/rest/pom.xml i/extensions/geonames/rest/pom.xml\nindex 34b3f1ce3..4093f1a3e 100644\n--- c/extensions/geonames/rest/pom.xml\n+++ i/extensions/geonames/rest/pom.xml\n@@ -17,13 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003ecxs-geonames\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-geonames-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Geonames Database :: REST API\u003c/name\u003e\n     \u003cdescription\u003eREST API for the Apache Unomi Context Server extension that integrates with the Geonames database\u003c/description\u003e\n@@ -33,14 +32,22 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-geonames-services\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxs-geonames-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -49,7 +56,16 @@\n             \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.geronimo.specs\u003c/groupId\u003e\n+            \u003cartifactId\u003egeronimo-ws-metadata_2.0_spec\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-frontend-jaxws\u003c/artifactId\u003e\n@@ -68,20 +84,11 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.jaxrs\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/geonames/services/pom.xml i/extensions/geonames/services/pom.xml\nindex 0fe65c5b9..b532dcd8a 100644\n--- c/extensions/geonames/services/pom.xml\n+++ i/extensions/geonames/services/pom.xml\n@@ -17,14 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003ecxs-geonames\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-geonames-services\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Geonames Database :: Service\u003c/name\u003e\n     \u003cdescription\u003eService implementation for the Apache Unomi Context Server extension that integrates with the Geonames database\u003c/description\u003e\n@@ -34,15 +32,14 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n@@ -51,10 +48,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-beanutils\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-beanutils\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\ndiff --git c/extensions/groovy-actions/karaf-kar/pom.xml i/extensions/groovy-actions/karaf-kar/pom.xml\nindex ff874dc6d..a1de6ad96 100644\n--- c/extensions/groovy-actions/karaf-kar/pom.xml\n+++ i/extensions/groovy-actions/karaf-kar/pom.xml\n@@ -17,18 +17,15 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-groovy-actions-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-groovy-actions\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Groovy Actions :: Apache Karaf Feature and KAR archive\u003c/name\u003e\n-    \u003cdescription\u003eApache Karaf Feature and KAR archive for the Apache Unomi Context Server extension that provides the possibility to use\n-        Groovy for actions\n-    \u003c/description\u003e\n+    \u003cdescription\u003eApache Karaf Feature and KAR archive for the Apache Unomi Context Server extension that provides the possibility to use Groovy for actions\u003c/description\u003e\n     \u003cpackaging\u003ekar\u003c/packaging\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/groovy-actions/pom.xml i/extensions/groovy-actions/pom.xml\nindex 53892b110..9a76295aa 100644\n--- c/extensions/groovy-actions/pom.xml\n+++ i/extensions/groovy-actions/pom.xml\n@@ -21,9 +21,8 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003eunomi-groovy-actions-root\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Groovy Actions\u003c/name\u003e\n     \u003cdescription\u003eApache Unomi Context Server extension that provides support for Groovy Actions\u003c/description\u003e\ndiff --git c/extensions/groovy-actions/rest/pom.xml i/extensions/groovy-actions/rest/pom.xml\nindex de1052262..db2f221a8 100644\n--- c/extensions/groovy-actions/rest/pom.xml\n+++ i/extensions/groovy-actions/rest/pom.xml\n@@ -17,13 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-groovy-actions-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-groovy-actions-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Groovy Actions :: REST API\u003c/name\u003e\n     \u003cdescription\u003eREST API for the Apache Unomi Context Server extension that integrates with groovy actions\n@@ -34,14 +33,22 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-groovy-actions-services\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-groovy-actions-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -51,6 +58,11 @@\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-frontend-jaxws\u003c/artifactId\u003e\n@@ -76,21 +88,6 @@\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n-            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n     \u003cbuild\u003e\n         \u003cplugins\u003e\ndiff --git c/extensions/groovy-actions/services/pom.xml i/extensions/groovy-actions/services/pom.xml\nindex 3d4de386e..76c30b85b 100644\n--- c/extensions/groovy-actions/services/pom.xml\n+++ i/extensions/groovy-actions/services/pom.xml\n@@ -17,57 +17,65 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-groovy-actions-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-groovy-actions-services\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Groovy Actions :: Service\u003c/name\u003e\n-    \u003cdescription\u003eService implementation for the Apache Unomi Context Server extension that provides the possibility to implement actions in\n-        Groovy\n-    \u003c/description\u003e\n+    \u003cdescription\u003eService implementation for the Apache Unomi Context Server extension that provides the possibility to implement actions in Groovy\u003c/description\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.core\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-metrics\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eosgi.core\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.metatype.annotations\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-core\u003c/artifactId\u003e\n@@ -90,10 +98,6 @@\n             \u003cversion\u003e${groovy.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n-            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/healthcheck/pom.xml i/extensions/healthcheck/pom.xml\nindex 8b5f9253b..a41479ad8 100644\n--- c/extensions/healthcheck/pom.xml\n+++ i/extensions/healthcheck/pom.xml\n@@ -21,9 +21,8 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003ehealthcheck\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: HealthCheck\u003c/name\u003e\n     \u003cdescription\u003eApache Unomi HealthCheck extension that provide liveliness information about unomi\u003c/description\u003e\n@@ -33,27 +32,24 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-lifecycle-watcher\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eshell-commands\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n             \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n@@ -61,17 +57,29 @@\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.useradmin\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.http\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n             \u003cartifactId\u003ehttpclient-osgi\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n-            \u003cartifactId\u003ehttpcore-osgi\u003c/artifactId\u003e\n+            \u003ctype\u003ebundle\u003c/type\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n@@ -82,7 +90,6 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.karaf.jaas\u003c/groupId\u003e\n             \u003cartifactId\u003eorg.apache.karaf.jaas.boot\u003c/artifactId\u003e\n-            \u003cversion\u003e${karaf.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\nindex 361e68df7..96a17db1a 100644\n--- c/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\n+++ i/extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/provider/ElasticSearchHealthCheckProvider.java\n@@ -26,11 +26,10 @@ import org.apache.http.client.methods.CloseableHttpResponse;\n import org.apache.http.client.methods.HttpGet;\n import org.apache.http.impl.client.BasicCredentialsProvider;\n import org.apache.http.impl.client.CloseableHttpClient;\n-import org.apache.http.impl.client.HttpClients;\n import org.apache.http.util.EntityUtils;\n import org.apache.unomi.healthcheck.HealthCheckConfig;\n-import org.apache.unomi.healthcheck.HealthCheckResponse;\n import org.apache.unomi.healthcheck.HealthCheckProvider;\n+import org.apache.unomi.healthcheck.HealthCheckResponse;\n import org.apache.unomi.healthcheck.util.CachedValue;\n import org.apache.unomi.shell.migration.utils.HttpUtils;\n import org.osgi.service.component.annotations.Activate;\ndiff --git c/extensions/json-schema/pom.xml i/extensions/json-schema/pom.xml\nindex a38969f6a..8223b7753 100644\n--- c/extensions/json-schema/pom.xml\n+++ i/extensions/json-schema/pom.xml\n@@ -21,7 +21,7 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cartifactId\u003eunomi-json-schema-root\u003c/artifactId\u003e\ndiff --git c/extensions/json-schema/rest/pom.xml i/extensions/json-schema/rest/pom.xml\nindex a9d9094d6..0753ad861 100644\n--- c/extensions/json-schema/rest/pom.xml\n+++ i/extensions/json-schema/rest/pom.xml\n@@ -17,12 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-json-schema-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n\n     \u003cartifactId\u003eunomi-json-schema-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: JSON Schema :: REST API\u003c/name\u003e\n@@ -33,21 +33,22 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-json-schema-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-rest\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-rest\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -56,20 +57,26 @@\n             \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ejakarta.jws\u003c/groupId\u003e\n+            \u003cartifactId\u003ejakarta.jws-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxf-rt-frontend-jaxws\u003c/artifactId\u003e\n+            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxf-rt-frontend-jaxrs\u003c/artifactId\u003e\n+            \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxf-rt-transports-http\u003c/artifactId\u003e\n+            \u003cgroupId\u003ejavax.ws.rs\u003c/groupId\u003e\n+            \u003cartifactId\u003ejavax.ws.rs-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n@@ -77,20 +84,7 @@\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003ecom.fasterxml.jackson.jaxrs\u003c/groupId\u003e\n-            \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n-            \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n+\n     \u003c/dependencies\u003e\n     \u003cbuild\u003e\n         \u003cplugins\u003e\ndiff --git c/extensions/json-schema/services/pom.xml i/extensions/json-schema/services/pom.xml\nindex 4538c8846..b69f8609f 100644\n--- c/extensions/json-schema/services/pom.xml\n+++ i/extensions/json-schema/services/pom.xml\n@@ -20,7 +20,7 @@\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-json-schema-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n@@ -40,7 +40,11 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -50,22 +54,16 @@\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n+            \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003c!-- dependencies required for json-schema framework --\u003e\n@@ -113,7 +111,6 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.yaml\u003c/groupId\u003e\n             \u003cartifactId\u003esnakeyaml\u003c/artifactId\u003e\n-            \u003cversion\u003e2.2\u003c/version\u003e\n             \u003cscope\u003ecompile\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationError.java i/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationError.java\nindex 7adfabef1..7dc9cb3eb 100644\n--- c/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationError.java\n+++ i/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationError.java\n@@ -17,8 +17,6 @@\n\n package org.apache.unomi.schema.api;\n\n-import com.networknt.schema.ValidationMessage;\n-\n import java.io.Serializable;\n\n /**\ndiff --git c/extensions/lists-extension/actions/pom.xml i/extensions/lists-extension/actions/pom.xml\nindex e6a1f753d..4e6e0b887 100644\n--- c/extensions/lists-extension/actions/pom.xml\n+++ i/extensions/lists-extension/actions/pom.xml\n@@ -17,31 +17,26 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003ecxs-lists-extension\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-lists-extension-actions\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Lists :: Actions\u003c/name\u003e\n     \u003cdescription\u003eList extension rule actions for the Apache Unomi Context Server\u003c/description\u003e\n-\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003ecxs-lists-extension-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/lists-extension/pom.xml i/extensions/lists-extension/pom.xml\nindex 426d9f4ff..f68461fe1 100644\n--- c/extensions/lists-extension/pom.xml\n+++ i/extensions/lists-extension/pom.xml\n@@ -18,21 +18,20 @@\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n-    \u003cmodules\u003e\n-        \u003cmodule\u003eservices\u003c/module\u003e\n-        \u003cmodule\u003erest\u003c/module\u003e\n-        \u003cmodule\u003eactions\u003c/module\u003e\n-    \u003c/modules\u003e\n-\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n\n     \u003cartifactId\u003ecxs-lists-extension\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Lists\u003c/name\u003e\n     \u003cdescription\u003eList extension for the Apache Unomi Context Server\u003c/description\u003e\n     \u003cpackaging\u003epom\u003c/packaging\u003e\n+\n+    \u003cmodules\u003e\n+        \u003cmodule\u003eservices\u003c/module\u003e\n+        \u003cmodule\u003erest\u003c/module\u003e\n+        \u003cmodule\u003eactions\u003c/module\u003e\n+    \u003c/modules\u003e\n \u003c/project\u003e\ndiff --git c/extensions/lists-extension/rest/pom.xml i/extensions/lists-extension/rest/pom.xml\nindex 2ef53bcba..db0c58cac 100644\n--- c/extensions/lists-extension/rest/pom.xml\n+++ i/extensions/lists-extension/rest/pom.xml\n@@ -17,31 +17,31 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003ecxs-lists-extension\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-lists-extension-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Lists :: REST API\u003c/name\u003e\n     \u003cdescription\u003eList extension REST API for the Apache Unomi Context Server\u003c/description\u003e\n-\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003ecxs-lists-extension-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -50,6 +50,16 @@\n             \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.geronimo.specs\u003c/groupId\u003e\n+            \u003cartifactId\u003egeronimo-ws-metadata_2.0_spec\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n@@ -69,20 +79,11 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.jaxrs\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/lists-extension/services/pom.xml i/extensions/lists-extension/services/pom.xml\nindex 7cabb2a02..ce01f8c77 100644\n--- c/extensions/lists-extension/services/pom.xml\n+++ i/extensions/lists-extension/services/pom.xml\n@@ -17,13 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003ecxs-lists-extension\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-lists-extension-services\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Lists :: Service\u003c/name\u003e\n     \u003cdescription\u003eList extension service implementation for the Apache Unomi Context Server\u003c/description\u003e\n@@ -33,15 +32,14 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\ndiff --git c/extensions/log4j-extension/pom.xml i/extensions/log4j-extension/pom.xml\nindex 007010d3b..f38accb0f 100644\n--- c/extensions/log4j-extension/pom.xml\n+++ i/extensions/log4j-extension/pom.xml\n@@ -17,39 +17,27 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\"\u003e\n-\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n-        \u003crelativePath\u003e../pom.xml\u003c/relativePath\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003elog4j-extension\u003c/artifactId\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Log4j Extension\u003c/name\u003e\n     \u003cdescription\u003eApache Unomi log4j extensions\u003c/description\u003e\n\n-    \u003cproperties\u003e\n-        \u003cproject.build.sourceEncoding\u003eUTF-8\u003c/project.build.sourceEncoding\u003e\n-        \u003cmaven.compiler.source\u003e1.8\u003c/maven.compiler.source\u003e\n-        \u003cmaven.compiler.target\u003e1.8\u003c/maven.compiler.target\u003e\n-    \u003c/properties\u003e\n-\n     \u003cdependencies\u003e\n-        \u003c!-- Apache Commons --\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n-            \u003cversion\u003e3.15.0\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n             \u003cartifactId\u003elog4j-core\u003c/artifactId\u003e\n-            \u003cversion\u003e2.19.0\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/pom.xml i/extensions/pom.xml\nindex 707f8b78a..3b29d26cc 100644\n--- c/extensions/pom.xml\n+++ i/extensions/pom.xml\n@@ -18,13 +18,11 @@\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions\u003c/name\u003e\n     \u003cdescription\u003eApache Unomi Context Server extensions\u003c/description\u003e\ndiff --git c/extensions/privacy-extension/pom.xml i/extensions/privacy-extension/pom.xml\nindex e11174c96..f2700b46d 100644\n--- c/extensions/privacy-extension/pom.xml\n+++ i/extensions/privacy-extension/pom.xml\n@@ -18,21 +18,18 @@\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n+    \u003cparent\u003e\n+        \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+        \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n+    \u003c/parent\u003e\n+    \u003cartifactId\u003ecxs-privacy-extension\u003c/artifactId\u003e\n+    \u003cname\u003eApache Unomi :: Extensions :: Privacy\u003c/name\u003e\n+    \u003cdescription\u003ePrivacy management extension for the Apache Unomi Context Server\u003c/description\u003e\n+    \u003cpackaging\u003epom\u003c/packaging\u003e\n\n     \u003cmodules\u003e\n         \u003cmodule\u003eservices\u003c/module\u003e\n         \u003cmodule\u003erest\u003c/module\u003e\n     \u003c/modules\u003e\n-\n-    \u003cparent\u003e\n-        \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n-    \u003c/parent\u003e\n-\n-    \u003cartifactId\u003ecxs-privacy-extension\u003c/artifactId\u003e\n-    \u003cname\u003eApache Unomi :: Extensions :: Privacy\u003c/name\u003e\n-    \u003cdescription\u003ePrivacy management extension for the Apache Unomi Context Server\u003c/description\u003e\n-\n-    \u003cpackaging\u003epom\u003c/packaging\u003e\n \u003c/project\u003e\ndiff --git c/extensions/privacy-extension/rest/pom.xml i/extensions/privacy-extension/rest/pom.xml\nindex ebfa43556..ed5cc9843 100644\n--- c/extensions/privacy-extension/rest/pom.xml\n+++ i/extensions/privacy-extension/rest/pom.xml\n@@ -17,13 +17,12 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003ecxs-privacy-extension\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-privacy-extension-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Privacy :: REST API\u003c/name\u003e\n     \u003cdescription\u003ePrivacy management extension REST API for the Apache Unomi Context Server\u003c/description\u003e\n@@ -33,14 +32,22 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxs-privacy-extension-services\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxs-privacy-extension-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -49,6 +56,10 @@\n             \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.geronimo.specs\u003c/groupId\u003e\n+            \u003cartifactId\u003egeronimo-ws-metadata_2.0_spec\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n@@ -68,20 +79,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.jaxrs\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/privacy-extension/services/pom.xml i/extensions/privacy-extension/services/pom.xml\nindex ff8b64442..2e22cf82d 100644\n--- c/extensions/privacy-extension/services/pom.xml\n+++ i/extensions/privacy-extension/services/pom.xml\n@@ -17,46 +17,43 @@\n   --\u003e\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003ecxs-privacy-extension\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003ecxs-privacy-extension-services\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Privacy :: Services\u003c/name\u003e\n     \u003cdescription\u003ePrivacy management extension service implementation for the Apache Unomi Context Server\u003c/description\u003e\n-    \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.core\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-lifecycle-watcher\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eosgi.core\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/router/pom.xml i/extensions/router/pom.xml\nindex 952614678..8ceb69a33 100644\n--- c/extensions/router/pom.xml\n+++ i/extensions/router/pom.xml\n@@ -16,13 +16,11 @@\n   --\u003e\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-extensions\u003c/artifactId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003eunomi-router\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Router\u003c/name\u003e\n     \u003cdescription\u003eApache Camel Router for the Apache Unomi Context server\u003c/description\u003e\n@@ -31,7 +29,6 @@\n     \u003cproperties\u003e\n         \u003ccamel.version\u003e2.23.1\u003c/camel.version\u003e\n         \u003ckafka.client.version\u003e0.11.0.3\u003c/kafka.client.version\u003e\n-        \u003ccommons-net.version\u003e3.10.0\u003c/commons-net.version\u003e\n     \u003c/properties\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/router/router-api/pom.xml i/extensions/router/router-api/pom.xml\nindex ef5a6d63c..f3fe6f9f4 100644\n--- c/extensions/router/router-api/pom.xml\n+++ i/extensions/router/router-api/pom.xml\n@@ -16,13 +16,12 @@\n   ~ limitations under the License.\n   --\u003e\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003eunomi-router\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Router :: API\u003c/name\u003e\n     \u003cdescription\u003eRouter Specification API\u003c/description\u003e\n@@ -32,7 +31,6 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\ndiff --git c/extensions/router/router-core/pom.xml i/extensions/router/router-core/pom.xml\nindex 8b7d46aad..379302271 100644\n--- c/extensions/router/router-core/pom.xml\n+++ i/extensions/router/router-core/pom.xml\n@@ -16,19 +16,38 @@\n   ~ limitations under the License.\n   --\u003e\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003eunomi-router\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-router-core\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Router :: Core\u003c/name\u003e\n     \u003cdescription\u003eRouter Core (Apache Camel Routes)\u003c/description\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n             \u003cartifactId\u003eosgi.core\u003c/artifactId\u003e\n@@ -36,32 +55,10 @@\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n-            \u003cartifactId\u003eosgi.cmpn\u003c/artifactId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.camel\u003c/groupId\u003e\n             \u003cartifactId\u003ecamel-core\u003c/artifactId\u003e\n@@ -90,6 +87,7 @@\n             \u003cgroupId\u003eorg.apache.camel\u003c/groupId\u003e\n             \u003cartifactId\u003ecamel-ftp\u003c/artifactId\u003e\n             \u003cversion\u003e${camel.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.camel\u003c/groupId\u003e\n@@ -97,14 +95,15 @@\n             \u003cversion\u003e${camel.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-net\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-net\u003c/artifactId\u003e\n-            \u003cversion\u003e${commons-net.version}\u003c/version\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-beanutils\u003c/groupId\u003e\n@@ -113,13 +112,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-logging\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-logging\u003c/artifactId\u003e\n-            \u003cversion\u003e1.1.1\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.opencsv\u003c/groupId\u003e\n             \u003cartifactId\u003eopencsv\u003c/artifactId\u003e\n-            \u003cversion\u003e3.10\u003c/version\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.servicemix.bundles\u003c/groupId\u003e\ndiff --git c/extensions/router/router-karaf-feature/pom.xml i/extensions/router/router-karaf-feature/pom.xml\nindex 1ef821ef1..d7b8e6c40 100644\n--- c/extensions/router/router-karaf-feature/pom.xml\n+++ i/extensions/router/router-karaf-feature/pom.xml\n@@ -16,27 +16,61 @@\n   ~ limitations under the License.\n   --\u003e\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003eunomi-router\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-router-karaf-feature\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Router :: Apache Karaf Feature\u003c/name\u003e\n     \u003cdescription\u003eApache Karaf feature for the Apache Unomi Context Server extension\u003c/description\u003e\n     \u003cpackaging\u003ekar\u003c/packaging\u003e\n     \u003cdependencies\u003e\n         \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.servicemix.bundles\u003c/groupId\u003e\n-            \u003cartifactId\u003eorg.apache.servicemix.bundles.jsch\u003c/artifactId\u003e\n-            \u003cversion\u003e0.1.54_1\u003c/version\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-core\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-service\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-rest\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n+            \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-net\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-net\u003c/artifactId\u003e\n-            \u003cversion\u003e${commons-net.version}\u003c/version\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n+            \u003cartifactId\u003ehttpclient-osgi\u003c/artifactId\u003e\n+            \u003ctype\u003ebundle\u003c/type\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n+            \u003cartifactId\u003ehttpcore-osgi\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.servicemix.bundles\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.apache.servicemix.bundles.jsch\u003c/artifactId\u003e\n+            \u003cversion\u003e0.1.54_1\u003c/version\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.kafka\u003c/groupId\u003e\n@@ -88,49 +122,6 @@\n             \u003cartifactId\u003ecamel-kafka\u003c/artifactId\u003e\n             \u003cversion\u003e${camel.version}\u003c/version\u003e\n         \u003c/dependency\u003e\n-\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n-            \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n-            \u003cversion\u003e${cxf.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n-\n-        \u003c!-- UNOMI ROUTER Modules Dependencies --\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-core\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-service\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-rest\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n-            \u003cartifactId\u003ehttpclient-osgi\u003c/artifactId\u003e\n-            \u003ctype\u003ebundle\u003c/type\u003e\n-        \u003c/dependency\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n-            \u003cartifactId\u003ehttpcore-osgi\u003c/artifactId\u003e\n-        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/router/router-karaf-feature/src/main/feature/feature.xml i/extensions/router/router-karaf-feature/src/main/feature/feature.xml\nindex 6d707cf67..17e9cab7e 100644\n--- c/extensions/router/router-karaf-feature/src/main/feature/feature.xml\n+++ i/extensions/router/router-karaf-feature/src/main/feature/feature.xml\n@@ -15,7 +15,7 @@\n   ~ See the License for the specific language governing permissions and\n   ~ limitations under the License.\n   --\u003e\n-\u003cfeatures xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.3.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0\" name\u003d\"unomi-router-karaf-feature\"\u003e\n+\u003cfeatures xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 https://karaf.apache.org/xmlns/features/v1.6.0\" name\u003d\"unomi-router-karaf-feature\"\u003e\n     \u003cfeature name\u003d\"unomi-router-karaf-feature\" version\u003d\"${project.version}\" description\u003d\"Apache Unomi :: Extensions :: Router :: Apache Karaf Feature\"\u003e\n         \u003cdetails\u003eApache Karaf feature for the Apache Unomi Context Server extension\u003c/details\u003e\n         \u003cfeature\u003ewrap\u003c/feature\u003e\ndiff --git c/extensions/router/router-rest/pom.xml i/extensions/router/router-rest/pom.xml\nindex 341594b03..076618366 100644\n--- c/extensions/router/router-rest/pom.xml\n+++ i/extensions/router/router-rest/pom.xml\n@@ -16,43 +16,59 @@\n   ~ limitations under the License.\n   --\u003e\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n+    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n     \u003cparent\u003e\n         \u003cartifactId\u003eunomi-router\u003c/artifactId\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-        \u003cversion\u003e2.7.0-SNAPSHOT\u003c/version\u003e\n+        \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-    \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cartifactId\u003eunomi-router-rest\u003c/artifactId\u003e\n     \u003cname\u003eApache Unomi :: Extensions :: Router :: REST API\u003c/name\u003e\n     \u003cdescription\u003eRouter REST API\u003c/description\u003e\n     \u003cpackaging\u003ebundle\u003c/packaging\u003e\n\n     \u003cdependencies\u003e\n-        \u003cdependency\u003e\n-            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n-            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n-        \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-persistence-spi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+            \u003cartifactId\u003eunomi-router-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.osgi\u003c/groupId\u003e\n+            \u003cartifactId\u003eorg.osgi.service.component.annotations\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n+            \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003ejavax.validation\u003c/groupId\u003e\n+            \u003cartifactId\u003evalidation-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejavax.ws.rs\u003c/groupId\u003e\n             \u003cartifactId\u003ejavax.ws.rs-api\u003c/artifactId\u003e\n-            \u003cversion\u003e2.0.1\u003c/version\u003e\n-            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.geronimo.specs\u003c/groupId\u003e\n+            \u003cartifactId\u003egeronimo-ws-metadata_2.0_spec\u003c/artifactId\u003e\n+        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n@@ -72,24 +88,24 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jac…\n\n* UNOMI-876: Upgrade to Java 17\n\n* UNOMI-876: Restore unomi feature elements\n\ndiff --git c/package/pom.xml i/package/pom.xml\nindex f5b20c806..b325e8f10 100644\n--- c/package/pom.xml\n+++ i/package/pom.xml\n@@ -73,16 +73,13 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-kar\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cclassifier\u003efeatures\u003c/classifier\u003e\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        \u003c!--\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-router-karaf-feature\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cclassifier\u003efeatures\u003c/classifier\u003e\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n@@ -90,7 +87,6 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-groovy-actions\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cclassifier\u003efeatures\u003c/classifier\u003e\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n@@ -98,12 +94,10 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003ecdp-graphql-feature\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003cclassifier\u003efeatures\u003c/classifier\u003e\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n         \u003c/dependency\u003e\n-        --\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\n@@ -154,7 +148,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-wab\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003eunomicfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -163,7 +156,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-persistence-elasticsearch-core\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003eelasticsearchcfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -172,7 +164,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003eclustercfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -181,17 +172,14 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-services\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003eservicescfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n                                     \u003cdestFileName\u003eorg.apache.unomi.services.cfg\u003c/destFileName\u003e\n                                 \u003c/artifactItem\u003e\n-                                \u003c!--\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-plugins-request\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003erequestcfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -200,7 +188,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-plugins-base\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003epluginsbasecfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -209,7 +196,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-groovy-actions-services\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003egroovyactionscfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -218,7 +204,6 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-plugins-mail\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003emailcfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n@@ -227,13 +212,11 @@\n                                 \u003cartifactItem\u003e\n                                     \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                                     \u003cartifactId\u003eunomi-router-core\u003c/artifactId\u003e\n-                                    \u003cversion\u003e${project.version}\u003c/version\u003e\n                                     \u003cclassifier\u003eroutercfg\u003c/classifier\u003e\n                                     \u003ctype\u003ecfg\u003c/type\u003e\n                                     \u003coutputDirectory\u003e${project.build.directory}/assembly/etc\u003c/outputDirectory\u003e\n                                     \u003cdestFileName\u003eorg.apache.unomi.router.cfg\u003c/destFileName\u003e\n                                 \u003c/artifactItem\u003e\n-                                --\u003e\n                             \u003c/artifactItems\u003e\n                         \u003c/configuration\u003e\n                     \u003c/execution\u003e\n@@ -277,11 +260,9 @@\n                     \u003c/execution\u003e\n                 \u003c/executions\u003e\n                 \u003cconfiguration\u003e\n-                    \u003c!--\n                     \u003cstartupBundles\u003e\n                         \u003cbundle\u003emvn:org.apache.unomi/log4j-extension/${project.version}\u003c/bundle\u003e\n                     \u003c/startupBundles\u003e\n-                    --\u003e\n                     \u003cinstalledFeatures\u003e\n                         \u003cfeature\u003ewrapper\u003c/feature\u003e\n                         \u003cfeature\u003ecxf-commands\u003c/feature\u003e\n@@ -310,11 +291,9 @@\n                         \u003cfeature\u003earies-blueprint\u003c/feature\u003e\n                         \u003cfeature\u003eshell-compat\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-kar\u003c/feature\u003e\n-                        \u003c!--\n                         \u003cfeature\u003eunomi-router-karaf-feature\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-groovy-actions\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-rest-ui\u003c/feature\u003e\n-                        --\u003e\n                     \u003c/bootFeatures\u003e\n                     \u003cjavase\u003e17\u003c/javase\u003e\n                 \u003c/configuration\u003e\ndiff --git c/pom.xml i/pom.xml\nindex 5b2e7ce44..fe0bc5db9 100644\n--- c/pom.xml\n+++ i/pom.xml\n@@ -101,7 +101,6 @@\n         \u003chttpclient-osgi.version\u003e4.5.14\u003c/httpclient-osgi.version\u003e\n         \u003chttpcore-osgi.version\u003e4.4.16\u003c/httpcore-osgi.version\u003e\n         \u003cjunit.version\u003e4.13.2\u003c/junit.version\u003e\n-        \u003cognl.version\u003e3.4.3\u003c/ognl.version\u003e\n         \u003ckafka-client.version\u003e2.2.1\u003c/kafka-client.version\u003e\n         \u003cst4.version\u003e4.3.4\u003c/st4.version\u003e\n         \u003ccommons-email.version\u003e1.6.0\u003c/commons-email.version\u003e\n@@ -937,11 +936,21 @@\n                 \u003cartifactId\u003eunomi-groovy-actions-services\u003c/artifactId\u003e\n                 \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-groovy-actions\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n             \u003cdependency\u003e\n                 \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                 \u003cartifactId\u003ecdp-graphql-api-impl\u003c/artifactId\u003e\n                 \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003ecdp-graphql-feature\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n             \u003cdependency\u003e\n                 \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n                 \u003cartifactId\u003egraphql-providers-sample\u003c/artifactId\u003e\n@@ -967,6 +976,16 @@\n                 \u003cartifactId\u003eunomi-plugins-optimization-test\u003c/artifactId\u003e\n                 \u003cversion\u003e${project.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-kar\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n+                \u003cartifactId\u003eunomi-router-karaf-feature\u003c/artifactId\u003e\n+                \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n\n             \u003cdependency\u003e\n                 \u003cgroupId\u003ejavax.validation\u003c/groupId\u003e\n\n* UNOMI-876: Remove OGNL\n\n* UNOMI-876: Switch swagger generator for some extension (may be used globally or removed)\n\n* UNOMI-876: remove swagger plugin.\n\n* UNOMI-876: Fix wiring for extensions packaged as features (groovy, router, salesforce, ...)\n\n* UNOMI-876: Switch to Java 21, Upgrade to Karaf 4.4.8, Upgrade groovy from 4.0.21 to 4.0.28 and move groovy bundles into unomi feature because used by shell command and included in unomi base feature.\n\ndiff --git c/extensions/groovy-actions/karaf-kar/pom.xml i/extensions/groovy-actions/karaf-kar/pom.xml\nindex f1233013b..579764b7f 100644\n--- c/extensions/groovy-actions/karaf-kar/pom.xml\n+++ i/extensions/groovy-actions/karaf-kar/pom.xml\n@@ -74,7 +74,7 @@\n                                 \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n                             \u003c/descriptors\u003e\n                             \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n-                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cjavase\u003e21\u003c/javase\u003e\n                             \u003cframework\u003e\n                                 \u003cfeature\u003eframework\u003c/feature\u003e\n                             \u003c/framework\u003e\ndiff --git c/extensions/groovy-actions/karaf-kar/src/main/feature/feature.xml i/extensions/groovy-actions/karaf-kar/src/main/feature/feature.xml\nindex f9e397439..8c2893e9a 100644\n--- c/extensions/groovy-actions/karaf-kar/src/main/feature/feature.xml\n+++ i/extensions/groovy-actions/karaf-kar/src/main/feature/feature.xml\n@@ -17,19 +17,10 @@\n   --\u003e\n \u003cfeatures xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" name\u003d\"unomi-groovy-actions\"\u003e\n\n-    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n-\n     \u003cfeature name\u003d\"unomi-groovy-actions\" description\u003d\"${project.name}\" version\u003d\"${project.version}\"\u003e\n         \u003cdetails\u003e${project.description}\u003c/details\u003e\n         \u003cfeature\u003ewrap\u003c/feature\u003e\n-        \u003cfeature\u003espifly\u003c/feature\u003e\n         \u003cfeature\u003eunomi-kar\u003c/feature\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003emvn:org.apache.groovy/groovy/${groovy.version}\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003emvn:org.apache.groovy/groovy-xml/${groovy.version}\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003emvn:org.apache.groovy/groovy-json/${groovy.version}\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003ewrap:mvn:io.github.http-builder-ng/http-builder-ng-core/1.0.4\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003emvn:org.jsoup/jsoup/1.13.1\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"85\"\u003emvn:com.sun.activation/javax.activation/1.2.0\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"85\" start\u003d\"false\"\u003emvn:org.apache.unomi/unomi-groovy-actions-services/${project.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"85\" start\u003d\"false\"\u003emvn:org.apache.unomi/unomi-groovy-actions-rest/${project.version}\u003c/bundle\u003e\n     \u003c/feature\u003e\ndiff --git c/extensions/router/router-karaf-feature/pom.xml i/extensions/router/router-karaf-feature/pom.xml\nindex 801a1a05e..093ef944d 100644\n--- c/extensions/router/router-karaf-feature/pom.xml\n+++ i/extensions/router/router-karaf-feature/pom.xml\n@@ -170,7 +170,7 @@\n                                 \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n                             \u003c/descriptors\u003e\n                             \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n-                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cjavase\u003e21\u003c/javase\u003e\n                             \u003cframework\u003e\n                                 \u003cfeature\u003eframework\u003c/feature\u003e\n                             \u003c/framework\u003e\ndiff --git c/extensions/salesforce-connector/karaf-kar/pom.xml i/extensions/salesforce-connector/karaf-kar/pom.xml\nindex fb1a113bd..d9392e917 100644\n--- c/extensions/salesforce-connector/karaf-kar/pom.xml\n+++ i/extensions/salesforce-connector/karaf-kar/pom.xml\n@@ -103,7 +103,7 @@\n                                 \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n                             \u003c/descriptors\u003e\n                             \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n-                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cjavase\u003e21\u003c/javase\u003e\n                             \u003cframework\u003e\n                                 \u003cfeature\u003eframework\u003c/feature\u003e\n                             \u003c/framework\u003e\ndiff --git c/extensions/weather-update/karaf-kar/pom.xml i/extensions/weather-update/karaf-kar/pom.xml\nindex 2bb01b6c9..826243aed 100644\n--- c/extensions/weather-update/karaf-kar/pom.xml\n+++ i/extensions/weather-update/karaf-kar/pom.xml\n@@ -95,7 +95,7 @@\n                                 \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n                             \u003c/descriptors\u003e\n                             \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n-                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cjavase\u003e21\u003c/javase\u003e\n                             \u003cframework\u003e\n                                 \u003cfeature\u003eframework\u003c/feature\u003e\n                             \u003c/framework\u003e\ndiff --git c/itests/pom.xml i/itests/pom.xml\nindex 9a0cb178f..25722cab0 100644\n--- c/itests/pom.xml\n+++ i/itests/pom.xml\n@@ -40,7 +40,7 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi\u003c/artifactId\u003e\n-            \u003cversion\u003e${project.version}\u003c/version\u003e\n+            \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n             \u003ctype\u003etar.gz\u003c/type\u003e\n             \u003cscope\u003etest\u003c/scope\u003e\n             \u003cexclusions\u003e\n@@ -161,13 +161,13 @@\n                             \u003c/execution\u003e\n                         \u003c/executions\u003e\n                     \u003c/plugin\u003e\n-                    \u003c!-- Needed if you use versionAsInProject() --\u003e\n                     \u003cplugin\u003e\n                         \u003cgroupId\u003eorg.apache.servicemix.tooling\u003c/groupId\u003e\n                         \u003cartifactId\u003edepends-maven-plugin\u003c/artifactId\u003e\n                         \u003cexecutions\u003e\n                             \u003cexecution\u003e\n                                 \u003cid\u003egenerate-depends-file\u003c/id\u003e\n+                                \u003cphase\u003egenerate-resources\u003c/phase\u003e\n                                 \u003cgoals\u003e\n                                     \u003cgoal\u003egenerate-depends-file\u003c/goal\u003e\n                                 \u003c/goals\u003e\ndiff --git c/kar/pom.xml i/kar/pom.xml\nindex 82fdbce8f..dcad6cb66 100644\n--- c/kar/pom.xml\n+++ i/kar/pom.xml\n@@ -184,7 +184,7 @@\n                                 \u003cdescriptor\u003efile:${project.build.directory}/feature/feature.xml\u003c/descriptor\u003e\n                             \u003c/descriptors\u003e\n                             \u003cdistribution\u003eorg.apache.karaf:apache-karaf:zip:${karaf.version}\u003c/distribution\u003e\n-                            \u003cjavase\u003e17\u003c/javase\u003e\n+                            \u003cjavase\u003e21\u003c/javase\u003e\n                             \u003cframework\u003e\n                                 \u003cfeature\u003eframework\u003c/feature\u003e\n                             \u003c/framework\u003e\ndiff --git c/kar/src/main/feature/feature.xml i/kar/src/main/feature/feature.xml\nindex dc9eb7102..057555bda 100644\n--- c/kar/src/main/feature/feature.xml\n+++ i/kar/src/main/feature/feature.xml\n@@ -18,6 +18,7 @@\n\n \u003cfeatures name\u003d\"unomi-kar\" xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0 http://karaf.apache.org/xmlns/features/v1.6.0\"\u003e\n\n+    \u003crepository\u003emvn:org.apache.karaf.features/specs/${karaf.version}/xml/features\u003c/repository\u003e\n     \u003crepository\u003emvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features\u003c/repository\u003e\n\n     \u003cfeature description\u003d\"unomi-kar\" version\u003d\"${project.version}\" name\u003d\"unomi-kar\" start-level\u003d\"70\"\u003e\n@@ -35,6 +36,7 @@\n         \u003cfeature\u003ecxf-rs-description-openapi-v3\u003c/feature\u003e\n         \u003cfeature\u003eeventadmin\u003c/feature\u003e\n         \u003cfeature\u003efeature\u003c/feature\u003e\n+        \u003cfeature\u003espifly\u003c/feature\u003e\n         \u003cfeature\u003eshell-compat\u003c/feature\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.web.cfg\"\u003emvn:org.apache.unomi/unomi-wab/${project.version}/cfg/unomicfg\u003c/configfile\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.persistence.elasticsearch.cfg\"\u003emvn:org.apache.unomi/unomi-persistence-elasticsearch-core/${project.version}/cfg/elasticsearchcfg\u003c/configfile\u003e\n@@ -70,6 +72,9 @@\n         \u003cbundle start-level\u003d\"55\"\u003emvn:joda-time/joda-time/${joda-time.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"55\"\u003emvn:jakarta.annotation/jakarta.annotation-api/${jakarta-annotation-api.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"55\"\u003emvn:com.google.code.findbugs/jsr305/${jsr305.version}\u003c/bundle\u003e\n+        \u003cbundle start-level\u003d\"55\"\u003emvn:org.apache.groovy/groovy/${groovy.version}\u003c/bundle\u003e\n+        \u003cbundle start-level\u003d\"55\"\u003emvn:org.apache.groovy/groovy-xml/${groovy.version}\u003c/bundle\u003e\n+        \u003cbundle start-level\u003d\"55\"\u003emvn:org.apache.groovy/groovy-json/${groovy.version}\u003c/bundle\u003e\n\n         \u003cbundle start-level\u003d\"70\" start\u003d\"false\"\u003emvn:org.apache.unomi/unomi-lifecycle-watcher/${project.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"75\" start\u003d\"false\"\u003emvn:org.apache.unomi/unomi-api/${project.version}\u003c/bundle\u003e\ndiff --git c/package/pom.xml i/package/pom.xml\nindex b325e8f10..e687a6b7c 100644\n--- c/package/pom.xml\n+++ i/package/pom.xml\n@@ -18,14 +18,13 @@\n\n \u003cproject xmlns\u003d\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi\u003d\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation\u003d\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n     \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n-\n     \u003cparent\u003e\n         \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n         \u003cartifactId\u003eunomi-root\u003c/artifactId\u003e\n         \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003c/parent\u003e\n-\n     \u003cartifactId\u003eunomi\u003c/artifactId\u003e\n+    \u003cversion\u003e3.0.0-SNAPSHOT\u003c/version\u003e\n     \u003cpackaging\u003epom\u003c/packaging\u003e\n     \u003cname\u003eApache Unomi :: Distribution Package\u003c/name\u003e\n     \u003cdescription\u003ePackaged distributions of the Apache Unomi Context Server\u003c/description\u003e\n@@ -68,6 +67,13 @@\n             \u003ctype\u003exml\u003c/type\u003e\n             \u003cscope\u003eruntime\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.apache.karaf.features\u003c/groupId\u003e\n+            \u003cartifactId\u003especs\u003c/artifactId\u003e\n+            \u003cclassifier\u003efeatures\u003c/classifier\u003e\n+            \u003ctype\u003exml\u003c/type\u003e\n+            \u003cscope\u003eruntime\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003c!-- Additional Apache Unomi features --\u003e\n         \u003cdependency\u003e\n@@ -295,7 +301,7 @@\n                         \u003cfeature\u003eunomi-groovy-actions\u003c/feature\u003e\n                         \u003cfeature\u003eunomi-rest-ui\u003c/feature\u003e\n                     \u003c/bootFeatures\u003e\n-                    \u003cjavase\u003e17\u003c/javase\u003e\n+                    \u003cjavase\u003e21\u003c/javase\u003e\n                 \u003c/configuration\u003e\n             \u003c/plugin\u003e\n             \u003cplugin\u003e\ndiff --git c/pom.xml i/pom.xml\nindex 60730e55d..b6342881a 100644\n--- c/pom.xml\n+++ i/pom.xml\n@@ -61,11 +61,11 @@\n         \u003cproject.build.sourceEncoding\u003eUTF-8\u003c/project.build.sourceEncoding\u003e\n         \u003cencoding\u003eUTF-8\u003c/encoding\u003e\n\n-        \u003cjava.version\u003e17\u003c/java.version\u003e\n+        \u003cjava.version\u003e21\u003c/java.version\u003e\n         \u003cmaven.compiler.source\u003e${java.version}\u003c/maven.compiler.source\u003e\n         \u003cmaven.compiler.target\u003e${java.version}\u003c/maven.compiler.target\u003e\n\n-        \u003ckaraf.version\u003e4.4.7\u003c/karaf.version\u003e\n+        \u003ckaraf.version\u003e4.4.8\u003c/karaf.version\u003e\n         \u003celasticsearch.version\u003e7.4.2\u003c/elasticsearch.version\u003e\n         \u003celasticsearch.test.version\u003e7.11.0\u003c/elasticsearch.test.version\u003e\n         \u003cjavax-validation.version\u003e1.1.0.Final\u003c/javax-validation.version\u003e\n@@ -97,7 +97,7 @@\n         \u003ccxf.version\u003e3.6.5\u003c/cxf.version\u003e\n         \u003crs-api.version\u003e2.1\u003c/rs-api.version\u003e\n         \u003cgeronimo-ws.version\u003e1.1.3\u003c/geronimo-ws.version\u003e\n-        \u003cgroovy.version\u003e4.0.21\u003c/groovy.version\u003e\n+        \u003cgroovy.version\u003e4.0.28\u003c/groovy.version\u003e\n         \u003chttpclient-osgi.version\u003e4.5.14\u003c/httpclient-osgi.version\u003e\n         \u003chttpcore-osgi.version\u003e4.4.16\u003c/httpcore-osgi.version\u003e\n         \u003cjunit.version\u003e4.13.2\u003c/junit.version\u003e\n@@ -106,7 +106,9 @@\n         \u003ccommons-email.version\u003e1.6.0\u003c/commons-email.version\u003e\n         \u003ccommons-fileupload.version\u003e1.3.1\u003c/commons-fileupload.version\u003e\n         \u003cgeoip2.version\u003e0.9.0\u003c/geoip2.version\u003e\n+        \u003cantlr.version\u003e3.5.3\u003c/antlr.version\u003e\n         \u003cantlr4.version\u003e4.7.1\u003c/antlr4.version\u003e\n+        \u003cstringtemplate.version\u003e4.0.2\u003c/stringtemplate.version\u003e\n         \u003cjava-dataloader.version\u003e2.2.0\u003c/java-dataloader.version\u003e\n         \u003creactive-stream.version\u003e1.0.2\u003c/reactive-stream.version\u003e\n         \u003cyauaa.version\u003e7.31.0\u003c/yauaa.version\u003e\n@@ -124,6 +126,7 @@\n         \u003canimal-sniffer-annotations.version\u003e1.14\u003c/animal-sniffer-annotations.version\u003e\n         \u003cokhttp.version\u003e3.2.0\u003c/okhttp.version\u003e\n         \u003cokio.version\u003e1.6.0\u003c/okio.version\u003e\n+        \u003ctreelayout.version\u003e1.0.3\u003c/treelayout.version\u003e\n         \u003cservlet.spec.groupId\u003ejavax.servlet\u003c/servlet.spec.groupId\u003e\n         \u003cservlet.spec.artifactId\u003ejavax.servlet-api\u003c/servlet.spec.artifactId\u003e\n         \u003cservlet.spec.version\u003e3.1.0\u003c/servlet.spec.version\u003e\n@@ -1327,11 +1330,26 @@\n                 \u003cartifactId\u003erxjava\u003c/artifactId\u003e\n                 \u003cversion\u003e${reactivex.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.antlr\u003c/groupId\u003e\n+                \u003cartifactId\u003eantlr-runtime\u003c/artifactId\u003e\n+                \u003cversion\u003e${antlr.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n             \u003cdependency\u003e\n                 \u003cgroupId\u003eorg.antlr\u003c/groupId\u003e\n                 \u003cartifactId\u003eantlr4-runtime\u003c/artifactId\u003e\n                 \u003cversion\u003e${antlr4.version}\u003c/version\u003e\n             \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.antlr\u003c/groupId\u003e\n+                \u003cartifactId\u003estringtemplate\u003c/artifactId\u003e\n+                \u003cversion\u003e${stringtemplate.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n+            \u003cdependency\u003e\n+                \u003cgroupId\u003eorg.abego.treelayout\u003c/groupId\u003e\n+                \u003cartifactId\u003eorg.abego.treelayout.core\u003c/artifactId\u003e\n+                \u003cversion\u003e${treelayout.version}\u003c/version\u003e\n+            \u003c/dependency\u003e\n             \u003cdependency\u003e\n                 \u003cgroupId\u003ecom.graphql-java\u003c/groupId\u003e\n                 \u003cartifactId\u003ejava-dataloader\u003c/artifactId\u003e\ndiff --git c/samples/graphql-providers-feature/pom.xml i/samples/graphql-providers-feature/pom.xml\nindex 79748878d..6c0b85f28 100644\n--- c/samples/graphql-providers-feature/pom.xml\n+++ i/samples/graphql-providers-feature/pom.xml\n@@ -68,10 +68,10 @@\n                 \u003cexecutions\u003e\n                     \u003cexecution\u003e\n                         \u003cid\u003egenerate-features\u003c/id\u003e\n+                        \u003cphase\u003egenerate-resources\u003c/phase\u003e\n                         \u003cgoals\u003e\n                             \u003cgoal\u003efeatures-generate-descriptor\u003c/goal\u003e\n                         \u003c/goals\u003e\n-                        \u003cphase\u003ecompile\u003c/phase\u003e\n                     \u003c/execution\u003e\n                 \u003c/executions\u003e\n             \u003c/plugin\u003e\ndiff --git c/setenv.sh i/setenv.sh\nindex f826319e6..dd042c07f 100755\n--- c/setenv.sh\n+++ i/setenv.sh\n@@ -19,6 +19,6 @@\n ################################################################################\n export UNOMI_VERSION\u003d`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression\u003dproject.version | grep -Ev \u0027(^\\[|Download\\w+:)\u0027`\n echo Detected project version\u003d$UNOMI_VERSION\n-export KARAF_VERSION\u003d4.4.7\n+export KARAF_VERSION\u003d4.4.8\n # Uncomment the following line if you need Apache Unomi to start automatically at the first start\n # export KARAF_OPTS\u003d\"-Dunomi.autoStart\u003dtrue\"\ndiff --git c/tools/shell-commands/pom.xml i/tools/shell-commands/pom.xml\nindex c1fef34c5..c9032dd54 100644\n--- c/tools/shell-commands/pom.xml\n+++ i/tools/shell-commands/pom.xml\n@@ -96,10 +96,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.groovy\u003c/groupId\u003e\n             \u003cartifactId\u003egroovy\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.groovy\u003c/groupId\u003e\n             \u003cartifactId\u003egroovy-json\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n\n* UNOMI-876: Upgrade jacoco for JDK 21, add a dedicated users.properties for itests as required since KARAF-7086\n\n* UNOMI-876: Remove embedded jackson into elasticsearch persistence, update xsd for blueprint to v1.3.0\n\n* UNOMI-876: Remove SOAP annotations and dependencies\n\n* UNOMI-876: Remove useless dependency of slf4j\n\n* UNOMI-876: Rename tools module to command and refactor build order to allow verification of features during build.\n\n* UNOMI-876: Refactor build to ensure dependency order and feature verification. Fix slf4j provided dependency.\n\ndiff --git c/extensions/geonames/rest/pom.xml i/extensions/geonames/rest/pom.xml\nindex 1ab94f658..5b0e05863 100644\n--- c/extensions/geonames/rest/pom.xml\n+++ i/extensions/geonames/rest/pom.xml\n@@ -87,6 +87,11 @@\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n \u003c/project\u003e\ndiff --git c/extensions/geonames/services/pom.xml i/extensions/geonames/services/pom.xml\nindex b532dcd8a..a4c69fef2 100644\n--- c/extensions/geonames/services/pom.xml\n+++ i/extensions/geonames/services/pom.xml\n@@ -55,6 +55,11 @@\n             \u003cartifactId\u003ecommons-beanutils\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/groovy-actions/rest/pom.xml i/extensions/groovy-actions/rest/pom.xml\nindex 856051a3e..1f9d77e80 100644\n--- c/extensions/groovy-actions/rest/pom.xml\n+++ i/extensions/groovy-actions/rest/pom.xml\n@@ -92,6 +92,11 @@\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n     \u003cbuild\u003e\n         \u003cplugins\u003e\ndiff --git c/extensions/groovy-actions/services/pom.xml i/extensions/groovy-actions/services/pom.xml\nindex 76c30b85b..48c24abb7 100644\n--- c/extensions/groovy-actions/services/pom.xml\n+++ i/extensions/groovy-actions/services/pom.xml\n@@ -74,8 +74,8 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-io\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-io\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-core\u003c/artifactId\u003e\n@@ -86,6 +86,11 @@\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.groovy\u003c/groupId\u003e\n             \u003cartifactId\u003egroovy\u003c/artifactId\u003e\ndiff --git c/extensions/healthcheck/pom.xml i/extensions/healthcheck/pom.xml\nindex a41479ad8..3de7e60e9 100644\n--- c/extensions/healthcheck/pom.xml\n+++ i/extensions/healthcheck/pom.xml\n@@ -76,6 +76,11 @@\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.httpcomponents\u003c/groupId\u003e\n             \u003cartifactId\u003ehttpclient-osgi\u003c/artifactId\u003e\ndiff --git c/extensions/json-schema/rest/pom.xml i/extensions/json-schema/rest/pom.xml\nindex 0753ad861..a787b2094 100644\n--- c/extensions/json-schema/rest/pom.xml\n+++ i/extensions/json-schema/rest/pom.xml\n@@ -58,8 +58,8 @@\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n-            \u003cgroupId\u003ejakarta.jws\u003c/groupId\u003e\n-            \u003cartifactId\u003ejakarta.jws-api\u003c/artifactId\u003e\n+            \u003cgroupId\u003ejavax.ws.rs\u003c/groupId\u003e\n+            \u003cartifactId\u003ejavax.ws.rs-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n@@ -73,10 +73,9 @@\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n-\n         \u003cdependency\u003e\n-            \u003cgroupId\u003ejavax.ws.rs\u003c/groupId\u003e\n-            \u003cartifactId\u003ejavax.ws.rs-api\u003c/artifactId\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\ndiff --git c/extensions/json-schema/services/pom.xml i/extensions/json-schema/services/pom.xml\nindex b69f8609f..48bdb16e5 100644\n--- c/extensions/json-schema/services/pom.xml\n+++ i/extensions/json-schema/services/pom.xml\n@@ -81,37 +81,36 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-core\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.schema.jackson}\u003c/version\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.schema.jackson}\u003c/version\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-annotations\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.schema.jackson}\u003c/version\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.dataformat\u003c/groupId\u003e\n             \u003cartifactId\u003ejackson-dataformat-yaml\u003c/artifactId\u003e\n-            \u003cversion\u003e${version.schema.jackson}\u003c/version\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.ethlo.time\u003c/groupId\u003e\n             \u003cartifactId\u003eitu\u003c/artifactId\u003e\n             \u003cversion\u003e${version.schema.itu}\u003c/version\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.yaml\u003c/groupId\u003e\n             \u003cartifactId\u003esnakeyaml\u003c/artifactId\u003e\n-            \u003cscope\u003ecompile\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\ndiff --git c/extensions/lists-extension/rest/pom.xml i/extensions/lists-extension/rest/pom.xml\nindex 94e025562..befb85496 100644\n--- c/extensions/lists-extension/rest/pom.xml\n+++ i/extensions/lists-extension/rest/pom.xml\n@@ -81,6 +81,11 @@\n             \u003cartifactId\u003ejackson-jaxrs-json-provider\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n \u003c/project\u003e\ndiff --git c/extensions/pom.xml i/extensions/pom.xml\nindex 3b29d26cc..df1084a3b 100644\n--- c/extensions/pom.xml\n+++ i/extensions/pom.xml\n@@ -28,18 +28,4 @@\n     \u003cdescription\u003eApache Unomi Context Server extensions\u003c/description\u003e\n     \u003cpackaging\u003epom\u003c/packaging\u003e\n\n-    \u003cmodules\u003e\n-        \u003cmodule\u003elists-extension\u003c/module\u003e\n-        \u003cmodule\u003eprivacy-extension\u003c/module\u003e\n-        \u003cmodule\u003egeonames\u003c/module\u003e\n-        \u003cmodule\u003erouter\u003c/module\u003e\n-        \u003cmodule\u003esalesforce-connector\u003c/module\u003e\n-        \u003cmodule\u003eweather-update\u003c/module\u003e\n-        \u003cmodule\u003eweb-tracker\u003c/module\u003e\n-        \u003cmodule\u003egroovy-actions\u003c/module\u003e\n-        \u003cmodule\u003ejson-schema\u003c/module\u003e\n-        \u003cmodule\u003elog4j-extension\u003c/module\u003e\n-        \u003cmodule\u003ehealthcheck\u003c/module\u003e\n-    \u003c/modules\u003e\n-\n \u003c/project\u003e\ndiff --git c/extensions/privacy-extension/services/pom.xml i/extensions/privacy-extension/services/pom.xml\nindex 2e22cf82d..fc111966f 100644\n--- c/extensions/privacy-extension/services/pom.xml\n+++ i/extensions/privacy-extension/services/pom.xml\n@@ -56,6 +56,11 @@\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/router/router-core/pom.xml i/extensions/router/router-core/pom.xml\nindex 379302271..884cfe6dd 100644\n--- c/extensions/router/router-core/pom.xml\n+++ i/extensions/router/router-core/pom.xml\n@@ -131,6 +131,11 @@\n             \u003cversion\u003e${kafka.client.version}\u003c/version\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/router/router-rest/pom.xml i/extensions/router/router-rest/pom.xml\nindex 7d1749314..b4b2d72a6 100644\n--- c/extensions/router/router-rest/pom.xml\n+++ i/extensions/router/router-rest/pom.xml\n@@ -62,6 +62,7 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejavax.ws.rs\u003c/groupId\u003e\n             \u003cartifactId\u003ejavax.ws.rs-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n@@ -85,6 +86,11 @@\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/extensions/router/router-service/pom.xml i/extensions/router/router-service/pom.xml\nindex 1456a75ed..39215d0ca 100644\n--- c/extensions/router/router-service/pom.xml\n+++ i/extensions/router/router-service/pom.xml\n@@ -58,10 +58,17 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecommons-beanutils\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-beanutils\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\ndiff --git c/extensions/salesforce-connector/services/pom.xml i/extensions/salesforce-connector/services/pom.xml\nindex 8ab1d1e54..9ee206f81 100644\n--- c/extensions/salesforce-connector/services/pom.xml\n+++ i/extensions/salesforce-connector/services/pom.xml\n@@ -43,6 +43,7 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n@@ -101,6 +102,11 @@\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003c!-- Unit tests --\u003e\n         \u003cdependency\u003e\ndiff --git c/extensions/weather-update/core/pom.xml i/extensions/weather-update/core/pom.xml\nindex fa2aff031..a72d1493e 100755\n--- c/extensions/weather-update/core/pom.xml\n+++ i/extensions/weather-update/core/pom.xml\n@@ -50,6 +50,11 @@\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/graphql/karaf-feature/src/main/feature/feature.xml i/graphql/karaf-feature/src/main/feature/feature.xml\nindex 95552d6c0..fecbc0508 100644\n--- c/graphql/karaf-feature/src/main/feature/feature.xml\n+++ i/graphql/karaf-feature/src/main/feature/feature.xml\n@@ -16,8 +16,7 @@\n   ~ limitations under the License.\n   --\u003e\n \u003cfeatures xmlns\u003d\"http://karaf.apache.org/xmlns/features/v1.6.0\" name\u003d\"cdp-graphql-features\"\u003e\n-    \u003cfeature name\u003d\"cdp-graphql-feature\" description\u003d\"Apache Unomi :: GraphQL API :: Karaf Feature\"\n-             version\u003d\"${project.version}\"\u003e\n+    \u003cfeature name\u003d\"cdp-graphql-feature\" description\u003d\"Apache Unomi :: GraphQL API :: Karaf Feature\" version\u003d\"${project.version}\"\u003e\n         \u003cfeature\u003eunomi-kar\u003c/feature\u003e\n         \u003cbundle start-level\u003d\"80\"\u003ewrap:mvn:org.checkerframework/checker-compat-qual/${checker-compat-qual.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"80\"\u003ewrap:mvn:com.google.errorprone/error_prone_annotations/${error_prone_annotations.version}\u003c/bundle\u003e\n@@ -47,7 +46,7 @@\n         \u003cbundle start-level\u003d\"80\"\u003emvn:org.eclipse.jetty/jetty-security/${jetty.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"80\"\u003emvn:org.eclipse.jetty/jetty-server/${jetty.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"80\"\u003emvn:org.eclipse.jetty/jetty-http/${jetty.version}\u003c/bundle\u003e\n-        \u003cbundle start-level\u003d\"80\"\u003emvn:${servlet.spec.groupId}/${servlet.spec.artefactId}/${servlet.spec.version}\u003c/bundle\u003e\n+        \u003cbundle start-level\u003d\"80\"\u003emvn:${servlet.spec.groupId}/${servlet.spec.artifactId}/${servlet.spec.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"80\"\u003emvn:org.apache.unomi/cdp-graphql-api-impl/${project.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"80\"\u003emvn:org.apache.unomi/unomi-graphql-ui/${project.version}\u003c/bundle\u003e\n     \u003c/feature\u003e\ndiff --git c/kar/src/main/feature/feature.xml i/kar/src/main/feature/feature.xml\nindex 9b1fbfadb..01d087ff8 100644\n--- c/kar/src/main/feature/feature.xml\n+++ i/kar/src/main/feature/feature.xml\n@@ -28,7 +28,7 @@\n         \u003cfeature prerequisite\u003d\"true\"\u003econfig\u003c/feature\u003e\n         \u003cfeature prerequisite\u003d\"true\"\u003escr\u003c/feature\u003e\n         \u003cfeature prerequisite\u003d\"true\"\u003ehttp\u003c/feature\u003e\n-        \u003cfeature\u003epax-logging\u003c/feature\u003e\n+        \u003cfeature prerequisite\u003d\"true\"\u003elog\u003c/feature\u003e\n         \u003cfeature\u003ecxf\u003c/feature\u003e\n         \u003cfeature\u003ecxf-jaxrs\u003c/feature\u003e\n         \u003cfeature\u003ecxf-features-metrics\u003c/feature\u003e\n@@ -47,7 +47,6 @@\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.plugins.request.cfg\"\u003emvn:org.apache.unomi/unomi-plugins-request/${project.version}/cfg/requestcfg\u003c/configfile\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.plugins.base.cfg\"\u003emvn:org.apache.unomi/unomi-plugins-base/${project.version}/cfg/pluginsbasecfg\u003c/configfile\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.geonames.cfg\"\u003emvn:org.apache.unomi/cxs-geonames-services/${project.version}/cfg/geonamescfg\u003c/configfile\u003e\n-        \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.groovy.actions.cfg\"\u003emvn:org.apache.unomi/unomi-groovy-actions-services/${project.version}/cfg/groovyactionscfg\u003c/configfile\u003e\n         \u003cconfigfile finalname\u003d\"/etc/org.apache.unomi.schema.cfg\"\u003emvn:org.apache.unomi/unomi-json-schema-services/${project.version}/cfg/schemacfg\u003c/configfile\u003e\n         \u003cbundle start-level\u003d\"55\"\u003emvn:commons-collections/commons-collections/${commons-collections.version}\u003c/bundle\u003e\n         \u003cbundle start-level\u003d\"55\"\u003emvn:org.apache.commons/commons-lang3/${commons-lang3.version}\u003c/bundle\u003e\ndiff --git c/persistence-elasticsearch/core/pom.xml i/persistence-elasticsearch/core/pom.xml\nindex 31b46f3d8..6e1fccdc5 100644\n--- c/persistence-elasticsearch/core/pom.xml\n+++ i/persistence-elasticsearch/core/pom.xml\n@@ -67,6 +67,11 @@\n             \u003cartifactId\u003ehazelcast-all\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003cdependency\u003e\n             \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\ndiff --git c/persistence-spi/pom.xml i/persistence-spi/pom.xml\nindex 7f5e30217..81c410e5e 100644\n--- c/persistence-spi/pom.xml\n+++ i/persistence-spi/pom.xml\n@@ -61,6 +61,11 @@\n             \u003cartifactId\u003ecommons-collections\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003c!-- Unit tests --\u003e\n         \u003cdependency\u003e\ndiff --git c/plugins/baseplugin/pom.xml i/plugins/baseplugin/pom.xml\nindex cbe8c37f3..971f87566 100644\n--- c/plugins/baseplugin/pom.xml\n+++ i/plugins/baseplugin/pom.xml\n@@ -81,6 +81,11 @@\n             \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n\n         \u003c!-- tests --\u003e\n         \u003cdependency\u003e\ndiff --git c/plugins/mail/pom.xml i/plugins/mail/pom.xml\nindex cbd324c27..3d67809dd 100644\n--- c/plugins/mail/pom.xml\n+++ i/plugins/mail/pom.xml\n@@ -43,6 +43,12 @@\n             \u003cgroupId\u003eorg.antlr\u003c/groupId\u003e\n             \u003cartifactId\u003eST4\u003c/artifactId\u003e\n         \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/plugins/pom.xml i/plugins/pom.xml\nindex d88748ff5..c06b4f2fc 100644\n--- c/plugins/pom.xml\n+++ i/plugins/pom.xml\n@@ -28,18 +28,7 @@\n     \u003cdescription\u003eApache Unomi Context Server plugins\u003c/description\u003e\n     \u003cpackaging\u003epom\u003c/packaging\u003e\n\n-    \u003cmodules\u003e\n-        \u003cmodule\u003ebaseplugin\u003c/module\u003e\n-        \u003cmodule\u003erequest\u003c/module\u003e\n-        \u003cmodule\u003email\u003c/module\u003e\n-        \u003cmodule\u003eoptimization-test\u003c/module\u003e\n-        \u003cmodule\u003ehover-event\u003c/module\u003e\n-        \u003cmodule\u003epast-event\u003c/module\u003e\n-        \u003cmodule\u003etracked-event\u003c/module\u003e\n-        \u003cmodule\u003ekafka-injector\u003c/module\u003e\n-    \u003c/modules\u003e\n-\n-    \u003cdependencies\u003e\n+   \u003cdependencies\u003e\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.unomi\u003c/groupId\u003e\n             \u003cartifactId\u003eunomi-api\u003c/artifactId\u003e\ndiff --git c/plugins/request/pom.xml i/plugins/request/pom.xml\nindex 926dd4b1f..2663e426d 100644\n--- c/plugins/request/pom.xml\n+++ i/plugins/request/pom.xml\n@@ -49,6 +49,12 @@\n             \u003cartifactId\u003eyauaa\u003c/artifactId\u003e\n         \u003c/dependency\u003e\n\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+\n         \u003cdependency\u003e\n             \u003cgroupId\u003ejunit\u003c/groupId\u003e\n             \u003cartifactId\u003ejunit\u003c/artifactId\u003e\ndiff --git c/pom.xml i/pom.xml\nindex 90bc44494..80ad69118 100644\n--- c/pom.xml\n+++ i/pom.xml\n@@ -1444,6 +1444,7 @@\n         \u003cmodule\u003epersistence-elasticsearch\u003c/module\u003e\n         \u003cmodule\u003eservices\u003c/module\u003e\n         \u003c!-- plugins --\u003e\n+        \u003cmodule\u003eplugins\u003c/module\u003e\n         \u003cmodule\u003eplugins/baseplugin\u003c/module\u003e\n         \u003cmodule\u003eplugins/hover-event\u003c/module\u003e\n         \u003cmodule\u003eplugins/past-event\u003c/module\u003e\n@@ -1453,6 +1454,7 @@\n         \u003cmodule\u003eplugins/optimization-test\u003c/module\u003e\n         \u003cmodule\u003eplugins/request\u003c/module\u003e\n         \u003c!-- root level extensions --\u003e\n+        \u003cmodule\u003eextensions\u003c/module\u003e\n         \u003cmodule\u003eextensions/healthcheck\u003c/module\u003e\n         \u003cmodule\u003eextensions/log4j-extension\u003c/module\u003e\n         \u003cmodule\u003eextensions/geonames\u003c/module\u003e\n@@ -1463,6 +1465,7 @@\n         \u003cmodule\u003ecommands\u003c/module\u003e\n         \u003cmodule\u003ewab\u003c/module\u003e\n         \u003cmodule\u003erest\u003c/module\u003e\n+        \u003cmodule\u003emanual\u003c/module\u003e\n         \u003cmodule\u003ekar\u003c/module\u003e\n         \u003c!-- other extensions --\u003e\n         \u003cmodule\u003eextensions/groovy-actions\u003c/module\u003e\n@@ -1470,7 +1473,6 @@\n         \u003cmodule\u003eextensions/salesforce-connector\u003c/module\u003e\n         \u003cmodule\u003eextensions/weather-update\u003c/module\u003e\n         \u003cmodule\u003egraphql\u003c/module\u003e\n-        \u003cmodule\u003emanual\u003c/module\u003e\n         \u003cmodule\u003esamples\u003c/module\u003e\n         \u003cmodule\u003epackage\u003c/module\u003e\n     \u003c/modules\u003e\ndiff --git c/rest/pom.xml i/rest/pom.xml\nindex 318427279..1059b9dfd 100644\n--- c/rest/pom.xml\n+++ i/rest/pom.xml\n@@ -154,6 +154,12 @@\n             \u003cartifactId\u003ecxf-rt-rs-security-cors\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\ndiff --git c/scripting/pom.xml i/scripting/pom.xml\nindex 64d684853..e0489ff17 100644\n--- c/scripting/pom.xml\n+++ i/scripting/pom.xml\n@@ -53,6 +53,12 @@\n         \u003cdependency\u003e\n             \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n             \u003cartifactId\u003ecommons-lang3\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n\n         \u003cdependency\u003e\ndiff --git c/wab/pom.xml i/wab/pom.xml\nindex 2d399f88b..8c58283ba 100644\n--- c/wab/pom.xml\n+++ i/wab/pom.xml\n@@ -102,6 +102,11 @@\n             \u003cartifactId\u003ecommons-beanutils\u003c/artifactId\u003e\n             \u003cscope\u003eprovided\u003c/scope\u003e\n         \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+            \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n+            \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n+            \u003cscope\u003eprovided\u003c/scope\u003e\n+        \u003c/dependency\u003e\n     \u003c/dependencies\u003e\n\n     \u003cbuild\u003e\n\n* UNOMI-876: Refactor web to avoid relying on servlet.init() for config init and propagation. Fix some provided deps. Remove unused SOAP endpoints and deps. Remove old sun.nio.ch imports. Remove blueprint from wab due to incompatibility.\n\n* UNOMI-876: Remove empty test, adapt lifecycle watcher\n\n* UNOMI-876: Adapt GraphQL Servlet declaration to use HttpService. Fix authentication problem.\n\n* UNOMI-876: Fix property for actions\n\n* UNOMI-876: Externalize all dependencies in a dedicated BOM and BOM Artifacts module (as in karaf)\n\n* UNOMI-876: Fix MigrationIT test by retrieving karaf data folder from ConfigurationManager instead of environment variable\n\n* UNOMI-876: Fix OffsetDateTime Jackson serialization problem in GraphQLSegmentIT by adding jackson-datatype-jsr310 in the CustomObjectMapper\n\n* UNOMI-876: Upgrade CI to Java 17\n\n* UNOMI-876: Adapt DateUtils to avoid parsing Map of int in GraphQL\n\n* UNOMI-876: fix missing dependency after rebase\n\n* UNOMI-876: fix missing dependency after rebase\n\n* UNOMI-876: fix bad rebase for feature\n\n* UNOMI-876: revert tools to commands module renaming\n\n* UNOMI-876: revert tools to commands module renaming\n\n* UNOMI-876: restore REST-UI feature\n\n* UNOMI-876: restore REST-UI feature, document pom.xml for splitting extensions submodules"
    },
    {
      "commit": "e7be881e535ab10819c28ed850f5b1bccc3d6c05",
      "tree": "5b0650e5631e7d54121dcd680421b9d3b5011ac2",
      "parents": [
        "c22ff47221112ae6aa02a7a0c492e93840062d4d"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@apache.org",
        "time": "Wed Aug 27 07:12:48 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 27 07:12:48 2025 +0200"
      },
      "message": "UNOMI-877: Remove all reference to cellar and hazelcast. (#725)\n\n* UNOMI-877: Remove all reference to cellar and hazelcast.\nUNOMI-877: Not sending event to cluster anymore.\nUNOMI-877: Replace Karaf Cellar and Hazelcast with PersistenceService for cluster synchronization (code isolated from branch unomi-3-dev made by Serge Huber)\n\n* Remove unused imports from ClusterNode, RouterCamelContext, and ClusterService.\n\n* Remove unused `clusterService` property from blueprint.xml.\n\n* Add `bundleWatcher` reference and properties to blueprint.xml.\n\n* Add clusterNode mapping definition for Elasticsearch.\n\n* Reorder `shutdownNow` to ensure proper node removal from PersistenceService during shutdown.\n\n* Clarify comment on node removal timing in `destroy` method.\n\n* Refactor configuration handling and remove unused OSGi ServiceTracker references.\n\n* Cache cluster nodes to optimize retrieval and reduce reliance on PersistenceService."
    },
    {
      "commit": "c22ff47221112ae6aa02a7a0c492e93840062d4d",
      "tree": "2e2d87f64f884014180bb600ec9f1492d9258d26",
      "parents": [
        "3f995e47ea8fbd33ca226e04f9f5cd0dfb719fff"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Aug 22 15:47:24 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 22 15:47:24 2025 +0200"
      },
      "message": "Revert \"UNOMI-877: Replace Karaf Cellar and Hazelcast with PersistenceService…\" (#724)\n\nThis reverts commit 3f995e47ea8fbd33ca226e04f9f5cd0dfb719fff."
    },
    {
      "commit": "3f995e47ea8fbd33ca226e04f9f5cd0dfb719fff",
      "tree": "49ab179b93efe38ae48be0db0f1e1578fc1ab6b4",
      "parents": [
        "f5223b8ca7bba9302f0c1362e77d79838721a186"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Fri Aug 22 13:33:20 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 22 13:33:20 2025 +0200"
      },
      "message": "UNOMI-877: Replace Karaf Cellar and Hazelcast with PersistenceService for cluster synchronization (#723)\n\n* UNOMI-877: Replace Karaf Cellar and Hazelcast with PersistenceService for cluster synchronization (code isolated from branch unomi-3-dev made by Serge Hubert)\n\n* UNOMI-877: Not sending event to cluster anymore.\n\n---------\n\nCo-authored-by: Serge Huber \u003cshuber@apache.org\u003e"
    },
    {
      "commit": "f5223b8ca7bba9302f0c1362e77d79838721a186",
      "tree": "2e2d87f64f884014180bb600ec9f1492d9258d26",
      "parents": [
        "e1b939e7d14c23d012ea1d5f586236418f42c5f4"
      ],
      "author": {
        "name": "Serge Huber",
        "email": "shuber@jahia.com",
        "time": "Mon Jul 21 16:54:42 2025 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 21 16:54:42 2025 +0200"
      },
      "message": "[UNOMI-897] Groovy data corruption and performance fixes (#720)\n\n* UNOMI-897: Fix data corruption and performance issues in GroovyActionDispatcher\n\n  - Fixed data corruption issue by removing shared GroovyShell instance with separate script instances for separate variables\n  - Improved performance by moving to pre-compilation of scripts to avoid on-the-fly and previously systematic compilation of Groovy scripts\n  - Add ScriptMetadata class for script management\n\n* UNOMI-897: Fix data corruption and performance issues in GroovyActionDispatcher\n\n  - Fixed data corruption issue by removing shared GroovyShell instance with separate script instances for separate variables\n  - Improved performance by moving to pre-compilation of scripts to avoid on-the-fly and previously systematic compilation of Groovy scripts\n  - Add ScriptMetadata class for script management\n\n* UNOMI-897 Code cleanup\n\n* UNOMI-897 Fix issues reported by initial code review\n\n* UNOMI-897 Fix issues reported by code review\n- Standardized API parameter naming on actionName\n- Added logic to avoid logging compilation error on refreshes multiple times\n- Removed the unused getOrCompileScript method\n\n* Add new error count to prevent from logging errors all the time."
    },
    {
      "commit": "02f819dbf48daa2d5b7d8aa6c651865ea32b7dae",
      "tree": "fd0f996476108c3304f8d1c52df1e1882a448868",
      "parents": [
        "e1b939e7d14c23d012ea1d5f586236418f42c5f4"
      ],
      "author": {
        "name": "Ashwin",
        "email": "8037381+ashwinrayaprolu@users.noreply.github.com",
        "time": "Thu Mar 27 11:55:51 2025 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 27 11:55:51 2025 -0400"
      },
      "message": "Updated health check even for insecure elastic deployments\n\nUpdated health check even for insecure elastic deployments"
    },
    {
      "commit": "e1b939e7d14c23d012ea1d5f586236418f42c5f4",
      "tree": "f4c0014df2c91923c33f5be75a646adb38c46d31",
      "parents": [
        "ce569e35058cd68d7c93c2f1c4da1f8091d95f48"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Mar 10 18:40:14 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 10 18:40:14 2025 +0100"
      },
      "message": "UNOMI-886: consider profileId from the event collector request (#717)\n\n"
    },
    {
      "commit": "ce569e35058cd68d7c93c2f1c4da1f8091d95f48",
      "tree": "7fe2a30037a070af62fb27565f6b35dc552b9734",
      "parents": [
        "81989bd816f49337d33171541a24daaef0856221"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Fri Mar 07 12:11:03 2025 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 07 12:11:03 2025 +0100"
      },
      "message": "UNOMI-885: fix migration error on rollover alias (#716)\n\n* UNOMI-885: fix migration error on rollover alias\n\n* UNOMI-885: change rollover value to have more than one rollover index after migration\n\n* UNOMI-885: update test to check rollover indices after migration\n\n* UNOMI-885: remove the check on duplicate session as indices are rolloved during migration"
    },
    {
      "commit": "81989bd816f49337d33171541a24daaef0856221",
      "tree": "e024a92fbec44d5bd2c23c7be25af213575c414a",
      "parents": [
        "82e0da30360ab727c269ed938d2a6725662434d3"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Dec 10 15:05:34 2024 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Dec 10 15:05:34 2024 +0100"
      },
      "message": "[maven-release-plugin] prepare for next development iteration\n"
    },
    {
      "commit": "82e0da30360ab727c269ed938d2a6725662434d3",
      "tree": "7ddee69008b33a01bf0015b7754323887fcdeb6e",
      "parents": [
        "f0a17d4548d2b3cb0501319c783a365fde7f26c6"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Dec 10 15:05:18 2024 +0100"
      },
      "committer": {
        "name": "jsinovassin",
        "email": "jsinovassinnaik@jahia.com",
        "time": "Tue Dec 10 15:05:18 2024 +0100"
      },
      "message": "[maven-release-plugin] prepare release unomi-root-2.6.1\n"
    },
    {
      "commit": "f0a17d4548d2b3cb0501319c783a365fde7f26c6",
      "tree": "32e724b3c98afd71e8a9e978d4814f32c22d38a7",
      "parents": [
        "b68c626a4982f63db74c6dabab6698eb84e0b582"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Tue Dec 10 11:18:57 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 10 11:18:57 2024 +0100"
      },
      "message": "fix integrations tests (#714)\n\n"
    },
    {
      "commit": "b68c626a4982f63db74c6dabab6698eb84e0b582",
      "tree": "82ecbf61c87f32f836661be1525cdfe2480898eb",
      "parents": [
        "5dd0aa4c62cb29ef0d23d91ff314e71e0f7550d7"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Dec 09 10:57:59 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 09 10:57:59 2024 +0100"
      },
      "message": "UNOMI-867: add unique name on refresh (#713)\n\n"
    },
    {
      "commit": "5dd0aa4c62cb29ef0d23d91ff314e71e0f7550d7",
      "tree": "5116ead84ccc59d87196eefdcd16a8a3d471f828",
      "parents": [
        "5947ed04e17ec8905ac3bfee8fcfcf5d778fe7c7"
      ],
      "author": {
        "name": "Jonathan SINOVASSIN-NAIK",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Dec 09 09:49:27 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 09 09:49:27 2024 +0100"
      },
      "message": "UNOMI-867: use a unique name in reindex step in migration (#712)\n\n"
    },
    {
      "commit": "5947ed04e17ec8905ac3bfee8fcfcf5d778fe7c7",
      "tree": "e776fe28ef470e06cf5a0263a61d8181210d5eb4",
      "parents": [
        "4b51c6d7295c2eeaec269fb4d17f819d2359a3ca"
      ],
      "author": {
        "name": "Francois G.",
        "email": "fgerthoffert@jahia.com",
        "time": "Fri Nov 29 02:12:11 2024 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 29 08:12:11 2024 +0100"
      },
      "message": "UNOMI-866:  Used project.version for log4j-extension version (#711)\n\n"
    },
    {
      "commit": "4b51c6d7295c2eeaec269fb4d17f819d2359a3ca",
      "tree": "080a17f9ff01bb565f0ed0bc2b947690ed39fe58",
      "parents": [
        "926598bd05575a1856a92a4c7ec3cc7ff749790e"
      ],
      "author": {
        "name": "David Griffon",
        "email": "dgriffon@jahia.com",
        "time": "Tue Nov 26 14:31:46 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 26 14:31:46 2024 +0100"
      },
      "message": "UNOMI-855 : set next version to 2.7.0-SNAPSHOT (#710)\n\n"
    },
    {
      "commit": "926598bd05575a1856a92a4c7ec3cc7ff749790e",
      "tree": "48f143ab3f4b25331d2d99d8487b2f5d8df9aad6",
      "parents": [
        "9c22f622dbc9cffd7773c5c20063cda39881aa78"
      ],
      "author": {
        "name": "anatol-sialitski",
        "email": "53557255+anatol-sialitski@users.noreply.github.com",
        "time": "Mon Nov 18 18:20:50 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 18 18:20:50 2024 +0100"
      },
      "message": "UNOMI-616: Update GraphQL Playground to the latest version or switch to GraphiQL (#694)\n\n"
    },
    {
      "commit": "9c22f622dbc9cffd7773c5c20063cda39881aa78",
      "tree": "ed07c5bf84fcbcbd260a0ea5a25ac46a0c239274",
      "parents": [
        "06689e867b91d0debea9f45f17fc0b3a0fc23e96"
      ],
      "author": {
        "name": "Francois G.",
        "email": "fgerthoffert@jahia.com",
        "time": "Tue Nov 12 16:54:45 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 12 16:54:45 2024 +0100"
      },
      "message": "UNOMI-864: Remove incorrect space in env variables in custom.system.properties (#709)\n\n"
    },
    {
      "commit": "06689e867b91d0debea9f45f17fc0b3a0fc23e96",
      "tree": "b000b991ec12daaecc49320eacf404f75e960a6f",
      "parents": [
        "5f325846344a94af6cf75ec2c96d08cb9236a1c1"
      ],
      "author": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Thu Nov 07 14:20:40 2024 +0100"
      },
      "committer": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Thu Nov 07 14:20:40 2024 +0100"
      },
      "message": "[maven-release-plugin] prepare for next development iteration\n"
    },
    {
      "commit": "5f325846344a94af6cf75ec2c96d08cb9236a1c1",
      "tree": "2ce809def43b2e3b4f44acc3744c453dd2598eac",
      "parents": [
        "43bebe7def6b9873563ee9a8f5b89d79be6d7133"
      ],
      "author": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Thu Nov 07 14:20:31 2024 +0100"
      },
      "committer": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Thu Nov 07 14:20:31 2024 +0100"
      },
      "message": "[maven-release-plugin] prepare release unomi-root-2.6.0\n"
    },
    {
      "commit": "43bebe7def6b9873563ee9a8f5b89d79be6d7133",
      "tree": "6ba820c6cec5c4e1e15a23a267f8ed25af832753",
      "parents": [
        "d6ee5bd804e17e728e94ffcdafa45d29c7cc2e0a"
      ],
      "author": {
        "name": "David Griffon",
        "email": "dgriffon@jahia.com",
        "time": "Thu Nov 07 10:35:34 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 07 10:35:34 2024 +0100"
      },
      "message": "UNOMI-863: set up OSGi DS to allow config update in the HeathCheck service. (#708)\n\n"
    },
    {
      "commit": "d6ee5bd804e17e728e94ffcdafa45d29c7cc2e0a",
      "tree": "22953a966baf071ebfa469fb8c64a2c0ba14a4e2",
      "parents": [
        "97830e3a0cab6f1e3ee757e6178b99b863d161b1"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Tue Nov 05 14:31:44 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 05 14:31:44 2024 +0100"
      },
      "message": "UNOMI-856: return all rules when calling /rules endpoints (#707)\n\n* UNOMI-856: return all rules when calling /rules endpoints\r\n\r\n* UNOMI-856: add javadoc"
    },
    {
      "commit": "97830e3a0cab6f1e3ee757e6178b99b863d161b1",
      "tree": "2ae325c8f638f2d775ae01a13a577cc1fbf5594c",
      "parents": [
        "0ac13a44dbcea5310da49b8f1b4ffa7d96a49674"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Thu Oct 31 17:26:34 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 31 17:26:34 2024 +0100"
      },
      "message": "UNOMI-862: fix scope check on migration (#706)\n\n* UNOMI-862: fix scope check on migration\r\n\r\n* replace space by - in the scope name"
    },
    {
      "commit": "0ac13a44dbcea5310da49b8f1b4ffa7d96a49674",
      "tree": "f041ee246c01c6b4e3dbdbce90109b9b49d9850d",
      "parents": [
        "3b2da028d6ac50b2b276c1150491bf0fc9cd689a"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Tue Oct 29 16:41:11 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 29 16:41:11 2024 +0100"
      },
      "message": "UNOMI-861: fix task check in migration\" (#705)\n\n"
    },
    {
      "commit": "3b2da028d6ac50b2b276c1150491bf0fc9cd689a",
      "tree": "3f37fd785dd0517c7a5227ee18c46ae473836a0e",
      "parents": [
        "b41e642536f28ba47716c1a80e0067dc3ebb8ca1"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Thu Oct 24 16:09:03 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 24 16:09:03 2024 +0100"
      },
      "message": "UNOMI-861: use asynchronous delete_by_query in migration scripts to a… (#704)\n\n* UNOMI-861: use asynchronous delete_by_query in migration scripts to avoid timeout\r\n\r\n* UNOMI-861: use asynchronous update_by_query in migration scripts to avoid timeout\r\n\r\n* UNOMI-861: surround code by try catch to avoid unwanted rerun\r\n"
    },
    {
      "commit": "b41e642536f28ba47716c1a80e0067dc3ebb8ca1",
      "tree": "242aed2cc48e72be4926041ad6913eca40fc578c",
      "parents": [
        "c5a2030a6927890b1aa75b7ae299a5a5b437f5ae"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Oct 21 15:17:47 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 21 14:17:47 2024 +0100"
      },
      "message": "[UNOMI-854] Add a HealthCheck Endpoint (#703)\n\n* UNOMI-854: Fix JSON representation for health check response.\r\n\r\n* UNOMI-854: Disable health check by default.\r\n\r\n* UNOMI-854: Adapt test"
    },
    {
      "commit": "c5a2030a6927890b1aa75b7ae299a5a5b437f5ae",
      "tree": "a4c4860d272e3839b8a52fac17966633484cecd6",
      "parents": [
        "64aa2a87446694e497991a3b5cdcfebd3039a48e"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Thu Oct 17 18:24:49 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 17 17:24:49 2024 +0100"
      },
      "message": "[UNOMI-854] Add a HealthCheck Endpoint (#698)\n\n* UNOMI-854: Add a healthcheck extension\r\n\r\n* UNOMI-854: Add configuration to healthcheck\r\n\r\n* UNOMI-854: Integrate authentication for servlet using JAAS and realm config\r\n\r\n* UNOMI-854: Add documentation (javadoc and adoc) for the healthcheck extension\r\n\r\n* UNOMI-854: Include Integration Test\r\n\r\n* UNOMI-854: Change log level to debug for some unrelevant runtime logs, add timeout default response, add exception details in logs.\r\n\r\n* UNOMI-853: Avoid using 2 testsuite because of conflict.\r\n\r\n* UNOMI-854: Add a healthcheck extension\r\n\r\n* UNOMI-854: Add configuration to healthcheck\r\n\r\n* UNOMI-854: Integrate authentication for servlet using JAAS and realm config\r\n\r\n* UNOMI-854: Include Integration Test\r\n\r\n* UNOMI-854: Update config capabilities, use code 206 when all checks are not LIVE, fix order of checks.\r\n\r\n* UNOMI-854: Include small value cache to ensure better memory consumption and avoid DoS.\r\n\r\n* UNOMI-854: Missed test suite removal.\r\n"
    },
    {
      "commit": "64aa2a87446694e497991a3b5cdcfebd3039a48e",
      "tree": "70197db752dcd3f50fc778d1dcfdc3c610c69fa3",
      "parents": [
        "9022fc38f596c0f096e47cb645969ffdf22bac1f"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Oct 14 18:29:10 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 14 18:29:10 2024 +0100"
      },
      "message": "UNOMI-846: improve log for event validation (#687)\n\n"
    },
    {
      "commit": "9022fc38f596c0f096e47cb645969ffdf22bac1f",
      "tree": "cf65cff14498f315bde68bce86de36c144a65fec",
      "parents": [
        "694d671e516a0d4ecda1a723ed636d4cc35a6fa0"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Oct 14 17:05:58 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 14 17:05:58 2024 +0100"
      },
      "message": "UNOMI-847: update documentation to provide a working groovy action (#700)\n\n* UNOMI-847: update documentation to provide a working groovy action\r\n\r\n* remove useless parameter"
    },
    {
      "commit": "694d671e516a0d4ecda1a723ed636d4cc35a6fa0",
      "tree": "85aa0b7709ef041ab1be902a2f4881f9eaa2a2ef",
      "parents": [
        "315c4bfa9c85d744370d5d958eda98e60e452b65"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Oct 14 15:44:30 2024 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 14 15:44:30 2024 +0100"
      },
      "message": "UNOMI-858: Fix CodeQL Java Error + Fix code scanning alert no. 11: Insecure randomness (#701)\n\n* Fix code scanning alert no. 11: Insecure randomness\r\n\r\nCo-authored-by: Copilot Autofix powered by AI \u003c62310815+github-advanced-security[bot]@users.noreply.github.com\u003e\r\n\r\n* Fix code scanning alert no. 12: Insecure randomness\r\n\r\nCo-authored-by: Copilot Autofix powered by AI \u003c62310815+github-advanced-security[bot]@users.noreply.github.com\u003e\r\n\r\n* Update index.html\r\n\r\n* UNOMI-858: upgrade java version + fix codeQL workflow\r\n\r\n---------\r\n\r\nCo-authored-by: Copilot Autofix powered by AI \u003c62310815+github-advanced-security[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "315c4bfa9c85d744370d5d958eda98e60e452b65",
      "tree": "55775db1e5eda95370181e12deb9b5248d04cc41",
      "parents": [
        "9323346a8f25bb96bdc8abdef45147b5a6a549d8"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Wed Oct 09 12:38:36 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 09 11:38:36 2024 +0100"
      },
      "message": "[UNOMI-853] Adapt migration job to use asynchronous mode avoiding timeout and connection lost (#697)\n\n* UNOMI-853: Adapt migration to handle long time reindex tasks with asynchronous mode.\r\n\r\n* UNOMI-853: Fix small typo and update documentation pointing to broken karaf link\r\n\r\n* UNOMI-853: Finally log a task waiting info every 15s."
    },
    {
      "commit": "9323346a8f25bb96bdc8abdef45147b5a6a549d8",
      "tree": "f9e557e2c57f01eafb91861debaf9c52332d4f8a",
      "parents": [
        "49c0ec97910c56fbf7433cb95eaefc6d4a6e3a8a"
      ],
      "author": {
        "name": "Jérôme Blanchard",
        "email": "jblanchard@jahia.com",
        "time": "Mon Sep 30 10:23:44 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 30 10:23:44 2024 +0200"
      },
      "message": "[UNOMI-852] - Improve robustness against log injection (#696)\n\nSee https://issues.apache.org/jira/browse/UNOMI-852"
    },
    {
      "commit": "49c0ec97910c56fbf7433cb95eaefc6d4a6e3a8a",
      "tree": "a8c6dbf0426d1a1546e1cc3b71f30e2bbb8a663b",
      "parents": [
        "3c4c3f25d5057d5cd9793c549e1240df9a39b428"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Tue Sep 03 16:02:37 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 03 16:02:37 2024 +0200"
      },
      "message": "add user public key (#690)\n\n"
    },
    {
      "commit": "3c4c3f25d5057d5cd9793c549e1240df9a39b428",
      "tree": "d8072bb24ec4d49d424f84acc71e8416d3e9d445",
      "parents": [
        "c0a2bc80c15b238891f1d443fd86ef4e21d2d968"
      ],
      "author": {
        "name": "Francois G.",
        "email": "fgerthoffert@jahia.com",
        "time": "Tue Aug 27 16:53:31 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 27 16:53:31 2024 +0200"
      },
      "message": "UNOMI-847: Updated the Groovy Action documentation (#688)\n\n"
    },
    {
      "commit": "c0a2bc80c15b238891f1d443fd86ef4e21d2d968",
      "tree": "23bb75030136c43868d4cdbcfe28a4835802e2b6",
      "parents": [
        "f25ebe89127cf243e11eecb6de3df18cc6433acd"
      ],
      "author": {
        "name": "Francois G",
        "email": "fgerthoffert@jahia.com",
        "time": "Tue Jun 25 14:57:49 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 25 14:57:49 2024 +0200"
      },
      "message": "UNOMI-842: Updated version to 2.6.0-SNAPSHOT (#682)\n\n"
    },
    {
      "commit": "f25ebe89127cf243e11eecb6de3df18cc6433acd",
      "tree": "6af737a3191caaaabb7d4cc7ec1ac05f1759288b",
      "parents": [
        "d0985f61a3c2861db2f0616d3690008f97c35143"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Jun 13 18:48:08 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 13 18:48:08 2024 +0200"
      },
      "message": "Bump junit from 4.11 to 4.13.1 in /plugins/request (#491)\n\nBumps [junit](https://github.com/junit-team/junit4) from 4.11 to 4.13.1.\r\n- [Release notes](https://github.com/junit-team/junit4/releases)\r\n- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.11.md)\r\n- [Commits](https://github.com/junit-team/junit4/compare/r4.11...r4.13.1)\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: junit:junit\r\n  dependency-type: direct:development\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "d0985f61a3c2861db2f0616d3690008f97c35143",
      "tree": "4b807df3e0329fe39c61abf100ab937e6321a4b4",
      "parents": [
        "92da944f7acd8107524a5afcdcd3ac31fac791c2"
      ],
      "author": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Wed Jun 12 14:08:06 2024 +0200"
      },
      "committer": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Wed Jun 12 14:08:06 2024 +0200"
      },
      "message": "[maven-release-plugin] prepare for next development iteration\n"
    },
    {
      "commit": "92da944f7acd8107524a5afcdcd3ac31fac791c2",
      "tree": "cfa8844f58d3ebd0c3d60330c5ea5bd3a3f74c27",
      "parents": [
        "16fc140badc2fe70d9170664529d40b3e3714395"
      ],
      "author": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Wed Jun 12 14:05:36 2024 +0200"
      },
      "committer": {
        "name": "david.griffon",
        "email": "dgriffon@jahia.com",
        "time": "Wed Jun 12 14:05:36 2024 +0200"
      },
      "message": "[maven-release-plugin] prepare release unomi-root-2.5.0\n"
    },
    {
      "commit": "16fc140badc2fe70d9170664529d40b3e3714395",
      "tree": "4b13219cb6c1f124e7ebb69d92eee31f05ea03dc",
      "parents": [
        "37c4948f417ce1c0a86dab526f762da1591f44b1"
      ],
      "author": {
        "name": "David Griffon",
        "email": "dgriffon@jahia.com",
        "time": "Tue Jun 11 16:34:47 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 11 16:34:47 2024 +0200"
      },
      "message": "UNOMI-840 : prepare release 2.5.0 (#670)\n\n"
    },
    {
      "commit": "37c4948f417ce1c0a86dab526f762da1591f44b1",
      "tree": "96815534c37788036ce144157979d4cfb0522dde",
      "parents": [
        "56e896f20cf81163a523d157d55af1deebc304e4"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Mon Jun 10 14:50:02 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 10 14:50:02 2024 +0200"
      },
      "message": "UNOMI-841: move dependency as provided to remove error at startup (#669)\n\n"
    },
    {
      "commit": "56e896f20cf81163a523d157d55af1deebc304e4",
      "tree": "53578e1dddcfc36e7f57a17137721e4df84b637c",
      "parents": [
        "e93b936c50f8e93a6ec6538ef22cbf0ffe71b332"
      ],
      "author": {
        "name": "David Griffon",
        "email": "dgriffon@jahia.com",
        "time": "Fri Jun 07 09:51:14 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 07 09:51:14 2024 +0200"
      },
      "message": "UNOMI-816 : ensure empty scope are filled properly at migration time (#666)\n\n* UNOMI-816 : ensure empty scope are filled properly at migration time\r\n\r\n* UNOMI-816 : fix archive to match ES version (+ improve doc)\r\n\r\n* UNOMI-816 : fix test\r\n\r\n* UNOMI-816 : move scope migration execution to 2.5.0\r\n\r\n* UNOMI-816 : small improvements"
    },
    {
      "commit": "e93b936c50f8e93a6ec6538ef22cbf0ffe71b332",
      "tree": "d220d326765e92776ec319c76cbc6bff090c7973",
      "parents": [
        "ab8e9634ec3d9366840ebc927238f7652d80a72b"
      ],
      "author": {
        "name": "jsinovassin",
        "email": "58434978+jsinovassin@users.noreply.github.com",
        "time": "Wed Jun 05 08:38:57 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 05 08:38:57 2024 +0200"
      },
      "message": "UNOMI-829: upgrade camel, snakeyaml, junit (#667)\n\n* UNOMI-829: upgrade camel, snakeyaml, junit\r\n\r\n* upgrade kafka\r\n\r\n* update commons-net"
    }
  ],
  "next": "ab8e9634ec3d9366840ebc927238f7652d80a72b"
}
