Resolve "Code refactor"

Proposers

  • Jorge Moratinos Salcines (Telefónica)

Description

SDK needs a code review, in order to remove spanish text and also some refactor that will require.

Acknowledgements

This work is funded by the European Commission through the project with Grant Agreement number . example: This work is funded by the European Commission through the FIDAL project with Grant Agreement number 101096146.

Merge request reports

Loading
+4 −2
Changes for .githooks/pre-push: 4 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@

echo "--- 🚀 Running 'make lint' before push ---"

# Run the linter
make fix
# Run the linter (check only: run 'make fix' yourself and commit the result)
make lint

# Save the exit code of the last command
EXIT_CODE=$?
@@ -15,6 +15,8 @@ if [ $EXIT_CODE -ne 0 ]; then
    echo "-----------------------------------------------"
    echo "|        ⛔ The linter has failed! ⛔.        |"
    echo "|     Please fix the errors before pushing.   |"
    echo "|  ('make fix' corrects most of them; commit  |"
    echo "|   the changes and push again)               |"
    echo "-----------------------------------------------"
    exit 1 # Abort the push
fi
+6 −6
Changes for .github/workflows/gitlab.yml: 6 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -3,28 +3,28 @@ name: Sync GitHub to GitLab
on:
  push:
    branches:
      - develop  # Se activa cuando hay cambios en la rama develop
      - develop  # Triggered when there are changes on the develop branch

jobs:
  create-merge-request:
    runs-on: ubuntu-latest

    steps:
      # 1. Checkout del código desde GitHub
      # 1. Check out the code from GitHub
      - name: Checkout GitHub repository
        uses: actions/checkout@v4

      # 2. Crear un Merge Request en GitLab
      # 2. Create a Merge Request in GitLab
      - name: Create Merge Request in GitLab
        env:
          GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
        run: |
          # Información del MR
          PROJECT_ID="335" # Reemplaza con el ID del proyecto de GitLab
          # MR information
          PROJECT_ID="335" # Replace with the GitLab project ID
          SOURCE_BRANCH="develop"
          TARGET_BRANCH="main"

          # Crear el Merge Request usando la API de GitLab
          # Create the Merge Request using the GitLab API
          curl -X POST \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $GITLAB_TOKEN" \
+6 −0
Changes for ci_cd_test/testing_samples/testing_invoker_sample/capif_sdk_config_sample.json: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -37,6 +37,12 @@
      "api-supported-features": "",
      "ue-ip-addr": "",
      "service-kpis": ""
    },
    "security_context": {
      "pref_security_context": ["OAUTH","PKI","PSK"]
    },
    "api_invocation": {
      "ca_cert": "../aef_server_certificate/aef_server.crt"
    }
  }
}
+92 −24
Changes for ci_cd_test/testing_samples/testing_invoker_sample/network_app_invoker.py: 92 added lines, 24 removed lines.
Original line number Diff line number Diff line
import json
import time
import requests
from opencapif_sdk import capif_invoker_connector, service_discoverer
import logging
import os
import sys
import traceback

import requests

from opencapif_sdk import capif_invoker_connector, service_discoverer

# Path to the OpenCAPIF SDK configuration file
capif_sdk_config_path = "./capif_sdk_config_sample.json"

import requests
import json
import sys
# API published by the provider test, exposed by one AEF per security method (OAUTH, PKI and PSK)
API_NAME = "6G-resilience"
# Security methods to check (all by default). PSK requires OpenCAPIF 5.1.0 or later.
SECURITY_METHODS = [
    method.strip().upper()
    for method in os.getenv("SDK_TEST_SECURITY_METHODS", "OAUTH,PKI,PSK").split(",") if method.strip()
]

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

def invoke_with_each_security_method(discoverer, security_response):
    """Invokes the API at the AEF of each security method and checks that the AEF authenticated the invoker."""
    invoker_id = discoverer.invoker_capif_details["api_invoker_id"]
    selected = {
        security_info["aefId"]: security_info["selSecurityMethod"]
        for security_info in security_response["securityInfo"]
    }
    for method in SECURITY_METHODS:
        aef_ids = [aef_id for aef_id, selected_method in selected.items() if selected_method == method]
        if not aef_ids:
            raise RuntimeError(f"CAPIF did not select {method} for any AEF of the API: {selected}")

        for aef_id in aef_ids:
            response = discoverer.invoke_api(API_NAME, "GET", resource="RESILIENCE_MANAGEMENT", aef_id=aef_id)
            answer = response.json()
            expected = {"aefId": aef_id, "securityMethod": method, "invoker": invoker_id}
            received = {key: answer.get(key) for key in expected}
            if received != expected:
                raise RuntimeError(f"Unexpected answer of AEF {aef_id} with {method}: {answer} (expected {expected})")
            print(f"✅ API INVOKED WITH {method}: {response.request.method} {response.url} -> {answer}")
            check_rejected_without_credentials(response.url, method, discoverer.aef_ca_cert)


