From 26fa6041e9471e3035d88df2ef84e14be0f419b1 Mon Sep 17 00:00:00 2001 From: rartych Date: Mon, 16 Oct 2023 12:37:13 +0200 Subject: [PATCH 01/22] Github templates --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++ .github/ISSUE_TEMPLATE/issue_bug_template.md | 33 ++++++++++++++ .../issue_correction_template.md | 21 +++++++++ .../issue_documentation_template.md | 18 ++++++++ .../issue_enhancement_template.md | 20 +++++++++ .github/ISSUE_TEMPLATE/issue_pm_template.md | 18 ++++++++ .../ISSUE_TEMPLATE/issue_tests_template.md | 18 ++++++++ .github/pull_request_template.md | 45 +++++++++++++++++++ 8 files changed, 181 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/issue_bug_template.md create mode 100644 .github/ISSUE_TEMPLATE/issue_correction_template.md create mode 100644 .github/ISSUE_TEMPLATE/issue_documentation_template.md create mode 100644 .github/ISSUE_TEMPLATE/issue_enhancement_template.md create mode 100644 .github/ISSUE_TEMPLATE/issue_pm_template.md create mode 100644 .github/ISSUE_TEMPLATE/issue_tests_template.md create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..a7976669 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: šŸ—£ Subproject discussions + url: https://github.com/camaraproject/EdgeCloud/discussions + about: Please ask and answer questions here. + - name: šŸ“– CAMARA API Design Guidelines + url: https://github.com/camaraproject/Commonalities/blob/main/documentation/API-design-guidelines.md + about: Please refer to the design guidelines. diff --git a/.github/ISSUE_TEMPLATE/issue_bug_template.md b/.github/ISSUE_TEMPLATE/issue_bug_template.md new file mode 100644 index 00000000..74b42179 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_bug_template.md @@ -0,0 +1,33 @@ +--- +name: ā€¼ Bug šŸ› +about: Describe the bug in Provider Implementation +title: '' +labels: 'implementation:bug' +assignees: '' + +--- + +**Describe the bug** + + +**To Reproduce** + + +**Expected behavior** + + +**Screenshots** + + +**Environment:** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/issue_correction_template.md b/.github/ISSUE_TEMPLATE/issue_correction_template.md new file mode 100644 index 00000000..488e70b5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_correction_template.md @@ -0,0 +1,21 @@ +--- +name: ā— Correction šŸ‘£ +about: Suggest the correction of an issue in API specification or a misalignment with API design guidelines +title: '' +labels: 'correction' +assignees: '' + +--- + +**Problem description** + + +**Expected behavior** + + + +**Alternative solution** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/issue_documentation_template.md b/.github/ISSUE_TEMPLATE/issue_documentation_template.md new file mode 100644 index 00000000..f7b8de02 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_documentation_template.md @@ -0,0 +1,18 @@ +--- +name: ā• Documentation šŸ“ +about: Indicate an issue with API documentation or supplementary documents +title: '' +labels: 'documentation' +assignees: '' + +--- + +**Problem description** + + +**Expected action** + + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/issue_enhancement_template.md b/.github/ISSUE_TEMPLATE/issue_enhancement_template.md new file mode 100644 index 00000000..279ce49a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_enhancement_template.md @@ -0,0 +1,20 @@ +--- +name: šŸ’” Enhancement šŸŒŸ +about: Suggest an idea for a new API feature or pose a question on directions for API evolution +title: '' +labels: 'enhancement' +assignees: '' + +--- + +**Problem description** + + +**Possible evolution** + + +**Alternative solution** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/issue_pm_template.md b/.github/ISSUE_TEMPLATE/issue_pm_template.md new file mode 100644 index 00000000..210a2f06 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_pm_template.md @@ -0,0 +1,18 @@ +--- +name: ā˜ Subproject management šŸŽ‚ +about: Indicate an issue with subproject repository or release management +title: '' +labels: 'subproject management' +assignees: '' + +--- + +**Problem description** + + +**Expected action** + + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/issue_tests_template.md b/.github/ISSUE_TEMPLATE/issue_tests_template.md new file mode 100644 index 00000000..170874a8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_tests_template.md @@ -0,0 +1,18 @@ +--- +name: ā‰ Tests šŸ”Ž +about: Indicate an issue with API tests +title: '' +labels: 'tests' +assignees: '' + +--- + +**Problem description** + + +**Expected action** + + + +**Additional context** + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..37952b59 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,45 @@ +#### What type of PR is this? + +Add one of the following kinds: +* bug +* correction +* enhancement/feature +* cleanup +* documentation +* subproject management +* tests + + +#### What this PR does / why we need it: + + + + +#### Which issue(s) this PR fixes: + + + +Fixes # + +#### Special notes for reviewers: + + + +#### Changelog input + +``` + release-note + +``` + +#### Additional documentation + +This section can be blank. + + + +``` +docs + +``` From 12a3503d7585bbf6a12f96d175c0f1df31105039 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:11:22 +0200 Subject: [PATCH 02/22] Delete .github/ISSUE_TEMPLATE/issue_bug_template.md Bug category is for Provider Implementation repositories only --- .github/ISSUE_TEMPLATE/issue_bug_template.md | 33 -------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/issue_bug_template.md diff --git a/.github/ISSUE_TEMPLATE/issue_bug_template.md b/.github/ISSUE_TEMPLATE/issue_bug_template.md deleted file mode 100644 index 74b42179..00000000 --- a/.github/ISSUE_TEMPLATE/issue_bug_template.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: ā€¼ Bug šŸ› -about: Describe the bug in Provider Implementation -title: '' -labels: 'implementation:bug' -assignees: '' - ---- - -**Describe the bug** - - -**To Reproduce** - - -**Expected behavior** - - -**Screenshots** - - -**Environment:** - - -**Additional context** - From bf716415c29864bc2ab672a500250c4e1fc9c1a2 Mon Sep 17 00:00:00 2001 From: gunjald <107645297+gunjald@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:02:47 +0530 Subject: [PATCH 03/22] Update EdgeCloud_LcM.yaml Added version filed for info element as aligned with other API to indicate the API version --- code/API_definitions/EdgeCloud_LcM.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/code/API_definitions/EdgeCloud_LcM.yaml b/code/API_definitions/EdgeCloud_LcM.yaml index e2f9af20..83f4f408 100644 --- a/code/API_definitions/EdgeCloud_LcM.yaml +++ b/code/API_definitions/EdgeCloud_LcM.yaml @@ -1,6 +1,7 @@ openapi: 3.0.3 info: title: Edge Cloud API + version: 0.9.1 description: | Edge Cloud API for Life Cycle Management and discovery of an application. From 338b8c46e8ec31beccb6b4ab78948b4ac2b0671a Mon Sep 17 00:00:00 2001 From: sergiofranciscoortiz <130382488+sergiofranciscoortiz@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:19:44 +0100 Subject: [PATCH 04/22] Update CODEOWNERS Added Nicola Cadenelli from NearbyComputing --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index b9909750..837a3102 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,4 +6,4 @@ # These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file. -* @gunjald @kevsy @crissancas @FabrizioMoggio @sergiofranciscoortiz +* @gunjald @kevsy @crissancas @FabrizioMoggio @sergiofranciscoortiz @nicolacdnll From 9faf4cfde5fe261a6e2f2009bc5886e67b01dff1 Mon Sep 17 00:00:00 2001 From: sergiofranciscoortiz <130382488+sergiofranciscoortiz@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:14:07 +0100 Subject: [PATCH 05/22] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 837a3102..68ce1f8c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,4 +6,4 @@ # These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file. -* @gunjald @kevsy @crissancas @FabrizioMoggio @sergiofranciscoortiz @nicolacdnll +* @gunjald @kevsy @crissancas @FabrizioMoggio @sergiofranciscoortiz @nicolacdnll @gainsley From 1f9fc0b13fb7eedc1c4d1fc398f257ae3dc60e28 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 12 Feb 2024 17:35:38 +0000 Subject: [PATCH 06/22] Update describing and harmonising the Edge APIs.md Corrected text to confirm that EDS can be called from an application server, or by an application client on a device. --- .../describing and harmonising the Edge APIs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/SupportingDocuments/Harmonisation of APIs/describing and harmonising the Edge APIs.md b/documentation/SupportingDocuments/Harmonisation of APIs/describing and harmonising the Edge APIs.md index 72d3a586..06e1f9c4 100644 --- a/documentation/SupportingDocuments/Harmonisation of APIs/describing and harmonising the Edge APIs.md +++ b/documentation/SupportingDocuments/Harmonisation of APIs/describing and harmonising the Edge APIs.md @@ -80,7 +80,7 @@ Abbreviations used for API names: ## Constraints of the APIs ### Simple Edge Discovery - not application aware (does not take into account the application's requirements for MEC, e.g. compute resources) -- must be called by the network-attached UE hosting the client application +- may be called by either: (1) the network-attached UE hosting the client application, or (2) an application developer's server. ### MEC Exposure & Experience Management - no constraints (to be checked) From 91a14b734082360c055f9db10591848c710aa2d8 Mon Sep 17 00:00:00 2001 From: sergiofranciscoortiz <130382488+sergiofranciscoortiz@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:24:38 +0100 Subject: [PATCH 07/22] Gherkin Test feature file for EdgeCloud_LCM First version of Gherkin test feature file for EdgeCloud_LCM including at lis one test with response ok and one test with response nok for all existing POST,GET,DELETE methods in version 0.9.2 (https://github.com/camaraproject/EdgeCloud/pull/208) --- .../Edgecloud_LCM_Test.feature | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 code/Test_definitions/Edgecloud_LCM_Test.feature diff --git a/code/Test_definitions/Edgecloud_LCM_Test.feature b/code/Test_definitions/Edgecloud_LCM_Test.feature new file mode 100644 index 00000000..d62fb3b0 --- /dev/null +++ b/code/Test_definitions/Edgecloud_LCM_Test.feature @@ -0,0 +1,139 @@ +#/*- ---license-start +#* CAMARA Project +#* --- +#* Copyright (C) 2022 - 2023 Contributors | Deutsche Telekom AG to CAMARA a Series of LF Projects, LLC +#* The contributor of this file confirms his sign-off for the +#* Developer Certificate of Origin (http://developercertificate.org). +#* --- +#* Licensed under the Apache License, Version 2.0 (the "License"); +#* you may not use this file except in compliance with the License. +#* You may obtain a copy of the License at +#* +#* http://www.apache.org/licenses/LICENSE-2.0 +#* +#* Unless required by applicable law or agreed to in writing, software +#* distributed under the License is distributed on an "AS IS" BASIS, +#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#* See the License for the specific language governing permissions and +#* limitations under the License. +#* ---license-end +#*/ + +@EdgeCloudLCM @EdgeCloudLCMSanity +Feature:Automated Edge Cloud API System Integration Test + + +@EdgeCloud_LCM_app_submittion_ok +Scenario: Submit an Application with mandatory parameters +When invoking with the POST method to submit an app with all required parameters +Then response code is 201 + +@EdgeCloud_LCM_app_submittion_conflict +Scenario: Submit an Application with mandatory parameters +Given an aplication with the same name and version had already been submitted +When invoking with the POST method to submit an app with all required parameters +Then response code is 409 + +@EdgeCloud_LCM_app_get_info_valid_parameter +Scenario: Get application info with mandatory parameter ("appId") +When invoking the GET method to obtain app information with mandatory parameter ("appId") +Then response code is 200 + +@EdgeCloud_LCM_app_get_info_invalid_parameter +Scenario: Get application info with mandatory parameter ("appId") +Given appId provided does not exist +When invoking the GET method to obtain submittion app information with mandatory parameter ("appId") +Then response code is 404 + +@EdgeCloud_LCM_app_delete_valid_parameter +Scenario: Delete all the information and content related to an Application with mandatory parameter ("appId") +Given there are no running instances of the app +When invoking with the DELETE method to delete an app with just mandatory parameter ("appId") +Then response code is 202 +And the application information is deleted + +@EdgeCloud_LCM_app_delete_conflict +Scenario: Delete all the information and content related to an Application with mandatory parameter ("appId") +Given there are running instances of the app +When invoking with the DELETE method to delete an app with just mandatory parameter ("appId") +Then response code is 409 + +@EdgeCloud_LCM_app_delete_invalid_parameter +Scenario: Delete all the information and content related to an Application with mandatory parameter ("appId") +Given appId provided does not exist +When invoking with the DELETE method to delete an app with just mandatory parameter ("appId") +Then response code is 404 + +@EdgeCloud_LCM_app_instantiation_ok_mandatory_parameter +Scenario: Instantiate an Application with just mandatory parameter ("appId") +Given an aplication has already been submitted +When invoking with the POST method to instantiate an app with just mandatory parameter ("appId") +Then response code is 202 +And the process of instantiating the app starts in all available regions and edge cloud zones + +@EdgeCloud_LCM_app_instantiation_ok_optional_parameters +Scenario: Instantiate an Application with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Given an aplication has already been submitted +When invoking with the POST method to instantiate an app with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Then response code is 202 +And the process of intantiating the app starts only in given region and edge cloud zone + +@EdgeCloud_LCM_app_instantiation_conflict +Scenario: Instantiate an Application with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Given an aplication has already been submitted, but already instantiated in given EdgeCloudZone +When invoking with the POST method to instantiate an app with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Then response code is 409 + +@EdgeCloud_LCM_app_instance_get_info_valid_parameter +Scenario: Get application instance info with mandatory parameter ("appId") +When invoking the GET method to obtain information an app instance with mandatory parameter ("appId") +Then response code is 200 +And information of all existing app instances of given app is returned + +@EdgeCloud_LCM_app_instance_get_info_invalid_parameter +Scenario: Get application instance info with mandatory parameter ("appId") +Given appId provided does not exist +When invoking the GET method to obtain information an app instance with mandatory parameter ("appId") +Then response code is 404 + +@EdgeCloud_LCM_app_innstance_delete_all_instances +Scenario: Delete all running instances of an application in Edge Cloud +When invoking with the DELETE method to terminate running instances of an application within Edge Cloudwith with just mandatory parameter ("appId") +Then response code is 202 +And all the application instances are deleted + +@EdgeCloud_LCM_app_innstance_delete_valid_parameter +Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") +When invoking with the DELETE method to terminate a running instance of an application including optional parameter ("appInstanceId") and mandatory parameter ("appId") +Then response code is 202 +And the application instance is deleted + +@EdgeCloud_LCM_app_innstance_delete_invalid_parameter +Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") +When invoking with the DELETE method to terminate a running instance of an application including optional parameter ("appInstanceId") and mandatory parameter ("appId") +Then response code is 202 +And the application instance is deleted + +@EdgeCloud_LCM_app_innstance_delete_invalid_parameter +Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") +Given appInstanceId provided does not exist +When invoking with the DELETE method to terminate a running instance of an application including optional parameter ("appInstanceId") and mandatory parameter ("appId") +Then response code is 404 + +@EdgeCloud_LCM_get_all_edge_cloud_zones_ok +Scenario: Get information of all existing Edge Cloud Zones +When invoking the GET method to obtain information of Edge Cloud Zones with no optional parameters +Then response code is 200 +And information of all existing edge cloud zones is returned + +@EdgeCloud_LCM_get_filtered_edge_cloud_zones_ok +Scenario: Get information of existing Edge Cloud Zones with optional parameters ("region","status") +When invoking the GET method to obtain information of Edge Cloud Zones with a region and a status (active,inactive,unknown) +Then response code is 200 +And only information of cloud zones in the region and with the current status given in the input is returned + +@EdgeCloud_LCM_get_filtered_edge_cloud_zones_nok +Scenario: Get information of existing Edge Cloud Zones with optional parameters ("region","status") +Given region provided that not exist +When invoking the GET method to obtain information of Edge Cloud Zones with a region and a status (active,inactive,unknown) +Then response code is 404 From 9f38e2e09247236f82cf4747f62038e3cee6467f Mon Sep 17 00:00:00 2001 From: sergiofranciscoortiz <130382488+sergiofranciscoortiz@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:27:31 +0100 Subject: [PATCH 08/22] Update Edgecloud_LCM_Test.feature Correct mandatory parameters for app_instantiation, changed result of deletion from deletion to termination initiated --- .../Edgecloud_LCM_Test.feature | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/code/Test_definitions/Edgecloud_LCM_Test.feature b/code/Test_definitions/Edgecloud_LCM_Test.feature index d62fb3b0..a06df0bc 100644 --- a/code/Test_definitions/Edgecloud_LCM_Test.feature +++ b/code/Test_definitions/Edgecloud_LCM_Test.feature @@ -64,24 +64,24 @@ Given appId provided does not exist When invoking with the DELETE method to delete an app with just mandatory parameter ("appId") Then response code is 404 -@EdgeCloud_LCM_app_instantiation_ok_mandatory_parameter -Scenario: Instantiate an Application with just mandatory parameter ("appId") +@EdgeCloud_LCM_app_instantiation_ok_mandatory_parameters +Scenario: Instantiate an Application with just mandatory parameters ("appId" in path, and "region" in body) Given an aplication has already been submitted -When invoking with the POST method to instantiate an app with just mandatory parameter ("appId") +When invoking with the POST method to instantiate an app with just mandatory parameters ("appId" in path, and "region" in body) Then response code is 202 -And the process of instantiating the app starts in all available regions and edge cloud zones +And the process of instantiating the app starts in all available edge cloud zones in the region provided @EdgeCloud_LCM_app_instantiation_ok_optional_parameters -Scenario: Instantiate an Application with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Scenario: Instantiate an Application with mandatory parameters ("appId" in path, and "region" in body) and optional parameter ("EdgeCloudZone") Given an aplication has already been submitted -When invoking with the POST method to instantiate an app with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +When invoking with the POST method to instantiate an app with mandatory mandatory parameters ("appId" in path, and "region" in body) and optional parameter ("EdgeCloudZone") Then response code is 202 And the process of intantiating the app starts only in given region and edge cloud zone @EdgeCloud_LCM_app_instantiation_conflict -Scenario: Instantiate an Application with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +Scenario: Instantiate an Application with mandatory parameters ("appId" in path, and "region" in body) and optional parameter ("EdgeCloudZone") Given an aplication has already been submitted, but already instantiated in given EdgeCloudZone -When invoking with the POST method to instantiate an app with mandatory parameter ("appId") and optional parameters ("region","EdgeCloudZone") +When invoking with the POST method to instantiate an app with mandatory mandatory parameters ("appId" in path, and "region" in body) and optional parameter ("EdgeCloudZone") Then response code is 409 @EdgeCloud_LCM_app_instance_get_info_valid_parameter @@ -100,19 +100,14 @@ Then response code is 404 Scenario: Delete all running instances of an application in Edge Cloud When invoking with the DELETE method to terminate running instances of an application within Edge Cloudwith with just mandatory parameter ("appId") Then response code is 202 -And all the application instances are deleted +And all the application instances termination initiated @EdgeCloud_LCM_app_innstance_delete_valid_parameter Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") When invoking with the DELETE method to terminate a running instance of an application including optional parameter ("appInstanceId") and mandatory parameter ("appId") Then response code is 202 -And the application instance is deleted +And the application instance termination initiated -@EdgeCloud_LCM_app_innstance_delete_invalid_parameter -Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") -When invoking with the DELETE method to terminate a running instance of an application including optional parameter ("appInstanceId") and mandatory parameter ("appId") -Then response code is 202 -And the application instance is deleted @EdgeCloud_LCM_app_innstance_delete_invalid_parameter Scenario: Delete a running instance of an application within an Edge Cloud Zone with optional parameter ("appInstanceId") From 46da9593d7422a57fb675185d49ed7dc2682c7b2 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 23 Feb 2024 17:08:58 +0000 Subject: [PATCH 09/22] Add files via upload --- camara-language-avoid-telco.js | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 camara-language-avoid-telco.js diff --git a/camara-language-avoid-telco.js b/camara-language-avoid-telco.js new file mode 100644 index 00000000..061b5431 --- /dev/null +++ b/camara-language-avoid-telco.js @@ -0,0 +1,40 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const replacements = [ + { original: 'UE', recommended: 'device' }, + { original: 'MSISDN', recommended: 'phone number' }, + { original: 'mobile network', recommended: 'network' } +]; + +export default async function (input) { + const errors = []; + const suggestions = []; + + // Iterate over properties of the input object + for (const path in input) { + const value = input[path]; + + // Check if the value is a string + if (typeof value === 'string') { + for (const replacement of replacements) { + const original = replacement.original; + const recommended = replacement.recommended; + + // Use a regular expression to match 'original' as a standalone word + const regex = new RegExp(`\\b${original}\\b`, 'g'); + + // Check if 'original' exists in the value + if (regex.test(value)) { + errors.push(replacement); + suggestions.push(` Telco-specific terminology found in input: Consider replacing '${original}' with '${recommended}'.`); + } + } + } + } + + // Check if any word from 'replacements' is in the suggestions + if (errors.length > 0) { + console.log(`Hint camara-language-avoid-telco ` + suggestions.join(', ')); + } +}; From a8161d3e163c16e6a2ac0521c534138507e71eda Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:13:15 +0000 Subject: [PATCH 10/22] Rename camara-language-avoid-telco.js to lint_function/camara-language-avoid-telco.js --- .../camara-language-avoid-telco.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename camara-language-avoid-telco.js => lint_function/camara-language-avoid-telco.js (100%) diff --git a/camara-language-avoid-telco.js b/lint_function/camara-language-avoid-telco.js similarity index 100% rename from camara-language-avoid-telco.js rename to lint_function/camara-language-avoid-telco.js From 937d4b8e9874b5e3d33c0139a8c21f5a9ab42912 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:15:50 +0000 Subject: [PATCH 11/22] Added lint files --- lint_function/camara-reserved-words.js | 98 +++++++++++++++++++ ...-no-secrets-in-path-or-query-parameters.js | 26 +++++ 2 files changed, 124 insertions(+) create mode 100644 lint_function/camara-reserved-words.js create mode 100644 lint_function/camara-security-no-secrets-in-path-or-query-parameters.js diff --git a/lint_function/camara-reserved-words.js b/lint_function/camara-reserved-words.js new file mode 100644 index 00000000..c28e63ab --- /dev/null +++ b/lint_function/camara-reserved-words.js @@ -0,0 +1,98 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const reservedWords = [ + 'abstract', + 'apiclient', + 'apiexception', + 'apiresponse', + 'assert', + 'boolean', + 'break', + 'byte', + 'case', + 'catch', + 'char', + 'class', + 'configuration', + 'const', + 'continue', + 'do', + 'double', + 'else', + 'extends', + 'file', + 'final', + 'finally', + 'float', + 'for', + 'goto', + 'if', + 'implements', + 'import', + 'instanceof', + 'int', + 'interface', + 'list', + 'localdate', + 'localreturntype', + 'localtime', + 'localvaraccept', + 'localvaraccepts', + 'localvarauthnames', + 'localvarcollectionqueryparams', + 'localvarcontenttype', + 'localvarcontenttypes', + 'localvarcookieparams', + 'localvarformparams', + 'localvarheaderparams', + 'localvarpath', + 'localvarpostbody', + 'localvarqueryparams', + 'long', + 'native', + 'new', + 'null', + 'object', + 'offsetdatetime', + 'package', + 'private', + 'protected', + 'public', + 'return', + 'short', + 'static', + 'strictfp', + 'stringutil', + 'super', + 'switch', + 'synchronized', + 'this', + 'throw', + 'throws', + 'transient', + 'try', + 'void', + 'volatile', + 'while' +]; +// Reserved word 'enum' and 'default' are removed from above reserved word array as they are common in openAPI keyword +export default async function lintReservedWords(input) { + // Iterate over properties of the input object + for (const path in input) { + if (typeof path === 'string') { + + for (const word of reservedWords) { + const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word + + if (regex.test(path)) { + const warningRuleName = 'camara-reserved-words'; + const description = `Reserved words found in input: Consider avoiding the use of reserved word '${word}'`; + // const location = `${path}`; + + console.log(`warning ${warningRuleName} ${description} ${path}`); + } + } + } + } +} diff --git a/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js b/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js new file mode 100644 index 00000000..ebbff2a4 --- /dev/null +++ b/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js @@ -0,0 +1,26 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const sensitiveData = ['MSISDN','IMSI','phoneNumber']; + +export default async function (input) { + + // Iterate over properties of the input object + for (const path in input) { + + if (typeof path === 'string') { + for (const word of sensitiveData ) { + const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word + + if (regex.test(path)) { + + const warningRuleName = 'camara-security-no-secrets-in-path-or-query-parameters'; + const description = `sensitiveData Data found in path: Consider avoiding the use of sensitiveData data '${word}'`; + const location = `paths.${path}`; + console.log(`warning ${warningRuleName} ${description} ${location}`); + + } + } + } + } +} From 9237e83cf54abd9c76fc16ad4839b9e2c02a25b9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:17:41 +0000 Subject: [PATCH 12/22] added spectral rules --- spectral.yml | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 spectral.yml diff --git a/spectral.yml b/spectral.yml new file mode 100644 index 00000000..0b16508e --- /dev/null +++ b/spectral.yml @@ -0,0 +1,258 @@ +# CAMARA Project - linting ruleset - documentation avaialable here: +# https://github.com/camaraproject/Commonalities/blob/main/documentation/Linting-rules.md +# 31.01.2024 - initial version + +extends: "spectral:oas" +functions: + - camara-reserved-words + - camara-language-avoid-telco + - camara-security-no-secrets-in-path-or-query-parameters +functionsDir: "./lint_function" +rules: + # Built-in OpenAPI Specification ruleset. Each rule then can be enabled individually. + # The severity keyword is optional in rule definition and can be error, warn, info, hint, or off. The default value is warn. + contact-properties: false + duplicated-entry-in-enum: true + info-contact: true + info-description: true + info-license: true + license-url: true + no-$ref-siblings: error + no-eval-in-markdown: true + no-script-tags-in-markdown: true + openapi-tags: false + openapi-tags-alphabetical: false + openapi-tags-uniqueness: error + operation-description: true + operation-operationId: true + operation-operationId-unique: error + operation-operationId-valid-in-url: true + operation-parameters: true + operation-singular-tag: true + operation-success-response: true + operation-tags: true + operation-tag-defined: true + path-declarations-must-exist: true + path-keys-no-trailing-slash: true + path-not-include-query: true + path-params: error + tag-description: false + typed-enum: true + oas3-api-servers: true + oas3-examples-value-or-externalValue: true + oas3-operation-security-defined: false + oas3-parameter-description: false + oas3-schema: true + oas3-server-not-example.com: false + oas3-server-trailing-slash: true + oas3-unused-component: true + oas3-valid-media-example: true + oas3-valid-schema-example: true + # oas3-server-variables: true + + # Custom Rules Utilizing Spectral's Built-in Functions and JavaScript Implementations + + camara-language-avoid-telco: + message: "{{error}}" + severity: hint + description: | + This rule checks for telco-specific terminology in your API definitions and suggests more inclusive terms. + given: "$..*.*" + then: + function: camara-language-avoid-telco + recommended: false # Set to true/false to enable/disable this rule + + camara-oas-version: + message: "OpenAPI Version Error: The OpenAPI specification must adhere to version 3.0.3." + severity: error + description: | + This rule validates the OpenAPI version in your specification and requires compliance with version 3.0.3. + given: "$" + then: + field: openapi + function: pattern + functionOptions: + match: 3.0.3 + recommended: true # Set to true/false to enable/disable this rule + + camara-path-param-id: + message: "Path Parameter Naming Warning: Use 'resource_id' instead of just 'id' in path parameters." + severity: warn + description: | + This rule ensures consistent and descriptive naming for path parameters in your OpenAPI specification. + Please use 'resource_id' instead of just 'id' for your path parameters. + given: "$..parameters[?(@.in == 'path')]" + then: + field: name + function: pattern + functionOptions: + notMatch: \b(id|Id|ID|iD)\b + recommended: true # Set to true/false to enable/disable this rule + + camara-security-no-secrets-in-path-or-query-parameters: + message: "Sensitive data found in path: {{error}} Consider avoiding the use of Sesentive data " + severity: warn + description: | + This rule checks for sensitive data ('MSISDN' and 'IMSI') in API paths and suggests avoiding their use. + given: + - "$.paths" + then: + function: camara-security-no-secrets-in-path-or-query-parameters + recommended: true # Set to true/false to enable/disable this rule + + camara-http-methods: + description: "Ensure that all path URLs have valid HTTP methods (GET, PUT, POST, DELETE, PATCH, OPTIONS)." + message: "Invalid HTTP method for '{{path}}'. Must be one of get, put, post, delete, patch, options." + severity: error + given: $.paths[*][*]~ + then: + function: pattern + functionOptions: + match: "^(get|put|post|delete|patch|options)$" + recommended: true # Set to true/false to enable/disable this rule + + camara-get-no-request-body: + message: There must be no request body for Get and DELETE + severity: error + given: + - "$.paths.*.get" + - "$.paths.*.delete" + then: + field: requestBody + function: falsy + recommended: true # Set to true/false to enable/disable this rule + + camara-reserved-words: + message: "Reserved words found {{error}} Consider avoiding the use of reserved word " + severity: warn + description: | + This rule checks Reserved words must not be used in the following parts of an API specification [Paths, Request Body properties, Component, Operation Id, Security Schema] + given: + - "$.paths" # Paths + - "$..parameters[*]" # Path or Query Parameter Names: + - "$..components.schemas.*.properties.*" # Request and Response body parameter + - "$.paths.*." # Path and Operation Names: + - "$.components.securitySchemes" # Security Schemes: + - "$.components.*.*" # Component Names: + - "$.paths.*.*.operationId" # OperationIds: + then: + function: camara-reserved-words + recommended: true # Set to true/false to enable/disable this rule + + camara-routes-description: + message: "Functionality method description Warning: Each method should have description." + severity: warn + description: | + This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a description. + Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. + given: + - "$.paths.*.post" + - "$.paths.*.get" + - "$.paths.*.delete" + - "$.paths.*.put" + - "$.paths.*.patch" + - "$.paths.*.options" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-parameters-descriptions: + message: "Parameter description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each path parameter in the API specification has a descriptive and meaningful description. + given: + - "$.paths..parameters.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-response-descriptions: + message: "Parameter description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each responese object in the API specification has a descriptive and meaningful description. + given: + - "$.paths..responses.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-properties-descriptions: + message: "Property description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each propoerty within objects in the API specification has a descriptive and meaningful description. + given: + - "$.components.*.*" + - "$.components.*.*.properties.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-operation-summary: + message: "Operation Summary Warning: Each operation should include a short summary for better understanding." + severity: warn + description: | + This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a meaningful summary. + Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. + given: + - "$.paths.*.post" + - "$.paths.*.get" + - "$.paths.*.delete" + - "$.paths.*.put" + - "$.paths.*.patch" + - "$.paths.*.options" + then: + field: summary + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-discriminator-use: + description: | + Ensure that API definition YAML files with oneOf or anyOf sections include a discriminator object for serialization, deserialization, and validation. + severity: hint + given: "$..[?(@.oneOf || @.anyOf)]" + then: + field: discriminator + function: truthy + description: "Discriminator object is required when using oneOf or anyOf." + recommended: true # Set to true/false to enable/disable this rule + + camara-operationid-casing-convention: + message: Operation Id must be in Camel case "{{error}}" + severity: hint + description: | + This rule checks Operation ids should follow a specific case convention: camel case. + given: "$.paths.*.*.operationId" + then: + function: casing + functionOptions: + type: camel + recommended: true # Set to true/false to enable/disable this rule + + camara-schema-casing-convention: + description: This rule checks schema should follow a specific case convention pascal case. + message: "{{property}} should be pascal case (UppperCamelCase)" + severity: warn + given: $.components.schemas[*]~ + then: + function: casing + functionOptions: + type: pascal + recommended: true # Set to true/false to enable/disable this rule + + camara-parameter-casing-convention: + description: Paths should be kebab-case. + severity: error + message: "{{property}} is not kebab-case: {{error}}" + given: $.paths[*]~ + then: + function: pattern + functionOptions: + match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces + recommended: true # Set to true/false to enable/disable this rule From fd3b706fcad67abbf8cb2446eb67aaf45e109f19 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:18:01 +0000 Subject: [PATCH 13/22] Rename spectral.yml to .spectral.yml --- spectral.yml => .spectral.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spectral.yml => .spectral.yml (100%) diff --git a/spectral.yml b/.spectral.yml similarity index 100% rename from spectral.yml rename to .spectral.yml From fd4e80c61eb6d6457a0af8cbea2287aedeba67b8 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:20:31 +0000 Subject: [PATCH 14/22] Added workflow files --- megalinter.yml | 78 +++++++++++++++++++++++++++++++++++++++++++ spectral_oas_lint.yml | 36 ++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 megalinter.yml create mode 100644 spectral_oas_lint.yml diff --git a/megalinter.yml b/megalinter.yml new file mode 100644 index 00000000..6bda7009 --- /dev/null +++ b/megalinter.yml @@ -0,0 +1,78 @@ +--- +# MegaLinter GitHub Action configuration file +# More info at https://megalinter.io +# CAMARA Project - Github Action for Pull Reqests +# 31.01.2024 - initial version + +name: MegaLinter + +on: # yamllint disable-line rule:truthy + # Pull Requests to main + pull_request: + branches: [master, main] + +env: # Comment env block if you do not want to apply fixes + # Apply linter fixes configuration + APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) + APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) + APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build: + name: MegaLinter + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + # Git Checkout + - name: Checkout Code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances + - name: Install Spectral + run: npm install -g @stoplight/spectral + - name: Install Spectral functions + run: npm install -g @stoplight/spectral-functions + # - name: Run spectral:oas Spectral Linting + # run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml + # Replace openapi.yaml file with your API specification file + + # MegaLinter + - name: MegaLinter + id: ml + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/flavors/ + uses: oxsecurity/megalinter/flavors/java@v7.3.0 + env: + # All available variables are described in documentation + # https://megalinter.io/configuration/ + PRINT_ALPACA: false + # VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources + VALIDATE_ALL_CODEBASE: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY + DISABLE: COPYPASTE,MARKDOWN + DISABLE_LINTERS: SPELL_CSPELL,SPELL_LYCHEE,YAML_PRETTIER,REPOSITORY_GRYPE, REPOSITORY_SEMGREP,REPOSITORY_DEVSKIM,REPOSITORY_KICS,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_CHECKOV,REPOSITORY_GITLEAKS,YAML_V8R,JAVA_PMD,JAVA_CHECKSTYLE + YAML_YAMLLINT_CONFIG_FILE: ".yamllint.yaml" + OPENAPI_SPECTRAL_CONFIG_FILE: ".spectral.yml" + YAML_YAMLLINT_FILTER_REGEX_INCLUDE: "(code/)" + OPENAPI_SPECTRAL_FILTER_REGEX_INCLUDE: "(code/)" + + # Upload MegaLinter artifacts + - name: Archive production artifacts + if: ${{ success() }} || ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log diff --git a/spectral_oas_lint.yml b/spectral_oas_lint.yml new file mode 100644 index 00000000..a828fd58 --- /dev/null +++ b/spectral_oas_lint.yml @@ -0,0 +1,36 @@ +--- +# CAMARA Project - workflow configuration to manually run CAMARA OAS rules +# see https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow +# 31.01.2024 - initial version + +name: Spectral manual run + +on: workflow_dispatch + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build: + name: Spectral linting + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + # Git Checkout + - name: Checkout Code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances + - name: Install Spectral + run: npm install -g @stoplight/spectral + - name: Install Spectral functions + run: npm install -g @stoplight/spectral-functions + - name: Run Spectral linting + run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml From 48fa6c98cd4f2dbe0d9b3a9d78e4a724f890176d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:21:52 +0000 Subject: [PATCH 15/22] Rename megalinter.yml to .github/workflows/megalinter.yml --- megalinter.yml => .github/workflows/megalinter.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename megalinter.yml => .github/workflows/megalinter.yml (100%) diff --git a/megalinter.yml b/.github/workflows/megalinter.yml similarity index 100% rename from megalinter.yml rename to .github/workflows/megalinter.yml From 6f7a192082c07608a6b6af8d842b758a62e69da9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Feb 2024 12:22:14 +0000 Subject: [PATCH 16/22] Rename spectral_oas_lint.yml to .github/workflows/spectral_oas_lint.yml --- spectral_oas_lint.yml => .github/workflows/spectral_oas_lint.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spectral_oas_lint.yml => .github/workflows/spectral_oas_lint.yml (100%) diff --git a/spectral_oas_lint.yml b/.github/workflows/spectral_oas_lint.yml similarity index 100% rename from spectral_oas_lint.yml rename to .github/workflows/spectral_oas_lint.yml From e2bcd3b74d55406099176ebf73f987a65a569f52 Mon Sep 17 00:00:00 2001 From: sergiofranciscoortiz <130382488+sergiofranciscoortiz@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:33:40 +0100 Subject: [PATCH 17/22] Update CODEOWNERS substitute Telefonica representative Request to modify current telefonica technical representative in codeowners from Sergio Francisco Ortiz to Javier Loza who is currently contributing with LCM API --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 68ce1f8c..c8c9f971 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,4 +6,4 @@ # These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file. -* @gunjald @kevsy @crissancas @FabrizioMoggio @sergiofranciscoortiz @nicolacdnll @gainsley +* @gunjald @kevsy @crissancas @FabrizioMoggio @nicolacdnll @gainsley @javierlozallu From 0b01960d71553ba0f4ad517e1b4539f533ad537a Mon Sep 17 00:00:00 2001 From: JoseMConde <162570687+JoseMConde@users.noreply.github.com> Date: Wed, 20 Mar 2024 12:25:19 +0100 Subject: [PATCH 18/22] =?UTF-8?q?Update=20README.md=20to=20change=20meetin?= =?UTF-8?q?g=C2=B4s=20platform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to be able to record the meetings, we change the meetingĀ“s platform from teams to LFX Zoom. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index d18f0602..bd5ec057 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,7 @@ Repository to describe, develop, document and test the EdgeCloud API family ## Meetings * Meetings are held virtually * Schedule: Tuesdays 16h-17 CET, every two weeks. -* Meeting link: [Link](https://teams.microsoft.com/l/meetup-join/19%3ameeting_ZTk5NjBiZTgtYjc5OS00ODA5LTljMTEtNjZkNjNmYzdmZTE3%40thread.v2/0?context=%7b%22Tid%22%3a%229744600e-3e04-492e-baa1-25ec245c6f10%22%2c%22Oid%22%3a%2259beacec-cc69-4b31-873d-ba429711a3a7%22%7d) - +* Meeting link: [LFX Zoom](https://www.google.com/url?q=https://zoom-lfx.platform.linuxfoundation.org/meeting/94237809115?password%3D05fb6d8a-a913-47d8-b003-db75ecdaa5d9&sa=D&source=calendar&ust=1711304713775725&usg=AOvVaw2KsTGn2S2i4Bu5V-nusuUI) ## Results * Sub Project is in progress From 17a00c04dd3e25025f5361f82dcc17c644f569a6 Mon Sep 17 00:00:00 2001 From: Bernardo Date: Thu, 21 Mar 2024 10:13:04 +0000 Subject: [PATCH 19/22] fixed typos and punctuation --- .../Discovery/simple_edge_discovery.yaml | 233 +++++++++--------- 1 file changed, 115 insertions(+), 118 deletions(-) diff --git a/code/API_definitions/Discovery/simple_edge_discovery.yaml b/code/API_definitions/Discovery/simple_edge_discovery.yaml index 53baa463..ee38f842 100644 --- a/code/API_definitions/Discovery/simple_edge_discovery.yaml +++ b/code/API_definitions/Discovery/simple_edge_discovery.yaml @@ -6,17 +6,17 @@ info: # Find the closest MEC platform --- # Summary - + The Simple Edge Discovery API returns the name of the closest operator MEC platform to a particular user device. - + # Purpose Network operators may host multiple Multi-access Edge Computing (MEC, or 'Edge') platforms in a given territory. Connecting your application to a server on the closest MEC platform means packets travel the shortest distance between endpoints, typically resulting in the lowest round-trip latency. Note, the physical (GPS) location of a user device is not a reliable way to determine the closest MEC platform, due to the way operator networks are routed - so the operator will calculate the MEC platform with the _shortest network path_ to the network-attached device identified in the API request. - + Once you have the name of the closest MEC platform to the user device, you may: - + * connect the application client on the user device to your application server instance on that MEC platform. Note: the address of that server instance is not part of the API response, but should be known in advance. * or, if you have no instance on that MEC platform, you may wish to deploy one there. - + # Usage The API may be called either by an application client hosted on a device attached to the operator network (i.e. phone, tablet), or by a server. @@ -33,11 +33,11 @@ info: * if you call the API from a device attached to the operator network, you _may_ omit the explicit device identifier(s)from the request header. If such a request fails with a `404 Not Found` error then retry the request but this time include a device identifier. The provider of the MEC Platform may be an operator, or a cloud provider. The - + # Example requests: - + Examples for all API clients: - + GET /mec-platforms?filter=closest HTTP/1.1 Host: example.com Accept: application/json @@ -54,15 +54,15 @@ info: Phone-Number: 441234567890 Example where API client is on a network-attached device: - + GET /mec-platforms?filter=closest HTTP/1.1 Host: example.com Accept: application/json - + # Responses - + ## Success - + A JSON object is returned containing a `MECPlatforms` array with a single member, along with the HTTP `200 OK` status code. The value of the `edgeCloudProvider` object is the name of the operator or cloud provider of the MEC Platform. `edgeResourceName` object is the name of the closest MEC platform to the user device. An example of this JSON object is as follows: ``` { @@ -75,20 +75,20 @@ info: } ``` ## Errors - - If the authentication token is not valid, a `401 UNAUTHENTICATED` error is returned - + + If the authentication token is not valid, a `401 UNAUTHENTICATED` error is returned. + If the mobile subscription parameters contain a formatting error, a `400 INVALID_ARGUMENT` error is returned. - + If the mobile subscription cannot be identified from the provided parameters, a `404 NOT_FOUND` error is returned. - + Any more general service failures will result in an error in the `5xx`range with an explanation. - + # Note for Simple Edge API publishers The API publisher (i.e. the operator implementation) must ensure that the tuple of edgeCloudProvider+edgeResourceName in the success reponse is unique. - + # Further info and support - + --- contact: email: sp-edc@lists.camaraproject.org @@ -96,41 +96,39 @@ info: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html externalDocs: - description: Product documentation at CAMARA + description: Product documentation at CAMARA. url: https://github.com/camaraproject/EdgeCloud - + servers: - url: "{apiRoot}/{basePath}" variables: apiRoot: default: https://localhost:443 - description: API root + description: API root. basePath: default: eds/v0 - description: Base path for the Simple Edge Discovery API + description: Base path for the Simple Edge Discovery API. tags: - name: Discovery description: | - Find the closest MEC platform to the user device. + Find the closest MEC platform to the user device. paths: /mec-platforms: get: - security: + security: - oAuth2ClientCredentials: [] operationId: getMecplatforms parameters: - name: filter in: query required: true - description: filter the MEC Platforms according to the parameter value. For this API the only supported value is `closest` + description: Filter the MEC Platforms according to the parameter value. For this API the only supported value is `closest`. schema: type: string - enum: [ - "closest" - ] - + enum: ["closest"] + - name: IP-Address in: header required: false @@ -145,11 +143,11 @@ paths: format: ipv4/ipv6 oneOf: - pattern: '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$' - - pattern: '^((:|(0?|([1-9a-f][0-9a-f]{0,3}))):)((0?|([1-9a-f][0-9a-f]{0,3})):){0,6}(:|(0?|([1-9a-f][0-9a-f]{0,3})))$' + - pattern: "^((:|(0?|([1-9a-f][0-9a-f]{0,3}))):)((0?|([1-9a-f][0-9a-f]{0,3})):){0,6}(:|(0?|([1-9a-f][0-9a-f]{0,3})))$" - name: Network-Access-Identifier in: header - description: 3GPP network access identifier for the subscription being used by the device + description: 3GPP network access identifier for the subscription being used by the device. example: "4d596ac1-7822-4927-a3c5-d72e1f922c94@domain.com" required: false schema: @@ -166,38 +164,38 @@ paths: responses: "200": - description: Successful reaponse, returning the closest MEC platform to the user device identified in the request header + description: Successful response, returning the closest MEC platform to the user device identified in the request header. content: application/json: schema: - $ref: '#/components/schemas/MecPlatforms' + $ref: "#/components/schemas/MecPlatforms" "400": - $ref: '#/components/responses/400BadRequest' + $ref: "#/components/responses/400BadRequest" "401": - $ref: '#/components/responses/401Unauthorized' + $ref: "#/components/responses/401Unauthorized" "403": - $ref: '#/components/responses/403Forbidden' + $ref: "#/components/responses/403Forbidden" "404": - $ref: '#/components/responses/404NotFound' + $ref: "#/components/responses/404NotFound" "405": - $ref: '#/components/responses/405MethodNotAllowed' + $ref: "#/components/responses/405MethodNotAllowed" "406": - $ref: '#/components/responses/406Unacceptable' + $ref: "#/components/responses/406Unacceptable" "429": - $ref: '#/components/responses/429TooManyRequests' + $ref: "#/components/responses/429TooManyRequests" "500": - $ref: '#/components/responses/500InternalServerError' + $ref: "#/components/responses/500InternalServerError" "502": - $ref: '#/components/responses/502BadGateway' + $ref: "#/components/responses/502BadGateway" "503": - $ref: '#/components/responses/503ServiceUnavailable' + $ref: "#/components/responses/503ServiceUnavailable" "504": - $ref: '#/components/responses/504GatewayTimeout' + $ref: "#/components/responses/504GatewayTimeout" tags: - Discovery summary: Returns the name of the MEC platform closest to user device identified in the request. description: On receiving this request, the network will return the name of the MEC platform with the shortest network path to the end user device identified in the request. - + components: securitySchemes: oAuth2ClientCredentials: @@ -211,98 +209,97 @@ components: MecPlatforms: type: array items: - $ref: '#/components/schemas/MecPlatform' - description: A collection of MEC Platforms. For this Simple Edge Discovery API the collection will have at most one member (the closest MEC Platform to the user device indicated in the request). + $ref: "#/components/schemas/MecPlatform" + description: A collection of MEC Platforms. For this Simple Edge Discovery API the collection will have at most one member (the closest MEC Platform to the user device indicated in the request). additionalProperties: false - + MecPlatform: type: object - description: A MEC Platform, uniquely identified by a combination of the value of the Edge Resource Name object and the value of the Provider object (the name of the cloud provider or operator hosting that platform). + description: A MEC Platform, uniquely identified by a combination of the value of the Edge Resource Name object and the value of the Provider object (the name of the cloud provider or operator hosting that platform). properties: edgeCloudProvider: $ref: "#/components/schemas/EdgeCloudProvider" edgeResourceName: $ref: "#/components/schemas/EdgeResource" - + EdgeCloudProvider: description: | - The company name of the MEC Platform provider + The company name of the MEC Platform provider. type: string - + EdgeResource: description: | - Edge Resource Name - an identifier for an edge reource in the operator domain + Edge Resource Name - an identifier for an edge reource in the operator domain. type: string - additionalProperties: false - + additionalProperties: false + errorResponse: type: object properties: code: type: string - description: A short, human-readable summary of the problem type + description: A short, human-readable summary of the problem type. status: type: integer - description: The HTTP status code - message: + description: The HTTP status code. + message: type: string - description: This parameter appears when there was an error. Human readable explanation specific to this occurrence of the problem - + description: This parameter appears when there was an error. Human readable explanation specific to this occurrence of the problem. -################################### -# RESPONSES -#################################### + ################################### + # RESPONSES + #################################### responses: - 400BadRequest: + 400BadRequest: description: Bad Request content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: InsufficientParameters: - description: Sufficient parameters must be specified to allow the target UE to be identified + description: Sufficient parameters must be specified to allow the target UE to be identified. value: - { + { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Insufficient parameters: At least one of Network-Access-Identifier, Phone-Number or IP-Address must be specified, or, the API must be called by a client on a netwok-attached device (hence passing the source IP in the request header) " + "message": "Insufficient parameters: At least one of Network-Access-Identifier, Phone-Number or IP-Address must be specified, or, the API must be called by a client on a netwok-attached device (hence passing the source IP in the request header) ", } InvalidExternalId: value: - { + { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Invalid Header Format: Network-Access-Identifier" + "message": "Invalid Header Format: Network-Access-Identifier", } InvalidMSISDN: value: - { + { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Invalid Header Format: Phone-Number" + "message": "Invalid Header Format: Phone-Number", } InvalidIP: - description: This error will be returned if the IP address does not have a valid format, or if the IP address is a private IPv4 address + description: This error will be returned if the IP address does not have a valid format, or if the IP address is a private IPv4 address. value: - { + { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Invalid Header Format: IP-Address" + "message": "Invalid Header Format: IP-Address", } 401Unauthorized: - description: Unauthorized + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: InvalidCredentials: value: - { + { "code": "UNAUTHENTICATED", - "status": 401, - "message": "Request not authenticated due to missing, invalid, or expired credentials" + "status": 401, + "message": "Request not authenticated due to missing, invalid, or expired credentials", } 403Forbidden: @@ -310,91 +307,91 @@ components: content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: InsufficientPermissions: value: - { + { "code": "PERMISSION_DENIED", "status": 403, - "message": "Client does not have sufficient permissions to perform this action" + "message": "Client does not have sufficient permissions to perform this action", } - + 404NotFound: description: Subscriber Not Found content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: SubscriberNotFound: description: No device found for the specified parameters, meaning the closest MEC platform cannot be determined. value: - { + { "code": "NOT_FOUND", "status": 404, - "message": "No device found for the specified parameters" + "message": "No device found for the specified parameters", } - + 405MethodNotAllowed: description: Method Not Allowed content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: MethodNotAllowed: - description: An HTTP verb other than GET has been used to try and access the resource + description: An HTTP verb other than GET has been used to try and access the resource. value: - { + { "code": "METHOD_NOT_ALLOWED", "status": 405, - "message": "The request method is not supported by this resource" + "message": "The request method is not supported by this resource", } - + 406Unacceptable: description: Not Acceptable content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: NotAcceptable: - description: A response format other than JSON has been requested + description: A response format other than JSON has been requested. value: - { + { "code": "NOT_ACCEPTABLE", "status": 406, - "message": "The server cannot produce a response matching the content requested by the client through Accept-* headers" + "message": "The server cannot produce a response matching the content requested by the client through Accept-* headers", } - + 429TooManyRequests: description: Too Many Requests content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" examples: TooManyRequests: - description: Access to the API has been temporarily blocked due to quota or spike arrest limits being reached + description: Access to the API has been temporarily blocked due to quota or spike arrest limits being reached. value: - { + { "code": "TOO_MANY_REQUESTS", "status": 429, - "message": "Either out of resource quota or reaching rate limiting" + "message": "Either out of resource quota or reaching rate limiting", } - + 500InternalServerError: description: Internal Server Error content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" example: - { + { "code": "INTERNAL", "status": 500, - "message": "The service is currently not available" + "message": "The service is currently not available", } 502BadGateway: @@ -402,12 +399,12 @@ components: content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" example: - { + { "code": "BAD_GATEWAY", "status": 502, - "message": "The service is currently not available" + "message": "The service is currently not available", } 503ServiceUnavailable: @@ -415,23 +412,23 @@ components: content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" example: - { + { "code": "UNAVAILABLE", "status": 503, - "message": "The service is currently not available" + "message": "The service is currently not available", } - + 504GatewayTimeout: description: Gateway Time-Out content: application/json: schema: - $ref: '#/components/schemas/errorResponse' + $ref: "#/components/schemas/errorResponse" example: - { + { "code": "TIMEOUT", "status": 504, - "message": "The service is currently not available" + "message": "The service is currently not available", } From 500e1271c375bf82cc5e248407eee5a490a86d12 Mon Sep 17 00:00:00 2001 From: Nicola Cadenelli Date: Thu, 21 Mar 2024 14:17:11 +0100 Subject: [PATCH 20/22] Spelling and autolinting --- code/API_definitions/Discovery/README.md | 48 +++++++++++-------- .../Discovery/simple_edge_discovery.yaml | 23 +++++---- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/code/API_definitions/Discovery/README.md b/code/API_definitions/Discovery/README.md index 203298e8..a0239d3e 100644 --- a/code/API_definitions/Discovery/README.md +++ b/code/API_definitions/Discovery/README.md @@ -1,16 +1,20 @@ # Edge Discovery APIs ## Simple Discovery API -This API allows a client application to discover the closest MEC platform to the UE hosting the client application. 'Closest' means 'shorteset network path' as that will give the shortest propogation distance, which is a major factor in latency. + +This API allows a client application to discover the closest MEC platform to the UE hosting the client application. 'Closest' means 'shortest network path' as that will give the shortest propagation distance, which is a major factor in latency. ## MEC Experience Management and Exposure API + This API allows a developer to: + - discover available MEC platforms, ranked by proximity to a UE. - read the state (availability and capabilities) of an operator's various MEC platforms. - register a service profile (a description of the developer's edge service) with the MEC operator - register the deployed service endpoints with the MEC operator, which allows the closest service endpoint to be discovered at runtime -The API will also support the following capabilities: +The API will also support the following capabilities: + - events(such as change of status of a MEC platform or another event which could affect their service) - subscription to notification of events. @@ -23,28 +27,34 @@ These APIs fulfil the ['discovery' intents](https://github.com/camaraproject/Edg *MEC Exposure and Experience Management* is a more comprehensive discovery API and fulfils the following intents: ### Developer intents -#### Provisioning intents -1. ā€œI can retrieve a list of the operatorā€™s MECs and their status, ordering the results by location and filtering by status (active/inactive/unknown)ā€ -2. "I can discover the capabilities/resources available at an operatorā€™s MEC: CPU, Memory, Storage, GPU" -3. "I can discover the geographical regions covered by the operators MECs" -4. "I can discover the closest MEC platform to a specific terminal (closest in terms of shortest network path)" -16. ā€œI can ask the operator to provide the details of all the onboarded applicationsā€ -17. "I can ask the operator to inform about the application instance details e.g., communication endpoints, resource consumed etc" +#### Provisioning intents + +1. ā€œI can retrieve a list of the operatorā€™s MECs and their status, ordering the results by location and filtering by status (active/inactive/unknown)ā€ +2. "I can discover the capabilities/resources available at an operatorā€™s MEC: CPU, Memory, Storage, GPU" +3. "I can discover the geographical regions covered by the operators MECs" +4. "I can discover the closest MEC platform to a specific terminal (closest in terms of shortest network path)" +16. ā€œI can ask the operator to provide the details of all the on-boarded applicationsā€ +17. "I can ask the operator to inform about the application instance details e.g., communication endpoints, resource consumed etc" -#### Runtime intents -19. "I can discover the closest MEC platform to a particular terminal (closest in terms of shortest network path)" -20. "I can discover the optimal MEC platform for my application and a particular terminal, taking into account connectivity, shortest network path, cost, network load etc." (`A`) -21. "I can discover the optimal application service endpoint for a specific terminal, taking into account mobility events, connectivity, shortest network path, cost, network load, MEC platform load etc." +#### Runtime intents + +19. "I can discover the closest MEC platform to a particular terminal (closest in terms of shortest network path)" +20. "I can discover the optimal MEC platform for my application and a particular terminal, taking into account connectivity, shortest network path, cost, network load etc." (`A`) +21. "I can discover the optimal application service endpoint for a specific terminal, taking into account mobility events, connectivity, shortest network path, cost, network load, MEC platform load etc." ### Operator intents + #### Provisioning intents -23. ā€œI can publish an (ordered, filtered) list of my MECs, their coverage, capabilities and statusā€ _(aligns with 1,2,3 in the developer intents)_ -24. ā€œI can map an applicationā€™s requirements to the best MEC for hosting it, based on application demands for CPU,Memory,Storage,GPU,bandwith,Network forecast, mobilityā€ _(aligns with 4,5,8,9)_ -#### Runtime intents -25. ā€œI can inform the developer of any event which changes which MEC is optimal for their application and connected terminalsā€ _(aligns with 6)_ -## Notes: +23. ā€œI can publish an (ordered, filtered) list of my MECs, their coverage, capabilities and statusā€ *(aligns with 1,2,3 in the developer intents)* +24. ā€œI can map an applicationā€™s requirements to the best MEC for hosting it, based on application demands for CPU, Memory, Storage, GPU, bandwidth, Network forecast, mobilityā€ *(aligns with 4,5,8,9)* + +#### Runtime intents + +25. ā€œI can inform the developer of any event which changes which MEC is optimal for their application and connected terminalsā€ *(aligns with 6)* + +## Notes -`A` this may not be the closest MEC, rather the 'best MEC for this job' which accounts for current MEC or network load, MEC copmute power and features etc. +`A` this may not be the closest MEC, rather the 'best MEC for this job' which accounts for current MEC or network load, MEC compute power and features etc. diff --git a/code/API_definitions/Discovery/simple_edge_discovery.yaml b/code/API_definitions/Discovery/simple_edge_discovery.yaml index ee38f842..fe5725c8 100644 --- a/code/API_definitions/Discovery/simple_edge_discovery.yaml +++ b/code/API_definitions/Discovery/simple_edge_discovery.yaml @@ -7,7 +7,7 @@ info: --- # Summary - The Simple Edge Discovery API returns the name of the closest operator MEC platform to a particular user device. + The Simple Edge Discovery API returns the name of the closest operator MEC platform to a particular user device. # Purpose Network operators may host multiple Multi-access Edge Computing (MEC, or 'Edge') platforms in a given territory. Connecting your application to a server on the closest MEC platform means packets travel the shortest distance between endpoints, typically resulting in the lowest round-trip latency. Note, the physical (GPS) location of a user device is not a reliable way to determine the closest MEC platform, due to the way operator networks are routed - so the operator will calculate the MEC platform with the _shortest network path_ to the network-attached device identified in the API request. @@ -18,21 +18,20 @@ info: * or, if you have no instance on that MEC platform, you may wish to deploy one there. # Usage - + The API may be called either by an application client hosted on a device attached to the operator network (i.e. phone, tablet), or by a server. - + There is a single API endpoint: `/mecplatforms?filter=closest`. To call this endpoint, the API consumer must first obtain a valid OAuth2 token from the token endpoint, and pass it as an `Authorization` header in the API request. - The API returns the closest MEC platform to a given device, so that device needs to be identifiable by the network: * if you call the API from a server, you must explicitly pass one or more device identifiers in the HTTP request header: * `IP-Address`. This is the public IP address of the user device: this can be obtained by an application hosted on that device calling a public IP address API (e.g. GET https://api.ipify.org?format=json) * `Phone-Number` . The international E.164 format (starting with country code), e.g. +4407123123456 * `Network-Access-Identifier` (where available from the API host operator) - + * if you call the API from a device attached to the operator network, you _may_ omit the explicit device identifier(s)from the request header. If such a request fails with a `404 Not Found` error then retry the request but this time include a device identifier. - The provider of the MEC Platform may be an operator, or a cloud provider. The + The provider of the MEC Platform may be an operator, or a cloud provider. The # Example requests: @@ -47,12 +46,12 @@ info: Host: example.com Accept: application/json IP-Address: 84.125.93.10 - + GET /mec-platforms?filter=closest HTTP/1.1 Host: example.com Accept: application/json Phone-Number: 441234567890 - + Example where API client is on a network-attached device: GET /mec-platforms?filter=closest HTTP/1.1 @@ -85,9 +84,9 @@ info: Any more general service failures will result in an error in the `5xx`range with an explanation. # Note for Simple Edge API publishers - The API publisher (i.e. the operator implementation) must ensure that the tuple of edgeCloudProvider+edgeResourceName in the success reponse is unique. + The API publisher (i.e. the operator implementation) must ensure that the tuple of edgeCloudProvider+edgeResourceName in the success response is unique. - # Further info and support + # Further info and support --- contact: @@ -229,7 +228,7 @@ components: EdgeResource: description: | - Edge Resource Name - an identifier for an edge reource in the operator domain. + Edge Resource Name - an identifier for an edge resource in the operator domain. type: string additionalProperties: false @@ -263,7 +262,7 @@ components: { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Insufficient parameters: At least one of Network-Access-Identifier, Phone-Number or IP-Address must be specified, or, the API must be called by a client on a netwok-attached device (hence passing the source IP in the request header) ", + "message": "Insufficient parameters: At least one of Network-Access-Identifier, Phone-Number or IP-Address must be specified, or, the API must be called by a client on a network-attached device (hence passing the source IP in the request header) ", } InvalidExternalId: value: From eba9585ed9c03af5add8c8e92928c45b924e232d Mon Sep 17 00:00:00 2001 From: Nicola Cadenelli Date: Thu, 21 Mar 2024 14:23:04 +0100 Subject: [PATCH 21/22] Solve some markdown warnings --- code/API_definitions/Discovery/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/API_definitions/Discovery/README.md b/code/API_definitions/Discovery/README.md index a0239d3e..d0341f04 100644 --- a/code/API_definitions/Discovery/README.md +++ b/code/API_definitions/Discovery/README.md @@ -10,19 +10,19 @@ This API allows a developer to: - discover available MEC platforms, ranked by proximity to a UE. - read the state (availability and capabilities) of an operator's various MEC platforms. -- register a service profile (a description of the developer's edge service) with the MEC operator -- register the deployed service endpoints with the MEC operator, which allows the closest service endpoint to be discovered at runtime +- register a service profile (a description of the developer's edge service) with the MEC operator. +- register the deployed service endpoints with the MEC operator, which allows the closest service endpoint to be discovered at runtime. The API will also support the following capabilities: -- events(such as change of status of a MEC platform or another event which could affect their service) +- events(such as change of status of a MEC platform or another event which could affect their service). - subscription to notification of events. -# Mapping to the list of intents +## Mapping to the list of intents These APIs fulfil the ['discovery' intents](https://github.com/camaraproject/EdgeCloud/blob/main/documentation/SupportingDocuments/Harmonisation%20of%20APIs/describing%20and%20harmonising%20the%20Edge%20APIs.md) -*Simple Edge Discovery* fulfils a single intent, "4. I can discover the closest MEC platform to a specific terminal (closest in terms of shortest network path)" +*Simple Edge Discovery* fulfils a single intent, "4. I can discover the closest MEC platform to a specific terminal (closest in terms of shortest network path)" *MEC Exposure and Experience Management* is a more comprehensive discovery API and fulfils the following intents: @@ -30,12 +30,12 @@ These APIs fulfil the ['discovery' intents](https://github.com/camaraproject/Edg #### Provisioning intents -1. ā€œI can retrieve a list of the operatorā€™s MECs and their status, ordering the results by location and filtering by status (active/inactive/unknown)ā€ +1. "I can retrieve a list of the operatorā€™s MECs and their status, ordering the results by location and filtering by status (active/inactive/unknown)" 2. "I can discover the capabilities/resources available at an operatorā€™s MEC: CPU, Memory, Storage, GPU" 3. "I can discover the geographical regions covered by the operators MECs" 4. "I can discover the closest MEC platform to a specific terminal (closest in terms of shortest network path)" -16. ā€œI can ask the operator to provide the details of all the on-boarded applicationsā€ +16. "I can ask the operator to provide the details of all the on-boarded applications" 17. "I can ask the operator to inform about the application instance details e.g., communication endpoints, resource consumed etc" #### Runtime intents @@ -48,12 +48,12 @@ These APIs fulfil the ['discovery' intents](https://github.com/camaraproject/Edg #### Provisioning intents -23. ā€œI can publish an (ordered, filtered) list of my MECs, their coverage, capabilities and statusā€ *(aligns with 1,2,3 in the developer intents)* -24. ā€œI can map an applicationā€™s requirements to the best MEC for hosting it, based on application demands for CPU, Memory, Storage, GPU, bandwidth, Network forecast, mobilityā€ *(aligns with 4,5,8,9)* +23. "I can publish an (ordered, filtered) list of my MECs, their coverage, capabilities and status" *(aligns with 1,2,3 in the developer intents)* +24. "I can map an applicationā€™s requirements to the best MEC for hosting it, based on application demands for CPU, Memory, Storage, GPU, bandwidth, Network forecast, mobility" *(aligns with 4,5,8,9)* #### Runtime intents -25. ā€œI can inform the developer of any event which changes which MEC is optimal for their application and connected terminalsā€ *(aligns with 6)* +25. "I can inform the developer of any event which changes which MEC is optimal for their application and connected terminals" *(aligns with 6)* ## Notes From b971eda51e5604ec576a80782d60c72911006f59 Mon Sep 17 00:00:00 2001 From: Nicola Cadenelli Date: Thu, 21 Mar 2024 15:31:32 +0100 Subject: [PATCH 22/22] Enforce line-lenght at 80 characters --- .../Discovery/simple_edge_discovery.yaml | 201 ++++++++++++------ 1 file changed, 136 insertions(+), 65 deletions(-) diff --git a/code/API_definitions/Discovery/simple_edge_discovery.yaml b/code/API_definitions/Discovery/simple_edge_discovery.yaml index fe5725c8..9916190c 100644 --- a/code/API_definitions/Discovery/simple_edge_discovery.yaml +++ b/code/API_definitions/Discovery/simple_edge_discovery.yaml @@ -1,3 +1,4 @@ +--- openapi: 3.0.3 info: title: Simple Edge Discovery API @@ -7,62 +8,92 @@ info: --- # Summary - The Simple Edge Discovery API returns the name of the closest operator MEC platform to a particular user device. + The Simple Edge Discovery API returns the name of the closest operator MEC + platform to a particular user device. # Purpose - Network operators may host multiple Multi-access Edge Computing (MEC, or 'Edge') platforms in a given territory. Connecting your application to a server on the closest MEC platform means packets travel the shortest distance between endpoints, typically resulting in the lowest round-trip latency. Note, the physical (GPS) location of a user device is not a reliable way to determine the closest MEC platform, due to the way operator networks are routed - so the operator will calculate the MEC platform with the _shortest network path_ to the network-attached device identified in the API request. - - Once you have the name of the closest MEC platform to the user device, you may: - - * connect the application client on the user device to your application server instance on that MEC platform. Note: the address of that server instance is not part of the API response, but should be known in advance. - * or, if you have no instance on that MEC platform, you may wish to deploy one there. - - # Usage - - The API may be called either by an application client hosted on a device attached to the operator network (i.e. phone, tablet), or by a server. - - There is a single API endpoint: `/mecplatforms?filter=closest`. To call this endpoint, the API consumer must first obtain a valid OAuth2 token from the token endpoint, and pass it as an `Authorization` header in the API request. - - The API returns the closest MEC platform to a given device, so that device needs to be identifiable by the network: - * if you call the API from a server, you must explicitly pass one or more device identifiers in the HTTP request header: - * `IP-Address`. This is the public IP address of the user device: this can be obtained by an application hosted on that device calling a public IP address API (e.g. GET https://api.ipify.org?format=json) - * `Phone-Number` . The international E.164 format (starting with country code), e.g. +4407123123456 + Network operators may host multiple Multi-access Edge Computing (MEC, or + 'Edge') platforms in a given territory. Connecting your application to a + server on the closest MEC platform means packets travel the shortest + distance between endpoints, typically resulting in the lowest round-trip + latency. Note, the physical (GPS) location of a user device is not a + reliable way to determine the closest MEC platform, due to the way operator + networks are routed - so the operator will calculate the MEC platform with + the _shortest network path_ to the network-attached device identified in + the API request. + + Once you have the name of the closest MEC platform to the user device, you + may: + + * connect the application client on the user device to your application + server instance on that MEC platform. Note: the address of that server + instance is not part of the API response, but should be known in advance. + * or, if you have no instance on that MEC platform, you may wish to deploy + one there. + + # Usage + + The API may be called either by an application client hosted on a device + attached to the operator network (i.e. phone, tablet), or by a server. + + There is a single API endpoint: `/mecplatforms?filter=closest`. To call + this endpoint, the API consumer must first obtain a valid OAuth2 token from + the token endpoint, and pass it as an `Authorization` header in the API + request. + + The API returns the closest MEC platform to a given device, so that device + needs to be identifiable by the network: + + * If you call the API from a server, you must explicitly pass one or + more device identifiers in the HTTP request header: + * `IP-Address`. This is the public IP address of the user device: this can + be obtained by an application hosted on that device calling a public IP + address API (e.g. GET https://api.ipify.org?format=json) + * `Phone-Number` . The international E.164 format (starting with country + code), e.g. +4407123123456 * `Network-Access-Identifier` (where available from the API host operator) - * if you call the API from a device attached to the operator network, you _may_ omit the explicit device identifier(s)from the request header. If such a request fails with a `404 Not Found` error then retry the request but this time include a device identifier. + * If you call the API from a device attached to the operator network, you + _may_ omit the explicit device identifier(s)from the request header. If such + a request fails with a `404 Not Found` error then retry the request but this + time include a device identifier. - The provider of the MEC Platform may be an operator, or a cloud provider. The + The provider of the MEC Platform may be an operator, or a cloud provider. # Example requests: Examples for all API clients: - GET /mec-platforms?filter=closest HTTP/1.1 - Host: example.com - Accept: application/json - Network-Access-Identifier: 4d596ac1-7822-4927-a3c5-d72e1f922c94@domain.com + GET /mec-platforms?filter=closest HTTP/1.1 + Host: example.com + Accept: application/json + Network-Access-Identifier: 4d596ac1-7822-4927-a3c5-d72e1f922c94@domain.com - GET /mec-platforms?filter=closest HTTP/1.1 - Host: example.com - Accept: application/json - IP-Address: 84.125.93.10 + GET /mec-platforms?filter=closest HTTP/1.1 + Host: example.com + Accept: application/json + IP-Address: 84.125.93.10 - GET /mec-platforms?filter=closest HTTP/1.1 - Host: example.com - Accept: application/json - Phone-Number: 441234567890 + GET /mec-platforms?filter=closest HTTP/1.1 + Host: example.com + Accept: application/json + Phone-Number: 441234567890 Example where API client is on a network-attached device: - GET /mec-platforms?filter=closest HTTP/1.1 - Host: example.com - Accept: application/json + GET /mec-platforms?filter=closest HTTP/1.1 + Host: example.com + Accept: application/json # Responses ## Success - A JSON object is returned containing a `MECPlatforms` array with a single member, along with the HTTP `200 OK` status code. The value of the `edgeCloudProvider` object is the name of the operator or cloud provider of the MEC Platform. `edgeResourceName` object is the name of the closest MEC platform to the user device. An example of this JSON object is as follows: + A JSON object is returned containing a `MECPlatforms` array with a single + member, along with the HTTP `200 OK` status code. The value of the + `edgeCloudProvider` object is the name of the operator or cloud provider of + the MEC Platform. `edgeResourceName` object is the name of the closest MEC + platform to the user device. An example of this JSON object is as follows: ``` { "MecPlatforms": [ @@ -75,16 +106,22 @@ info: ``` ## Errors - If the authentication token is not valid, a `401 UNAUTHENTICATED` error is returned. + If the authentication token is not valid, a `401 UNAUTHENTICATED` error is + returned. - If the mobile subscription parameters contain a formatting error, a `400 INVALID_ARGUMENT` error is returned. + If the mobile subscription parameters contain a formatting error, a `400 + INVALID_ARGUMENT` error is returned. - If the mobile subscription cannot be identified from the provided parameters, a `404 NOT_FOUND` error is returned. + If the mobile subscription cannot be identified from the provided + parameters, a `404 NOT_FOUND` error is returned. - Any more general service failures will result in an error in the `5xx`range with an explanation. + Any more general service failures will result in an error in the `5xx`range + with an explanation. # Note for Simple Edge API publishers - The API publisher (i.e. the operator implementation) must ensure that the tuple of edgeCloudProvider+edgeResourceName in the success response is unique. + The API publisher (i.e. the operator implementation) must ensure that the + tuple of edgeCloudProvider+edgeResourceName in the success response is + unique. # Further info and support @@ -123,7 +160,8 @@ paths: - name: filter in: query required: true - description: Filter the MEC Platforms according to the parameter value. For this API the only supported value is `closest`. + description: Filter the MEC Platforms according to the parameter + value. For this API the only supported value is `closest`. schema: type: string enum: ["closest"] @@ -146,7 +184,8 @@ paths: - name: Network-Access-Identifier in: header - description: 3GPP network access identifier for the subscription being used by the device. + description: 3GPP network access identifier for the subscription being + used by the device. example: "4d596ac1-7822-4927-a3c5-d72e1f922c94@domain.com" required: false schema: @@ -156,14 +195,17 @@ paths: in: header example: "441234567890" required: false - description: MSISDN in E.164 format (starting with country code) of the mobile subscription being used by the device. Optionally prefixed with '+'. + description: MSISDN in E.164 format (starting with country code) of + the mobile subscription being used by the device. Optionally + prefixed with '+'. schema: type: string pattern: '^\+?[0-9]{5,15}$' responses: "200": - description: Successful response, returning the closest MEC platform to the user device identified in the request header. + description: Successful response, returning the closest MEC platform + to the user device identified in the request header. content: application/json: schema: @@ -192,14 +234,22 @@ paths: $ref: "#/components/responses/504GatewayTimeout" tags: - Discovery - summary: Returns the name of the MEC platform closest to user device identified in the request. - description: On receiving this request, the network will return the name of the MEC platform with the shortest network path to the end user device identified in the request. + summary: Returns the name of the MEC platform closest to user device + identified in the request. + description: On receiving this request, the network will return the name + of the MEC platform with the shortest network path to the end user + device identified in the request. components: securitySchemes: oAuth2ClientCredentials: type: oauth2 - description: The Simple Edge Discovery API makes use of the OAUTH 2.0 client credentials grant, which is applicable for server-to-server use cases involving trusted partners or clients without any protected user data involved. In this method the API invoker client is registered as a confidential client with an authorization grant type of client_credentials. + description: The Simple Edge Discovery API makes use of the OAUTH 2.0 + client credentials grant, which is applicable for server-to-server use + cases involving trusted partners or clients without any protected user + data involved. In this method the API invoker client is registered as a + confidential client with an authorization grant type of + client_credentials. flows: clientCredentials: tokenUrl: "{tokenUrl}" @@ -209,12 +259,17 @@ components: type: array items: $ref: "#/components/schemas/MecPlatform" - description: A collection of MEC Platforms. For this Simple Edge Discovery API the collection will have at most one member (the closest MEC Platform to the user device indicated in the request). + description: A collection of MEC Platforms. For this Simple Edge Discovery + API the collection will have at most one member (the closest MEC + Platform to the user device indicated in the request). additionalProperties: false MecPlatform: type: object - description: A MEC Platform, uniquely identified by a combination of the value of the Edge Resource Name object and the value of the Provider object (the name of the cloud provider or operator hosting that platform). + description: A MEC Platform, uniquely identified by a combination of the + value of the Edge Resource Name object and the value of the Provider + object (the name of the cloud provider or operator hosting that + platform). properties: edgeCloudProvider: $ref: "#/components/schemas/EdgeCloudProvider" @@ -228,7 +283,8 @@ components: EdgeResource: description: | - Edge Resource Name - an identifier for an edge resource in the operator domain. + Edge Resource Name - an identifier for an edge resource in the operator + domain. type: string additionalProperties: false @@ -243,7 +299,9 @@ components: description: The HTTP status code. message: type: string - description: This parameter appears when there was an error. Human readable explanation specific to this occurrence of the problem. + description: This parameter appears when there was an error. + Human readable explanation specific to this occurrence of the + problem. ################################### # RESPONSES @@ -257,12 +315,17 @@ components: $ref: "#/components/schemas/errorResponse" examples: InsufficientParameters: - description: Sufficient parameters must be specified to allow the target UE to be identified. + description: Sufficient parameters must be specified to allow the + target UE to be identified. value: { "code": "INVALID_ARGUMENT", "status": 400, - "message": "Insufficient parameters: At least one of Network-Access-Identifier, Phone-Number or IP-Address must be specified, or, the API must be called by a client on a network-attached device (hence passing the source IP in the request header) ", + "message": "Insufficient parameters: At least one of + Network-Access-Identifier, Phone-Number or IP-Address must be + specified, or, the API must be called by a client on a + network-attached device (hence passing the source IP in the + request header) ", } InvalidExternalId: value: @@ -279,7 +342,9 @@ components: "message": "Invalid Header Format: Phone-Number", } InvalidIP: - description: This error will be returned if the IP address does not have a valid format, or if the IP address is a private IPv4 address. + description: This error will be returned if the IP address does + not have a valid format, or if the IP address is a private IPv4 + address. value: { "code": "INVALID_ARGUMENT", @@ -298,7 +363,8 @@ components: { "code": "UNAUTHENTICATED", "status": 401, - "message": "Request not authenticated due to missing, invalid, or expired credentials", + "message": "Request not authenticated due to missing, invalid, + or expired credentials", } 403Forbidden: @@ -313,7 +379,8 @@ components: { "code": "PERMISSION_DENIED", "status": 403, - "message": "Client does not have sufficient permissions to perform this action", + "message": "Client does not have sufficient permissions to + perform this action", } 404NotFound: @@ -324,7 +391,8 @@ components: $ref: "#/components/schemas/errorResponse" examples: SubscriberNotFound: - description: No device found for the specified parameters, meaning the closest MEC platform cannot be determined. + description: No device found for the specified parameters, meaning + the closest MEC platform cannot be determined. value: { "code": "NOT_FOUND", @@ -340,12 +408,14 @@ components: $ref: "#/components/schemas/errorResponse" examples: MethodNotAllowed: - description: An HTTP verb other than GET has been used to try and access the resource. + description: An HTTP verb other than GET has been used to try and + access the resource. value: { "code": "METHOD_NOT_ALLOWED", "status": 405, - "message": "The request method is not supported by this resource", + "message": "The request method is not supported by this + resource", } 406Unacceptable: @@ -361,7 +431,8 @@ components: { "code": "NOT_ACCEPTABLE", "status": 406, - "message": "The server cannot produce a response matching the content requested by the client through Accept-* headers", + "message": "The server cannot produce a response matching the + content requested by the client through Accept-* headers", } 429TooManyRequests: @@ -372,12 +443,12 @@ components: $ref: "#/components/schemas/errorResponse" examples: TooManyRequests: - description: Access to the API has been temporarily blocked due to quota or spike arrest limits being reached. + description: Access to the API has been temporarily blocked due to + quota or spike arrest limits being reached. value: { - "code": "TOO_MANY_REQUESTS", - "status": 429, - "message": "Either out of resource quota or reaching rate limiting", + "code": "TOO_MANY_REQUESTS", "status": 429, "message": "Either + out of resource quota or reaching rate limiting", } 500InternalServerError: