OSGi extra-packages: return 409 on skipped manual write + handle it in the UI (follow-up to #36434)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Follow-up to #36434 / PR #36503.
Background
PR #36503 (High #2 fix) wrapped the manual PUT /api/v1/osgi/extra-packages writer (OSGIUtil.writeOsgiExtras, incl. RESET) in the cluster-wide OSGI_RESTART_LOCK_KEY shedlock, so it can no longer race the upload pipeline's read-merge-write of osgi-extra.conf.
The backend review noted (and it's correct) that ClusterLockManagerImpl.tryLock (ShedLock's executeWithLock) is a try-lock: if the lock is already held (e.g. an upload merge is in progress on any node), the callback is silently skipped — no exception. As a result, when a manual edit races an in-progress upload merge:
- the manual write/delete is skipped,
- no exception propagates,
OSGIResource.modifyExtraPackagesstill returns200 "OSGI Extra Packages Saved"— an optimistic success for a change that was not actually persisted.
This is a narrow, non-blocking window (the shared file itself never diverges; only this specific admin action can be silently superseded), so it was intentionally left out of #36503. This issue tracks closing it properly.
Why it needs both backend and frontend changes
Returning a 409 Conflict from the backend is the natural fix, but the UI would swallow it silently as-is:
DotHttpErrorManagerService(core-web/libs/data-access/src/lib/dot-http-error-manager/dot-http-error-manager.service.ts) only mapsNOT_FOUND,UNAUTHORIZED,FORBIDDEN,SERVER_ERROR,BAD_REQUEST,NO_CONTENT. There is noCONFLICT/409 handler, socallErrorHandler(409)returnsfalseand shows no toast.dot-plugins-extra-packages.component.tssave()/#doReset()only callhttpErrorManager.handle(error)incatchErrorwith no fallback message, so a 409 leaves the dialog open with zero user feedback — worse UX than the current optimistic 200.
So this must ship as a paired backend + frontend change.
Proposed work
Backend (dotCMS)
ClusterLockManager/writeOsgiExtras: surface whether the locked callback actually executed (ShedLockLockAssert/ awasExecutedboolean from the task result) instead of returning silently.OSGIResource.modifyExtraPackages: when the write was skipped because the lock was held, return409 Conflictwith a clear message (e.g. "An OSGi deployment is in progress; please retry.") instead of200. Update the@Operation/@ApiResponsedocs + regenerateopenapi.yaml.
Frontend (core-web)
- Add a
CONFLICT(409) handler toDotHttpErrorManagerService(or handle 409 explicitly in the extra-packages component) that shows a retriable-conflict message, so the admin sees "deployment in progress, retry" rather than nothing. - i18n key for the message.
- Jest coverage: 409 path shows the message and keeps the dialog open (does not close as success).
Acceptance criteria
- A manual extra-packages save/RESET that loses the lock returns
409and the UI shows a clear, retriable message; the dialog stays open and is not reported as saved. - A successful save still returns
200and closes the dialog as today.
Affected versions
- Current Evergreen 26.06.30-01.
Notes
- Non-blocking for #36503 — that PR's lock fix is correct; this only replaces the optimistic
200on the (now-serialized) contention path with an honest409+ matching UI feedback.
Refs: #36434, #36503
External Links
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ClusterLockManager, OSGIUtil.writeOsgiExtras, and OSGIResource.modifyExtraPackages to trace how a skipped lock callback is reported and how the response is documented. Then inspect core-web/libs/data-access/src/lib/dot-http-error-manager/dot-http-error-manager.service.ts and dot-plugins-extra-packages.component.ts, along with the related Jest tests. Done means lock contention returns 409 with updated OpenAPI documentation, the UI shows a retriable message and keeps the dialog open, and successful saves still return 200 and close it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, typescript
- Domain
- api, backend, documentation, frontend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100