From a14d125a48cfa0bfbb3e12cd6d82adeac7537383 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:38:42 +0100 Subject: [PATCH 01/19] Restore and update device error scenarios feature --- artifacts/testing/C01-device-errors.feature | 159 ++++++++++---------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/artifacts/testing/C01-device-errors.feature b/artifacts/testing/C01-device-errors.feature index f947ec5d..60845450 100644 --- a/artifacts/testing/C01-device-errors.feature +++ b/artifacts/testing/C01-device-errors.feature @@ -1,7 +1,7 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors CAMARA Commonalities: 0.6 - + Common error scenarios for operations with device as input either in the request body or implied from the access. @@ -18,91 +18,92 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors * {operationId} has to be substituted to the value of operationId for the tested operation - * {path_to_device} has to be substituted to the JSON path of the device property in the body request, typically + * {path_to_device} has to be substituted to the JSON path of the device property in the body request, typically "$.device" or "$.config.subscriptionDetail.device" for Subscription APIs # This feature file is to be used by CAMARA subproject when Common error scenarios for operations with device as input either in the request body or implied from the access. # # References to OAS spec schemas refer to schemas specified in {apiname}.yaml - # Error scenarios for management of input parameter device - - @{feature_identifier}_C01.01_device_empty - Scenario: The device value is an empty object - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is set to: {} - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text - - @{feature_identifier}_C01.02_device_identifiers_not_schema_compliant - Scenario Outline: Some device identifier value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "" does not comply with the OAS schema at "" - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text - - Examples: - | device_identifier | oas_spec_schema | - | {path_to_device}.phoneNumber | /components/schemas/PhoneNumber | - | {path_to_device}.ipv4Address | /components/schemas/DeviceIpv4Addr | - | {path_to_device}.ipv6Address | /components/schemas/DeviceIpv6Address | - | {path_to_device}.networkAccessIdentifier | /components/schemas/NetworkAccessIdentifier | +# Error scenarios for management of input parameter device + + @{feature_identifier}_C01.01_device_empty + Scenario: The device value is an empty object + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is set to: {} + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + @{feature_identifier}_C01.02_device_identifiers_not_schema_compliant + Scenario Outline: Some device identifier value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "" does not comply with the OAS schema at "" + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | device_identifier | oas_spec_schema | + | {path_to_device}.phoneNumber | /components/schemas/PhoneNumber | + | {path_to_device}.ipv4Address | /components/schemas/DeviceIpv4Addr | + | {path_to_device}.ipv6Address | /components/schemas/DeviceIpv6Address | + | {path_to_device}.networkAccessIdentifier | /components/schemas/NetworkAccessIdentifier | # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. - @{feature_identifier}_C01.03_device_not_found - Scenario: Some identifier cannot be matched to a device - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is compliant with the schema but does not identify a valid device - When the request "{operationId}" is sent - Then the response status code is 404 - And the response property "$.status" is 404 - And the response property "$.code" is "IDENTIFIER_NOT_FOUND" - And the response property "$.message" contains a user friendly text - - @{feature_identifier}_C01.04_unnecessary_device - Scenario: Device not to be included when it can be deduced from the access token - Given the header "Authorization" is set to a valid access token identifying a device - And the request body property "{path_to_device}" is set to a valid device - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains a user-friendly text - - @{feature_identifier}_C01.05_missing_device - Scenario: Device not included and cannot be deduced from the access token - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is not included - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "MISSING_IDENTIFIER" - And the response property "$.message" contains a user-friendly text - - @{feature_identifier}_C01.06_unsupported_device - Scenario: None of the provided device identifiers is supported by the implementation - Given that some types of device identifiers are not supported by the implementation - And the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" only includes device identifiers not supported by the implementation - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" - And the response property "$.message" contains a user-friendly text + @{feature_identifier}_C01.03_device_not_found + Scenario: Some identifier cannot be matched to a device + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is compliant with the schema but does not identify a valid device + When the request "{operationId}" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text + + @{feature_identifier}_C01.04_unnecessary_device + Scenario: Device not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a device + And the request body property "{path_to_device}" is set to a valid device + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @{feature_identifier}_C01.05_missing_device + Scenario: Device not included and cannot be deduced from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is not included + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @{feature_identifier}_C01.06_unsupported_device + Scenario: None of the provided device identifiers is supported by the implementation + Given that some types of device identifiers are not supported by the implementation + And the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" only includes device identifiers not supported by the implementation + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" + And the response property "$.message" contains a user-friendly text # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. - @{feature_identifier}_C01.07_device_not_supported - Scenario: Service not available for the device - Given that the service is not available for all devices commercialized by the operator - And a valid device, identified by the token or provided in the request body, for which the service is not applicable - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains a user-friendly text + @{feature_identifier}_C01.07_device_not_supported + Scenario: Service not available for the device + Given that the service is not available for all devices commercialized by the operator + And a valid device, identified by the token or provided in the request body, for which the service is not applicable + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user-friendly text + From bf938519300d043a9fc49ea3ff5e161d85356c67 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:40:13 +0100 Subject: [PATCH 02/19] Update C01-device-errors.feature --- artifacts/testing/C01-device-errors.feature | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/artifacts/testing/C01-device-errors.feature b/artifacts/testing/C01-device-errors.feature index 60845450..f74e7182 100644 --- a/artifacts/testing/C01-device-errors.feature +++ b/artifacts/testing/C01-device-errors.feature @@ -54,7 +54,7 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors | {path_to_device}.ipv6Address | /components/schemas/DeviceIpv6Address | | {path_to_device}.networkAccessIdentifier | /components/schemas/NetworkAccessIdentifier | - # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. + # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. @{feature_identifier}_C01.03_device_not_found Scenario: Some identifier cannot be matched to a device Given the header "Authorization" is set to a valid access token which does not identify a single device @@ -96,7 +96,7 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" And the response property "$.message" contains a user-friendly text - # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. + # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. @{feature_identifier}_C01.07_device_not_supported Scenario: Service not available for the device Given that the service is not available for all devices commercialized by the operator @@ -107,3 +107,4 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user-friendly text + From 9df6c13ccf98893d4278d72037eb5cb10bc87b7c Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:43:12 +0100 Subject: [PATCH 03/19] Update C02-phoneNumber-errors.feature --- .../testing/C02-phoneNumber-errors.feature | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/artifacts/testing/C02-phoneNumber-errors.feature b/artifacts/testing/C02-phoneNumber-errors.feature index 8330523b..a475f76e 100644 --- a/artifacts/testing/C02-phoneNumber-errors.feature +++ b/artifacts/testing/C02-phoneNumber-errors.feature @@ -18,62 +18,62 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors * {operationId} has to be substituted to the value of operationId for the tested operation - * {path_to_phoneNumber} has to be substituted to the JSON path of the phoneNumber property in the body request, typically + * {path_to_phoneNumber} has to be substituted to the JSON path of the phoneNumber property in the body request, typically "$.phoneNumber" or "$.config.subscriptionDetail.phoneNumber" for Subscription APIs # This feature file is to be used by CAMARA subproject when Common error scenarios for operations with phoneNumber as input either in the request body or implied from the access # # References to OAS spec schemas refer to schemas specified in {apiname}.yaml - # Error scenarios for management of input parameter phoneNumber + # Error scenarios for management of input parameter phoneNumber - @{feature_identifier}_C02.01_phone_number_not_schema_compliant - Scenario: Phone number value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" does not comply with the OAS schema at "/components/schemas/PhoneNumber" - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.01_phone_number_not_schema_compliant + Scenario: Phone number value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" does not comply with the OAS schema at "/components/schemas/PhoneNumber" + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text @{feature_identifier}_C02.02_phone_number_not_found Scenario: Phone number not found - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number - When the request "{operationId}" is sent - Then the response status code is 404 - And the response property "$.status" is 404 - And the response property "$.code" is "IDENTIFIER_NOT_FOUND" - And the response property "$.message" contains a user friendly text + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number + When the request "{operationId}" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.03_unnecessary_phone_number - Scenario: Phone number not to be included when it can be deduced from the access token - Given the header "Authorization" is set to a valid access token identifying a phone number - And the request body property "{path_to_phoneNumber}" is set to a valid phone number - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.03_unnecessary_phone_number + Scenario: Phone number not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a phone number + And the request body property "{path_to_phoneNumber}" is set to a valid phone number + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.04_missing_phone_number - Scenario: Phone number not included and cannot be deducted from the access token - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" is not included - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "MISSING_IDENTIFIER" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.04_missing_phone_number + Scenario: Phone number not included and cannot be deducted from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" is not included + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user friendly text - # When the service is only offered to certain type of subscriptions, e.g. IoT, , B2C, etc - @{feature_identifier}_C02.05_phone_number_not_supported - Scenario: Service not available for the phone number - Given that the service is not available for all phone numbers commercialized by the operator - And a valid phone number, identified by the token or provided in the request body, for which the service is not applicable - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains a user friendly text + # When the service is only offered to certain type of subscriptions, e.g. IoT, , B2C, etc + @{feature_identifier}_C02.05_phone_number_not_supported + Scenario: Service not available for the phone number + Given that the service is not available for all phone numbers commercialized by the operator + And a valid phone number, identified by the token or provided in the request body, for which the service is not applicable + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user friendly text From b8c3719d699b4a25b240cc9bfb8e2066f9abdf68 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:27:51 +0100 Subject: [PATCH 04/19] Linted artifacts gherkin (#31) * Restore and update device error scenarios feature * Update C01-device-errors.feature * Update C02-phoneNumber-errors.feature --- artifacts/testing/C01-device-errors.feature | 168 +++++++++--------- .../testing/C02-phoneNumber-errors.feature | 92 +++++----- 2 files changed, 131 insertions(+), 129 deletions(-) diff --git a/artifacts/testing/C01-device-errors.feature b/artifacts/testing/C01-device-errors.feature index f947ec5d..f74e7182 100644 --- a/artifacts/testing/C01-device-errors.feature +++ b/artifacts/testing/C01-device-errors.feature @@ -1,7 +1,7 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors CAMARA Commonalities: 0.6 - + Common error scenarios for operations with device as input either in the request body or implied from the access. @@ -18,91 +18,93 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors * {operationId} has to be substituted to the value of operationId for the tested operation - * {path_to_device} has to be substituted to the JSON path of the device property in the body request, typically + * {path_to_device} has to be substituted to the JSON path of the device property in the body request, typically "$.device" or "$.config.subscriptionDetail.device" for Subscription APIs # This feature file is to be used by CAMARA subproject when Common error scenarios for operations with device as input either in the request body or implied from the access. # # References to OAS spec schemas refer to schemas specified in {apiname}.yaml - # Error scenarios for management of input parameter device - - @{feature_identifier}_C01.01_device_empty - Scenario: The device value is an empty object - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is set to: {} - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text - - @{feature_identifier}_C01.02_device_identifiers_not_schema_compliant - Scenario Outline: Some device identifier value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "" does not comply with the OAS schema at "" - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text - - Examples: - | device_identifier | oas_spec_schema | - | {path_to_device}.phoneNumber | /components/schemas/PhoneNumber | - | {path_to_device}.ipv4Address | /components/schemas/DeviceIpv4Addr | - | {path_to_device}.ipv6Address | /components/schemas/DeviceIpv6Address | - | {path_to_device}.networkAccessIdentifier | /components/schemas/NetworkAccessIdentifier | - - # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. - @{feature_identifier}_C01.03_device_not_found - Scenario: Some identifier cannot be matched to a device - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is compliant with the schema but does not identify a valid device - When the request "{operationId}" is sent - Then the response status code is 404 - And the response property "$.status" is 404 - And the response property "$.code" is "IDENTIFIER_NOT_FOUND" - And the response property "$.message" contains a user friendly text - - @{feature_identifier}_C01.04_unnecessary_device - Scenario: Device not to be included when it can be deduced from the access token - Given the header "Authorization" is set to a valid access token identifying a device - And the request body property "{path_to_device}" is set to a valid device - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains a user-friendly text - - @{feature_identifier}_C01.05_missing_device - Scenario: Device not included and cannot be deduced from the access token - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" is not included - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "MISSING_IDENTIFIER" - And the response property "$.message" contains a user-friendly text - - @{feature_identifier}_C01.06_unsupported_device - Scenario: None of the provided device identifiers is supported by the implementation - Given that some types of device identifiers are not supported by the implementation - And the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "{path_to_device}" only includes device identifiers not supported by the implementation - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" - And the response property "$.message" contains a user-friendly text - - # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. - @{feature_identifier}_C01.07_device_not_supported - Scenario: Service not available for the device - Given that the service is not available for all devices commercialized by the operator - And a valid device, identified by the token or provided in the request body, for which the service is not applicable - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains a user-friendly text +# Error scenarios for management of input parameter device + + @{feature_identifier}_C01.01_device_empty + Scenario: The device value is an empty object + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is set to: {} + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + @{feature_identifier}_C01.02_device_identifiers_not_schema_compliant + Scenario Outline: Some device identifier value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "" does not comply with the OAS schema at "" + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | device_identifier | oas_spec_schema | + | {path_to_device}.phoneNumber | /components/schemas/PhoneNumber | + | {path_to_device}.ipv4Address | /components/schemas/DeviceIpv4Addr | + | {path_to_device}.ipv6Address | /components/schemas/DeviceIpv6Address | + | {path_to_device}.networkAccessIdentifier | /components/schemas/NetworkAccessIdentifier | + + # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. + @{feature_identifier}_C01.03_device_not_found + Scenario: Some identifier cannot be matched to a device + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is compliant with the schema but does not identify a valid device + When the request "{operationId}" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text + + @{feature_identifier}_C01.04_unnecessary_device + Scenario: Device not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a device + And the request body property "{path_to_device}" is set to a valid device + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @{feature_identifier}_C01.05_missing_device + Scenario: Device not included and cannot be deduced from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" is not included + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @{feature_identifier}_C01.06_unsupported_device + Scenario: None of the provided device identifiers is supported by the implementation + Given that some types of device identifiers are not supported by the implementation + And the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "{path_to_device}" only includes device identifiers not supported by the implementation + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. + @{feature_identifier}_C01.07_device_not_supported + Scenario: Service not available for the device + Given that the service is not available for all devices commercialized by the operator + And a valid device, identified by the token or provided in the request body, for which the service is not applicable + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user-friendly text + + diff --git a/artifacts/testing/C02-phoneNumber-errors.feature b/artifacts/testing/C02-phoneNumber-errors.feature index 8330523b..a475f76e 100644 --- a/artifacts/testing/C02-phoneNumber-errors.feature +++ b/artifacts/testing/C02-phoneNumber-errors.feature @@ -18,62 +18,62 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors * {operationId} has to be substituted to the value of operationId for the tested operation - * {path_to_phoneNumber} has to be substituted to the JSON path of the phoneNumber property in the body request, typically + * {path_to_phoneNumber} has to be substituted to the JSON path of the phoneNumber property in the body request, typically "$.phoneNumber" or "$.config.subscriptionDetail.phoneNumber" for Subscription APIs # This feature file is to be used by CAMARA subproject when Common error scenarios for operations with phoneNumber as input either in the request body or implied from the access # # References to OAS spec schemas refer to schemas specified in {apiname}.yaml - # Error scenarios for management of input parameter phoneNumber + # Error scenarios for management of input parameter phoneNumber - @{feature_identifier}_C02.01_phone_number_not_schema_compliant - Scenario: Phone number value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" does not comply with the OAS schema at "/components/schemas/PhoneNumber" - When the request "{operationId}" is sent - Then the response status code is 400 - And the response property "$.status" is 400 - And the response property "$.code" is "INVALID_ARGUMENT" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.01_phone_number_not_schema_compliant + Scenario: Phone number value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" does not comply with the OAS schema at "/components/schemas/PhoneNumber" + When the request "{operationId}" is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text @{feature_identifier}_C02.02_phone_number_not_found Scenario: Phone number not found - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number - When the request "{operationId}" is sent - Then the response status code is 404 - And the response property "$.status" is 404 - And the response property "$.code" is "IDENTIFIER_NOT_FOUND" - And the response property "$.message" contains a user friendly text + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number + When the request "{operationId}" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.03_unnecessary_phone_number - Scenario: Phone number not to be included when it can be deduced from the access token - Given the header "Authorization" is set to a valid access token identifying a phone number - And the request body property "{path_to_phoneNumber}" is set to a valid phone number - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.03_unnecessary_phone_number + Scenario: Phone number not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a phone number + And the request body property "{path_to_phoneNumber}" is set to a valid phone number + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.04_missing_phone_number - Scenario: Phone number not included and cannot be deducted from the access token - Given the header "Authorization" is set to a valid access token which does not identify a single phone number - And the request body property "{path_to_phoneNumber}" is not included - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "MISSING_IDENTIFIER" - And the response property "$.message" contains a user friendly text + @{feature_identifier}_C02.04_missing_phone_number + Scenario: Phone number not included and cannot be deducted from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single phone number + And the request body property "{path_to_phoneNumber}" is not included + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user friendly text - # When the service is only offered to certain type of subscriptions, e.g. IoT, , B2C, etc - @{feature_identifier}_C02.05_phone_number_not_supported - Scenario: Service not available for the phone number - Given that the service is not available for all phone numbers commercialized by the operator - And a valid phone number, identified by the token or provided in the request body, for which the service is not applicable - When the request "{operationId}" is sent - Then the response status code is 422 - And the response property "$.status" is 422 - And the response property "$.code" is "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains a user friendly text + # When the service is only offered to certain type of subscriptions, e.g. IoT, , B2C, etc + @{feature_identifier}_C02.05_phone_number_not_supported + Scenario: Service not available for the phone number + Given that the service is not available for all phone numbers commercialized by the operator + And a valid phone number, identified by the token or provided in the request body, for which the service is not applicable + When the request "{operationId}" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user friendly text From 34457c79dcf37c0627fe4d897a9ad8827ec7fe9f Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:25:19 +0100 Subject: [PATCH 05/19] Update C01-device-errors.feature --- artifacts/testing/C01-device-errors.feature | 2 -- 1 file changed, 2 deletions(-) diff --git a/artifacts/testing/C01-device-errors.feature b/artifacts/testing/C01-device-errors.feature index f74e7182..a3dcd23a 100644 --- a/artifacts/testing/C01-device-errors.feature +++ b/artifacts/testing/C01-device-errors.feature @@ -106,5 +106,3 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors And the response property "$.status" is 422 And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user-friendly text - - From 23f2497830952848170e0eda424d62cbece4ca9a Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:26:30 +0100 Subject: [PATCH 06/19] Update CAMARA_common.yaml --- artifacts/CAMARA_common.yaml | 95 +++++++++++++++++------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index 0fdd2c35..7d80d370 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -5,9 +5,9 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html - version: wip + version: wip x-camara-commonalities: "0.6" - + paths: {} components: securitySchemes: @@ -76,7 +76,7 @@ components: networkAccessIdentifier: $ref: "#/components/schemas/NetworkAccessIdentifier" ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Address" + $ref: "#/components/schemas/DeviceIpv4Addr" ipv6Address: $ref: "#/components/schemas/DeviceIpv6Address" minProperties: 1 @@ -102,7 +102,7 @@ components: type: string example: "123456789@example.com" - DeviceIpv4Address: + 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). @@ -114,9 +114,9 @@ components: 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/SingleIpv4Address" + $ref: "#/components/schemas/SingleIpv4Addr" privateAddress: - $ref: "#/components/schemas/SingleIpv4Address" + $ref: "#/components/schemas/SingleIpv4Addr" publicPort: $ref: "#/components/schemas/Port" anyOf: @@ -126,7 +126,7 @@ components: publicAddress: "84.125.93.10" publicPort: 59765 - SingleIpv4Address: + SingleIpv4Addr: description: A single IPv4 address with no subnet mask type: string format: ipv4 @@ -234,44 +234,44 @@ components: maximum: 180 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: -####################################################### -####################################################### + ####################################################### + ####################################################### + # 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: + ####################################################### + ####################################################### Generic400: description: Bad Request headers: @@ -510,7 +510,7 @@ components: value: status: 409 code: INCOMPATIBLE_STATE - message: A referenced resource is in an incompatible state. + message: A referenced resource is in an incompatible state. GENERIC_409_{{SPECIFIC_CODE}}: description: Specific conflict situation that is relevant in the context of the API value: @@ -802,6 +802,3 @@ components: status: 504 code: TIMEOUT message: Request timeout exceeded. - - - From 92c766d010ca4ea5ca06ffa94774053366f9e909 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:27:13 +0100 Subject: [PATCH 07/19] Update config.yml --- artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml b/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml index 0067a970..d94493b5 100644 --- a/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml +++ b/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml @@ -1,6 +1,6 @@ blank_issues_enabled: true contact_links: - - name: 🗣 Subproject discussions + - name: 🗣 Subproject discussions url: https://github.com/camaraproject/Commonalities/discussions about: Please ask and answer questions here. - name: 📖 CAMARA API Design Guidelines From 4b8da033e047332f0983a38a9be9fdafdd6fdaa7 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:28:23 +0100 Subject: [PATCH 08/19] Update event-subscription-template.yaml --- .../event-subscription-template.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/artifacts/camara-cloudevents/event-subscription-template.yaml b/artifacts/camara-cloudevents/event-subscription-template.yaml index 8a48405b..971724e1 100644 --- a/artifacts/camara-cloudevents/event-subscription-template.yaml +++ b/artifacts/camara-cloudevents/event-subscription-template.yaml @@ -14,14 +14,14 @@ info: url: https://www.apache.org/licenses/LICENSE-2.0.html version: wip x-camara-commonalities: "0.6" - + externalDocs: description: Product documentation at CAMARA - url: https://github.com/camaraproject/{apiRepository} + url: https://github.com/camaraproject/apiRepository # {apiRepository} MUST be replaced by the CAMARA Subproject Repository name where the API design based on this template is hosted. servers: - url: "{apiRoot}/api-name/vx.y" - # api-name and version should be valued accordingly to the CAMARA API versioning guidelines, e.g. for a version x.y.z, put v0.y for x=0 or just vx for x>0 in the url. + # api-name and version should be valued accordingly to the CAMARA API versioning guidelines, e.g. for a version x.y.z, put v0.y for x=0 or just vx for x>0 in the url. variables: apiRoot: default: http://localhost:9091 @@ -352,7 +352,7 @@ components: - ACCESSTOKEN - REFRESHTOKEN description: | - The type of the credential. + The type of the credential. Note: Type of the credential - MUST be set to ACCESSTOKEN for now discriminator: propertyName: credentialType @@ -924,7 +924,7 @@ components: code: INVALID_PROTOCOL message: Only HTTP is supported GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type + description: Invalid sink credential type value: status: 400 code: INVALID_CREDENTIAL @@ -1046,7 +1046,7 @@ components: 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. SubscriptionPermissionDenied403: description: Client does not have sufficient permission headers: From de6eea45a00e8f6263b4fe5803348ebd9b96b9e7 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:30:06 +0100 Subject: [PATCH 09/19] Update notification-as-cloud-event.yaml --- artifacts/notification-as-cloud-event.yaml | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/artifacts/notification-as-cloud-event.yaml b/artifacts/notification-as-cloud-event.yaml index f79b6d22..ffc30957 100644 --- a/artifacts/notification-as-cloud-event.yaml +++ b/artifacts/notification-as-cloud-event.yaml @@ -7,34 +7,34 @@ info: # Introduction A lot of CAMARA APIs offer the capability to API consumer to receive events. - Event data are defined in each API definition but in order to provide consistency across CAMARA APIs and to increase - interoperability we will use [cloudevents](https://cloudevents.io/) specifications. In particular, every CAMARA Event will + Event data are defined in each API definition but in order to provide consistency across CAMARA APIs and to increase + interoperability we will use [cloudevents](https://cloudevents.io/) specifications. In particular, every CAMARA Event will be defined using [cloudevents-json-format](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) - + # Relevant terms and definitions * **Occurrence** : An "occurrence" is the capture of a statement of fact during the operation of a software system. - * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an + * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an event producer (the source) to interested event consumers. - - * **Producer**: The "producer" is a specific instance, process or device that creates the data structure + + * **Producer**: The "producer" is a specific instance, process or device that creates the data structure describing the CloudEvent. - * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might - consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates + * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might + consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates the CloudEvent on behalf of the source. - - * **Consumer**: A "consumer" receives the event and acts upon it. It uses the context and data to execute some + + * **Consumer**: A "consumer" receives the event and acts upon it. It uses the context and data to execute some logic, which might lead to the occurrence of new events. - - * **Data**: Domain-specific information about the occurrence (i.e. the payload). This might + + * **Data**: Domain-specific information about the occurrence (i.e. the payload). This might include information about the occurrence, details about the data that was changed, or more. - + # API Functionality - + Only one endpoint/operation is provided: `POST /your_webhook_notification_url` - This endpoint describes the event notification received on subscription listener side when the event occurred. + This endpoint describes the event notification received on subscription listener side when the event occurred. A detailed description of the event notification is provided in the [CAMARA API Event Subscription and Notification Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Event-Subscription-and-Notification-Guide.md#3-event-notification) termsOfService: http://swagger.io/terms/ @@ -48,8 +48,8 @@ externalDocs: description: Product documentation at CAMARA url: https://github.com/camaraproject/Commonalities security: - - notificationsBearerAuth: [] - - {} + - notificationsBearerAuth: [] + - {} servers: - url: '{apiRoot}' @@ -62,14 +62,14 @@ tags: description: | Events received on subscription listener side. paths: - /your_webhook_notification_url: + /your-webhook-notification-url: post: tags: - CAMARA Cloud Event summary: "Cloud Event notification endpoint to notify consumer that statement of fact had occurred" description: | INFORMATIVE ENDPOINT: The value of this endpoint is freely declared by each client app by means of resource-based - subscription or instance-based subscription. /your_webhook_notification_url is + subscription or instance-based subscription. /your_webhook_notification_url is just a convention naming referring to an absolute URL, indeed the one indicated by API client in the triggering of the procedure (resource-based or instance-based). In this way, it represents an absolute URL, i.e.: notifications won't be sent to /event-notification/vX/your_webhook_notification_url. @@ -87,20 +87,20 @@ paths: $ref: '#/components/examples/QOS_STATUS_CHANGED_EXAMPLE' responses: - 204: + "204": description: No Content headers: x-correlator: $ref: "#/components/headers/x-correlator" - 400: + "400": $ref: "#/components/responses/Generic400" - 401: + "401": $ref: "#/components/responses/Generic401" - 403: + "403": $ref: "#/components/responses/Generic403" - 410: + "410": $ref: "#/components/responses/Generic410" - 429: + "429": $ref: "#/components/responses/Generic429" components: securitySchemes: @@ -125,7 +125,7 @@ components: message: type: string description: A human-readable description of what the event represents - + XCorrelator: type: string pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ From 8e65b74e0f500aab7eb24dd76fe53a70af6c867b Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:35:44 +0100 Subject: [PATCH 10/19] Linted artifacts (#32) * Restore and update device error scenarios feature * Update C01-device-errors.feature * Update C02-phoneNumber-errors.feature * Update C01-device-errors.feature * Update CAMARA_common.yaml * Update config.yml * Update event-subscription-template.yaml * Update notification-as-cloud-event.yaml --- artifacts/CAMARA_common.yaml | 95 +++++++++---------- .../.github/ISSUE_TEMPLATE/config.yml | 2 +- .../event-subscription-template.yaml | 12 +-- artifacts/notification-as-cloud-event.yaml | 52 +++++----- artifacts/testing/C01-device-errors.feature | 2 - 5 files changed, 79 insertions(+), 84 deletions(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index 0fdd2c35..7d80d370 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -5,9 +5,9 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html - version: wip + version: wip x-camara-commonalities: "0.6" - + paths: {} components: securitySchemes: @@ -76,7 +76,7 @@ components: networkAccessIdentifier: $ref: "#/components/schemas/NetworkAccessIdentifier" ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Address" + $ref: "#/components/schemas/DeviceIpv4Addr" ipv6Address: $ref: "#/components/schemas/DeviceIpv6Address" minProperties: 1 @@ -102,7 +102,7 @@ components: type: string example: "123456789@example.com" - DeviceIpv4Address: + 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). @@ -114,9 +114,9 @@ components: 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/SingleIpv4Address" + $ref: "#/components/schemas/SingleIpv4Addr" privateAddress: - $ref: "#/components/schemas/SingleIpv4Address" + $ref: "#/components/schemas/SingleIpv4Addr" publicPort: $ref: "#/components/schemas/Port" anyOf: @@ -126,7 +126,7 @@ components: publicAddress: "84.125.93.10" publicPort: 59765 - SingleIpv4Address: + SingleIpv4Addr: description: A single IPv4 address with no subnet mask type: string format: ipv4 @@ -234,44 +234,44 @@ components: maximum: 180 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: -####################################################### -####################################################### + ####################################################### + ####################################################### + # 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: + ####################################################### + ####################################################### Generic400: description: Bad Request headers: @@ -510,7 +510,7 @@ components: value: status: 409 code: INCOMPATIBLE_STATE - message: A referenced resource is in an incompatible state. + message: A referenced resource is in an incompatible state. GENERIC_409_{{SPECIFIC_CODE}}: description: Specific conflict situation that is relevant in the context of the API value: @@ -802,6 +802,3 @@ components: status: 504 code: TIMEOUT message: Request timeout exceeded. - - - diff --git a/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml b/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml index 0067a970..d94493b5 100644 --- a/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml +++ b/artifacts/Github_templates/.github/ISSUE_TEMPLATE/config.yml @@ -1,6 +1,6 @@ blank_issues_enabled: true contact_links: - - name: 🗣 Subproject discussions + - name: 🗣 Subproject discussions url: https://github.com/camaraproject/Commonalities/discussions about: Please ask and answer questions here. - name: 📖 CAMARA API Design Guidelines diff --git a/artifacts/camara-cloudevents/event-subscription-template.yaml b/artifacts/camara-cloudevents/event-subscription-template.yaml index 8a48405b..971724e1 100644 --- a/artifacts/camara-cloudevents/event-subscription-template.yaml +++ b/artifacts/camara-cloudevents/event-subscription-template.yaml @@ -14,14 +14,14 @@ info: url: https://www.apache.org/licenses/LICENSE-2.0.html version: wip x-camara-commonalities: "0.6" - + externalDocs: description: Product documentation at CAMARA - url: https://github.com/camaraproject/{apiRepository} + url: https://github.com/camaraproject/apiRepository # {apiRepository} MUST be replaced by the CAMARA Subproject Repository name where the API design based on this template is hosted. servers: - url: "{apiRoot}/api-name/vx.y" - # api-name and version should be valued accordingly to the CAMARA API versioning guidelines, e.g. for a version x.y.z, put v0.y for x=0 or just vx for x>0 in the url. + # api-name and version should be valued accordingly to the CAMARA API versioning guidelines, e.g. for a version x.y.z, put v0.y for x=0 or just vx for x>0 in the url. variables: apiRoot: default: http://localhost:9091 @@ -352,7 +352,7 @@ components: - ACCESSTOKEN - REFRESHTOKEN description: | - The type of the credential. + The type of the credential. Note: Type of the credential - MUST be set to ACCESSTOKEN for now discriminator: propertyName: credentialType @@ -924,7 +924,7 @@ components: code: INVALID_PROTOCOL message: Only HTTP is supported GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type + description: Invalid sink credential type value: status: 400 code: INVALID_CREDENTIAL @@ -1046,7 +1046,7 @@ components: 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. SubscriptionPermissionDenied403: description: Client does not have sufficient permission headers: diff --git a/artifacts/notification-as-cloud-event.yaml b/artifacts/notification-as-cloud-event.yaml index f79b6d22..ffc30957 100644 --- a/artifacts/notification-as-cloud-event.yaml +++ b/artifacts/notification-as-cloud-event.yaml @@ -7,34 +7,34 @@ info: # Introduction A lot of CAMARA APIs offer the capability to API consumer to receive events. - Event data are defined in each API definition but in order to provide consistency across CAMARA APIs and to increase - interoperability we will use [cloudevents](https://cloudevents.io/) specifications. In particular, every CAMARA Event will + Event data are defined in each API definition but in order to provide consistency across CAMARA APIs and to increase + interoperability we will use [cloudevents](https://cloudevents.io/) specifications. In particular, every CAMARA Event will be defined using [cloudevents-json-format](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) - + # Relevant terms and definitions * **Occurrence** : An "occurrence" is the capture of a statement of fact during the operation of a software system. - * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an + * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an event producer (the source) to interested event consumers. - - * **Producer**: The "producer" is a specific instance, process or device that creates the data structure + + * **Producer**: The "producer" is a specific instance, process or device that creates the data structure describing the CloudEvent. - * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might - consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates + * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might + consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates the CloudEvent on behalf of the source. - - * **Consumer**: A "consumer" receives the event and acts upon it. It uses the context and data to execute some + + * **Consumer**: A "consumer" receives the event and acts upon it. It uses the context and data to execute some logic, which might lead to the occurrence of new events. - - * **Data**: Domain-specific information about the occurrence (i.e. the payload). This might + + * **Data**: Domain-specific information about the occurrence (i.e. the payload). This might include information about the occurrence, details about the data that was changed, or more. - + # API Functionality - + Only one endpoint/operation is provided: `POST /your_webhook_notification_url` - This endpoint describes the event notification received on subscription listener side when the event occurred. + This endpoint describes the event notification received on subscription listener side when the event occurred. A detailed description of the event notification is provided in the [CAMARA API Event Subscription and Notification Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Event-Subscription-and-Notification-Guide.md#3-event-notification) termsOfService: http://swagger.io/terms/ @@ -48,8 +48,8 @@ externalDocs: description: Product documentation at CAMARA url: https://github.com/camaraproject/Commonalities security: - - notificationsBearerAuth: [] - - {} + - notificationsBearerAuth: [] + - {} servers: - url: '{apiRoot}' @@ -62,14 +62,14 @@ tags: description: | Events received on subscription listener side. paths: - /your_webhook_notification_url: + /your-webhook-notification-url: post: tags: - CAMARA Cloud Event summary: "Cloud Event notification endpoint to notify consumer that statement of fact had occurred" description: | INFORMATIVE ENDPOINT: The value of this endpoint is freely declared by each client app by means of resource-based - subscription or instance-based subscription. /your_webhook_notification_url is + subscription or instance-based subscription. /your_webhook_notification_url is just a convention naming referring to an absolute URL, indeed the one indicated by API client in the triggering of the procedure (resource-based or instance-based). In this way, it represents an absolute URL, i.e.: notifications won't be sent to /event-notification/vX/your_webhook_notification_url. @@ -87,20 +87,20 @@ paths: $ref: '#/components/examples/QOS_STATUS_CHANGED_EXAMPLE' responses: - 204: + "204": description: No Content headers: x-correlator: $ref: "#/components/headers/x-correlator" - 400: + "400": $ref: "#/components/responses/Generic400" - 401: + "401": $ref: "#/components/responses/Generic401" - 403: + "403": $ref: "#/components/responses/Generic403" - 410: + "410": $ref: "#/components/responses/Generic410" - 429: + "429": $ref: "#/components/responses/Generic429" components: securitySchemes: @@ -125,7 +125,7 @@ components: message: type: string description: A human-readable description of what the event represents - + XCorrelator: type: string pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ diff --git a/artifacts/testing/C01-device-errors.feature b/artifacts/testing/C01-device-errors.feature index f74e7182..a3dcd23a 100644 --- a/artifacts/testing/C01-device-errors.feature +++ b/artifacts/testing/C01-device-errors.feature @@ -106,5 +106,3 @@ Feature: CAMARA Common Artifact C01 - Test scenarios for device errors And the response property "$.status" is 422 And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user-friendly text - - From 21d4856437fc5ae0c115712da62150271847f2e7 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:50:30 +0100 Subject: [PATCH 11/19] Update C02-phoneNumber-errors.feature --- artifacts/testing/C02-phoneNumber-errors.feature | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/artifacts/testing/C02-phoneNumber-errors.feature b/artifacts/testing/C02-phoneNumber-errors.feature index a475f76e..690443d3 100644 --- a/artifacts/testing/C02-phoneNumber-errors.feature +++ b/artifacts/testing/C02-phoneNumber-errors.feature @@ -37,8 +37,8 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors And the response property "$.code" is "INVALID_ARGUMENT" And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.02_phone_number_not_found - Scenario: Phone number not found + @{feature_identifier}_C02.02_phone_number_not_found + Scenario: Phone number not found Given the header "Authorization" is set to a valid access token which does not identify a single phone number And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number When the request "{operationId}" is sent @@ -77,3 +77,4 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors And the response property "$.status" is 422 And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user friendly text + From 40dbebbec8de61633cd9eeb3e3398593d08d992e Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:51:29 +0100 Subject: [PATCH 12/19] Update CAMARA_common.yaml --- artifacts/CAMARA_common.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index 7d80d370..cc11326a 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -510,7 +510,7 @@ components: value: status: 409 code: INCOMPATIBLE_STATE - message: A referenced resource is in an incompatible state. + message: A referenced resource is in an incompatible state. GENERIC_409_{{SPECIFIC_CODE}}: description: Specific conflict situation that is relevant in the context of the API value: @@ -802,3 +802,4 @@ components: status: 504 code: TIMEOUT message: Request timeout exceeded. + From 950d1527cc26b4f61c8dcd85a34f23eeba582ffa Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:56:05 +0100 Subject: [PATCH 13/19] Update notification-as-cloud-event.yaml --- artifacts/notification-as-cloud-event.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/artifacts/notification-as-cloud-event.yaml b/artifacts/notification-as-cloud-event.yaml index ffc30957..2093c40f 100644 --- a/artifacts/notification-as-cloud-event.yaml +++ b/artifacts/notification-as-cloud-event.yaml @@ -14,13 +14,13 @@ info: # Relevant terms and definitions * **Occurrence** : An "occurrence" is the capture of a statement of fact during the operation of a software system. - + * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an event producer (the source) to interested event consumers. * **Producer**: The "producer" is a specific instance, process or device that creates the data structure describing the CloudEvent. - + * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates the CloudEvent on behalf of the source. @@ -32,7 +32,7 @@ info: include information about the occurrence, details about the data that was changed, or more. # API Functionality - + Only one endpoint/operation is provided: `POST /your_webhook_notification_url` This endpoint describes the event notification received on subscription listener side when the event occurred. A detailed description of the event notification is provided in the [CAMARA API Event Subscription and Notification Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Event-Subscription-and-Notification-Guide.md#3-event-notification) @@ -125,7 +125,7 @@ components: message: type: string description: A human-readable description of what the event represents - + XCorrelator: type: string pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ From 620ede6fa1f1a16ad3d865755f20b8cc2c55e086 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:57:38 +0100 Subject: [PATCH 14/19] Update event-subscription-template.yaml --- artifacts/camara-cloudevents/event-subscription-template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artifacts/camara-cloudevents/event-subscription-template.yaml b/artifacts/camara-cloudevents/event-subscription-template.yaml index 971724e1..f8235309 100644 --- a/artifacts/camara-cloudevents/event-subscription-template.yaml +++ b/artifacts/camara-cloudevents/event-subscription-template.yaml @@ -1046,7 +1046,7 @@ components: 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. SubscriptionPermissionDenied403: description: Client does not have sufficient permission headers: From fe15b9d03913f7fa0c4b5f9c2062cb1405cad612 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:24:52 +0100 Subject: [PATCH 15/19] Update CAMARA_common.yaml --- artifacts/CAMARA_common.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index cc11326a..717460b6 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -76,7 +76,7 @@ components: networkAccessIdentifier: $ref: "#/components/schemas/NetworkAccessIdentifier" ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Addr" + $ref: "#/components/schemas/DeviceIpv4Address" ipv6Address: $ref: "#/components/schemas/DeviceIpv6Address" minProperties: 1 @@ -102,7 +102,7 @@ components: type: string example: "123456789@example.com" - DeviceIpv4Addr: + 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). @@ -114,9 +114,9 @@ components: 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" anyOf: @@ -126,7 +126,7 @@ components: publicAddress: "84.125.93.10" publicPort: 59765 - SingleIpv4Addr: + SingleIpv4Address: description: A single IPv4 address with no subnet mask type: string format: ipv4 @@ -803,3 +803,4 @@ components: code: TIMEOUT message: Request timeout exceeded. + From 04dc95bc70fca1b524fe27c950464c66c4818bca Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:29:46 +0100 Subject: [PATCH 16/19] Linted artifacts 2 (#35) * Restore and update device error scenarios feature * Update C01-device-errors.feature * Update C02-phoneNumber-errors.feature * Update C01-device-errors.feature * Update CAMARA_common.yaml * Update config.yml * Update event-subscription-template.yaml * Update notification-as-cloud-event.yaml * Update C02-phoneNumber-errors.feature * Update CAMARA_common.yaml * Update notification-as-cloud-event.yaml * Update event-subscription-template.yaml * Update CAMARA_common.yaml --- artifacts/CAMARA_common.yaml | 3 ++- .../camara-cloudevents/event-subscription-template.yaml | 3 ++- artifacts/notification-as-cloud-event.yaml | 6 +++--- artifacts/testing/C02-phoneNumber-errors.feature | 5 +++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index 7d80d370..9202f404 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -510,7 +510,8 @@ components: value: status: 409 code: INCOMPATIBLE_STATE - message: A referenced resource is in an incompatible state. + message: A referenced resource is in an incompatible state. + GENERIC_409_{{SPECIFIC_CODE}}: description: Specific conflict situation that is relevant in the context of the API value: diff --git a/artifacts/camara-cloudevents/event-subscription-template.yaml b/artifacts/camara-cloudevents/event-subscription-template.yaml index 971724e1..8d782acb 100644 --- a/artifacts/camara-cloudevents/event-subscription-template.yaml +++ b/artifacts/camara-cloudevents/event-subscription-template.yaml @@ -1046,7 +1046,8 @@ components: 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. + SubscriptionPermissionDenied403: description: Client does not have sufficient permission headers: diff --git a/artifacts/notification-as-cloud-event.yaml b/artifacts/notification-as-cloud-event.yaml index ffc30957..65f84e20 100644 --- a/artifacts/notification-as-cloud-event.yaml +++ b/artifacts/notification-as-cloud-event.yaml @@ -20,7 +20,7 @@ info: * **Producer**: The "producer" is a specific instance, process or device that creates the data structure describing the CloudEvent. - + * **Source**: The "source" is the context in which the occurrence happened. In a distributed system it might consist of multiple producers. If a source is not aware of CloudEvents, an external producer creates the CloudEvent on behalf of the source. @@ -32,7 +32,7 @@ info: include information about the occurrence, details about the data that was changed, or more. # API Functionality - + Only one endpoint/operation is provided: `POST /your_webhook_notification_url` This endpoint describes the event notification received on subscription listener side when the event occurred. A detailed description of the event notification is provided in the [CAMARA API Event Subscription and Notification Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Event-Subscription-and-Notification-Guide.md#3-event-notification) @@ -125,7 +125,7 @@ components: message: type: string description: A human-readable description of what the event represents - + XCorrelator: type: string pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ diff --git a/artifacts/testing/C02-phoneNumber-errors.feature b/artifacts/testing/C02-phoneNumber-errors.feature index a475f76e..690443d3 100644 --- a/artifacts/testing/C02-phoneNumber-errors.feature +++ b/artifacts/testing/C02-phoneNumber-errors.feature @@ -37,8 +37,8 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors And the response property "$.code" is "INVALID_ARGUMENT" And the response property "$.message" contains a user friendly text - @{feature_identifier}_C02.02_phone_number_not_found - Scenario: Phone number not found + @{feature_identifier}_C02.02_phone_number_not_found + Scenario: Phone number not found Given the header "Authorization" is set to a valid access token which does not identify a single phone number And the request body property "{path_to_phoneNumber}" is compliant with the schema but does not identify a valid phone number When the request "{operationId}" is sent @@ -77,3 +77,4 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors And the response property "$.status" is 422 And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user friendly text + From e230bc78a68dbeb2e730fc606ad4241f737d063f Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:33:12 +0100 Subject: [PATCH 17/19] Update C02-phoneNumber-errors.feature --- artifacts/testing/C02-phoneNumber-errors.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/artifacts/testing/C02-phoneNumber-errors.feature b/artifacts/testing/C02-phoneNumber-errors.feature index 690443d3..4487700e 100644 --- a/artifacts/testing/C02-phoneNumber-errors.feature +++ b/artifacts/testing/C02-phoneNumber-errors.feature @@ -77,4 +77,3 @@ Feature: CAMARA Common Artifact C02 - Test scenarios for phoneNumber errors And the response property "$.status" is 422 And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user friendly text - From 321d44b878843b129724c7383544fa4a9fd09753 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:34:06 +0100 Subject: [PATCH 18/19] Update CAMARA_common.yaml --- artifacts/CAMARA_common.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/artifacts/CAMARA_common.yaml b/artifacts/CAMARA_common.yaml index 9202f404..14364341 100644 --- a/artifacts/CAMARA_common.yaml +++ b/artifacts/CAMARA_common.yaml @@ -510,8 +510,7 @@ components: value: status: 409 code: INCOMPATIBLE_STATE - message: A referenced resource is in an incompatible state. - + message: A referenced resource is in an incompatible state. GENERIC_409_{{SPECIFIC_CODE}}: description: Specific conflict situation that is relevant in the context of the API value: @@ -803,3 +802,4 @@ components: status: 504 code: TIMEOUT message: Request timeout exceeded. + From 0bb9d3423263f0679d17c6758dfc34e237c83c0a Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:34:55 +0100 Subject: [PATCH 19/19] Update notification-as-cloud-event.yaml --- artifacts/notification-as-cloud-event.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artifacts/notification-as-cloud-event.yaml b/artifacts/notification-as-cloud-event.yaml index 65f84e20..2093c40f 100644 --- a/artifacts/notification-as-cloud-event.yaml +++ b/artifacts/notification-as-cloud-event.yaml @@ -14,7 +14,7 @@ info: # Relevant terms and definitions * **Occurrence** : An "occurrence" is the capture of a statement of fact during the operation of a software system. - + * **Event**: An "event" is a data record expressing an occurrence and its context. Events are routed from an event producer (the source) to interested event consumers.