Loading
Follow-up fixes to the federation-lifecycle proxy
What
Follow-up fixes to the federation-lifecycle proxy (/platform/v1/federation/partners/{partnerOpId}/federations/...)
merged in refactor/fm, so OEG matches the spec (oeg/interface-contract.md §K.6a, §N.7; ADR-0050, ADR-0051)
and FM's actual /internal routes.
Changes
Errors are always GSMA ProblemDetails on this surface (§K.6a)
- OEG-authored errors now carry
type,title,status,detail,cause(+invalidParamsfor validation errors).detailis a fixed sentence per case; no exception text or upstream diagnostics. - Errors raised outside the route handler (bad path/query/header params, 404, 405, unhandled 500) no
longer fall back to CAMARA
ErrorInfoon federation paths. - FM's response is checked against its contract before relaying: an undeclared status, an error
without
application/problem+json, or a success body that doesn't match the operation's schema becomes OEG's502. Anything that passes is still relayed byte-for-byte.
Relay behaviour
- The resolved
X-Correlatoris always forwarded to FM, including the one OEG generates when the caller sends none, so FM's logs and the caller's response share one id. - Request bodies no longer reject unknown fields; they are gated for shape and forwarded as the original raw bytes.
Schema fixes against OPG.04 v1.4.0 and FM
ZoneSubscribe:availZoneNotifLinkis optional. v1.4.0 only requiresacceptedAvailabilityZones, and FM fills in its own notification link.partnerOpIdmust be a UUID. FM assigns partner ids as UUIDs and its/internalroutes accept nothing else, so a slug used to pass OEG and then fail at FM as a confusing502; it's now an immediate400namingpartnerOpId.
Chore
uv.lockrelocked for thesqlalchemy[asyncio]dependency change (pulls ingreenlet).
Testing
tests/unit/test_federation_manager_endpoints.pyextended: ProblemDetails shape for every OEG error case, framework-level errors on federation paths, the FM-contract502gate,X-Correlatorforwarding,ZoneSubscribewithoutavailZoneNotifLink, and non-UUIDpartnerOpId.- Full unit suite: 652 passed, 1 skipped. ruff and mypy clean.
Not in this MR
operatorrole check on these routes: waits forfeat/keycloakto land indevelop.