fix(index): clean up indicies DB rows on all physical delete paths#35342
fix(index): clean up indicies DB rows on all physical delete paths#35342fabrizzio-dotCMS wants to merge 2 commits intomainfrom
Conversation
|
Claude finished @fabrizzio-dotCMS's task in 2m 23s —— View job PR Review
Three issues worth addressing: 1. Test assertion passes vacuously — the actual bug path is not exercised
The bug path described in the PR — create → activate → delete without deactivating — is not tested. A correct test would:
Additionally, the assertion only checks bare names ( 2. Silent DB failure returns
|
…35306 ContentletIndexAPIImpl.delete() physically removed the index from the search provider but never deleted the corresponding row from the indicies table, leaving stale DB entries that could cause startup failures or silent inconsistencies on the next boot. After a successful physical delete, versionedIndicesAPI.removeByIndexName() is now called to clean up both the bare and os:: forms of the row. The cleanup is phase-safe: - Physical delete: indexAPI (IndexAPIImpl router) fans out to ES, OS, or both depending on the active migration phase. - DB cleanup: versionedIndicesAPI.removeByIndexName() deletes by index_name and handles both legacy (index_version IS NULL) and versioned (os:: tagged) rows in a single call. The deprecated legacyIndiciesAPI is not involved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
18ef102 to
dbeef92
Compare
Summary
Fixes #35306 —
ContentletIndexAPIImpl.delete()physically removed the index from the search provider but never deleted the corresponding row from theindiciestable.After a successful physical delete, a stale DB entry would remain pointing to a non-existent index, which could cause startup failures or silent inconsistencies on the next boot.
Root cause
The bug only occurs when
delete()is called on an active index without a priordeactivateIndex()call (e.g., direct REST call toDELETE /api/v1/esindex/{name}). In the normal UI workflow,deactivateIndex()clears the DB row viapoint()beforedelete()is called, so no orphan is left.Fix
After a successful physical delete,
versionedIndicesAPI.removeByIndexName()is called to clean up theindiciesrow.Phase safety:
indexAPIresolves toIndexAPIImpl(the phase-aware router) — fans out to ES, OS, or both depending on the active migration phase.versionedIndicesAPI.removeByIndexName()issuesDELETE FROM indicies WHERE index_name = ? OR index_name = ?(bare +os::tagged forms), covering both legacy non-versioned rows (ES, phases 0/1/2) and versioned OS rows (phase 3) in a single call. The deprecatedlegacyIndiciesAPIis not involved.Test plan
DELETE /api/v1/esindex/{name}on an active index → row removed fromindiciestableDELETE /api/v1/esindex/{name}on an already-deactivated index → no error (row already gone,removeByIndexNameis a no-op)🤖 Generated with Claude Code