Commit 86acb110 authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

docs: Update correlation ID handling across OEG and SRM specifications to use...

docs: Update correlation ID handling across OEG and SRM specifications to use x-correlator and enhance clarity on error response models
parent 90f0ec77
Loading
Loading
Loading
Loading
+4 −4
Changes for oeg/architecture.md: 4 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -85,9 +85,9 @@ Detailed delivery planning belongs outside this specification. This document def
| **Rate limiting and usage metering** | Per-subscription rate limits enforced by OEG runtime controls. API usage records in PostgreSQL for billing/analytics. |
| **Catalog read-through** | Proxy SRM catalog reads for a consistent NBI surface. Invalidate cache on `event.srm.catalog.updated` events. |
| **Callback delivery** | POST CloudEvent callbacks (`application/cloudevents+json`) to registered sinks on terminal operation state; authenticate with `Authorization: Bearer` using the request's `sinkCredential` (ADR-0008). Retry through an implementation-specific background mechanism. |
| **CAMARA `ErrorInfo` error model** | All outward errors as CAMARA's `ErrorInfo` (`status`/`code`/`message`) with `X-Correlator` header per CAMARA Commonalities r4.3 — not RFC 7807 `application/problem+json`, which the vendored spec never defines. `X-Correlator` on error responses carries the same value as the request's `X-Request-ID`/`correlation_id` — they are the same correlation value, exposed under different names on the external (`X-Correlator`) vs. internal (`X-Request-ID`/`correlation_id`) surfaces. |
| **CAMARA `ErrorInfo` error model** | All outward errors as CAMARA's `ErrorInfo` (`status`/`code`/`message`) with `X-Correlator` header per CAMARA Commonalities r4.3 — not RFC 7807 `application/problem+json`, which the vendored spec never defines. `X-Correlator` on error responses carries the same value as the inbound request's `x-correlator` and as `correlation_id` in internal bodies — one correlation value, generated at the edge when the client sends none, under the same header name inward and outward. |
| **Idempotency** | `Idempotency-Key` header (e.g. client retries) prevents duplicate PENDING rows and duplicate `command.srm.*` publishes. |
| **Correlation ID propagation** | `X-Request-ID` / `correlation_id` attached to every `command.srm.*` envelope and internal HTTP call; same value as the external `X-Correlator`. |
| **Correlation ID propagation** | `correlation_id` attached to every `command.srm.*` envelope, and the `x-correlator` header to every internal HTTP call; same value as the external `X-Correlator`. |

### A.2 Non-Functional Targets

@@ -208,7 +208,7 @@ This section is the boundary contract for OEG. If a responsibility seems ambiguo
- **Synchronous query/data proxy**: forward stateless CAMARA requests to SRM internal HTTP, log usage, return response.
- **Usage metering**: structured logging + `api_usage_records` (PostgreSQL) + runtime rate-limiting counters.
- **CAMARA `ErrorInfo`** error responses for all outward APIs (not RFC 7807).
- **Correlation ID** propagation (`X-Request-ID` / `correlation_id` in `command.srm.*` envelopes).
- **Correlation ID** propagation (`correlation_id` in `command.srm.*` envelopes, `x-correlator` header on internal HTTP).
- **Callback delivery**: CloudEvent status-change notifications to registered sinks (`application/cloudevents+json`, `sinkCredential` bearer auth per ADR-0008), with retry.
- **API Product Catalog ownership**: what APIs are published to consumers, their versions, rate limit policies, subscription tiers.
- **Database ownership**: PostgreSQL `oeg_db` is OEG-owned; other services do not read or write it directly.
@@ -281,7 +281,7 @@ These questions are not resolved by the current architecture text. Keep them vis
| REQ-OEG-10 | The system shall emit structured JSON logs (via `oop-commons`) including `correlation_id`, `operation_id`, `app_provider_id`, HTTP method/path, and outcome. | Platform baseline |
| REQ-OEG-11 | The system shall record API usage for billing/analytics in `api_usage_records` with timestamp, API family, HTTP status, and bytes estimate. | OPG.02 v10.0 |
| REQ-OEG-12 | The system shall proxy or aggregate read-only catalog calls to SRM and shall invalidate cache on `event.srm.catalog.updated` DataBus events. | TMF633 v4 |
| REQ-OEG-13 | The system shall attach `correlation_id` to every `command.srm.*` envelope and propagate `X-Request-ID` to downstream HTTP calls to SRM. | CAMARA Commonalities r4.3 |
| REQ-OEG-13 | The system shall attach `correlation_id` to every `command.srm.*` envelope and propagate the `x-correlator` header to downstream HTTP calls to SRM. | CAMARA Commonalities r4.3 |
| REQ-OEG-14 | The system shall expose GET `/healthz` and GET `/readyz` via `oop-commons` health router (PostgreSQL + DataBus checks for readiness). | Platform baseline |
| REQ-OEG-15 | For requests subject to privacy / consent, the system shall forward privacy-relevant headers and identifiers required by product policy to SRM without storing unnecessary PII in logs. | OPG.02 v10.0 |
| REQ-OEG-16 | The system shall persist enough context in `api_usage_records` and operation metadata to support IEC/PEC models downstream (Phase 1: record app id, API product id, timestamp; real-time CHF — 3GPP convergent charging function, see [platform/future-architecture.md](/platform/future-architecture.md) — in Phase 2). IEC/PEC are not otherwise defined in this repo; confirm exact meaning with the charging domain owner before implementation. | OPG.02 v10.0 |
+25 −6
Changes for oeg/interface-contract.md: 25 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -145,8 +145,11 @@ This is the simplest read path: OEG answers from its own operation record when t
| POST | `http://srm:8081/internal/network-queries/location` | Sync CAMARA Device Location query |
| POST | `http://srm:8081/internal/network-queries/device-status` | Sync CAMARA Device Status query |

