Skip to content

fix: Index no page of a site users don't navigate, and create each init plugin's metadata on its own EXO-91183 - #6263

Merged
boubaker merged 1 commit into
developfrom
backport/EXO-91183-page-content-indexing
Oct 27, 2026
Merged

boubaker merged 1 commit into
developfrom
backport/EXO-91183-page-content-indexing

Conversation

@boubaker

Copy link
Copy Markdown
Member

Symptom:

  • Search showed the content blocks of the pages of a space template, and of other sites users don't navigate (portal templates, user sites), to every user the page grants access to, with a link that leads nowhere. They were indexed on a full reindex, on every save of such a page through Layout, and on a space template's "Restore default pages", which refreshes the index of every page of the template with fix: Refuse to hand on the layout of a site that couldn't be read, and a site restore refreshes its pages' search index EXO-91183 layout#581.
  • With fix: Restoring the built-in sites can leave the main sites with empty pages EXO-91183 portal#1338, a method whose transaction was marked rollback-only fails instead of returning. A metadata init plugin whose metadata can't be stored at startup would then fail the start of MetadataServiceImpl, and with it the portal container start. Before, the outcome depended on the database. On MySQL/MariaDB (identity ids, the INSERT runs at persist), the start logged a WARN, and the metadata of every plugin of that start were silently rolled back. On the databases whose ids come from a sequence, the INSERT waits for the flush: it failed at the commit of the start's transaction, failing the container start with no WARN, or, when a later plugin's lookup flushed it first, the start logged a WARN under that later plugin's metadata (its lookup threw the flush failure as IllegalStateException: Error retrieving value with key …), and the whole start was silently rolled back.

Cause:

  • PageContentIndexingConnector builds no bare page document for a page of a site users don't navigate (isIndexableSite: portal and group sites), but built its content block documents, and listed them for a full reindex. PageContentBlockIndexingListener reindexed them on layout.page.updated.
  • MetadataServiceImpl#start created the metadata of every plugin in one @ExoTransactional transaction, and caught each plugin's failure to go on.

Fix:

  • PageContentIndexingConnector builds no document, block or bare, for a page of a site users don't navigate, and a full reindex doesn't list the content blocks of such a page.
  • When such a page is updated through Layout (layout.page.updated, layout.page.permissions.updated), PageContentBlockIndexingListener removes every document the index holds for it, so the blocks indexed before leave search.
  • MetadataServiceImpl#start creates each plugin's metadata in a transaction of its own: a plugin that fails is logged (WARN), and the metadata of the others are created.
  • Pinned by PageContentIndexingConnectorTest (a block of a template page builds no document; a full reindex lists none), PageContentBlockIndexingListenerTest (a template page update unindexes its documents and reindexes none) and MetadataServiceTest#testStartCreatesTheMetadataOfTheOtherPluginsWhenOneFails (a real container: a metadata whose name is longer than its column, then a valid one). Each pin was mutation-verified on the committed tree.

Upgrade impact:

  • The content blocks of the pages of space templates, portal templates and user sites (dashboards) leave search: on the next full reindex, or when such a page is next updated through Layout. The bare page documents of those sites were already not indexed.
  • At startup, the metadata of the init plugins are created one plugin at a time: a plugin that fails is logged under its own name, no longer rolls back the metadata of the others, and, on the databases whose ids come from a sequence, no longer fails the container start.

Known limits:

  • A page of such a site saved outside Layout (a configuration re-import, for instance) builds no document, and the indexing framework skips a missing document instead of removing it: the blocks indexed before stay until the next full reindex, or the next update of the page through Layout.

Release order: merge it before, or with, Meeds-io/portal#1338 and Meeds-io/layout#581. The metadata fix is needed by Meeds-io/portal#1338, which would otherwise turn a failing metadata init plugin into a failed start. The search fix is needed by Meeds-io/layout#581, whose space template restore would otherwise index the template's content blocks.

Tests: mvn -B -ntp -o clean verify javadoc:javadoc -Pcoverage -pl component/core at c2106c8844: BUILD SUCCESS, 1357 tests, 0 failures, 0 errors (MetadataServiceTest 32, PageContentIndexingConnectorTest 33, PageContentBlockIndexingListenerTest 11), against the local 7.3.x-maintenance-SNAPSHOT of Meeds-io/portal#1338, which carries its RollbackException.

Knowledge: Meeds-io/eng-standards#409, #560, #586, #587

This change is classified N1 (proposed, recall-first) — the JPA transaction boundary over the kernel DAO writes of a component's start, whose failure fails the portal container start with Meeds-io/portal#1338, and which permission-bearing page documents search exposes. Its approver must be an Archi/Dev who knows it is N1, not an approval on AI review alone; author ≠ approver.

🤖 Generated with Claude Code

…it plugin's metadata on its own EXO-91183 (#6245)

**Symptom**:
- Search showed the content blocks of the pages of a space template, and
of other sites users don't navigate (portal templates, user sites), to
every user the page grants access to, with a link that leads nowhere.
They were indexed on a full reindex, on every save of such a page
through Layout, and on a space template's "Restore default pages", which
refreshes the index of every page of the template with
Meeds-io/layout#581.
- With Meeds-io/portal#1338, a method whose transaction was marked
rollback-only fails instead of returning. A metadata init plugin whose
metadata can't be stored at startup would then fail the start of
`MetadataServiceImpl`, and with it the portal container start. Before,
the outcome depended on the database. On MySQL/MariaDB (identity ids,
the INSERT runs at persist), the start logged a WARN, and the metadata
of every plugin of that start were silently rolled back. On the
databases whose ids come from a sequence, the INSERT waits for the
flush: it failed at the commit of the start's transaction, failing the
container start with no WARN, or, when a later plugin's lookup flushed
it first, the start logged a WARN under that later plugin's metadata
(its lookup threw the flush failure as `IllegalStateException: Error
retrieving value with key …`), and the whole start was silently rolled
back.

