From 00a13c8bb83c0270e705d34122c6cfdb9de53646 Mon Sep 17 00:00:00 2001 From: DlondonoD Date: Tue, 4 Aug 2026 22:31:53 +0200 Subject: [PATCH 1/3] Remove irrelevant/undocumented-by-default error codes per issue #72 Per CAMARA API Design Guide 3.2.1, error statuses 5xx are not documented by default in the API specification unless a relevant use case justifies it. This API has no such use case for the operation-level 500/503 responses (they were the plain generic server-error boilerplate), so all 15 operations' 500/503 responses are removed. Callback 410/429 responses are kept, since they are justified by the notification/callback flow context per the same guideline and the CAMARA Event Subscription and Notification Guide. Also introduced local, API-scoped Generic400/403/404 response objects (replacing the direct $ref to CAMARA_common.yaml's generic ones) that restrict the documented error codes to only those that actually apply to this API's business logic: - 400: only INVALID_ARGUMENT (dropped OUT_OF_RANGE - EAM has no range-constrained query/body fields that would justify this code) - 403: only PERMISSION_DENIED (dropped INVALID_TOKEN_CONTEXT - EAM is a B2B management API with no per-request identity binding to an OAuth2 token to validate against) - 404: only NOT_FOUND (dropped IDENTIFIER_NOT_FOUND - this code is device-identification specific per the Design Guide's own example; EAM never identifies a 'device', only apps/instances/deployments/ clusters/zones, already covered by NOT_FOUND) 401 (UNAUTHENTICATED only) and 409 (already using API-specific inline ALREADY_EXISTS/INCOMPATIBLE_STATE/ABORTED responses, never CONFLICT) were already correct and left untouched. Fixes #72 --- .../edge-application-management.yaml | 219 ++++++++++-------- 1 file changed, 118 insertions(+), 101 deletions(-) diff --git a/code/API_definitions/edge-application-management.yaml b/code/API_definitions/edge-application-management.yaml index 12f7b10..a68bd26 100644 --- a/code/API_definitions/edge-application-management.yaml +++ b/code/API_definitions/edge-application-management.yaml @@ -243,11 +243,11 @@ paths: schema: $ref: "#/components/schemas/SubmittedApp" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "409": description: Conflict headers: @@ -261,10 +261,6 @@ paths: status: 409 code: ALREADY_EXISTS message: "App already exists" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" get: security: - openId: @@ -292,15 +288,11 @@ paths: items: $ref: "#/components/schemas/AppManifestInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic403" /apps/{appId}: get: @@ -336,17 +328,13 @@ paths: schema: $ref: "#/components/schemas/AppManifestInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic404" delete: security: - openId: @@ -380,13 +368,13 @@ paths: x-correlator: $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" + $ref: "#/components/responses/Generic404" "409": description: Conflict headers: @@ -400,10 +388,6 @@ paths: status: 409 code: INCOMPATIBLE_STATE message: "App with a running application instance cannot be deleted" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" /app-instances: post: @@ -463,11 +447,11 @@ paths: schema: $ref: "#/components/schemas/AppInstanceInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "409": description: Conflict headers: @@ -481,10 +465,6 @@ paths: status: 409 code: ALREADY_EXISTS message: "Application already instantiated in the given Edge Cloud Zone" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" callbacks: onAppInstanceStatusChange: $ref: "#/components/callbacks/onAppInstanceStatusChange" @@ -536,15 +516,11 @@ paths: items: $ref: "#/components/schemas/AppInstanceInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic403" /app-instances/{appInstanceId}: get: security: @@ -579,17 +555,13 @@ paths: schema: $ref: "#/components/schemas/AppInstanceInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic404" delete: security: - openId: @@ -625,17 +597,13 @@ paths: x-correlator: $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic404" /deployments: post: @@ -704,11 +672,11 @@ paths: appDeploymentId: $ref: "#/components/schemas/AppDeploymentId" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "409": description: Conflict headers: @@ -722,10 +690,6 @@ paths: status: 409 code: ALREADY_EXISTS message: "Deployment already exists" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" callbacks: onAppDeploymentStatusChange: $ref: "#/components/callbacks/onAppDeploymentStatusChange" @@ -769,15 +733,11 @@ paths: items: $ref: "#/components/schemas/AppDeploymentInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic403" /deployments/{appDeploymentId}: get: security: @@ -812,17 +772,13 @@ paths: schema: $ref: "#/components/schemas/AppDeploymentInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic404" delete: security: - openId: @@ -852,17 +808,13 @@ paths: x-correlator: $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic404" patch: security: - openId: @@ -969,13 +921,13 @@ paths: schema: $ref: "#/components/schemas/AppDeploymentInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" + $ref: "#/components/responses/Generic404" "409": description: Conflict headers: @@ -989,10 +941,6 @@ paths: status: 409 code: ABORTED message: "Update conflict" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" /clusters: get: @@ -1048,15 +996,11 @@ paths: items: $ref: "#/components/schemas/ClusterInfo" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic403" /edge-cloud-zones: get: security: @@ -1099,15 +1043,11 @@ paths: schema: $ref: "#/components/schemas/EdgeCloudZones" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" - "500": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic503" + $ref: "#/components/responses/Generic403" components: securitySchemes: openId: @@ -1130,6 +1070,83 @@ components: schema: $ref: "#/components/schemas/XCorrelator" + responses: + Generic400: + description: Bad Request + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/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. + Generic403: + description: Forbidden + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + 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. + Generic404: + description: Not found + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - 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. + callbacks: onAppInstanceStatusChange: "{$request.body#/subscriptionRequest/sink}": @@ -1164,11 +1181,11 @@ components: x-correlator: $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "410": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic410" "429": @@ -1206,11 +1223,11 @@ components: x-correlator: $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "410": $ref: "../common/CAMARA_common.yaml#/components/responses/Generic410" "429": From 531d71dae9ad5a70c4a956e353cfaa08d23a67e8 Mon Sep 17 00:00:00 2001 From: DlondonoD Date: Wed, 5 Aug 2026 15:57:56 +0200 Subject: [PATCH 2/3] Remove phantom 404 scenarios from collection-list feature files Verified every .feature file's tested status codes against the actual responses documented per operation in the spec. Found 3 more phantom error scenarios testing a 404 that the corresponding operation never declares - all are plain collection GETs with only optional query filters, which per REST/CAMARA semantics return 200 with an empty list when nothing matches, not 404: - getApps.feature: no filters at all, 404 never applied - getAppDeployments.feature: 404 filtered-by-appId scenario left behind when 404 was removed from the operation's YAML in PR #56 (8755fb2) - getClusters.feature: 404 filtered-by-region scenario, same pattern All other operations' tested status codes (200/201/202/204, 400, 401, 403, 404 on by-id operations, 409 with API-specific codes) were verified to match exactly what edge-application-management.yaml documents for each operationId; no other discrepancies found. --- ...e-application-management-getAppDeployments.feature | 11 ----------- .../edge-application-management-getApps.feature | 11 ----------- .../edge-application-management-getClusters.feature | 11 ----------- 3 files changed, 33 deletions(-) diff --git a/code/Test_definitions/edge-application-management-getAppDeployments.feature b/code/Test_definitions/edge-application-management-getAppDeployments.feature index 2764a0e..94bef30 100644 --- a/code/Test_definitions/edge-application-management-getAppDeployments.feature +++ b/code/Test_definitions/edge-application-management-getAppDeployments.feature @@ -35,17 +35,6 @@ Feature: CAMARA Edge Application Management API, vwip - Operation getAppDeployme And information of all existing app deployments of given app is returned And the response body is an array complying with the OAS schema at "/components/schemas/AppDeploymentInfo" # Errors - # Error 404 - @eam_getAppDeployments_404.1_not_found_filtered_by_appId - Scenario: Get a list of application deployments info with a non-existing appId - Given the query parameter "appId" is set to a random UUID - When the request "getAppDeployments" is sent - Then the response status code is 404 - And the response header "Content-Type" is "application/json" - And the response header "x-correlator" has same value as the request header "x-correlator" - And the response property "$.status" is 404 - And the response property "$.code" is "NOT_FOUND" - And the response property "$.message" contains a user friendly text # Error 401 @eam_getAppDeployments_401.1_missing_access_token Scenario: Missing access token diff --git a/code/Test_definitions/edge-application-management-getApps.feature b/code/Test_definitions/edge-application-management-getApps.feature index 16b319b..b602fff 100644 --- a/code/Test_definitions/edge-application-management-getApps.feature +++ b/code/Test_definitions/edge-application-management-getApps.feature @@ -25,17 +25,6 @@ Feature: CAMARA Edge Application Management API, vwip - Operations getApps And A list of applications with information of them is returned And the response body complies with the OAS schema at "/components/schemas/AppManifestInfo" # Errors - # Error 404 - @eam_getApps_404.1_apps_not_found - Scenario: Get a list of application that the user has permission to view - Given there are not any application submitted by operation submitApp - When the request "getApps" is sent - Then the response status code is 404 - And the response header "x-correlator" has same value as the request header "x-correlator" - And the response header "Content-Type" is "application/json" - And the response property "$.status" is 404 - And the response property "$.code" is "NOT_FOUND" - And the response property "$.message" contains a user friendly text # Error 401 @eam_getApps_401.1_missing_access_token Scenario: Missing access token diff --git a/code/Test_definitions/edge-application-management-getClusters.feature b/code/Test_definitions/edge-application-management-getClusters.feature index 7b6f57d..d231de2 100644 --- a/code/Test_definitions/edge-application-management-getClusters.feature +++ b/code/Test_definitions/edge-application-management-getClusters.feature @@ -59,17 +59,6 @@ Feature: CAMARA Edge Application Management API, vwip - Operation getClusters And information of clusters of "$.edgeCloudZoneId" is returned And the response body complies with the OAS schema at "/components/schemas/ClusterInfo" #Errors - #/clusters GET 404 - @eam_getClusters_404.1_not_found - Scenario: Get information of existing clusters with invalid optional parameters ("region") - Given the request query parameter "$.region" is set to an invalid region - When the request "getClusters" is sent - Then the response status code is 404 - And the response header "x-correlator" has same value as the request header "x-correlator" - And the response header "Content-Type" is "application/json" - And the response property "$.status" is 404 - And the response property "$.code" is "NOT_FOUND" - And the response property "$.message" contains a user friendly text # Error 401 @eam_getClusters_401.1_missing_access_token Scenario: Missing access token From 9db2ae11adb89ca81b23a7121ee96f4871e90dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Londo=C3=B1o?= Date: Thu, 6 Aug 2026 12:47:24 +0200 Subject: [PATCH 3/3] Apply suggestion from @seralogar Co-authored-by: Sergi --- code/API_definitions/edge-application-management.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/API_definitions/edge-application-management.yaml b/code/API_definitions/edge-application-management.yaml index a68bd26..4cb475f 100644 --- a/code/API_definitions/edge-application-management.yaml +++ b/code/API_definitions/edge-application-management.yaml @@ -1116,7 +1116,7 @@ components: - PERMISSION_DENIED 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 value: status: 403 code: PERMISSION_DENIED