By the way: 'dependencies.dependency.(groupId:artifactId:type:classifier)'
must be unique: org.apache.cxf:cxf-rt-frontend-jaxrs:jar -> version
(?) vs ${cxf.version} @ line 185, column 21on main Regards JB On Mon, Oct 5, 2026 at 7:42 PM Serge Huber <[email protected]> wrote: > > Hi all, > > I'm cancelling the vote for Apache Unomi 4.0.0 RC1. > > Thank you, Jonathan, for the very thorough review. It also confirmed > that the release mechanics are sound: the signatures, checksums, > source archive, RAT check and build from source all passed. I went > through every point in your mail against the code. They hold, with a > few small corrections that are noted in the tickets. > > The issues are tracked in Jira, all targeted at 4.0.0: > > Migration from 3.0: > > - UNOMI-996 Migration from Unomi 3.0 stops before it finishes > - UNOMI-997 After migration from 3.0, some data ends up in the wrong tenant > - UNOMI-998 Migration tests do not cover an upgrade from Unomi 3.0 > > Regressions: > > - UNOMI-999 Deleting the data of one scope deletes all the data of the tenant > - UNOMI-1000 Background tasks only process the internal "system" tenant > - UNOMI-1001 In compatibility mode, 3.0 third-party servers lose features > - UNOMI-1002 In compatibility mode, all public requests wait on each other > - UNOMI-1003 Segment and scoring lists ignore the sort, and fail with no limit > - UNOMI-1004 A hover condition with only a target id matches every hover event > - UNOMI-1005 The web tracker and the server disagree on cookies across sites > - UNOMI-1006 All Unomi nodes share the same scheduler node id by default > - UNOMI-1007 Health check environment variables no longer have any effect > - UNOMI-1008 Admin requests without a tenant header do not see migrated data > > Documentation and packaging: > > - UNOMI-1009 The 3.0 to 4.0 migration guide misses several breaking changes > - UNOMI-1010 Some manual pages still describe Unomi 3.0 behaviour > - UNOMI-1011 The release publishes an extra build cache artifact > > Each ticket lists the automated tests needed to confirm the fix and to > prevent the problem from coming back. Any remaining point from the > review will be followed up before the next candidate. Help is very > welcome. Jonathan, thank you for offering a fix for UNOMI-1002. > > The cleanup for RC1: > > - the Nexus staging repository will be dropped, > - the RC1 archives will be removed from dist/dev, > - the tag unomi-root-4.0.0 will be renamed to unomi-root-4.0.0-rc1, so > the 4.0.0 tag can be - created again for the next candidate. > - I'll start a new vote for 4.0.0 RC2 once these tickets are resolved. > > Regards, > Serge Huber > > On Mon, Oct 5, 2026 at 6:19 PM Serge Huber <[email protected]> wrote: > > > > Thanks for the review Jonathan, > > > > I will cancel the release, create JIRA issues for these points and > > then fix all of them. > > > > Best regards, > > Serge... > > > > On Mon, Oct 5, 2026 at 5:48 PM Jonathan Sinovassin-Naïk via dev > > <[email protected]> wrote: > > > > > > Hi Serge, > > > > > > -1 > > > > > > Thank you for the work on this release. The release mechanics are correct, > > > but the migration from 3.0.x fails on real 3.0.1 data, and several > > > regressions affect existing features. > > > > > > I compared each item below with the unomi-root-3.0.1 tag, and all of them > > > are new in 4.0.0. > > > > > > What I checked, and what passed: > > > > > > - The sha512 checksums and the GPG signatures of the 3 archives are > > > correct. The key 16DF 7E56 7738 172F 945F 0402 7C19 D1FB BD1A B1DF is in > > > KEYS. > > > - The source zip matches the unomi-root-4.0.0 tag, apart from the files > > > that Maven generates or that git ignores. The staging source-release zip > > > is > > > identical to the dist one. > > > - RAT reports 0 unapproved files. > > > - The build from the source zip with JDK 17 and Maven 3.9.11 succeeds, > > > with > > > 1681 unit tests and 0 failures. > > > > > > > > > BLOCKING ISSUES > > > > > > 1. Migration from 3.0.x > > > > > > I ran the procedure of migrate-3.0-to-4.0.adoc on a Unomi 3.0.1 data set, > > > on Elasticsearch 9.4.3, with the binary from dist/dev. > > > > > > a. unomi:migrate fails at the first reindex with "no mapping found in > > > bundles for: event.json". Before unomi:start, the only Unomi features > > > installed are unomi-base and unomi-startup, so > > > MigrationUtils.extractMappingFromBundles (MigrationUtils.java:305) finds > > > no > > > mapping file. The mappings of unomi-persistence-elasticsearch-core and > > > cxs-geonames-services are both missing. In 3.0.1, the boot feature > > > unomi-kar installed these two bundles together with shell-commands. > > > Migrate16xToCurrentVersionIT cannot detect this, because Pax Exam installs > > > unomi-elasticsearch-core and the other features before the migration runs. > > > > > > b. An index with no known mapping stops the migration with "no mapping > > > found in bundles for: generic.json" > > > (migrate-4.0.0-01-tenantDocumentIds.groovy:82,136). A 3.0.1 cluster always > > > has a context-clusternode index. A cluster that saved a Salesforce > > > connector configuration also has context-sfdcconfiguration, which takes > > > the > > > same path. > > > > > > c. The built-in definitions of 3.0.1 hide the built-in definitions of > > > 4.0.0. The script initialize_tenant_and_audit_fields.painless:22,95 tests > > > scope == 'system', but no 3.0.1 item has this value. In 3.0.1, rules, > > > segments, scorings and goals keep the scope "systemscope" under > > > metadata.scope. The built-in condition types, action types and property > > > types have no scope. All the 3.x items go to the "default" tenant, and the > > > copy in that tenant wins over the copy in "system" > > > (MultiTypeCacheServiceImpl.java:126-139, RulesServiceImpl.java:281-304). > > > > > > After the migration, the built-in definitions that changed in 4.0.0 > > > keep > > > their 3.0.1 form, such as sessionAssigned, pastEventCondition, > > > profilePropertyCondition and booleanCondition. For example, a new visit > > > increments nbOfVisits but not totalNbOfVisits. > > > > > > d. migrate-4.0.0-05-fixSystemItemIds.groovy:60 uses a term query on the > > > analysed field itemType. The camelCase types, such as conditionType, > > > actionType and propertyType, match nothing, and the log still says > > > "Fixed". > > > > > > e. migrate-4.0.0-10-tenantInitialization.groovy:109,112 writes a key file > > > that names the headers X-Unomi-Public-Key and X-Unomi-Key. > > > AuthenticationFilter.java:69 reads the header X-Unomi-Api-Key. > > > > > > f. The tests on -systemitems and -geonames in the painless script are > > > always false. During the reindex, ctx._index is "<index>-cloned", and the > > > geonames index is "geonameentry". The migrated geonames entries go to > > > "default", but GeonamesServiceImpl reads them as "system". > > > > > > g. The migration tests do not detect the issues above. > > > Migrate16xToCurrentVersionIT has 4.0.0 checks, and MigrationIT tests the > > > resume with synthetic scripts. But the 4.0.0 checks have these limits: > > > > > > - The IT restores a 1.6.x snapshot and runs "unomi:migrate 1.6.0 true", > > > so no test starts from 3.x data. The snapshot has no context-clusternode > > > index. > > > - Pax Exam installs unomi-elasticsearch-core before the migration runs, > > > so the missing mapping bundles of item a do not fail the test. > > > - checkDefinitionsServiceObjects accepts a "system_" prefix or a test > > > tenant prefix. It does not check that the 4.0.0 version of a built-in > > > definition is the one in use, which is item c. > > > - checkDefaultTenantCreated checks that the tenant index exists, but it > > > makes no assertion when tenantService.getTenant() returns null and the > > > search finds no tenant document. > > > - checkMigratedData runs only on Elasticsearch. > > > > > > I reproduced a to e. I found f in the code and did not reproduce it. > > > > > > 2. ElasticSearchPersistenceServiceImpl.purge(scope) deletes documents of > > > other scopes > > > > > > At ElasticSearchPersistenceServiceImpl.java:2734, the call TermQuery.of(b > > > -> b.field("scope").value(scope).field("tenantId").value(...)) keeps only > > > the last field and value, because the builder overwrites them. The query > > > has no scope filter. DELETE /cxs/cluster/{scope} therefore deletes > > > documents of any type of the tenant, in all the indices with the index > > > prefix. In 3.0.1, the query filtered on the scope. The OpenSearch > > > implementation filters on the scope and on the tenant. > > > > > > 3. Scheduled tasks run only for the "system" tenant > > > > > > Inside executeAsSystem, the persistence layer adds a filter on tenantId > > > "system" (ElasticSearchPersistenceServiceImpl.java:2982-3000). These tasks > > > therefore see only the "system" tenant: > > > > > > - The profile-purge task (ProfileServiceImpl.java:363-376) runs > > > purgeProfiles, purgeSessionItems and purgeEventItems inside > > > executeAsSystem. The settings org.apache.unomi.profile.purge.*, > > > org.apache.unomi.session.purge.existTime and > > > org.apache.unomi.event.purge.existTime have no effect on the data of > > > "default" or of any other tenant. > > > - The daily recalculation of segments and scorings with relative dates > > > reads the cache of the "system" tenant (SegmentServiceImpl.java:1252-1290 > > > and 1553). A tenant segment such as "visited in the last 7 days" is never > > > evaluated again. > > > - After a restart, initCamel runs with no execution context, so the > > > persistence layer uses the "system" tenant. The recurrent import and > > > export > > > configurations of the tenants are not scheduled > > > (ProfileImportFromSourceRouteBuilder.java:104, > > > RouterCamelContext.java:317). A configuration comes back only when someone > > > saves it again. > > > > > > RulesServiceImpl and TenantUsageServiceImpl loop over the tenants with > > > executeAsTenant, but these three tasks do not. > > > > > > 4. Single-tenant compatibility mode > > > > > > - On a public path, the mode always creates a guest subject > > > (AuthenticationFilter.java:311). The mode still checks X-Unomi-Peer and > > > the > > > IP address to accept a protected event, but the header gives no role. A > > > 3.0 > > > third-party server that sends X-Unomi-Peer loses these features: > > > > > > - the profile merge on login, > > > - the profileId of the request body, > > > - the itemId of events, > > > - the cross-profile updateProperties, and the writes to > > > systemProperties, > > > segments, scores and consents. > > > > > > The Javadoc of the method says "Protected events require IP + > > > X-Unomi-Peer (like V2)". The 3.0.x backport of UNOMI-975 (commit > > > 8824da595) > > > keeps X-Unomi-Peer as the trusted caller for the profile binding. > > > - Each public request calls TenantServiceImpl.getOrCreateTenant, which is > > > synchronized (TenantServiceImpl.java:117). The method reads the tenant > > > from > > > the persistence layer with no cache (TenantServiceImpl.java:213-214), so > > > all the context.json requests go through one JVM lock and one > > > Elasticsearch > > > round trip. Each public request already read the tenant with no cache > > > before my change for UNOMI-980 (https://github.com/apache/unomi/pull/861). > > > That change added the lock, and I can propose a fix. > > > > > > OTHER REGRESSIONS > > > > > > - GET /cxs/query/{type}/{property}, and POST on the same path with no > > > condition, count the data of all the tenants. The persistence layer adds > > > the tenant filter only when the request carries a condition > > > (ElasticSearchPersistenceServiceImpl.java:2500-2513). POST > > > /cxs/query/{type}/{property}/{metricTypes} never filters on the tenant > > > (getSingleValuesMetrics, line 2780). OpenSearch behaves the same way. > > > - Segment and scoring lists ignore the sort. SegmentServiceImpl merges the > > > sorted results into a HashMap, and the sort is a TODO > > > (SegmentServiceImpl.java:352, 1637 and 1720). In POST /cxs/segments/query > > > and POST /cxs/scoring/query, a missing limit or a limit of -1 gives a > > > negative toIndex to subList (line 1732). When at least one item matches, > > > the call answers 400 instead of the list. > > > - hoverEventCondition with only targetId matches every hover event, > > > because > > > since UNOMI-828 the condition is an OR of targetId and targetPath. My > > > change for UNOMI-982 (https://github.com/apache/unomi/pull/864) makes a > > > branch with an absent parameter evaluate to true. The OR is therefore > > > always true when one of the two parameters is missing. > > > - context.json, eventcollector and client now set allowCredentials=false ( > > > https://github.com/apache/unomi/pull/878). The shipped tracker sends > > > withCredentials=true, so a browser blocks the response on a cross-origin > > > setup. > > > - Unomi no longer reads UNOMI_HEALTHCHECK_ENABLED, > > > UNOMI_HEALTHCHECK_PROVIDERS and UNOMI_HEALTHCHECK_TIMEOUT. Commit > > > cef067f2d > > > (UNOMI-919) removed their mapping from custom.system.properties. > > > configuration.adoc:1856-1862, index.adoc:180-181 and the quickstart > > > (5-min-quickstart.adoc:98) still document them. > > > - scheduler.nodeId defaults to "test-scheduler-node", and no environment > > > variable sets it. TaskLockManager compares the lock owner with this id > > > (TaskLockManager.java:240). Two nodes that keep the default can therefore > > > both take the lock and run the same task. > > > > > > > > > UNDOCUMENTED BREAKING CHANGES > > > > > > migrate-3.0-to-4.0.adoc covers the API keys, the cookie, the mandatory > > > passwords, the conditions with no type, the router file paths and the > > > privileged REST roles. The guide does not document these changes: > > > > > > - An admin call with Basic auth and no X-Unomi-Tenant-Id header runs in > > > the > > > "system" tenant. It does not see the data that the migration put in > > > "default". The guide shows this call at lines 125-130. security.adoc calls > > > the header optional, but no page says what happens without it. An unknown > > > tenant id also falls back to "system" with only a warning. But > > > how-profile-tracking-works.adoc:126-128 says that the tenant must exist, > > > and that the request fails with 401. > > > - X-Unomi-Peer and thirdparty.cfg apply only in compatibility mode. > > > recipes.adoc and builtin-event-types.adoc say this for X-Unomi-Peer, but > > > configuration.adoc:165-222 still presents the thirdparty settings as > > > active. No page documents the tenant fields restrictedEventTypes and > > > authorizedIPs, which now control the protected events. > > > - These Java API changes are not mentioned: > > > - SchedulerService.getScheduleExecutorService() and > > > getSharedScheduleExecutorService() are removed. > > > - EventService.authenticateThirdPartyServer and isEventAllowed are > > > removed, and isEventAllowedForTenant replaces them. > > > - Parameter.getDefaultValue() now returns Object, and setDefaultValue > > > now > > > takes an Object, which breaks binary compatibility. > > > - DefinitionsService.extractConditionsByType now returns a List instead > > > of a Set. > > > - The empty unomi-plugins-past-event artifact is removed. > > > PastEventConditionEvaluator and SourceEventPropertyConditionEvaluator > > > moved > > > from unomi-plugins-baseplugin to the new > > > unomi-plugins-advanced-conditions, > > > in the package org.apache.unomi.plugins.advancedconditions.conditions. > > > HoverEventConditionESQueryBuilder is removed. > > > - 18 shell commands are removed in favour of unomi:crud, among them > > > profile-list, rule-list and segment-view. shell-commands.adoc:99-189 still > > > lists them, and tutorial.adoc:226 and 274 still use them. > > > - Document ids now start with the tenant id: <tenantId>_<itemId>, or > > > <tenantId>_<itemId>_<itemType> for the system items. This change affects > > > any script or dashboard that reads _id. > > > - UNOMI_GRAPHQL_FEATURE_ACTIVATED is removed, and only the graphql > > > distributions or the cdp-graphql-feature enable GraphQL. In the health > > > check, org.apache.unomi.healthcheck.cfg becomes > > > org.apache.unomi.healthcheck-elasticsearch.cfg, and > > > httpClient.trustAllCertificates becomes esHttpClient.trustAllCertificates. > > > configuration.adoc still names the old file. POST /cxs/profiles with no > > > itemId now answers 400. > > > - condition-validation.adoc:187 says that the REST client receives the > > > validation message. The client receives {"errorMessage":"badRequest"}. > > > > > > MINOR, NOT BLOCKING > > > > > > The staging repository holds unomi-4.0.0-buildcache.jar. Unomi 3.0.1 did > > > not publish this artifact. > > > > > > Regards, > > > Jonathan > > > > > > On Sun, Oct 4, 2026 at 4:19 PM Mohamed-Tayeb BENTERKI <[email protected]> > > > wrote: > > > > > > > +1 🚀 > > > > > > > > On Sun, 4 Oct 2026 at 14:18, Serge Huber <[email protected]> wrote: > > > > > > > > > Hi all, > > > > > > > > > > I (finally !) submit Apache Unomi 4.0.0 to your vote. > > > > > > > > > > This release has been a long time coming. The work began as the "Unomi > > > > > Version 3" plan (UNOMI-875, February 2025), with implementation from > > > > March > > > > > 2025 — months before Unomi 3.0.0 was cut in November 2025. By > > > > > September > > > > > 2025 the tree was already versioned 3.1.0-SNAPSHOT; 3.0.0 (and later > > > > > 3.0.1 in July 2026) was a first slice, while this line continued in > > > > > parallel. As the scope grew — multi-tenancy, a second persistence > > > > backend, > > > > > a large platform refresh, and a much stronger REST and operations > > > > > story — > > > > > we renamed it 4.0.0 so the version number matches the size of the > > > > > change. > > > > > This candidate is the result. > > > > > > > > > > A short view of what 4.0 brings: > > > > > > > > > > Features > > > > > - Multi-tenancy, with a compatibility mode for single-tenant setups > > > > > - OpenSearch as a persistence option alongside Elasticsearch > > > > > - Cluster-aware scheduling, unified tenant caching, and a unified > > > > > shell > > > > > CRUD > > > > > - Tenant usage through the REST API, plus event retention purge > > > > > - Request tracing, and a rangeQuery API on persistence > > > > > - REST V2 compatibility mode, better input validation, and clearer > > > > > error > > > > > responses > > > > > - Migration scripts from 3.x, including resume-safe 3.1/4.0 migration > > > > > > > > > > Platform and libraries > > > > > - Newer Karaf, Elasticsearch, OpenSearch, and Log4j > > > > > - Further third-party updates (UNOMI-990 and related) > > > > > - Stricter startup (explicit admin and health-check passwords) and > > > > tighter > > > > > control of privileged REST, Groovy actions, and import/export > > > > > - Build cache, BOM coverage for advanced conditions, and a published > > > > > distribution again > > > > > > > > > > Fixes > > > > > - Condition validation and matching (optional parameters, unresolved > > > > > types, segment/scoring save) > > > > > - Context/profile binding, CSV import, persona sessions, health-check > > > > > concurrency > > > > > - Scheduler locks and recovery in a cluster > > > > > - Tracker WAB, visit/session counts, logging, and several CI/IT flakes > > > > > > > > > > Documentation and developer experience > > > > > - Manual refresh with diagrams, Javadoc, and OpenAPI filled from > > > > > Javadoc > > > > > - Pluggable persistence ITs, better IT progress/tooling, improved > > > > build.sh, > > > > > and contributor guidelines > > > > > > > > > > Tests grew a lot compared with 3.0.1. Annotated test methods went from > > > > > about > > > > > 280 to about 2,130. Most of that is new unit tests: roughly 90 unit > > > > > tests > > > > > in > > > > > 15 classes became about 1,640 in 120 classes, while integration tests > > > > rose > > > > > from about 190 to about 490. The bulk of the unit work uses a new > > > > in-memory > > > > > persistence manager (UNOMI-881), so core services can be tested > > > > > without > > > > > Elasticsearch or OpenSearch. That harness also has its own suite > > > > > (about > > > > 200 > > > > > tests on the in-memory store), and more than a dozen service tests > > > > > (profiles, > > > > > events, rules, segments, scheduler, conditions, and others) now run on > > > > it. > > > > > > > > > > Full JIRA notes (about 79 issues): > > > > > > > > > > > > > > https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12319220&version=12356384 > > > > > > > > > > Staging repository: > > > > > https://repository.apache.org/content/repositories/orgapacheunomi-1054/ > > > > > > > > > > Source: > > > > > > > > > > > > > > https://repository.apache.org/content/repositories/orgapacheunomi-1054/org/apache/unomi/unomi-root/4.0.0/unomi-root-4.0.0-source-release.zip > > > > > > > > > > Convenience binaries: > > > > > > > > > > > > > > https://repository.apache.org/content/repositories/orgapacheunomi-1054/org/apache/unomi/unomi/4.0.0/ > > > > > > > > > > Git tag: > > > > > unomi-root-4.0.0 > > > > > > > > > > Dist: > > > > > https://dist.apache.org/repos/dist/dev/unomi/4.0.0/ > > > > > > > > > > Please vote to approve this release: > > > > > > > > > > [ ] +1 Approve the release > > > > > [ ] -1 Don't approve the release (please provide specific comments) > > > > > > > > > > This vote will be open for at least 72 hours, or until the necessary > > > > > number of binding votes (3 +1) is reached. > > > > > > > > > > Please let me know if you have any questions. > > > > > > > > > > Thanks, > > > > > Serge > > > > > > > > > > > > > > > > > > -- > > > [image: Dev] > > > > > > > > > *Jonathan SINOVASSIN NAIK*FULLSTACK DEVELOPPER > > > [image: linkedin] > > > <https://app.signitic.com/l/ACdRwwAAABAAAAAABhZkJQ.t7MdoRPQji8> [image: > > > web] > > > <https://app.signitic.com/l/ACdRwwAAABYAAAAABhZkJQ.8yvongia6Lk> [image: > > > github] > > > <https://app.signitic.com/l/ZGhoWnNIeVJXV051NzBOYmZMMTFaUT09-NlpUZ01IaXcvRTNYWnk5bEtRWEZCdz09> > > > > > > [image: Bannière Jahia avec badges G2 - Leader - Best Relationship - Best > > > Results - Best Usability] > > > <https://app.signitic.com/l/ACdRwwAAABUAAo7LBhZkJQ.r8W_TAY9ofY>