**Cause**:
- `PageContentIndexingConnector` builds no bare page document for a page
of a site users don't navigate (`isIndexableSite`: portal and group
sites), but built its content block documents, and listed them for a
full reindex. `PageContentBlockIndexingListener` reindexed them on
`layout.page.updated`.
- `MetadataServiceImpl#start` created the metadata of every plugin in
one `@ExoTransactional` transaction, and caught each plugin's failure to
go on.

**Fix**:
- `PageContentIndexingConnector` builds no document, block or bare, for
a page of a site users don't navigate, and a full reindex doesn't list
the content blocks of such a page.
- When such a page is updated through Layout (`layout.page.updated`,
`layout.page.permissions.updated`), `PageContentBlockIndexingListener`
removes every document the index holds for it, so the blocks indexed
before leave search.
- `MetadataServiceImpl#start` creates each plugin's metadata in a
transaction of its own: a plugin that fails is logged (WARN), and the
metadata of the others are created.
- Pinned by `PageContentIndexingConnectorTest` (a block of a template
page builds no document; a full reindex lists none),
`PageContentBlockIndexingListenerTest` (a template page update unindexes
its documents and reindexes none) and
`MetadataServiceTest#testStartCreatesTheMetadataOfTheOtherPluginsWhenOneFails`
(a real container: a metadata whose name is longer than its column, then
a valid one). Each pin was mutation-verified on the committed tree.

**Upgrade impact**:
- The content blocks of the pages of space templates, portal templates
and user sites (dashboards) leave search: on the next full reindex, or
when such a page is next updated through Layout. The bare page documents
of those sites were already not indexed.
- At startup, the metadata of the init plugins are created one plugin at
a time: a plugin that fails is logged under its own name, no longer
rolls back the metadata of the others, and, on the databases whose ids
come from a sequence, no longer fails the container start.

**Known limits**:
- A page of such a site saved outside Layout (a configuration re-import,
for instance) builds no document, and the indexing framework skips a
missing document instead of removing it: the blocks indexed before stay
until the next full reindex, or the next update of the page through
Layout.

**Release order**: merge it before, or with, Meeds-io/portal#1338 and
Meeds-io/layout#581. The metadata fix is needed by Meeds-io/portal#1338,
which would otherwise turn a failing metadata init plugin into a failed
start. The search fix is needed by Meeds-io/layout#581, whose space
template restore would otherwise index the template's content blocks.

**Tests**: `mvn -B -ntp -o clean verify javadoc:javadoc -Pcoverage -pl
component/core` at `c2106c8844`: BUILD SUCCESS, 1357 tests, 0 failures,
0 errors (`MetadataServiceTest` 32, `PageContentIndexingConnectorTest`
33, `PageContentBlockIndexingListenerTest` 11), against the local
`7.3.x-maintenance-SNAPSHOT` of Meeds-io/portal#1338, which carries its
`RollbackException`.

Knowledge: Meeds-io/eng-standards#409, #560, #586, #587

This change is classified N1 (proposed, recall-first) — the JPA
transaction boundary over the kernel DAO writes of a component's start,
whose failure fails the portal container start with
Meeds-io/portal#1338, and which permission-bearing page documents search
exposes. Its approver must be an Archi/Dev who knows it is N1, not an
approval on AI review alone; author ≠ approver.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c45fb98)
@boubaker

Copy link
Copy Markdown
Member Author

Backport evidence

Source: #6245, squash-merged into feature/maintenance. Its change is on origin/feature/maintenance at c45fb9813e (matched against the branch's current head, 2026-10-27). The PO validated it on the maintenance acceptance server on 2026-10-27.

Picks: 55c4c51fd3 = git cherry-pick -x c45fb9813e, on origin/develop (74bc409736).

Adaptations: none. The pick applied cleanly, and no commit was added.

Verification

  • git show -U0 <pick> | git patch-id --stable gives the same result on 55c4c51fd3 and on c45fb9813e: 3059dd750779.
  • gh pr diff 6245 | git patch-id --stable equals git show 55c4c51fd3 | git patch-id --stable: 1b17d6159833.
  • The source's approval is on its head: APPROVED by ahamdi at c2106c8844, which is the source PR's head.
  • mvn -B -ntp -Dcheckstyle.skip=true -pl component/core -am verify at 55c4c51fd3: Tests run: 1357, Failures: 0, Errors: 0, Skipped: 0, BUILD SUCCESS.
  • Merge order: after the Meeds-io/portal EXO-91183 backport (Task-54742: Dispatch post-activity event when the activity type is not simple, file or link activity #1357), as the source required portal#1338 first.
  • Open-PR overlap: git merge-tree is clean against every open PR to develop, except Fix swagger configuration #5091, which already conflicts with develop on its own.

Level: N1, restated from the source. A backport from feature/maintenance whose every pick's patch-id equals its source's diff merges on its first approval (ai-review-and-merge.md §3). It lands by squash, with the source's body as its message.

@boubaker
boubaker requested review from Jihed525 and ahamdi October 27, 2026 12:31
@sonarqubecloud

Copy link
Copy Markdown

@boubaker
boubaker merged commit dc8e269 into develop Oct 27, 2026
15 checks passed
@boubaker
boubaker deleted the backport/EXO-91183-page-content-indexing branch October 27, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants