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 21

on 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>

Reply via email to