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 (+ invalidParams for validation errors). detail is 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 ErrorInfo on 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's 502. Anything that passes is still relayed byte-for-byte.

Relay behaviour

  • The resolved X-Correlator is 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: availZoneNotifLink is optional. v1.4.0 only requires acceptedAvailabilityZones, and FM fills in its own notification link.
  • partnerOpId must be a UUID. FM assigns partner ids as UUIDs and its /internal routes accept nothing else, so a slug used to pass OEG and then fail at FM as a confusing 502; it's now an immediate 400 naming partnerOpId.

Chore

  • uv.lock relocked for the sqlalchemy[asyncio] dependency change (pulls in greenlet).

Testing

  • tests/unit/test_federation_manager_endpoints.py extended: ProblemDetails shape for every OEG error case, framework-level errors on federation paths, the FM-contract 502 gate, X-Correlator forwarding, ZoneSubscribe without availZoneNotifLink, and non-UUID partnerOpId.
  • Full unit suite: 652 passed, 1 skipped. ruff and mypy clean.

Not in this MR

  • operator role check on these routes: waits for feat/keycloak to land in develop.

Merge request reports

Loading
Loading