Every internal HTTP call propagates `X-Request-ID` (the internal analogue of the external
`X-Correlator`/`x-correlator`) — see the worked examples in §N.3/N.4.
Every internal HTTP call carries the correlation value in an **`x-correlator`** request header,
and in the body as `correlation_id` on calls that have one. When the client sends no
`x-correlator`, OEG generates one at the edge; that one value is used for the internal header,
the body's `correlation_id`, and the `X-Correlator` response header — see
[oeg/architecture.md](/oeg/architecture.md) REQ-OEG-13 and the worked examples in §N.3/N.4.

Number Verification is **not** part of the synchronous query contract — it must be modelled separately before exposure (see [srm/interface-contract.md](/srm/interface-contract.md) §E.2).

@@ -205,6 +208,21 @@ All outward errors use CAMARA's `ErrorInfo` shape (`status`, `code`, `message`)

Response header: `X-Correlator: req-abc-123`

**Sync query status mapping.** For the query families in
[srm/interface-contract.md](/srm/interface-contract.md) §E.2:

| SRM answer | Outward |
|---|---|
| `404` | `404` / `IDENTIFIER_NOT_FOUND` |
| `422` with a problem `type` listed in §E.2 | `422` / that row's CAMARA code |
| `422` with any other `type` | `422` / `SERVICE_NOT_APPLICABLE` |
| `422` whose body is not a problem document | `503` / `UNAVAILABLE` |
| `200` whose body does not satisfy the CAMARA response schema | `503` / `UNAVAILABLE` |

The last two are downstream faults, not caller faults, and are never reported as `5xx`
`INTERNAL` — same rule as the whole-read failure for `GET /apps` and `GET /edge-cloud-zones`
in §K.7.

### K.7 Common misunderstandings

- `operationId` identifies the OEG-side async request and is **internal** — not a CAMARA EAM field. CAMARA correlates via `X-Correlator`, the `Location` header, and the resource ids (`appInstanceId`, `appDeploymentId`). It is not the same as a deployed instance id.
@@ -397,7 +415,7 @@ Authorization: Bearer <JWT>

```http
GET http://srm:8081/internal/catalog/service-specifications
X-Request-ID: req-cat-001
x-correlator: req-cat-001
```

**Later invalidation**
@@ -428,7 +446,7 @@ Content-Type: application/json

```http
POST http://srm:8081/internal/network-queries/location
X-Request-ID: req-loc-001
x-correlator: req-loc-001
Content-Type: application/json
```

@@ -464,8 +482,9 @@ Content-Type: application/json
```

The `device` echo names the **one** identifier that produced this answer, as CAMARA requires
when the caller supplied any. It is copied from `srm_resolved_identifier` when SRM reports
one; otherwise OEG falls back to a fixed precedence order and the echo is a best guess.
when the caller supplied any. It is copied from `srm_resolved_identifier` when SRM reports one.
Otherwise OEG echoes the first identifier the request supplied in the order `ipv4`,
`phone_number`, `ipv6`, `network_access_id`.

**Key lesson**  
Some API families are query-like enough that the sync path is the right fit. They still go through OEG so auth, policy, and metering stay consistent. The synchronous contract covers Device Location and Device Status only; Number Verification is not yet contracted (see [srm/interface-contract.md](/srm/interface-contract.md) §E.2).
+3 −3
Changes for platform/architecture.md: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ An app developer wants to retrieve a device's current location. This is a real-t
1. **OEG:** Validates JWT, checks rate limits.
2. **OEG → SRM:** Calls `POST /internal/network-queries/location` with normalized body (device identity, max_age, max_surface).
3. **SRM:** Validates request. Resolves network domain and adapter.
4. **SRM → TF-SDK:** Calls `query_capability(request)` with `capability_kind="device_location"`.
4. **SRM → TF-SDK:** Calls `query_capability(request)` with `capability_kind="location_context"`.
5. **TF-SDK:** Validates payload. Resolves device identity (vendor-specific: IPv4 → ExternalId for OAI, MSISDN for Open5GS). Builds 3GPP MonitoringEventSubscriptionRequest. Calls NEF.
6. **NEF → TF-SDK:** Returns location data (polygon, point with uncertainty, or cell-level).
7. **TF-SDK → SRM → OEG → App Provider:** Location data flows back synchronously.
@@ -691,7 +691,7 @@ These decisions are **binding** — they have been made and should not be reopen
- **Capability gating:** If an adapter doesn't support a requested `capability_kind`/action, it fails fast with a typed error — not deep inside vendor-specific code.
- **Internal adapter organization is not prescribed by the contract:** how a given adapter shares code across vendors internally (e.g. common HTTP client, auth, circuit breaker) is an implementation detail behind `CapabilityExecutionAdapter`, not part of the SRM-facing interface.

**How adapters work (network):** SRM calls `activate_capability(request)` with `capability_kind="qod_session"` (or `"traffic_influence"`, `"device_location"`, …) and a `control_path_ref` already resolved by placement. The OAI/Open5GS/Open5GCore/i2cat adapter behind that `control_path_ref` translates the normalized request into the vendor-specific 3GPP NEF/RIC call.
**How adapters work (network):** SRM calls `activate_capability(request)` with `capability_kind="qod_session"` (or `"traffic_influence"`, …) and a `control_path_ref` already resolved by placement. The OAI/Open5GS/Open5GCore/i2cat adapter behind that `control_path_ref` translates the normalized request into the vendor-specific 3GPP NEF/RIC call.

**How adapters work (compute):** SRM calls `activate_capability` / `update_capability` / `deactivate_capability` with `capability_kind="deploy_workload"` / `"scale_workload"` / `"terminate_workload"`. The Kubernetes/i2Edge/aerOS adapter behind the resolved `control_path_ref` translates the normalized `DeploymentUnit` into the vendor-specific deploy/scale/terminate call.

@@ -840,7 +840,7 @@ All components use `oop-commons` structured JSON logging. Every log entry includ
### Correlation ID Flow

```text
App Provider sets X-Request-ID → OEG propagates as correlation_id in command.srm.* envelope
App Provider sets x-correlator → OEG propagates as correlation_id in command.srm.* envelope
  → SRM propagates to TF-SDK → TF-SDK sets X-Correlation-ID in SBI HTTP calls
  → SRM includes in event.srm.operation.completed → OEG sets X-Correlator in response
```
+14 −2
Changes for srm/canonical-parameters-schema.md: 14 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ though they persist nothing.
  "target": {
    "device": {
      "phone_number": "+123456789",        // CAMARA device.phoneNumber
      "ipv4": "198.51.100.1",              // CAMARA device.ipv4Address
      "ipv4": "198.51.100.1",              // CAMARA device.ipv4Address.publicAddress
      "ipv4_port": 59765,                  // CAMARA device.ipv4Address.publicPort
      "ipv4_private": "10.0.0.5",          // CAMARA device.ipv4Address.privateAddress
      "ipv6": "2001:db8:85a3::370:7344",   // CAMARA device.ipv6Address
      "network_access_id": null,           // CAMARA device.networkAccessIdentifier
      "ports": {                            // CAMARA devicePorts (ADR-0037) — generic on
@@ -133,7 +135,9 @@ though they persist nothing.
| CAMARA field | Canonical path |
|---|---|
| `device.phoneNumber` | `target.device.phone_number` |
| `device.ipv4Address` | `target.device.ipv4` |
| `device.ipv4Address.publicAddress` | `target.device.ipv4` |
| `device.ipv4Address.publicPort` | `target.device.ipv4_port` |
| `device.ipv4Address.privateAddress` | `target.device.ipv4_private` |
| `device.ipv6Address` | `target.device.ipv6` |
| `device.networkAccessIdentifier` | `target.device.network_access_id` |
| `devicePorts` | `target.device.ports` (ADR-0037; generic across capabilities, not QoD-only) |
@@ -149,6 +153,14 @@ though they persist nothing.
| `destinationTrafficFilters.destinationProtocol` | `parameters.traffic_filters.destination.protocol` |
| `subscriptionRequest` | **NOT stored** — OEG owns subscription/callback state |

`ipv4`, `ipv4_port` and `ipv4_private` are the three parts of CAMARA's `DeviceIpv4Addr`, which
requires `publicAddress` plus at least one of `privateAddress` or `publicPort`. All three are
**identification** fields — they say *which device* the capability acts on, and a public IPv4
address alone does not identify a device behind carrier NAT.

`ports` is separate and says *which ports* the capability acts on (CAMARA `devicePorts`,
ADR-0037). A request may carry both; they are never merged.

### GSMA OPG → canonical mapping (same target, different source)

GSMA OPG network requests normalize into the **same** `target`/`parameters` shape;
+1 −1
Changes for srm/end-to-end-examples.md: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ stored — OEG owns subscription/callback state. The command carries only the ac

```
resolve control_path_ref for location_context capability
adapter.query_network_data(query_type="location_context", target=..., parameters=...) -> location
adapter.query_capability(capability_kind="location_context", target=..., parameters=...) -> location
return location directly (HTTP 200)
NO service_order, NO service_instance, NO capability_instance written.
NO command.srm.* published.
Loading