def check_rejected_without_credentials(url, method, ca_cert):
    """The AEF must reject a request without the credentials of its security method."""
    try:
        # Onboard the Invoker (creates keys, registers, obtains certs)
        capif_connector = capif_invoker_connector(config_file=capif_sdk_config_path)
        capif_connector.onboard_invoker()
        print("✅ INVOKER ONBOARDING COMPLETED")
        response = requests.get(url, verify=ca_cert, timeout=10)
        rejected = response.status_code == 401  # OAUTH: no access token
    except requests.ConnectionError:
        rejected = True  # PKI: no client certificate; PSK: no pre-shared key (TLS handshake fails)
    if not rejected:
        raise RuntimeError(f"The {method} AEF accepted a request without credentials: {url}")
    print(f"✅ The {method} AEF rejects a request without credentials")


        # Discover APIs and obtain JWT token
def run_invoker_flow():
    # Discover APIs and obtain the security context
    discoverer = service_discoverer(config_file=capif_sdk_config_path)
        discoverer.discover()
        discoverer.get_tokens()
    apis = discoverer.discover()
    if not apis or not apis.get("serviceAPIDescriptions"):
        raise RuntimeError("No API was discovered: the API published by the provider test should be available")
    print("✅ DISCOVERED APIs:")
    print(json.dumps(apis, indent=4, ensure_ascii=False))

    security_response = discoverer.get_security_context(supp_features='0')
    print("✅ SECURITY CONTEXT OBTAINED")
    print(json.dumps(security_response, indent=4, ensure_ascii=False))

    discoverer.get_tokens()
    # Show the token
    print("✅ ACCESS TOKEN:")
    print(discoverer.token)

        # End
    invoke_with_each_security_method(discoverer, security_response)

    print("🎉 Script finished successfully.")

    except FileNotFoundError as e:
        print(f"Error: {e}")
        sys.exit(1)
    except json.JSONDecodeError as e:
        print(f"Error reading the JSON file: {e}")
        sys.exit(1)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    exit_code = 0
    capif_connector = None
    onboarded = False
    try:
        # Onboard the Invoker (creates keys, registers, obtains certs)
        capif_connector = capif_invoker_connector(config_file=capif_sdk_config_path)
        capif_connector.onboard_invoker()
        onboarded = True
        print("✅ INVOKER ONBOARDING COMPLETED")

        run_invoker_flow()

    except Exception as e:
        print(f"Unexpected error: {e}")
        sys.exit(1)
        print(f"❌ Invoker test failed: {e}")
        traceback.print_exc()
        exit_code = 1

    finally:
        # Offboard the invoker even if a step failed, so OpenCAPIF is left clean
        if onboarded:
            try:
                capif_connector.offboard_invoker()
                print("Invoker removed successfully.")
            except Exception as e:
                print(f"❌ Invoker offboarding failed: {e}")
                traceback.print_exc()
                exit_code = 1

    sys.exit(exit_code)
+54 −141
Changes for ci_cd_test/testing_samples/testing_provider_sample/api_descriptor_testing.json: 54 added lines, 141 removed lines.
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
    "apiName": "6G-resilience",
    "aefProfiles": [
        {
            "aefId": "AEF6fc1d116574bcc797ecd74b8902b35",
            "aefId": "",
            "versions": [
                {
                    "apiVersion": "6G_Resilience_v1",
@@ -49,86 +49,6 @@
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
@@ -147,8 +67,8 @@
            ],
            "interfaceDescriptions": [
                {
                    "ipv4Addr": "localhost",
                    "port": 8088,
                    "ipv4Addr": "127.0.0.1",
                    "port": 8443,
                    "securityMethods": [
                        "OAUTH"
                    ]
@@ -156,34 +76,34 @@
            ]
        },
        {
            "aefId": "AEFa8e49e01d179c79e6a4750a8363f1d",
            "aefId": "",
            "versions": [
                {
                    "apiVersion": "6G_Resilience_v1",
                    "expiry": "2100-11-30T10:32:02.004Z",
                    "resources": [
                        {
                            "resourceName": "SLICE_RESILIENCE",
                            "resourceName": "RESILIENCE_MANAGEMENT",
                            "commType": "SUBSCRIBE_NOTIFY",
                            "uri": "/slice/resilience",
                            "uri": "/resilience",
                            "custOpName": "http_post",
                            "operations": [
                                "GET",
                                "POST"
                            ],
                            "description": "Endpoint for managing resilience in network slices"
                            "description": "Endpoint to manage resilience functionalities in 6G networks"
                        },
                        {
                            "resourceName": "SLICE_SINGLE_RESILIENCE",
                            "resourceName": "RESILIENCE_SINGLE",
                            "commType": "SUBSCRIBE_NOTIFY",
                            "uri": "/slice/{sliceId}/resilience",
                            "uri": "/resilience/{profileId}",
                            "custOpName": "http_get",
                            "operations": [
                                "GET",
                                "PUT",
                                "DELETE"
                            ],
                            "description": "Endpoint for managing a single slice's resilience"
                            "description": "Endpoint to manage a single resilience profile"
                        }
                    ],
                    "custOperations": [
@@ -193,7 +113,7 @@
                            "operations": [
                                "POST"
                            ],
                            "description": "Custom operation for configuring resilience in network slices"
                            "description": "Custom operation for managing 6G resilience parameters"
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
@@ -210,70 +130,64 @@
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                        }
                    ]
                }
            ],
                            "description": "Check authentication request."
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
            "protocol": "HTTP_1_1",
            "dataFormat": "JSON",
            "securityMethods": [
                "PKI"
            ],
                            "description": "Revoke authorization for service APIs."
                        },
            "interfaceDescriptions": [
                {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                    "ipv4Addr": "127.0.0.1",
                    "port": 8444,
                    "securityMethods": [
                        "PKI"
                    ]
                }
            ]
        },
        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                        },
            "aefId": "",
            "versions": [
                {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "operations": [
                                "POST"
                            ],
                            "description": "Check authentication request."
                        },
                    "apiVersion": "6G_Resilience_v1",
                    "expiry": "2100-11-30T10:32:02.004Z",
                    "resources": [
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "resourceName": "RESILIENCE_MANAGEMENT",
                            "commType": "SUBSCRIBE_NOTIFY",
                            "uri": "/resilience",
                            "custOpName": "http_post",
                            "operations": [
                                "GET",
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                            "description": "Endpoint to manage resilience functionalities in 6G networks"
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "check-authentication",
                            "resourceName": "RESILIENCE_SINGLE",
                            "commType": "SUBSCRIBE_NOTIFY",
                            "uri": "/resilience/{profileId}",
                            "custOpName": "http_get",
                            "operations": [
                                "POST"
                                "GET",
                                "PUT",
                                "DELETE"
                            ],
                            "description": "Check authentication request."
                        },
                            "description": "Endpoint to manage a single resilience profile"
                        }
                    ],
                    "custOperations": [
                        {
                            "commType": "REQUEST_RESPONSE",
                            "custOpName": "revoke-authentication",
                            "custOpName": "string",
                            "operations": [
                                "POST"
                            ],
                            "description": "Revoke authorization for service APIs."
                            "description": "Custom operation for managing 6G resilience parameters"
                        },
                        {
                            "commType": "REQUEST_RESPONSE",
@@ -297,21 +211,20 @@
            "protocol": "HTTP_1_1",
            "dataFormat": "JSON",
            "securityMethods": [
                "OAUTH",
                "PSK"
            ],
            "interfaceDescriptions": [
                {
                    "ipv4Addr": "localhost",
                    "port": 8088,
                    "ipv4Addr": "127.0.0.1",
                    "port": 8445,
                    "securityMethods": [
                        "OAUTH"
                        "PSK"
                    ]
                }
            ]
        }
    ],
    "description": "API of dummy Network-App to test",
    "description": "API of dummy Network-App to test, exposed by three AEFs: one per security method (OAUTH, PKI and PSK)",
    "supportedFeatures": "0",
    "shareableInfo": {
        "isShareable": true,
Loading
Loading