From e2e7e4ae160c35ae966546d67f4291bbca62cdcc Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Mon, 25 May 2026 15:26:07 -0400 Subject: [PATCH 01/10] Create effective-capabilities-and-restrictions.yaml Add OpenAPI specification for Effective Capabilities and Restrictions API. --- ...fective-capabilities-and-restrictions.yaml | 571 ++++++++++++++++++ 1 file changed, 571 insertions(+) create mode 100644 code/effective-capabilities-and-restrictions.yaml diff --git a/code/effective-capabilities-and-restrictions.yaml b/code/effective-capabilities-and-restrictions.yaml new file mode 100644 index 0000000..377b5d6 --- /dev/null +++ b/code/effective-capabilities-and-restrictions.yaml @@ -0,0 +1,571 @@ +openapi: 3.0.3 +info: + title: Effective Capabilities and Restrictions + description: | + The Effective Capabilities and Restrictions API lets an API Consumer + discover, before invocation, the producer-specific restrictions that apply + to one or more released CAMARA APIs in the context of a specific end-user + device. The producer returns, per requested CAMARA API, a standard + OpenAPI Overlay document — pinned to version + [**Overlay 1.1.0**](https://spec.openapis.org/overlay/v1.1.0.html) + — that the consumer can apply locally to the corresponding CAMARA API + specification to obtain a strictly-valid view of the API for that + device-context. + + This file is the Overlay-1.1.0-targeted sibling of + `effective-capabilities-and-restrictions.yaml`, which targets Overlay + 1.0.0. The two variants are kept side-by-side so that consuming + deployments can pick the Overlay version they support; they are NOT + compatible on the wire (returned overlay documents carry different + `overlay` version strings and the 1.1.0 variant forbids the `copy` + action introduced upstream — see "Restriction-only semantics" below). + + Note on Overlay versioning: this API targets the Overlay Specification + **version 1.1.0** specifically. Returned overlay documents will carry + `overlay: "1.1.0"` in their root field, and the schema referenced from + [`../modules/openapi-overlay-1.1.0.yaml`](../modules/openapi-overlay-1.1.0.yaml) + mirrors Overlay 1.1.0 exclusively. Consumers MUST NOT assume that + [`https://spec.openapis.org/overlay/latest.html`](https://spec.openapis.org/overlay/latest.html) + resolves to 1.1.0 — that URL follows the upstream release train and may + resolve to an Overlay version newer than 1.1.0. Adoption of a newer + Overlay version by this API would be a breaking change requiring a new + API version. + + # Restriction-only semantics + + Producers MUST emit only restrictive `actions[]` in every overlay returned + or delivered by this API. An action is restrictive when it either: + + - sets `remove: true` to delete an existing node from the target document, or + - sets `update: { ... }` whose top-level keys narrow the target node using + JSON Schema validation keywords — for example, an `enum` that is a strict + subset of the existing enum, a lowered `maximum`/`maxLength`/`maxItems`, + a raised `minimum`/`minLength`/`minItems`, a tightened `pattern`, a + `uniqueItems: true` constraint, or a `required` array that adds + previously-optional properties. + + Overlay 1.1.0 adds an optional `copy` field to the Action Object whose + semantics (injecting a value drawn from elsewhere in the target document + into the node selected by `target`) are not intrinsically restrictive: + a `copy` can just as easily widen as narrow the contract, and validating + "did this copy actually narrow the target's schema?" requires comparing + the JSON Schema at the copy source against the JSON Schema at the + target — meaningfully more complex than the keyword-level check used for + `update`. To keep validation tractable, this API forbids `copy` + outright: producers MUST NOT emit any action that carries a `copy` + field, and consumers MUST reject any overlay containing such an action. + Restrictive intent for this API is fully expressible with `remove` and + `update`. + + Precedence among the mutating fields follows Overlay 1.1.0 unchanged: + `remove: true` overrides both `update` and `copy`, and `update` and + `copy` are mutually exclusive on a single action. Combined with the + rule above, a well-formed restrictive action under this API carries + exactly one of `remove: true` or a narrowing `update: { ... }`, never + both, and never carries `copy`. + + Consumers MUST reject any overlay whose actions broaden the target + document — for example, actions that add new operations, widen an `enum`, + introduce new `oneOf` branches, raise a `maximum`, lower a `required` + array, or otherwise relax the contract of the underlying CAMARA API. + + **Capabilities are signaled by the absence of a restriction**: any element + of the target CAMARA API specification that is *not* referenced by an + `action.target` in the returned overlay is supported by the producer with + the unmodified semantics defined by that CAMARA API. The overlay therefore + enumerates only the producer-specific narrowings; consumers infer + capabilities from what the overlay leaves untouched. + + # Operation model + + The single operation `POST /retrieve-effective-overlay` accepts a list of + CAMARA API specification URLs (released GitHub versions) and a `device` + context. It has two delivery modes selected by whether the request carries + a `sink`: + + - **Synchronous** (no `sink`/`sinkCredential`): the producer evaluates the + request and returns `200 OK` with an array of OpenAPI Overlay 1.1.0 + documents, one per requested API, in the same order as the request's + `apis[]`. + - **Asynchronous (implicit subscription)** (`sink` and `sinkCredential` + both present): the producer returns `202 Accepted` immediately with an + echo of the registered `sink` (never the credential), and delivers each + computed overlay later via the sink as a single non-batch CloudEvent of + type + `org.camaraproject.effective-capabilities-and-restrictions.v0.overlay-updated`, + one CloudEvent per requested API. Subsequent producer-side state changes + (for example, the device moves to a new footprint) result in additional + CloudEvents of the same type carrying the updated overlay for the + affected API. + + # End-to-end flow at a glance + + ```text + App Backend ECR Producer Upstream CAMARA + (Consumer) (this API) API (e.g. QoD) + | | | + | (a) [dev-time, one-time] developer or | + | build pipeline fetches the upstream | + | CAMARA spec (e.g. QoD r3.2) and | + | bundles/ships it with the app | + |--------------------------------------------->| + |<---------------------------------------------| + | | | + | = = = = = = = = = = = = = = = = = = | + | runtime (per device) | + | | | + | (b) POST /retrieve-effective-overlay | + | { apis:[], device:{...} } | + |-------------------->| | + | | resolve (device, api): | + | | producer policy + | + | | device footprint | + | (c) 200 OK | | + | [{ overlay:"1.1.0", | + | extends:"", | + | actions:[ remove, | + | update{enum}, | + | update{maximum}, ... ] }] | + |<--------------------| | + | | | + | (d) apply overlay locally to cached spec | + | => effective contract for THIS device | + | | | + | (e) drive UI; pre-validate request bodies | + | against the effective contract | + | | | + | (f) POST upstream call (e.g. /sessions), | + | pre-validated vs. the narrowed schema | + |--------------------------------------------->| + |<---------------------------------------------| + | 200/201 -- no surprise 422s | + ``` + + Async variant: if the request body also carries `sink` and + `sinkCredential`, step (c) becomes `202 Accepted` (echoing only the + `sink`) and the producer later POSTs `overlay-updated` CloudEvents to + the sink — once on the initial evaluation and once on each subsequent + effective-view change. The consumer replaces its cached overlay for + `data.api` and re-applies, then re-renders step (e) without + re-mounting the form. + + # Recovery + + Notification delivery is at-most-once. To recover from a missed + notification, a consumer simply re-issues the original + `POST /retrieve-effective-overlay` request: the operation is idempotent + and the response always reflects the producer's current effective view for + the supplied context. There is no bitmap, no `mappingVersion`, no resync + state machine. + + # Authorization and authentication + + The "Authorization and authentication" common guidelines, defined in + [Commonalities](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-access-and-user-consent.md), + apply to this API. The API uses OpenID Connect (OIDC) authentication, and + grant management via CIBA. The required scope for the + `retrieveEffectiveOverlay` operation is + `effective-capabilities-and-restrictions:retrieve-effective-overlay`, which + grants the right to retrieve the effective overlay for a given device. + Callback (`sink`) authentication is conveyed out-of-band by the + `sinkCredential` supplied with the request; the credential itself is never + echoed in any response. + + # Additional CAMARA error responses + + The list of error codes in this API specification is not exhaustive. + Therefore the API specification may not document some non-mandatory error + statuses such as 504 (Gateway Timeout) introduced by Commonalities. + Consumers MUST be prepared to handle other error responses than those + listed here. Where appropriate, error responses follow the standard + CAMARA error structure defined in `CAMARA_common.yaml`. + + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: wip + x-camara-commonalities: 0.8.0-rc.2 + +externalDocs: + description: Product documentation at CAMARA + url: https://github.com/camaraproject/ + +servers: + - url: "{apiRoot}/effective-capabilities-and-restrictions/vwip" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by the service provider, e.g. + `api.example.com` or `api.example.com/somepath`. + +tags: + - name: Effective Overlay + description: | + Retrieve producer-specific effective overlay documents for one or more + CAMARA APIs in the context of a given device. Optionally subscribe to + overlay updates via an implicit `sink` callback. + +security: + - openId: + - effective-capabilities-and-restrictions:retrieve-effective-overlay + +paths: + /retrieve-effective-overlay: + post: + tags: + - Effective Overlay + summary: Retrieve the effective overlay for one or more CAMARA APIs + description: | + Computes the producer-specific effective overlay for each CAMARA API + listed in `apis[]`, in the context of the supplied `device`. + + - If neither `sink` nor `sinkCredential` is supplied, returns + `200 OK` synchronously with an array of + [OpenAPI Overlay 1.1.0](https://spec.openapis.org/overlay/v1.1.0.html) + documents, one per entry in `apis[]`, in the same order as the + request. + - If both `sink` and `sinkCredential` are supplied, returns + `202 Accepted` with no overlays in the body (the response echoes + only the registered `sink`) and the producer subsequently delivers + one CloudEvent of type + `org.camaraproject.effective-capabilities-and-restrictions.v0.overlay-updated` + per requested API via the registered `sink`. Additional CloudEvents + of the same type are delivered whenever the effective overlay for + any of the requested APIs changes. + + The operation is idempotent: repeating the same request returns the + same effective overlay set (or schedules the same async delivery) for + a stable producer-side configuration. To recover from a missed + notification, simply re-issue the request. + operationId: retrieveEffectiveOverlay + parameters: + - $ref: "../common/CAMARA_common.yaml#/components/parameters/x-correlator" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/RetrieveEffectiveOverlayRequest" + callbacks: + overlayUpdated: + "{$request.body#/sink}": + post: + summary: "overlay-updated notification callback" + description: | + Important: this endpoint is to be implemented by the API + consumer. The Effective Capabilities and Restrictions producer + POSTs to this endpoint once per affected CAMARA API whenever + the effective overlay changes for the device-context of an + active asynchronous request. Each notification is a single + (non-batch) CloudEvent. + operationId: postOverlayUpdated + parameters: + - $ref: "../common/CAMARA_common.yaml#/components/parameters/x-correlator" + requestBody: + required: true + content: + application/cloudevents+json: + schema: + $ref: "#/components/schemas/OverlayUpdatedEvent" + responses: + "204": + description: Successful notification + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + "400": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + "401": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" + "403": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + "410": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic410" + "429": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic429" + security: + - {} + - notificationsBearerAuth: [] + responses: + "200": + description: | + Synchronous response. The body is an array of + [OpenAPI Overlay 1.1.0](https://spec.openapis.org/overlay/v1.1.0.html) + documents, one per entry in the request's `apis[]`, in the same + order. Returned only when the request omits both `sink` and + `sinkCredential`. + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + type: array + minItems: 1 + maxItems: 20 + description: | + One [OpenAPI Overlay 1.1.0](https://spec.openapis.org/overlay/v1.1.0.html) + document per requested CAMARA API, in the same order as the + request's `apis[]`. Each document carries `overlay: "1.1.0"` + in its root field. + items: + $ref: "../modules/openapi-overlay-1.1.0.yaml#/components/schemas/Overlay" + "202": + description: | + Asynchronous acceptance. Returned only when both `sink` and + `sinkCredential` are present in the request. No overlays are + included in the body; the producer will deliver one CloudEvent + of type + `org.camaraproject.effective-capabilities-and-restrictions.v0.overlay-updated` + per requested API to the registered `sink`. The body echoes only + the registered `sink` so the consumer can confirm the value the + producer captured. The `sinkCredential` is never echoed. + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/RetrieveEffectiveOverlayAccepted" + "400": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + "401": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" + "403": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + "404": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" + "422": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic422" + "429": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic429" + "500": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" + "503": + $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + +components: + securitySchemes: + openId: + $ref: "../common/CAMARA_common.yaml#/components/securitySchemes/openId" + notificationsBearerAuth: + $ref: "../common/CAMARA_event_common.yaml#/components/securitySchemes/notificationsBearerAuth" + + schemas: + + # ───────────────────────────────────────────────────────────────────────── + # Device (inline) + # + # Inlined per design contract: this API exposes `device` as its sole wire + # context input. The shape mirrors the canonical CAMARA Device but is + # declared locally with no $refs to ../common so the wire contract for + # this API is fully self-contained. + # ───────────────────────────────────────────────────────────────────────── + + Device: + description: | + End-user equipment able to connect to a mobile network. Examples + include smartphones and IoT sensors/actuators. + + The API Consumer can provide one or more of the following identifiers + and the API Producer will use one identifier of its choice for the + producer-side policy evaluation: + - `phoneNumber` + - `networkAccessIdentifier` + - `ipv4Address` + - `ipv6Address` + + At least one identifier MUST be present. + type: object + minProperties: 1 + properties: + phoneNumber: + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + maxLength: 16 + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN, formatted in international + E.164 form prefixed with `+`. + example: "+123456789" + networkAccessIdentifier: + type: string + maxLength: 2048 + description: | + A public identifier addressing a subscription in a mobile network. + In 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier (`{Local Identifier}@{Domain Identifier}`). + example: "123456789@example.com" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Address" + ipv6Address: + type: string + format: ipv6 + maxLength: 45 + description: | + The device should be identified by the observed IPv6 address, or + by any single IPv6 address from within the subnet allocated to the + device. + example: "2001:db8:85a3:8d3:1319:8a2e:370:7344" + + DeviceIpv4Address: + description: | + The device IPv4 identification. `publicAddress` MUST always be present; + in addition, at least one of `privateAddress` or `publicPort` MUST be + present so the device can be uniquely identified through NAT. + type: object + properties: + publicAddress: + type: string + format: ipv4 + maxLength: 15 + description: A single public (observed) IPv4 address. + example: "84.125.93.10" + privateAddress: + type: string + format: ipv4 + maxLength: 15 + description: A single private (allocated) IPv4 address. + example: "10.0.0.5" + publicPort: + type: integer + format: int32 + minimum: 1 + maximum: 65535 + description: TCP or UDP source port observed at the application server. + example: 59765 + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + + # ───────────────────────────────────────────────────────────────────────── + # Request body + # ───────────────────────────────────────────────────────────────────────── + + RetrieveEffectiveOverlayRequest: + description: | + Request body for `POST /retrieve-effective-overlay`. Carries the list + of CAMARA APIs to evaluate, the device context, and (optionally) an + implicit-subscription `sink` + `sinkCredential` pair selecting + asynchronous delivery. + + Either both `sink` and `sinkCredential` are present (asynchronous + mode, `202` response) or neither is present (synchronous mode, + `200` response). + type: object + required: + - apis + properties: + apis: + type: array + minItems: 1 + maxItems: 20 + uniqueItems: true + description: | + One or more URLs identifying released GitHub versions of CAMARA + API specifications for which the producer's effective overlay is + requested. The producer returns one overlay per entry, in the + same order. + items: + type: string + format: uri + maxLength: 2048 + description: | + URL of a released version of a CAMARA API specification on + GitHub, e.g. + `https://github.com/camaraproject/QualityOnDemand/blob/r2.2/code/API_definitions/quality-on-demand.yaml`. + example: "https://github.com/camaraproject/QualityOnDemand/blob/r2.2/code/API_definitions/quality-on-demand.yaml" + device: + $ref: "#/components/schemas/Device" + sink: + type: string + format: uri + maxLength: 2048 + pattern: '^https://.+$' + description: | + HTTPS URL at which the API Consumer is willing to receive + `overlay-updated` CloudEvents. Presence of this property (together + with `sinkCredential`) selects the asynchronous delivery mode and + implicitly subscribes the consumer to overlay updates for the + requested APIs. + example: "https://consumer.example.com/effective-overlay/notifications" + sinkCredential: + $ref: "../common/CAMARA_event_common.yaml#/components/schemas/SinkCredential" + + # ───────────────────────────────────────────────────────────────────────── + # Accepted response (async mode) + # + # Echoes only the registered `sink` so the consumer can confirm the value + # the producer captured. The `sinkCredential` is never echoed. + # ───────────────────────────────────────────────────────────────────────── + + RetrieveEffectiveOverlayAccepted: + description: | + Acknowledges acceptance of an asynchronous request. Echoes only the + registered `sink`; overlays are delivered later via CloudEvents and + are not part of this response. + type: object + required: + - sink + properties: + sink: + type: string + format: uri + maxLength: 2048 + description: | + The HTTPS sink URL the producer has registered for this request. + Echoed verbatim from the request body for consumer confirmation. + example: "https://consumer.example.com/effective-overlay/notifications" + + # ───────────────────────────────────────────────────────────────────────── + # CloudEvent notification + # ───────────────────────────────────────────────────────────────────────── + + OverlayUpdatedEventType: + type: string + description: | + The single CloudEvent type emitted by this API. One CloudEvent is + delivered per affected CAMARA API. + enum: + - org.camaraproject.effective-capabilities-and-restrictions.v0.overlay-updated + + OverlayUpdatedEventData: + description: | + Payload of an `overlay-updated` CloudEvent. Identifies the CAMARA API + whose effective overlay has changed and carries the full replacement + overlay document. Consumers replace any prior overlay for `api` with + `overlay`. + type: object + required: + - api + - overlay + properties: + api: + type: string + format: uri + maxLength: 2048 + description: | + URL of the CAMARA API specification whose effective overlay has + changed. Matches one of the entries in the original request's + `apis[]`. + example: "https://github.com/camaraproject/QualityOnDemand/blob/r2.2/code/API_definitions/quality-on-demand.yaml" + overlay: + $ref: "../modules/openapi-overlay-1.1.0.yaml#/components/schemas/Overlay" + + OverlayUpdatedEvent: + description: | + CloudEvents 1.0 envelope for an `overlay-updated` notification. The + `type` is constrained to the single value defined by this API and the + `data` payload carries the replacement overlay for one CAMARA API. + allOf: + - $ref: "../common/CAMARA_event_common.yaml#/components/schemas/CloudEvent" + - type: object + required: + - type + - data + properties: + type: + $ref: "#/components/schemas/OverlayUpdatedEventType" + data: + $ref: "#/components/schemas/OverlayUpdatedEventData" From 7b7da67773da21361073c26eb0f1b9ab55955324 Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Mon, 25 May 2026 15:33:32 -0400 Subject: [PATCH 02/10] Enhance descriptions and update schema definitions Updated the CAMARA common data types YAML file to enhance descriptions, modify versioning, and refine schema definitions. --- code/common/CAMARA_common.yaml | 801 +++++++++++++++------------------ 1 file changed, 373 insertions(+), 428 deletions(-) diff --git a/code/common/CAMARA_common.yaml b/code/common/CAMARA_common.yaml index c2ddd8d..399ae11 100644 --- a/code/common/CAMARA_common.yaml +++ b/code/common/CAMARA_common.yaml @@ -1,153 +1,134 @@ ---- -openapi: 3.0.3 info: title: CAMARA common data types - description: Common data types for CAMARA APIs + description: | + Common data types for CAMARA APIs. + This file contains Commonalities-owned schemas that are identical across all + CAMARA APIs, including error responses, common parameters, headers, and + reusable data types. + + API repositories place this file in `code/common/` and reference schemas + via `$ref: "../common/CAMARA_common.yaml#/components/schemas/"`. license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html version: wip - x-camara-commonalities: tbd -paths: {} + x-camara-commonalities: 0.8.0-rc.2 + components: securitySchemes: openId: - description: OpenID Connect authentication. type: openIdConnect openIdConnectUrl: https://example.com/.well-known/openid-configuration - notificationsBearerAuth: - description: Notification bearer authentication. - type: http - scheme: bearer - bearerFormat: '{$request.body#/sinkCredential.credentialType}' + description: OpenID Connect authentication via discovery metadata. + headers: x-correlator: description: Correlation id for the different services schema: - $ref: '#/components/schemas/XCorrelator' - Cache-Control: - description: Public cacheable for 10 minutes + $ref: "#/components/schemas/XCorrelator" + + x-total-count: + description: Total number of items. Mirrors `pagination.totalCount` in the response body. + required: false schema: - type: string - example: public, max-age=600 - ETag: - description: Entity tag for caching - schema: - type: string - Last-Modified: - description: Timestamp of last modification + $ref: "#/components/schemas/TotalCount" + + x-total-pages: + description: Total number of pages. Mirrors `pagination.totalPages` in the response body. + required: false schema: - type: string - format: date-time - Accept-Patch: - description: Advertises which media types the server is able to understand in - a PATCH request + $ref: "#/components/schemas/TotalPages" + + link: + description: | + Navigation links for paginated results following + [RFC 8288](https://www.rfc-editor.org/rfc/rfc8288). + Includes only the rels applicable to the current position + (`first`, `prev`, `next`, `last`). All original query parameters + are preserved in Link URLs. + Example: + Link: ; rel="first", + ; rel="prev", + ; rel="next", + ; rel="last" + required: false schema: type: string - example: application/merge-patch+json, application/json-patch+json + maxLength: 8192 + parameters: x-correlator: name: x-correlator in: header description: Correlation id for the different services schema: - $ref: '#/components/schemas/XCorrelator' - If-Match: - name: If-Match - in: header - description: Apply only if the ETag matches (RFC 7232). - schema: - type: string - If-None-Match: - name: If-None-Match - in: header - description: ETag for conditional requests - schema: - type: string - If-Modified-Since: - name: If-Modified-Since - in: header - description: Timestamp for conditional requests + $ref: "#/components/schemas/XCorrelator" + + page: + name: page + in: query + description: > + Requested page number. Pages are 1-indexed. + Values below 1 are rejected with `400 INVALID_ARGUMENT`. + required: false schema: - type: string - format: date-time - GroupId: - name: GroupId - in: path - required: true - description: Reference Id for a created group + $ref: "#/components/schemas/Page" + + perPage: + name: perPage + in: query + description: > + Number of subscriptions to return per page. + Values outside the allowed range are rejected with `400 INVALID_ARGUMENT`. + required: false schema: - type: string - format: uuid + $ref: "#/components/schemas/PerPage" + schemas: XCorrelator: type: string - description: XCorrelator + description: Correlator string, UUID format recommended but any string matching the pattern can be used pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ - example: b4333c46-49c0-4f62-80d7-f0ef930f1c46 + maxLength: 256 + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + DateTime: + type: string + format: date-time + maxLength: 64 + description: Timestamp. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2018-04-05T17:31:00Z" TimePeriod: type: object - description: TimePeriod + description: A period of time defined by a start date and an optional end date. If `endDate` is not included, then the period has no ending date. properties: startDate: - type: string - format: date-time - description: An instant of time, starting of the TimePeriod. It must follow - [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) - and must have time zone. + $ref: "#/components/schemas/DateTime" endDate: - type: string - format: date-time - description: An instant of time, ending of the TimePeriod. If not included, - then the period has no ending date. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) - and must have time zone. - required: [startDate] + $ref: "#/components/schemas/DateTime" + required: + - startDate ErrorInfo: type: object - description: ErrorInfo - required: [status, code, message] + description: A structured error response providing details about a failed request, including the HTTP status code, an error code, and a human-readable message + required: + - status + - code + - message properties: status: type: integer + format: int32 + minimum: 100 + maximum: 599 description: HTTP response status code code: type: string + maxLength: 96 description: A human-readable code to describe the error message: type: string + maxLength: 512 description: A human-readable description of what the event represents - ApplicationServer: - description: | - A server hosting backend applications to deliver some business logic to clients. - The developer can choose to provide the below specified device identifiers: - * `ipv4Address` - * `ipv6Address` - type: object - properties: - ipv4Address: - $ref: '#/components/schemas/ApplicationServerIpv4Address' - ipv6Address: - $ref: '#/components/schemas/ApplicationServerIpv6Address' - minProperties: 1 - ApplicationServerIpv4Address: - type: string - example: 198.51.100.0/24 - description: | - IPv4 address may be specified in form
as: - - address - an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule. - - address/mask - an IP number as above with a mask width of the form 1.2.3.4/24. - In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version. - ApplicationServerIpv6Address: - type: string - example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - description: | - IPv6 address may be specified in form
as: - - address - The /128 subnet is optional for single addresses: - - 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - 2001:db8:85a3:8d3:1319:8a2e:370:7344/128 - - address/mask - an IP v6 number with a mask: - - 2001:db8:85a3:8d3::0/64 - - 2001:db8:85a3:8d3::/64 Device: description: | End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. @@ -156,207 +137,224 @@ components: * `ipv6Address` * `phoneNumber` * `networkAccessIdentifier` - NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE1: the network operator might support only a subset of these options. The API Consumer can provide multiple identifiers to ensure compatibility across different network operators. In this case, the API Provider will use one of the identifiers for the API logic without performing any matching checks among the provided identifiers. NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. type: object properties: phoneNumber: - $ref: '#/components/schemas/PhoneNumber' + $ref: "#/components/schemas/PhoneNumber" networkAccessIdentifier: - $ref: '#/components/schemas/NetworkAccessIdentifier' + $ref: "#/components/schemas/NetworkAccessIdentifier" ipv4Address: - $ref: '#/components/schemas/DeviceIpv4Addr' + $ref: "#/components/schemas/DeviceIpv4Address" ipv6Address: - $ref: '#/components/schemas/DeviceIpv6Address' + $ref: "#/components/schemas/DeviceIpv6Address" minProperties: 1 + DeviceResponse: description: | An identifier for the end-user equipment able to connect to the network that the response refers to. This parameter is only returned when the API consumer includes the `device` parameter in their request (i.e. they are using a two-legged access token), and is relevant when more than one device identifier is specified, as only one of those device identifiers is allowed in the response. + If the API consumer provides more than one device identifier in their request, and this schema is included in the response definition, the API provider MUST use it to return a single identifier which is the one they are using to fulfil the request, even if the identifiers do not match the same device. API provider does not perform any logic to validate/correlate that the indicated device identifiers match the same device. No error should be returned if the identifiers are otherwise valid to prevent API consumers correlating different identifiers with a given end user. + allOf: - - $ref: '#/components/schemas/Device' + - $ref: "#/components/schemas/Device" - maxProperties: 1 + PhoneNumber: - description: A public identifier addressing a telephone subscription. In mobile - networks it corresponds to the MSISDN (Mobile Station International Subscriber - Directory Number). In order to be globally unique it has to be formatted in - international format, according to E.164 standard, prefixed with '+'. + description: A public identifier addressing a telephone subscription. In mobile networks it corresponds to the MSISDN (Mobile Station International Subscriber Directory Number). In order to be globally unique it has to be formatted in international format, according to E.164 standard, prefixed with '+'. type: string - pattern: ^\+[1-9][0-9]{4,14}$ - example: '+123456789' + pattern: '^\+[1-9][0-9]{4,14}$' + maxLength: 16 + example: "+123456789" + NetworkAccessIdentifier: - description: A public identifier addressing a subscription in a mobile network. - In 3GPP terminology, it corresponds to the GPSI formatted with the External - Identifier ({Local Identifier}@{Domain Identifier}). Unlike the telephone - number, the network access identifier is not subjected to portability ruling - in force, and is individually managed by each operator. + description: A public identifier addressing a subscription in a mobile network. In 3GPP terminology, it corresponds to the GPSI formatted with the External Identifier ({Local Identifier}@{Domain Identifier}). Unlike the telephone number, the network access identifier is not subjected to portability ruling in force, and is individually managed by each operator. type: string - example: 123456789@example.com - DeviceIpv4Addr: + maxLength: 2048 + example: "123456789@example.com" + + DeviceIpv4Address: type: object description: | The device should be identified by either the public (observed) IP address and port as seen by the application server, or the private (local) and any public (observed) IP addresses in use by the device (this information can be obtained by various means, for example from some DNS servers). + If the allocated and observed IP addresses are the same (i.e. NAT is not in use) then the same address should be specified for both publicAddress and privateAddress. + If NAT64 is in use, the device should be identified by its publicAddress and publicPort, or separately by its allocated IPv6 address (field ipv6Address of the Device object) + In all cases, publicAddress must be specified, along with at least one of either privateAddress or publicPort, dependent upon which is known. In general, mobile devices cannot be identified by their public IPv4 address alone. properties: publicAddress: - $ref: '#/components/schemas/SingleIpv4Addr' + $ref: "#/components/schemas/SingleIpv4Address" privateAddress: - $ref: '#/components/schemas/SingleIpv4Addr' + $ref: "#/components/schemas/SingleIpv4Address" publicPort: - $ref: '#/components/schemas/Port' + $ref: "#/components/schemas/Port" anyOf: - required: [publicAddress, privateAddress] - required: [publicAddress, publicPort] example: - publicAddress: 84.125.93.10 + publicAddress: "84.125.93.10" publicPort: 59765 - SingleIpv4Addr: + + SingleIpv4Address: description: A single IPv4 address with no subnet mask type: string format: ipv4 - example: 84.125.93.10 + maxLength: 15 + example: "84.125.93.10" + Port: description: TCP or UDP port number type: integer - minimum: 0 + format: int32 + minimum: 1 maximum: 65535 - PortsSpec: - description: Specification of several TCP or UDP ports - type: object - minProperties: 1 - properties: - ranges: - description: Range of TCP or UDP ports - type: array - minItems: 1 - items: - type: object - required: [from, to] - properties: - from: - $ref: '#/components/schemas/Port' - to: - $ref: '#/components/schemas/Port' - ports: - description: Array of TCP or UDP ports - type: array - minItems: 1 - items: - $ref: '#/components/schemas/Port' - example: - ranges: - - from: 5010 - to: 5020 - ports: [5060, 5070] + DeviceIpv6Address: description: | The device should be identified by the observed IPv6 address, or by any single IPv6 address from within the subnet allocated to the device (e.g. adding ::0 to the /64 prefix). type: string format: ipv6 + maxLength: 45 example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + Area: description: Base schema for all areas type: object properties: areaType: - $ref: '#/components/schemas/AreaType' - required: [areaType] + $ref: "#/components/schemas/AreaType" + required: + - areaType discriminator: propertyName: areaType mapping: - CIRCLE: '#/components/schemas/Circle' - POLYGON: '#/components/schemas/Polygon' + CIRCLE: "#/components/schemas/Circle" + POLYGON: "#/components/schemas/Polygon" + AreaType: type: string description: | Type of this area. CIRCLE - The area is defined as a circle. POLYGON - The area is defined as a polygon. - enum: [CIRCLE, POLYGON] + enum: + - CIRCLE + - POLYGON + Circle: description: Circular area allOf: - - $ref: '#/components/schemas/Area' + - $ref: "#/components/schemas/Area" - type: object - required: [center, radius] + required: + - center + - radius properties: center: - $ref: '#/components/schemas/Point' + $ref: "#/components/schemas/Point" radius: type: number description: Distance from the center in meters minimum: 1 + Polygon: - description: Polygonal area. The Polygon should be a simple polygon, i.e. should - not intersect itself. + description: Polygonal area. The Polygon should be a simple polygon, i.e. should not intersect itself. allOf: - - $ref: '#/components/schemas/Area' + - $ref: "#/components/schemas/Area" - type: object - required: [boundary] + required: + - boundary properties: boundary: - $ref: '#/components/schemas/PointList' + $ref: "#/components/schemas/PointList" + PointList: description: List of points defining a polygon type: array items: - $ref: '#/components/schemas/Point' + $ref: "#/components/schemas/Point" minItems: 3 maxItems: 15 + Point: type: object description: Coordinates (latitude, longitude) defining a location in a map - required: [latitude, longitude] + required: + - latitude + - longitude properties: latitude: - $ref: '#/components/schemas/Latitude' + $ref: "#/components/schemas/Latitude" longitude: - $ref: '#/components/schemas/Longitude' + $ref: "#/components/schemas/Longitude" example: latitude: 50.735851 longitude: 7.10066 - QosProfileName: - description: | - A unique name for identifying a specific QoS profile. - This may follow different formats depending on the API provider implementation. - Some options addresses: - - A UUID style string - - Support for predefined profiles QOS_S, QOS_M, QOS_L, and QOS_E - - A searchable descriptive name - The set of QoS Profiles that an API provider is offering may be retrieved by means of the QoS Profile API (qos-profile) or agreed on onboarding time. - type: string - example: voice - minLength: 3 - maxLength: 256 - format: string - pattern: ^[a-zA-Z0-9_.-]+$ + Latitude: description: Latitude component of a location type: number format: double minimum: -90 maximum: 90 + Longitude: description: Longitude component of location type: number format: double minimum: -180 maximum: 180 - GroupId: - description: Reference Id for a created group - type: string - format: uuid - ResourceScopes: - description: A list of resource scopes - type: array - items: - anyOf: - - $ref: '#/components/schemas/Device' - - $ref: '#/components/schemas/Area' - - $ref: '#/components/schemas/GroupId' - - $ref: '#/components/schemas/PortsSpec' + + # ───────────────────────────────────────────────────────────────────────── + # Pagination + # ───────────────────────────────────────────────────────────────────────── + + Pagination: + description: Pagination details helping to navigate through paged results efficiently. + type: object + properties: + page: + $ref: "#/components/schemas/Page" + perPage: + $ref: "#/components/schemas/PerPage" + totalCount: + $ref: "#/components/schemas/TotalCount" + totalPages: + $ref: "#/components/schemas/TotalPages" + + Page: + type: integer + format: int32 + minimum: 1 + maximum: 2147483647 + default: 1 + description: Current page number (1-indexed). + example: 1 + PerPage: + type: integer + format: int32 + minimum: 1 + maximum: 100 + default: 20 + description: Number of items per page. + example: 20 + TotalCount: + type: integer + format: int32 + minimum: 0 + maximum: 2147483647 + description: Total number of items matching the query, after filters applied. MAY be omitted where a full count query is prohibitively expensive. + example: 87 + TotalPages: + type: integer + format: int32 + minimum: 0 + maximum: 2147483647 + description: Total number of pages. Equals ceil(totalCount / perPage). MAY be omitted where totalCount is omitted. + example: 5 responses: ####################################################### ####################################################### @@ -396,163 +394,130 @@ components: # message: ####################################################### ####################################################### - Generic304: - description: Not Modified - headers: - x-correlator: - $ref: '#/components/headers/x-correlator' - content: - application/json: - schema: - title: Generic304 - allOf: - - $ref: '#/components/schemas/ErrorInfo' - - type: object - properties: - status: - enum: [304] - code: - enum: [NOT_MODIFIED] - examples: - GENERIC_304_NOT_MODIFIED: - description: Not Modified. The resource has not been modified since - the last request. - value: - status: 304 - code: NOT_MODIFIED - message: The resource has not been modified since the last request. Generic400: description: Bad Request headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic400 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - type: integer - enum: [400] + enum: + - 400 code: - type: string - enum: [INVALID_ARGUMENT, OUT_OF_RANGE, '{{SPECIFIC_CODE}}'] + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + # - "{{SPECIFIC_CODE}}" - API-specific codes added if needed examples: GENERIC_400_INVALID_ARGUMENT: description: Invalid Argument. Generic Syntax Exception value: status: 400 code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query - param. + message: Client specified an invalid argument, request body or query param. GENERIC_400_OUT_OF_RANGE: - description: Out of Range. Specific Syntax Exception used when a given - field has a pre-defined range or an invalid filter criteria combination - is requested + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested value: status: 400 code: OUT_OF_RANGE message: Client specified an invalid range. - GENERIC_400_{{SPECIFIC_CODE}}: - description: Specific Syntax Exception regarding a field that is relevant - in the context of the API - value: - status: 400 - code: '{{SPECIFIC_CODE}}' - message: '{{SPECIFIC_CODE_MESSAGE}}' + # GENERIC_400_{{SPECIFIC_CODE}}: + # description: Specific Syntax Exception regarding a field that is relevant in the context of the API + # value: + # status: 400 + # code: "{{SPECIFIC_CODE}}" + # message: Message for specific code Generic401: description: Unauthorized headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic401 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [401] + enum: + - 401 code: - enum: [UNAUTHENTICATED, ACCESS_TOKEN_EXPIRED] + enum: + - UNAUTHENTICATED examples: GENERIC_401_UNAUTHENTICATED: - description: Request cannot be authenticated and a new authentication - is required + description: Request cannot be authenticated and a new authentication is required value: status: 401 code: UNAUTHENTICATED - message: Request not authenticated due to missing, invalid, or expired - credentials. A new authentication is required. - GENERIC_401_ACCESS_TOKEN_EXPIRED: - description: Request cannot be authenticated and access token expired - value: - status: 401 - code: ACCESS_TOKEN_EXPIRED - message: Request not authenticated due to expired access token. A - new authentication is required. + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. Generic403: description: Forbidden headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic403 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [403] + enum: + - 403 code: - enum: [PERMISSION_DENIED, INVALID_TOKEN_CONTEXT, '{{SPECIFIC_CODE}}'] + enum: + - PERMISSION_DENIED + - INVALID_TOKEN_CONTEXT + # - "{{SPECIFIC_CODE}}" - API-specific codes added if needed examples: GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the - required scope or when the user fails operational security + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security value: status: 403 code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this - action. + message: Client does not have sufficient permissions to perform this action. GENERIC_403_INVALID_TOKEN_CONTEXT: - description: Reflect some inconsistency between information in some - field of the API and the related OAuth2 Token + description: Reflect some inconsistency between information in some field of the API and the related OAuth2 Token value: status: 403 code: INVALID_TOKEN_CONTEXT - message: '{{field}} is not consistent with access token.' - GENERIC_403_{{SPECIFIC_CODE}}: - description: Indicate a Business Logic condition that forbids a process - not attached to a specific field in the context of the API - value: - status: 403 - code: '{{SPECIFIC_CODE}}' - message: '{{SPECIFIC_CODE_MESSAGE}}' + # message: "{{field}} is not consistent with access token." + message: "Request body is not consistent with access token." + # GENERIC_403_{{SPECIFIC_CODE}}: + # description: Indicate a Business Logic condition that forbids a process not attached to a specific field in the context of the API + # value: + # status: 403 + # code: "{{SPECIFIC_CODE}}" + # message: Message for specific code Generic404: description: Not found headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic404 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [404] + enum: + - 404 code: - enum: [NOT_FOUND, IDENTIFIER_NOT_FOUND, '{{SPECIFIC_CODE}}'] + enum: + - NOT_FOUND + - IDENTIFIER_NOT_FOUND + # - "{{SPECIFIC_CODE}}" - API-specific codes added if needed examples: GENERIC_404_NOT_FOUND: description: Resource is not found @@ -566,118 +531,91 @@ components: status: 404 code: IDENTIFIER_NOT_FOUND message: Device identifier not found. - GENERIC_404_{{SPECIFIC_CODE}}: - description: Specific situation to highlight the resource/concept not - found - value: - status: 404 - code: '{{SPECIFIC_CODE}}' - message: '{{SPECIFIC_CODE_MESSAGE}}' - GenericDevice404: - description: Not found - headers: - x-correlator: - $ref: '#/components/headers/x-correlator' - content: - application/json: - schema: - title: GenericDevice404 - allOf: - - $ref: '#/components/schemas/ErrorInfo' - - type: object - properties: - status: - enum: [404] - code: - enum: [NOT_FOUND, IDENTIFIER_NOT_FOUND] - examples: - GENERIC_404_NOT_FOUND: - description: Resource is not found - value: - status: 404 - code: NOT_FOUND - message: The specified resource is not found. - GENERIC_404_DEVICE_NOT_FOUND: - description: Device identifier not found - value: - status: 404 - code: IDENTIFIER_NOT_FOUND - message: Device identifier not found. + # GENERIC_404_{{SPECIFIC_CODE}}: + # description: Specific situation to highlight the resource/concept not found + # value: + # status: 404 + # code: "{{SPECIFIC_CODE}}" + # message: Message for specific code Generic405: description: Method Not Allowed headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic405 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [405] + enum: + - 405 code: - enum: [METHOD_NOT_ALLOWED] + enum: + - METHOD_NOT_ALLOWED examples: GENERIC_405_METHOD_NOT_ALLOWED: description: Invalid HTTP verb used with a given endpoint value: status: 405 code: METHOD_NOT_ALLOWED - message: The requested method is not allowed/supported on the target - resource. + message: The requested method is not allowed/supported on the target resource. Generic406: description: Not Acceptable headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic406 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [406] + enum: + - 406 code: - enum: [NOT_ACCEPTABLE] + enum: + - NOT_ACCEPTABLE examples: GENERIC_406_NOT_ACCEPTABLE: - description: API Server does not accept the media type (`Accept-*` header) - indicated by API client + description: API Server does not accept the media type (`Accept-*` header) indicated by API client value: status: 406 code: NOT_ACCEPTABLE - message: The server cannot produce a response matching the content - requested by the client through `Accept-*` headers. + message: The server cannot produce a response matching the content requested by the client through `Accept-*` headers. Generic409: description: Conflict headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic409 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [409] + enum: + - 409 code: - enum: [ABORTED, ALREADY_EXISTS, CONFLICT, '{{SPECIFIC_CODE}}'] + enum: + - ABORTED + - ALREADY_EXISTS + - CONFLICT + - INCOMPATIBLE_STATE + # - "{{SPECIFIC_CODE}}" - API-specific codes added if needed examples: GENERIC_409_ABORTED: - description: Concurreny of processes of the same nature/scope + description: The resource is undergoing modification by another process value: status: 409 code: ABORTED - message: Concurrency conflict. + message: Resource is being modified by another operation. Please wait, and retry if appropriate. GENERIC_409_ALREADY_EXISTS: description: Trying to create an existing resource value: @@ -685,39 +623,48 @@ components: code: ALREADY_EXISTS message: The resource that a client tried to create already exists. GENERIC_409_CONFLICT: + ################################### + # This Error Code is DEPRECATED + ################################### description: Duplication of an existing resource value: status: 409 code: CONFLICT message: A specified resource duplicate entry found. - GENERIC_409_{{SPECIFIC_CODE}}: - description: Specific conflict situation that is relevant in the context - of the API + GENERIC_409_INCOMPATIBLE_STATE: + description: | + The status of the referenced resource is not compatible. value: status: 409 - code: '{{SPECIFIC_CODE}}' - message: '{{SPECIFIC_CODE_MESSAGE}}' + code: INCOMPATIBLE_STATE + message: Resource must be in AVAILABLE state to extend. Current state is UNAVAILABLE. + # GENERIC_409_{{SPECIFIC_CODE}}: + # description: Specific conflict situation that is relevant in the context of the API + # value: + # status: 409 + # code: "{{SPECIFIC_CODE}}" + # message: Message for specific code Generic410: description: Gone headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic410 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [410] + enum: + - 410 code: - enum: [GONE] + enum: + - GONE examples: GENERIC_410_GONE: - description: Use in notifications flow to allow API Consumer to indicate - that its callback is no longer available + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available value: status: 410 code: GONE @@ -726,23 +673,23 @@ components: description: Failed precondition headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic412 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [412] + enum: + - 412 code: - enum: [FAILED_PRECONDITION] + enum: + - FAILED_PRECONDITION examples: GENERIC_412_FAILED_PRECONDITION: - description: Indication by the API Server that the request cannot be - processed in current system state + description: Indication by the API Server that the request cannot be processed in current system state value: status: 412 code: FAILED_PRECONDITION @@ -751,50 +698,49 @@ components: description: Unsupported Media Type headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic415 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [415] + enum: + - 415 code: - enum: [UNSUPPORTED_MEDIA_TYPE] + enum: + - UNSUPPORTED_MEDIA_TYPE examples: GENERIC_415_UNSUPPORTED_MEDIA_TYPE: - description: Payload format of the request is in an unsupported format - by the Server. Should not happen + description: Payload format of the request is in an unsupported format by the Server. Should not happen value: status: 415 code: UNSUPPORTED_MEDIA_TYPE - message: The server refuses to accept the request because the payload - format is in an unsupported format. + message: The server refuses to accept the request because the payload format is in an unsupported format. Generic422: description: Unprocessable Content headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic422 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [422] + enum: + - 422 code: enum: - SERVICE_NOT_APPLICABLE - MISSING_IDENTIFIER - UNSUPPORTED_IDENTIFIER - UNNECESSARY_IDENTIFIER - - '{{SPECIFIC_CODE}}' + # - "{{SPECIFIC_CODE}}" - API-specific codes added if needed examples: GENERIC_422_SERVICE_NOT_APPLICABLE: description: Service not applicable for the provided identifier @@ -803,9 +749,7 @@ components: code: SERVICE_NOT_APPLICABLE message: The service is not available for the provided identifier. GENERIC_422_MISSING_IDENTIFIER: - description: An identifier is not included in the request and the device - or phone number identification cannot be derived from the 3-legged - access token + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token value: status: 422 code: MISSING_IDENTIFIER @@ -817,36 +761,36 @@ components: code: UNSUPPORTED_IDENTIFIER message: The identifier provided is not supported. GENERIC_422_UNNECESSARY_IDENTIFIER: - description: An explicit identifier is provided when a device or phone - number has already been identified from the access token + description: An explicit identifier is provided when a device or phone number has already been identified from the access token value: status: 422 code: UNNECESSARY_IDENTIFIER message: The device is already identified by the access token. - GENERIC_422_{{SPECIFIC_CODE}}: - description: Any semantic condition associated to business logic, specifically - related to a field or data structure - value: - status: 422 - code: '{{SPECIFIC_CODE}}' - message: '{{SPECIFIC_CODE_MESSAGE}}' + # GENERIC_422_{{SPECIFIC_CODE}}: + # description: Any semantic condition associated to business logic, specifically related to a field or data structure + # value: + # status: 422 + # code: "{{SPECIFIC_CODE}}" + # message: Message for specific code Generic429: description: Too Many Requests headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic429 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [429] + enum: + - 429 code: - enum: [QUOTA_EXCEEDED, TOO_MANY_REQUESTS] + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS examples: GENERIC_429_QUOTA_EXCEEDED: description: Request is rejected due to exceeding a business quota limit @@ -855,8 +799,7 @@ components: code: QUOTA_EXCEEDED message: Out of resource quota. GENERIC_429_TOO_MANY_REQUESTS: - description: Access to the API has been temporarily blocked due to rate - or spike arrest limits being reached + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached value: status: 429 code: TOO_MANY_REQUESTS @@ -865,19 +808,20 @@ components: description: Internal Server Error headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic500 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [500] + enum: + - 500 code: - enum: [INTERNAL] + enum: + - INTERNAL examples: GENERIC_500_INTERNAL: description: Problem in Server side. Regular Server Exception @@ -889,23 +833,23 @@ components: description: Not Implemented headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic501 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [501] + enum: + - 501 code: - enum: [NOT_IMPLEMENTED] + enum: + - NOT_IMPLEMENTED examples: GENERIC_501_NOT_IMPLEMENTED: - description: Service not implemented. The use of this code should be - avoided as far as possible to get the objective to reach aligned implementations + description: Service not implemented. The use of this code should be avoided as far as possible to get the objective to reach aligned implementations value: status: 501 code: NOT_IMPLEMENTED @@ -914,23 +858,23 @@ components: description: Bad Gateway headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic502 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [502] + enum: + - 502 code: - enum: [BAD_GATEWAY] + enum: + - BAD_GATEWAY examples: GENERIC_502_BAD_GATEWAY: - description: Internal routing problem in the Server side that blocks - to manage the service properly + description: Internal routing problem in the Server side that blocks to manage the service properly value: status: 502 code: BAD_GATEWAY @@ -939,23 +883,23 @@ components: description: Service Unavailable headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic503 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [503] + enum: + - 503 code: - enum: [UNAVAILABLE] + enum: + - UNAVAILABLE examples: GENERIC_503_UNAVAILABLE: - description: Service is not available. Temporary situation usually related - to maintenance process in the server side + description: Service is not available. Temporary situation usually related to maintenance process in the server side value: status: 503 code: UNAVAILABLE @@ -964,19 +908,20 @@ components: description: Gateway Timeout headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: "#/components/headers/x-correlator" content: application/json: schema: - title: Generic504 allOf: - - $ref: '#/components/schemas/ErrorInfo' + - $ref: "#/components/schemas/ErrorInfo" - type: object properties: status: - enum: [504] + enum: + - 504 code: - enum: [TIMEOUT] + enum: + - TIMEOUT examples: GENERIC_504_TIMEOUT: description: API Server Timeout From c0e359e6938120de9b922a450cf3629262ebb377 Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Mon, 25 May 2026 15:36:15 -0400 Subject: [PATCH 03/10] Add CAMARA common event and subscription data types This file defines common data types for CAMARA event notifications and subscription management, including schemas for CloudEvents, subscription management, protocol support, and error responses. --- code/common/CAMARA_common_event.yaml | 627 +++++++++++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 code/common/CAMARA_common_event.yaml diff --git a/code/common/CAMARA_common_event.yaml b/code/common/CAMARA_common_event.yaml new file mode 100644 index 0000000..9d74ec5 --- /dev/null +++ b/code/common/CAMARA_common_event.yaml @@ -0,0 +1,627 @@ +info: + title: CAMARA common event and subscription data types + description: | + Common data types for CAMARA event notification and subscription management. + This file contains Commonalities-owned schemas that are identical across all + CAMARA APIs supporting event notifications and/or explicit subscriptions. + + API repositories place this file in `code/common/` alongside `CAMARA_common.yaml` + and reference schemas via `$ref: "../common/CAMARA_event_common.yaml#/components/schemas/"`. + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: wip + x-camara-commonalities: 0.8.0-rc.2 + +components: + securitySchemes: + notificationsBearerAuth: + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + description: | + Bearer token for notification delivery. Token format is determined + by `sinkCredential.credentialType` in the subscription request. + + schemas: + + # ───────────────────────────────────────────────────────────────────────── + # Section 1: CloudEvents 1.0 envelope + # + # Pure CloudEvents 1.0 specification envelope. Knows nothing about CAMARA + # event types, data payloads, or discriminator mappings. Any CAMARA API + # that needs to send a notification starts here. + # ───────────────────────────────────────────────────────────────────────── + + CloudEvent: + type: object + description: | + CloudEvents 1.0 specification envelope. + This schema is the stable base for all CAMARA event notifications. + It imposes no constraints on `type` values or `data` structure — + those concerns belong to the API-specific and lifecycle group schemas. + required: + - id + - source + - specversion + - type + - time + properties: + id: + type: string + maxLength: 256 + description: Identifier of this event, unique within the source context. + source: + $ref: "#/components/schemas/Source" + type: + type: string + maxLength: 512 + description: | + Identifies the event type. CAMARA APIs use reverse-DNS notation: + `org.camaraproject...` + The api-name segment makes each type globally unique across API groups. + specversion: + type: string + description: Version of the specification to which this event conforms (must be 1.0 if it conforms to cloudevents 1.0.2 version) + enum: + - "1.0" + datacontenttype: + type: string + description: 'media-type that describes the event payload encoding, must be "application/json" for CAMARA APIs' + enum: + - application/json + data: + type: object + description: Event details payload. Structure is defined by each concrete event schema. + time: + $ref: "CAMARA_common.yaml#/components/schemas/DateTime" + + Source: + type: string + format: uri-reference + minLength: 1 + maxLength: 2048 + description: | + Identifies the context in which an event happened - be a non-empty `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.example.com" + + # ───────────────────────────────────────────────────────────────────────── + # Section 2: Subscription management + # + # Configuration and identification schemas used by the subscription + # management endpoints. These are Commonalities-owned and identical + # across all CAMARA APIs that support explicit subscriptions. + # ───────────────────────────────────────────────────────────────────────── + + SubscriptionId: + type: string + maxLength: 256 + description: The unique identifier of the subscription in the scope of the subscription manager. When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + + Config: + description: | + Implementation-specific configuration parameters needed by the subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`, `subscriptionMaxEvents`, `initialEvent` + Specific event type attributes must be defined in `subscriptionDetail`. + Note: if a request is performed for several event types, all subscribed events will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + maxLength: 64 + example: 2023-01-17T13:18:23.682Z + description: The subscription expiration time (in date-time format) requested by the API consumer. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Up to API project decision to keep it. + subscriptionMaxEvents: + type: integer + format: int32 + description: Identifies the maximum number of event reports to be generated (>=1) requested by the API consumer - Once this number is reached, the subscription ends. Up to API project decision to keep it. + minimum: 1 + maximum: 1000000 + example: 5 + initialEvent: + type: boolean + description: | + Set to `true` by API consumer if consumer wants to get an event as soon as the subscription is created and current situation reflects event request. + Example: Consumer request Roaming event. If consumer sets initialEvent to true and device is in roaming situation, an event is triggered + Up to API project decision to keep it. + + CreateSubscriptionDetail: + description: The detail of the requested event subscription. + type: object + + # ───────────────────────────────────────────────────────────────────────── + # Section 3: Protocol support + # + # Protocol selection and protocol-specific delivery settings. + # These are Commonalities-owned and identical across all CAMARA APIs. + # ───────────────────────────────────────────────────────────────────────── + + Protocol: + type: string + enum: + - HTTP + # Future protocol support (not yet used in CAMARA): + # - MQTT3 + # - MQTT5 + # - AMQP + # - NATS + # - KAFKA + description: Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + + HTTPSettings: + type: object + description: HTTP protocol settings for event delivery. + properties: + headers: + type: object + description: |- + A set of key/value pairs that is copied into the HTTP request as custom headers. + + NOTE: Use/Applicability of this concept has not been discussed in Commonalities. When required by an API project as an option to meet a UC/Requirement, please generate an issue for Commonalities discussion about it. + additionalProperties: + type: string + maxLength: 512 + method: + type: string + description: The HTTP method to use for sending the message. + enum: + - POST + + # Future protocol support (not yet used in CAMARA): + # MQTTSettings: + # type: object + # properties: + # topicName: + # type: string + # maxLength: 256 + # description: MQTT topic name + # qos: + # type: integer + # format: int32 + # minimum: 0 + # maximum: 2 + # description: Quality of Service level (0, 1, or 2) + # retain: + # type: boolean + # expiry: + # type: integer + # format: int32 + # minimum: 0 + # maximum: 2147483647 + # description: Message expiry interval in seconds + # userProperties: + # type: object + # required: + # - topicName + + # AMQPSettings: + # type: object + # properties: + # address: + # type: string + # maxLength: 512 + # linkName: + # type: string + # maxLength: 256 + # senderSettlementMode: + # type: string + # enum: ["settled", "unsettled"] + # linkProperties: + # type: object + # additionalProperties: + # type: string + # maxLength: 1024 + + # ApacheKafkaSettings: + # type: object + # properties: + # topicName: + # type: string + # maxLength: 249 + # partitionKeyExtractor: + # type: string + # maxLength: 512 + # clientId: + # type: string + # maxLength: 256 + # ackMode: + # type: integer + # format: int32 + # minimum: 0 + # maximum: 2 + # description: Acknowledgment mode (0=no ack, 1=leader ack, 2=all replicas ack) + # required: + # - topicName + + # NATSSettings: + # type: object + # properties: + # subject: + # type: string + # maxLength: 256 + # description: NATS subject + # required: + # - subject + + # ───────────────────────────────────────────────────────────────────────── + # Section 4: Sink credentials + # + # Authentication and authorization information for event delivery. + # These are Commonalities-owned and identical across all CAMARA APIs. + # ───────────────────────────────────────────────────────────────────────── + + SinkCredential: + description: A sink credential provides authentication or authorization information necessary to enable delivery of events to a target. + type: object + properties: + credentialType: + type: string + enum: + # - PLAIN # not used in CAMARA + - ACCESSTOKEN + - PRIVATE_KEY_JWT + description: | + The type of the credential - MUST be set to ACCESSTOKEN or PRIVATE_KEY_JWT for now + discriminator: + propertyName: credentialType + mapping: + # PLAIN: "#/components/schemas/PlainCredential" # not used in CAMARA + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + PRIVATE_KEY_JWT: "#/components/schemas/PrivateKeyJWTCredential" + required: + - credentialType + + # PlainCredential: # not used in CAMARA + # type: object + # description: A plain credential as a combination of an identifier and a secret. + # allOf: + # - $ref: "#/components/schemas/SinkCredential" + # - type: object + # required: + # - identifier + # - secret + # properties: + # identifier: + # description: The identifier might be an account or username. + # type: string + # maxLength: 256 + # secret: + # description: The secret might be a password or passphrase. + # type: string + # maxLength: 512 + + AccessTokenCredential: + type: object + description: An access token credential. This type of credential is meant to be used by API Consumers that have limited capabilities to handle authorization requests. + allOf: + - $ref: "#/components/schemas/SinkCredential" + - type: object + properties: + accessToken: + description: REQUIRED. An access token is a token granting access to the target resource. + type: string + maxLength: 4096 + accessTokenExpiresUtc: + type: string + format: date-time + maxLength: 64 + description: | + REQUIRED. An absolute (UTC) timestamp at which the token shall be considered expired. + In the case of an ACCESS_TOKEN_EXPIRED termination reason, implementation should notify the client before the expiration date. + If the access token is a JWT and registered "exp" (Expiration Time) claim is present, the two expiry times should match. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + accessTokenType: + description: REQUIRED. Type of the access token (See [OAuth 2.0](https://tools.ietf.org/html/rfc6749#section-7.1)). + type: string + enum: + - bearer + required: + - accessToken + - accessTokenExpiresUtc + - accessTokenType + + PrivateKeyJWTCredential: + type: object + description: Use PRIVATE_KEY_JWT to get an access token. The authorization server information needed for this type of sink credential (token endpoint, client ID, JWKS URL) is shared upfront between the client and the CAMARA entity. This type of credential is to be used by clients that have an authorization server. + allOf: + - $ref: "#/components/schemas/SinkCredential" + + # ───────────────────────────────────────────────────────────────────────── + # Section 5: Subscription lifecycle data + # + # Data payload schemas for subscription lifecycle events. These define the + # `data` content of subscription-started, subscription-updated, and + # subscription-ended events. The lifecycle event wrappers (which contain + # api-name placeholders in their event type strings) stay in API templates. + # ───────────────────────────────────────────────────────────────────────── + + SubscriptionStarted: + description: Event detail structure for subscription started event + type: object + required: + - initiationReason + - subscriptionId + properties: + initiationReason: + $ref: "#/components/schemas/InitiationReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + initiationDescription: + type: string + maxLength: 512 + description: Description of subscription initiation + + InitiationReason: + type: string + description: | + - SUBSCRIPTION_CREATED - Subscription created by API Server + enum: + - SUBSCRIPTION_CREATED + + SubscriptionUpdated: + description: Event detail structure for subscription updated event + type: object + required: + - updateReason + - subscriptionId + properties: + updateReason: + $ref: "#/components/schemas/UpdateReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + updateDescription: + type: string + maxLength: 512 + description: Description of subscription update + + UpdateReason: + type: string + description: | + - SUBSCRIPTION_ACTIVE - API server transitioned subscription status to `ACTIVE` + - SUBSCRIPTION_INACTIVE - API server transitioned subscription status to `INACTIVE` + enum: + - SUBSCRIPTION_ACTIVE + - SUBSCRIPTION_INACTIVE + + SubscriptionEnded: + description: Event detail structure for subscription ended event + type: object + required: + - terminationReason + - subscriptionId + properties: + terminationReason: + $ref: "#/components/schemas/TerminationReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + terminationDescription: + type: string + maxLength: 512 + description: Description of subscription termination + + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by the requester with credential type `ACCESSTOKEN`) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + # ───────────────────────────────────────────────────────────────────────── + # Subscription-specific error responses + # + # These extend generic CAMARA error codes with subscription-specific codes. + # Commonalities-owned and identical across all APIs using explicit subscriptions. + # ───────────────────────────────────────────────────────────────────────── + + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token or Private key JWT are supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNSUPPORTED_IDENTIFIER + - UNNECESSARY_IDENTIFIER + - MULTIEVENT_SUBSCRIPTION_NOT_SUPPORTED + - MULTIEVENT_COMBINATION_TEMPORARILY_NOT_SUPPORTED + - PRIVATE_KEY_JWT_NOT_CONFIGURED + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNSUPPORTED_IDENTIFIER: + description: None of the provided identifiers is supported by the implementation + value: + status: 422 + code: UNSUPPORTED_IDENTIFIER + message: The identifier provided is not supported. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + GENERIC_422_MULTIEVENT_SUBSCRIPTION_NOT_SUPPORTED: + description: Multi event types subscription is not supported + value: + status: 422 + code: MULTIEVENT_SUBSCRIPTION_NOT_SUPPORTED + message: Multi event types subscription not managed + GENERIC_422_MULTIEVENT_COMBINATION_TEMPORARILY_NOT_SUPPORTED: + description: Combination of multiple event types is temporarily not supported + value: + status: 422 + code: MULTIEVENT_COMBINATION_TEMPORARILY_NOT_SUPPORTED + message: The requested combination of event types is temporarily not supported. + GENERIC_422_PRIVATE_KEY_JWT_NOT_CONFIGURED: + description: Private key JWT sink credential type is used but no configuration was pre-shared + value: + status: 422 + code: PRIVATE_KEY_JWT_NOT_CONFIGURED + message: No JWK Set configured for PRIVATE_KEY_JWT authentication. From 340a06a995bd972d715b6572c373bbb92dd8bd71 Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Mon, 25 May 2026 15:39:56 -0400 Subject: [PATCH 04/10] Add OpenAPI Overlay Specification version 1.1.0 This file provides a YAML representation of the OpenAPI Overlay Specification version 1.1.0, including schemas for Overlay, OverlayInfo, and OverlayAction. It is designed to be a reference for CAMARA API specifications without encoding CAMARA-specific semantics. --- code/modules/openapi-overlay-1.1.0.yaml | 193 ++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 code/modules/openapi-overlay-1.1.0.yaml diff --git a/code/modules/openapi-overlay-1.1.0.yaml b/code/modules/openapi-overlay-1.1.0.yaml new file mode 100644 index 0000000..3f286fd --- /dev/null +++ b/code/modules/openapi-overlay-1.1.0.yaml @@ -0,0 +1,193 @@ +# Hand-authored YAML mirror of the OpenAPI Overlay Specification, version 1.1.0. +# Authoritative source (version-pinned): https://spec.openapis.org/overlay/v1.1.0.html +# +# IMPORTANT: this file targets Overlay 1.1.0 *specifically*. Do NOT replace the +# version-pinned URL above with https://spec.openapis.org/overlay/latest.html — +# `latest.html` follows the upstream release train (Overlay 1.2.0 and beyond) +# and would silently change the contract this file is meant to mirror. If a +# future CAMARA design adopts a newer Overlay version, create a sibling file +# (e.g. `openapi-overlay-1.2.0.yaml`) rather than mutating this one. The +# Overlay 1.0.0 mirror is preserved alongside this one as +# `openapi-overlay-1.0.0.yaml`; pick the file that matches the Overlay version +# the consuming CAMARA API is designed against. +# +# This file exists solely to provide a $ref-able JSON Schema representation of +# the upstream Overlay 1.1.0 object family (Overlay, Info, Action). It is NOT +# a CAMARA API in its own right. Do not modify the schemas below to reflect +# CAMARA-specific constraints; CAMARA-side narrowing (such as the +# "restriction-only" rule) is expressed in prose by the consuming API. +openapi: 3.0.3 +info: + title: OpenAPI Overlay 1.1.0 Schemas + description: | + Hand-authored YAML mirror of the [OpenAPI Overlay Specification, version + 1.1.0](https://spec.openapis.org/overlay/v1.1.0.html). The version-pinned + URL is deliberate: `https://spec.openapis.org/overlay/latest.html` follows + the upstream release train and may resolve to a newer Overlay version, + which would change the contract this file mirrors. + + Provides a referencable JSON Schema representation of the upstream Overlay, + Info and Action object families so that CAMARA API specifications can type + their request/response payloads and CloudEvent `data` payloads against the + Overlay 1.1.0 shape without inventing CAMARA-private schemas. + + Differences from the sibling `openapi-overlay-1.0.0.yaml` mirror reflect + the upstream 1.0.0 → 1.1.0 delta: the `overlay` version field value + changes to `1.1.0`; the Action Object gains an optional `copy` field + (RFC 9535 JSONPath selecting a single source node in the target document); + precedence among `update`, `copy`, and `remove` is restated so that + `remove` wins over both, and `update` and `copy` are mutually exclusive; + and the `update` semantics for multi-node targets are clarified. + + This file MUST NOT be modified to encode CAMARA-specific semantics. Any + narrowing of valid overlay content (e.g. the CAMARA "restriction-only" + rule) is the responsibility of the consuming CAMARA API and is expressed + in prose on that API, not on this file. To adopt a newer Overlay version, + create a sibling file rather than editing this one. + version: 1.1.0 + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +paths: {} + +components: + schemas: + + Overlay: + description: | + An OpenAPI Overlay document, as defined by version 1.1.0 of the + [OpenAPI Overlay Specification](https://spec.openapis.org/overlay/v1.1.0.html). + An Overlay declares a set of `actions` to be applied to a target + OpenAPI document, allowing the document to be amended without + modifying it directly. Schemas in this file mirror Overlay 1.1.0 + specifically; other Overlay versions are represented in sibling + files (e.g. `openapi-overlay-1.0.0.yaml`). + type: object + required: + - overlay + - info + - actions + properties: + overlay: + type: string + description: | + The version of the Overlay Specification that this Overlay document + uses. For documents conforming to this version of the specification, + the value MUST be `1.1.0`. + enum: + - 1.1.0 + info: + $ref: "#/components/schemas/OverlayInfo" + extends: + type: string + format: uri + maxLength: 2048 + description: | + URI reference identifying the target document (such as an OpenAPI + document) that the Overlay applies to. Optional. When present, + processors MAY use this value to locate the target document. + Both absolute and relative URI references are permitted. + actions: + type: array + minItems: 1 + maxItems: 1000 + description: | + An ordered list of Action objects to be applied to the target + document in sequential order; each action operates on the + document state produced by the actions preceding it. + items: + $ref: "#/components/schemas/OverlayAction" + + OverlayInfo: + description: | + Provides metadata about the Overlay. Mirrors the Info Object as + defined by version 1.1.0 of the + [OpenAPI Overlay Specification](https://spec.openapis.org/overlay/v1.1.0.html). + type: object + required: + - title + - version + properties: + title: + type: string + minLength: 1 + maxLength: 256 + description: | + A human-readable description of the purpose of the Overlay. + description: + type: string + maxLength: 4096 + description: | + A description of the Overlay document. [CommonMark](https://commonmark.org/) + syntax MAY be used for rich text representation. + version: + type: string + minLength: 1 + maxLength: 64 + description: | + A version identifier for indicating changes to the Overlay + document. Distinct from the `overlay` field above, which identifies + the version of the Overlay Specification. + + OverlayAction: + description: | + Describes a single action to be applied to the target document. + Mirrors the Action Object as defined by version 1.1.0 of the + [OpenAPI Overlay Specification](https://spec.openapis.org/overlay/v1.1.0.html). + Per Overlay 1.1.0, precedence among the three mutating fields is: + `remove: true` overrides both `update` and `copy`; otherwise `update` + and `copy` are mutually exclusive and a processor that encounters + both on the same action MUST treat each as having no effect on the + other (i.e. neither is applied). When none of `update`, `copy`, or + a truthy `remove` is present, the action is a no-op. When `target` + selects multiple nodes, those nodes MUST all be objects, all be + arrays, or all be primitives. + type: object + required: + - target + properties: + target: + type: string + minLength: 1 + maxLength: 4096 + description: | + A JSONPath query expression (as defined by [RFC 9535](https://www.rfc-editor.org/rfc/rfc9535)) + that identifies the node(s) in the target document on which this + action operates. + description: + type: string + maxLength: 4096 + description: | + A description of the action. [CommonMark](https://commonmark.org/) + syntax MAY be used for rich text representation. + update: + description: | + A value to be merged with (or appended to) each node selected by + `target`. If the selected nodes are objects, the value MUST be an + object and its properties are merged into each target object. If + the selected nodes are arrays, the value is appended to each + target array. If the selected nodes are primitives, each target + value is replaced by this value. Has no effect when `remove` is + `true` or when `copy` is also present on the same action. + copy: + type: string + minLength: 1 + maxLength: 4096 + description: | + A JSONPath query expression (as defined by [RFC 9535](https://www.rfc-editor.org/rfc/rfc9535)) + selecting a single node in the target document whose value is to + be copied into each node selected by `target`. Semantics parallel + `update`, but the source value is drawn from the document being + transformed rather than from the Overlay. Has no effect when + `remove` is `true` or when `update` is also present on the same + action. + remove: + type: boolean + default: false + description: | + When `true`, each node selected by `target` is removed from its + containing object or array. When `false` (or absent), the target + nodes are retained and `update` or `copy` (if any) is applied. + If `remove` is `true` it takes precedence over both `update` and + `copy`. From ce7c6b2ec1925a41469fec67d3bb214ada733b0b Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:21:54 -0400 Subject: [PATCH 05/10] Move code/effective-capabilities-and-restrictions.yaml to code/API_definitions/effective-capabilities-and-restrictions.yaml --- .../effective-capabilities-and-restrictions.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename code/{ => API_definitions}/effective-capabilities-and-restrictions.yaml (100%) diff --git a/code/effective-capabilities-and-restrictions.yaml b/code/API_definitions/effective-capabilities-and-restrictions.yaml similarity index 100% rename from code/effective-capabilities-and-restrictions.yaml rename to code/API_definitions/effective-capabilities-and-restrictions.yaml From cd48611367d6638d0cf123bbd5f440b20ec6ef1a Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:33:39 -0400 Subject: [PATCH 06/10] renaming the CAMARA_common.yaml to old-CAMARA_common.yaml for passing the linting errors for the existing design This YAML file defines the common data types for CAMARA APIs, including security schemes, headers, parameters, and response schemas. --- code/common/old-CAMARA_common-.yaml | 986 ++++++++++++++++++++++++++++ 1 file changed, 986 insertions(+) create mode 100644 code/common/old-CAMARA_common-.yaml diff --git a/code/common/old-CAMARA_common-.yaml b/code/common/old-CAMARA_common-.yaml new file mode 100644 index 0000000..c2ddd8d --- /dev/null +++ b/code/common/old-CAMARA_common-.yaml @@ -0,0 +1,986 @@ +--- +openapi: 3.0.3 +info: + title: CAMARA common data types + description: Common data types for CAMARA APIs + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: wip + x-camara-commonalities: tbd +paths: {} +components: + securitySchemes: + openId: + description: OpenID Connect authentication. + type: openIdConnect + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Notification bearer authentication. + type: http + scheme: bearer + bearerFormat: '{$request.body#/sinkCredential.credentialType}' + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: '#/components/schemas/XCorrelator' + Cache-Control: + description: Public cacheable for 10 minutes + schema: + type: string + example: public, max-age=600 + ETag: + description: Entity tag for caching + schema: + type: string + Last-Modified: + description: Timestamp of last modification + schema: + type: string + format: date-time + Accept-Patch: + description: Advertises which media types the server is able to understand in + a PATCH request + schema: + type: string + example: application/merge-patch+json, application/json-patch+json + parameters: + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: '#/components/schemas/XCorrelator' + If-Match: + name: If-Match + in: header + description: Apply only if the ETag matches (RFC 7232). + schema: + type: string + If-None-Match: + name: If-None-Match + in: header + description: ETag for conditional requests + schema: + type: string + If-Modified-Since: + name: If-Modified-Since + in: header + description: Timestamp for conditional requests + schema: + type: string + format: date-time + GroupId: + name: GroupId + in: path + required: true + description: Reference Id for a created group + schema: + type: string + format: uuid + schemas: + XCorrelator: + type: string + description: XCorrelator + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: b4333c46-49c0-4f62-80d7-f0ef930f1c46 + TimePeriod: + type: object + description: TimePeriod + properties: + startDate: + type: string + format: date-time + description: An instant of time, starting of the TimePeriod. It must follow + [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) + and must have time zone. + endDate: + type: string + format: date-time + description: An instant of time, ending of the TimePeriod. If not included, + then the period has no ending date. It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) + and must have time zone. + required: [startDate] + ErrorInfo: + type: object + description: ErrorInfo + required: [status, code, message] + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + ApplicationServer: + description: | + A server hosting backend applications to deliver some business logic to clients. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + type: object + properties: + ipv4Address: + $ref: '#/components/schemas/ApplicationServerIpv4Address' + ipv6Address: + $ref: '#/components/schemas/ApplicationServerIpv6Address' + minProperties: 1 + ApplicationServerIpv4Address: + type: string + example: 198.51.100.0/24 + description: | + IPv4 address may be specified in form
as: + - address - an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule. + - address/mask - an IP number as above with a mask width of the form 1.2.3.4/24. + In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version. + ApplicationServerIpv6Address: + type: string + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + description: | + IPv6 address may be specified in form
as: + - address - The /128 subnet is optional for single addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344/128 + - address/mask - an IP v6 number with a mask: + - 2001:db8:85a3:8d3::0/64 + - 2001:db8:85a3:8d3::/64 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: '#/components/schemas/PhoneNumber' + networkAccessIdentifier: + $ref: '#/components/schemas/NetworkAccessIdentifier' + ipv4Address: + $ref: '#/components/schemas/DeviceIpv4Addr' + ipv6Address: + $ref: '#/components/schemas/DeviceIpv6Address' + minProperties: 1 + DeviceResponse: + description: | + An identifier for the end-user equipment able to connect to the network that the response refers to. This parameter is only returned when the API consumer includes the `device` parameter in their request (i.e. they are using a two-legged access token), and is relevant when more than one device identifier is specified, as only one of those device identifiers is allowed in the response. + If the API consumer provides more than one device identifier in their request, and this schema is included in the response definition, the API provider MUST use it to return a single identifier which is the one they are using to fulfil the request, even if the identifiers do not match the same device. API provider does not perform any logic to validate/correlate that the indicated device identifiers match the same device. No error should be returned if the identifiers are otherwise valid to prevent API consumers correlating different identifiers with a given end user. + allOf: + - $ref: '#/components/schemas/Device' + - maxProperties: 1 + PhoneNumber: + description: A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International Subscriber + Directory Number). In order to be globally unique it has to be formatted in + international format, according to E.164 standard, prefixed with '+'. + type: string + pattern: ^\+[1-9][0-9]{4,14}$ + example: '+123456789' + NetworkAccessIdentifier: + description: A public identifier addressing a subscription in a mobile network. + In 3GPP terminology, it corresponds to the GPSI formatted with the External + Identifier ({Local Identifier}@{Domain Identifier}). Unlike the telephone + number, the network access identifier is not subjected to portability ruling + in force, and is individually managed by each operator. + type: string + example: 123456789@example.com + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP address and port as seen by the application server, or the private (local) and any public (observed) IP addresses in use by the device (this information can be obtained by various means, for example from some DNS servers). + If the allocated and observed IP addresses are the same (i.e. NAT is not in use) then the same address should be specified for both publicAddress and privateAddress. + If NAT64 is in use, the device should be identified by its publicAddress and publicPort, or separately by its allocated IPv6 address (field ipv6Address of the Device object) + In all cases, publicAddress must be specified, along with at least one of either privateAddress or publicPort, dependent upon which is known. In general, mobile devices cannot be identified by their public IPv4 address alone. + properties: + publicAddress: + $ref: '#/components/schemas/SingleIpv4Addr' + privateAddress: + $ref: '#/components/schemas/SingleIpv4Addr' + publicPort: + $ref: '#/components/schemas/Port' + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: + publicAddress: 84.125.93.10 + publicPort: 59765 + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: 84.125.93.10 + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + PortsSpec: + description: Specification of several TCP or UDP ports + type: object + minProperties: 1 + properties: + ranges: + description: Range of TCP or UDP ports + type: array + minItems: 1 + items: + type: object + required: [from, to] + properties: + from: + $ref: '#/components/schemas/Port' + to: + $ref: '#/components/schemas/Port' + ports: + description: Array of TCP or UDP ports + type: array + minItems: 1 + items: + $ref: '#/components/schemas/Port' + example: + ranges: + - from: 5010 + to: 5020 + ports: [5060, 5070] + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any single IPv6 address from within the subnet allocated to the device (e.g. adding ::0 to the /64 prefix). + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + Area: + description: Base schema for all areas + type: object + properties: + areaType: + $ref: '#/components/schemas/AreaType' + required: [areaType] + discriminator: + propertyName: areaType + mapping: + CIRCLE: '#/components/schemas/Circle' + POLYGON: '#/components/schemas/Polygon' + AreaType: + type: string + description: | + Type of this area. + CIRCLE - The area is defined as a circle. + POLYGON - The area is defined as a polygon. + enum: [CIRCLE, POLYGON] + Circle: + description: Circular area + allOf: + - $ref: '#/components/schemas/Area' + - type: object + required: [center, radius] + properties: + center: + $ref: '#/components/schemas/Point' + radius: + type: number + description: Distance from the center in meters + minimum: 1 + Polygon: + description: Polygonal area. The Polygon should be a simple polygon, i.e. should + not intersect itself. + allOf: + - $ref: '#/components/schemas/Area' + - type: object + required: [boundary] + properties: + boundary: + $ref: '#/components/schemas/PointList' + PointList: + description: List of points defining a polygon + type: array + items: + $ref: '#/components/schemas/Point' + minItems: 3 + maxItems: 15 + Point: + type: object + description: Coordinates (latitude, longitude) defining a location in a map + required: [latitude, longitude] + properties: + latitude: + $ref: '#/components/schemas/Latitude' + longitude: + $ref: '#/components/schemas/Longitude' + example: + latitude: 50.735851 + longitude: 7.10066 + QosProfileName: + description: | + A unique name for identifying a specific QoS profile. + This may follow different formats depending on the API provider implementation. + Some options addresses: + - A UUID style string + - Support for predefined profiles QOS_S, QOS_M, QOS_L, and QOS_E + - A searchable descriptive name + The set of QoS Profiles that an API provider is offering may be retrieved by means of the QoS Profile API (qos-profile) or agreed on onboarding time. + type: string + example: voice + minLength: 3 + maxLength: 256 + format: string + pattern: ^[a-zA-Z0-9_.-]+$ + Latitude: + description: Latitude component of a location + type: number + format: double + minimum: -90 + maximum: 90 + Longitude: + description: Longitude component of location + type: number + format: double + minimum: -180 + maximum: 180 + GroupId: + description: Reference Id for a created group + type: string + format: uuid + ResourceScopes: + description: A list of resource scopes + type: array + items: + anyOf: + - $ref: '#/components/schemas/Device' + - $ref: '#/components/schemas/Area' + - $ref: '#/components/schemas/GroupId' + - $ref: '#/components/schemas/PortsSpec' + responses: + ####################################################### + ####################################################### + # ERROR RESPONSE SCHEMA TEMPLATE + # - Objective: Make normative error `status` and `code` values + # - Schema Template rationale: + # - The `allOf` in content.application/json.schema allows a combination of both the generic ErrorInfo schema and the specific schema for this error response, + # which validates that `status` and `code` have only the specified values. + # This `allOf` is used without discriminator because it does not imply any hierarchy between the models, just 2 schemas that must be independently validated. + ####################################################### + # ErrorResponseSchema: + # ... + # content: + # application/json: + # schema: + # allOf: + # - $ref: '#/components/schemas/ErrorInfo' + # - type: object + # properties: + # status: + # enum: + # - + # code: + # enum: + # - + # - + # examples: + # ExampleKey1: + # value: + # status: + # code: + # message: + # ExampleKey2: + # value: + # status: + # code: + # message: + ####################################################### + ####################################################### + Generic304: + description: Not Modified + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic304 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [304] + code: + enum: [NOT_MODIFIED] + examples: + GENERIC_304_NOT_MODIFIED: + description: Not Modified. The resource has not been modified since + the last request. + value: + status: 304 + code: NOT_MODIFIED + message: The resource has not been modified since the last request. + Generic400: + description: Bad Request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic400 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + type: integer + enum: [400] + code: + type: string + enum: [INVALID_ARGUMENT, OUT_OF_RANGE, '{{SPECIFIC_CODE}}'] + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query + param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given + field has a pre-defined range or an invalid filter criteria combination + is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_{{SPECIFIC_CODE}}: + description: Specific Syntax Exception regarding a field that is relevant + in the context of the API + value: + status: 400 + code: '{{SPECIFIC_CODE}}' + message: '{{SPECIFIC_CODE_MESSAGE}}' + Generic401: + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic401 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [401] + code: + enum: [UNAUTHENTICATED, ACCESS_TOKEN_EXPIRED] + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication + is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired + credentials. A new authentication is required. + GENERIC_401_ACCESS_TOKEN_EXPIRED: + description: Request cannot be authenticated and access token expired + value: + status: 401 + code: ACCESS_TOKEN_EXPIRED + message: Request not authenticated due to expired access token. A + new authentication is required. + Generic403: + description: Forbidden + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic403 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [403] + code: + enum: [PERMISSION_DENIED, INVALID_TOKEN_CONTEXT, '{{SPECIFIC_CODE}}'] + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the + required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this + action. + GENERIC_403_INVALID_TOKEN_CONTEXT: + description: Reflect some inconsistency between information in some + field of the API and the related OAuth2 Token + value: + status: 403 + code: INVALID_TOKEN_CONTEXT + message: '{{field}} is not consistent with access token.' + GENERIC_403_{{SPECIFIC_CODE}}: + description: Indicate a Business Logic condition that forbids a process + not attached to a specific field in the context of the API + value: + status: 403 + code: '{{SPECIFIC_CODE}}' + message: '{{SPECIFIC_CODE_MESSAGE}}' + Generic404: + description: Not found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic404 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [404] + code: + enum: [NOT_FOUND, IDENTIFIER_NOT_FOUND, '{{SPECIFIC_CODE}}'] + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + GENERIC_404_IDENTIFIER_NOT_FOUND: + description: Some identifier cannot be matched to a device + value: + status: 404 + code: IDENTIFIER_NOT_FOUND + message: Device identifier not found. + GENERIC_404_{{SPECIFIC_CODE}}: + description: Specific situation to highlight the resource/concept not + found + value: + status: 404 + code: '{{SPECIFIC_CODE}}' + message: '{{SPECIFIC_CODE_MESSAGE}}' + GenericDevice404: + description: Not found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: GenericDevice404 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [404] + code: + enum: [NOT_FOUND, IDENTIFIER_NOT_FOUND] + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + GENERIC_404_DEVICE_NOT_FOUND: + description: Device identifier not found + value: + status: 404 + code: IDENTIFIER_NOT_FOUND + message: Device identifier not found. + Generic405: + description: Method Not Allowed + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic405 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [405] + code: + enum: [METHOD_NOT_ALLOWED] + examples: + GENERIC_405_METHOD_NOT_ALLOWED: + description: Invalid HTTP verb used with a given endpoint + value: + status: 405 + code: METHOD_NOT_ALLOWED + message: The requested method is not allowed/supported on the target + resource. + Generic406: + description: Not Acceptable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic406 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [406] + code: + enum: [NOT_ACCEPTABLE] + examples: + GENERIC_406_NOT_ACCEPTABLE: + description: API Server does not accept the media type (`Accept-*` header) + indicated by API client + value: + status: 406 + code: NOT_ACCEPTABLE + message: The server cannot produce a response matching the content + requested by the client through `Accept-*` headers. + Generic409: + description: Conflict + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic409 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [409] + code: + enum: [ABORTED, ALREADY_EXISTS, CONFLICT, '{{SPECIFIC_CODE}}'] + examples: + GENERIC_409_ABORTED: + description: Concurreny of processes of the same nature/scope + value: + status: 409 + code: ABORTED + message: Concurrency conflict. + GENERIC_409_ALREADY_EXISTS: + description: Trying to create an existing resource + value: + status: 409 + code: ALREADY_EXISTS + message: The resource that a client tried to create already exists. + GENERIC_409_CONFLICT: + description: Duplication of an existing resource + value: + status: 409 + code: CONFLICT + message: A specified resource duplicate entry found. + GENERIC_409_{{SPECIFIC_CODE}}: + description: Specific conflict situation that is relevant in the context + of the API + value: + status: 409 + code: '{{SPECIFIC_CODE}}' + message: '{{SPECIFIC_CODE_MESSAGE}}' + Generic410: + description: Gone + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic410 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [410] + code: + enum: [GONE] + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate + that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + Generic412: + description: Failed precondition + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic412 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [412] + code: + enum: [FAILED_PRECONDITION] + examples: + GENERIC_412_FAILED_PRECONDITION: + description: Indication by the API Server that the request cannot be + processed in current system state + value: + status: 412 + code: FAILED_PRECONDITION + message: Request cannot be executed in the current system state. + Generic415: + description: Unsupported Media Type + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic415 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [415] + code: + enum: [UNSUPPORTED_MEDIA_TYPE] + examples: + GENERIC_415_UNSUPPORTED_MEDIA_TYPE: + description: Payload format of the request is in an unsupported format + by the Server. Should not happen + value: + status: 415 + code: UNSUPPORTED_MEDIA_TYPE + message: The server refuses to accept the request because the payload + format is in an unsupported format. + Generic422: + description: Unprocessable Content + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic422 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [422] + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNSUPPORTED_IDENTIFIER + - UNNECESSARY_IDENTIFIER + - '{{SPECIFIC_CODE}}' + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device + or phone number identification cannot be derived from the 3-legged + access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNSUPPORTED_IDENTIFIER: + description: None of the provided identifiers is supported by the implementation + value: + status: 422 + code: UNSUPPORTED_IDENTIFIER + message: The identifier provided is not supported. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone + number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + GENERIC_422_{{SPECIFIC_CODE}}: + description: Any semantic condition associated to business logic, specifically + related to a field or data structure + value: + status: 422 + code: '{{SPECIFIC_CODE}}' + message: '{{SPECIFIC_CODE_MESSAGE}}' + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic429 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [429] + code: + enum: [QUOTA_EXCEEDED, TOO_MANY_REQUESTS] + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate + or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. + Generic500: + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic500 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [500] + code: + enum: [INTERNAL] + examples: + GENERIC_500_INTERNAL: + description: Problem in Server side. Regular Server Exception + value: + status: 500 + code: INTERNAL + message: Unknown server error. Typically a server bug. + Generic501: + description: Not Implemented + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic501 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [501] + code: + enum: [NOT_IMPLEMENTED] + examples: + GENERIC_501_NOT_IMPLEMENTED: + description: Service not implemented. The use of this code should be + avoided as far as possible to get the objective to reach aligned implementations + value: + status: 501 + code: NOT_IMPLEMENTED + message: This functionality is not implemented yet. + Generic502: + description: Bad Gateway + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic502 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [502] + code: + enum: [BAD_GATEWAY] + examples: + GENERIC_502_BAD_GATEWAY: + description: Internal routing problem in the Server side that blocks + to manage the service properly + value: + status: 502 + code: BAD_GATEWAY + message: An upstream internal service cannot be reached. + Generic503: + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic503 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [503] + code: + enum: [UNAVAILABLE] + examples: + GENERIC_503_UNAVAILABLE: + description: Service is not available. Temporary situation usually related + to maintenance process in the server side + value: + status: 503 + code: UNAVAILABLE + message: Service Unavailable. + Generic504: + description: Gateway Timeout + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + title: Generic504 + allOf: + - $ref: '#/components/schemas/ErrorInfo' + - type: object + properties: + status: + enum: [504] + code: + enum: [TIMEOUT] + examples: + GENERIC_504_TIMEOUT: + description: API Server Timeout + value: + status: 504 + code: TIMEOUT + message: Request timeout exceeded. From 9c1fd189a18f1060e2940d674d395faa9e9ae8cb Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:36:52 -0400 Subject: [PATCH 07/10] Update references to old-CAMARA_common.yaml --- .../capabilities-and-restrictions.yaml | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/code/API_definitions/capabilities-and-restrictions.yaml b/code/API_definitions/capabilities-and-restrictions.yaml index 0ad7397..4f68fc7 100644 --- a/code/API_definitions/capabilities-and-restrictions.yaml +++ b/code/API_definitions/capabilities-and-restrictions.yaml @@ -265,25 +265,25 @@ paths: components: securitySchemes: openId: - $ref: ../common/CAMARA_common.yaml#/components/securitySchemes/openId + $ref: ../common/old-CAMARA_common.yaml#/components/securitySchemes/openId notificationsBearerAuth: - $ref: ../common/CAMARA_common.yaml#/components/securitySchemes/notificationsBearerAuth + $ref: ../common/old-CAMARA_common.yaml#/components/securitySchemes/notificationsBearerAuth parameters: x-correlator: - $ref: ../common/CAMARA_common.yaml#/components/parameters/x-correlator + $ref: ../common/old-CAMARA_common.yaml#/components/parameters/x-correlator If-None-Match: - $ref: ../common/CAMARA_common.yaml#/components/parameters/If-None-Match + $ref: ../common/old-CAMARA_common.yaml#/components/parameters/If-None-Match If-Modified-Since: - $ref: ../common/CAMARA_common.yaml#/components/parameters/If-Modified-Since + $ref: ../common/old-CAMARA_common.yaml#/components/parameters/If-Modified-Since headers: x-correlator: - $ref: ../common/CAMARA_common.yaml#/components/headers/x-correlator + $ref: ../common/old-CAMARA_common.yaml#/components/headers/x-correlator Cache-Control: - $ref: ../common/CAMARA_common.yaml#/components/headers/Cache-Control + $ref: ../common/old-CAMARA_common.yaml#/components/headers/Cache-Control ETag: - $ref: ../common/CAMARA_common.yaml#/components/headers/ETag + $ref: ../common/old-CAMARA_common.yaml#/components/headers/ETag Last-Modified: - $ref: ../common/CAMARA_common.yaml#/components/headers/Last-Modified + $ref: ../common/old-CAMARA_common.yaml#/components/headers/Last-Modified schemas: # General items used throughout the specification Contexts: @@ -963,9 +963,9 @@ components: $ref: '#/components/schemas/Extends' required: [overlayExtends] ResourceScopes: - $ref: ../common/CAMARA_common.yaml#/components/schemas/ResourceScopes + $ref: ../common/old-CAMARA_common.yaml#/components/schemas/ResourceScopes ErrorInfo: - $ref: ../common/CAMARA_common.yaml#/components/schemas/ErrorInfo + $ref: ../common/old-CAMARA_common.yaml#/components/schemas/ErrorInfo # Event structures CamaraExtendedSubscriptionRequest: @@ -1035,7 +1035,7 @@ components: x-correlator: $ref: '#/components/headers/x-correlator' Generic400: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic400 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic400 CapabilityApiBadRequest400: description: Bad Request when query capability headers: @@ -1084,11 +1084,11 @@ components: code: INVALID_TOKEN message: Only bearer token is supported Generic401: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic401 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic401 Generic403: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic403 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic403 Generic404: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic404 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic404 CapabilityApiNotFound404: description: Capability API not found content: @@ -1108,15 +1108,15 @@ components: code: NOT_FOUND message: No Capability API found Generic409: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic409 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic409 Generic410: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic410 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic410 Generic429: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic429 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic429 Generic500: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic500 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic500 Generic503: - $ref: ../common/CAMARA_common.yaml#/components/responses/Generic503 + $ref: ../common/old-CAMARA_common.yaml#/components/responses/Generic503 examples: CAMARA_CAPABILITY_QUERY_REQUEST_EXAMPLE: summary: Example of capability query From d223a1f8c069f8499beac3157e32b36c6d934f09 Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:37:08 -0400 Subject: [PATCH 08/10] Rename old-CAMARA_common-.yaml to old-CAMARA_common.yaml --- code/common/{old-CAMARA_common-.yaml => old-CAMARA_common.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename code/common/{old-CAMARA_common-.yaml => old-CAMARA_common.yaml} (100%) diff --git a/code/common/old-CAMARA_common-.yaml b/code/common/old-CAMARA_common.yaml similarity index 100% rename from code/common/old-CAMARA_common-.yaml rename to code/common/old-CAMARA_common.yaml From a8005b27960c91637d6ac9861f11c4e4ad8b7c01 Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:38:47 -0400 Subject: [PATCH 09/10] Update references from CAMARA_common to old-CAMARA_common --- code/common/CAMARA-subscriptions-openapi.yaml | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/code/common/CAMARA-subscriptions-openapi.yaml b/code/common/CAMARA-subscriptions-openapi.yaml index d151a20..a8b2769 100644 --- a/code/common/CAMARA-subscriptions-openapi.yaml +++ b/code/common/CAMARA-subscriptions-openapi.yaml @@ -567,9 +567,9 @@ paths: components: securitySchemes: openId: - $ref: CAMARA_common.yaml#/components/securitySchemes/openId + $ref: old-CAMARA_common.yaml#/components/securitySchemes/openId notificationsBearerAuth: - $ref: CAMARA_common.yaml#/components/securitySchemes/notificationsBearerAuth + $ref: old-CAMARA_common.yaml#/components/securitySchemes/notificationsBearerAuth parameters: SubscriptionId: name: id @@ -580,29 +580,29 @@ components: schema: $ref: '#/components/schemas/SubscriptionId' x-correlator: - $ref: CAMARA_common.yaml#/components/parameters/x-correlator + $ref: old-CAMARA_common.yaml#/components/parameters/x-correlator If-None-Match: - $ref: CAMARA_common.yaml#/components/parameters/If-None-Match + $ref: old-CAMARA_common.yaml#/components/parameters/If-None-Match If-Modified-Since: - $ref: CAMARA_common.yaml#/components/parameters/If-Modified-Since + $ref: old-CAMARA_common.yaml#/components/parameters/If-Modified-Since If-Match: - $ref: CAMARA_common.yaml#/components/parameters/If-Match + $ref: old-CAMARA_common.yaml#/components/parameters/If-Match headers: x-correlator: - $ref: CAMARA_common.yaml#/components/headers/x-correlator + $ref: old-CAMARA_common.yaml#/components/headers/x-correlator Cache-Control: - $ref: CAMARA_common.yaml#/components/headers/Cache-Control + $ref: old-CAMARA_common.yaml#/components/headers/Cache-Control ETag: - $ref: CAMARA_common.yaml#/components/headers/ETag + $ref: old-CAMARA_common.yaml#/components/headers/ETag Last-Modified: - $ref: CAMARA_common.yaml#/components/headers/Last-Modified + $ref: old-CAMARA_common.yaml#/components/headers/Last-Modified Accept-Patch: - $ref: CAMARA_common.yaml#/components/headers/Accept-Patch + $ref: old-CAMARA_common.yaml#/components/headers/Accept-Patch schemas: ErrorInfo: - $ref: CAMARA_common.yaml#/components/schemas/ErrorInfo + $ref: old-CAMARA_common.yaml#/components/schemas/ErrorInfo ResourceScopes: - $ref: CAMARA_common.yaml#/components/schemas/ResourceScopes + $ref: old-CAMARA_common.yaml#/components/schemas/ResourceScopes SubscriptionId: type: string description: | @@ -1155,9 +1155,9 @@ components: - ACCESS_TOKEN_EXPIRED responses: Generic304: - $ref: CAMARA_common.yaml#/components/responses/Generic304 + $ref: old-CAMARA_common.yaml#/components/responses/Generic304 Generic400: - $ref: CAMARA_common.yaml#/components/responses/Generic400 + $ref: old-CAMARA_common.yaml#/components/responses/Generic400 CreateSubscriptionBadRequest400: description: Problem with the client request. headers: @@ -1245,9 +1245,9 @@ components: code: INVALID_ARGUMENT message: 'Expected property is missing: subscriptionId' Generic401: - $ref: CAMARA_common.yaml#/components/responses/Generic401 + $ref: old-CAMARA_common.yaml#/components/responses/Generic401 Generic403: - $ref: CAMARA_common.yaml#/components/responses/Generic403 + $ref: old-CAMARA_common.yaml#/components/responses/Generic403 SubscriptionPermissionDenied403: description: Client does not have sufficient permission. headers: @@ -1278,15 +1278,15 @@ components: code: SUBSCRIPTION_MISMATCH message: Inconsistent access token for requested events subscription. Generic404: - $ref: CAMARA_common.yaml#/components/responses/Generic404 + $ref: old-CAMARA_common.yaml#/components/responses/Generic404 Generic409: - $ref: CAMARA_common.yaml#/components/responses/Generic409 + $ref: old-CAMARA_common.yaml#/components/responses/Generic409 Generic410: - $ref: CAMARA_common.yaml#/components/responses/Generic410 + $ref: old-CAMARA_common.yaml#/components/responses/Generic410 Generic412: - $ref: CAMARA_common.yaml#/components/responses/Generic412 + $ref: old-CAMARA_common.yaml#/components/responses/Generic412 Generic415: - $ref: CAMARA_common.yaml#/components/responses/Generic415 + $ref: old-CAMARA_common.yaml#/components/responses/Generic415 CreateSubscriptionUnprocessableEntity422: description: Unprocessable Entity headers: @@ -1394,4 +1394,4 @@ components: code: SEMANTIC_RULE_VIOLATED message: Semantic rule violated. Generic429: - $ref: CAMARA_common.yaml#/components/responses/Generic429 + $ref: old-CAMARA_common.yaml#/components/responses/Generic429 From 62fb6dabcb2c753ada75730985630fc47fb631ec Mon Sep 17 00:00:00 2001 From: Murat Karabulut <88037779+gmuratk@users.noreply.github.com> Date: Tue, 26 May 2026 10:47:18 -0400 Subject: [PATCH 10/10] Add CAMARA_event_common.yaml file --- .../common/{CAMARA_common_event.yaml => CAMARA_event_common.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename code/common/{CAMARA_common_event.yaml => CAMARA_event_common.yaml} (100%) diff --git a/code/common/CAMARA_common_event.yaml b/code/common/CAMARA_event_common.yaml similarity index 100% rename from code/common/CAMARA_common_event.yaml rename to code/common/CAMARA_event_common.yaml