diff --git a/README.md b/README.md index 9440a5bde0a3f3b1923f837fedaf275f4669402a..e6bcde5cd29b65a527eb11109e5affc970754209 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,15 @@ A NetApp development running as an Invoker would usually follow this process ste 4. **Discover available services:** \ Use the discover() method to retrieve a list of available APIs: + DISCLAIMER: if it's the first time the user runs discover() it will appear a warning alert like this + + WARNING - Received 404 error, redirecting to register security service + ```python service_discoverer.discover() ``` + + 5. **Retrieve security tokens:** \ Use the get_tokens() method to obtain the necessary tokens for authenticating API requests: diff --git a/doc/sdk-usage.md b/doc/sdk-usage.md index 37cf0c4081c99eaa480f682ed2110e438af62bc3..4c3788dd8546726226657b956b943ee3c04cec04 100644 --- a/doc/sdk-usage.md +++ b/doc/sdk-usage.md @@ -69,6 +69,11 @@ In this functionality it could be used [discover_filter](./sdk-configuration.md) It is mandatory to have onboarded as a [invoker](#onboard_invoker--script-invoker_capif_connectorpy) before +DISCLAIMER: if it's the first time the user runs discover() it will appear a warning alert like this + + WARNING - Received 404 error, redirecting to register security service + +  ### get_tokens() // Script invoker_service_get_token.py diff --git a/test/capif-sdk-config-sample-test.json b/test/capif-sdk-config-sample-test.json new file mode 100644 index 0000000000000000000000000000000000000000..308e20f46df1d47e833a260ab207918d950856bb --- /dev/null +++ b/test/capif-sdk-config-sample-test.json @@ -0,0 +1,45 @@ +{ + "invoker_folder": "/Users/IDB0128/Documents/OpenCapif/test_invoker_certificate_folder", + "provider_folder": "/Users/IDB0128/Documents/OpenCapif/test_provider_certificate_folder", + "capif_host": "capif-prev.mobilesandbox.cloud", + "register_host": "registercapif-prev.mobilesandbox.cloud", + "capif_https_port": "36212", + "capif_register_port": "36211", + "capif_callback_url": "http://localhost:5000", + "csr_common_name": "test03", + "csr_organizational_unit": "test_app_ou", + "csr_organization": "test_app_o", + "crs_locality": "Madrid", + "csr_state_or_province_name": "Madrid", + "csr_country_name": "ES", + "csr_email_address": "test@example.com", + "capif_username": "echeva_0", + "capif_password": "echevapass", + "apfs": "1", + "aefs": "2", + "debug_mode": "False", + "discover_filter": { + "api-name": "Test", + "api-version": "", + "comm-type": "", + "protocol": "", + "aef-id": "", + "data-format": "", + "api-cat": "", + "preferred-aef-loc": "", + "req-api-prov-name": "", + "supported-features": "", + "api-supported-features": "", + "ue-ip-addr": "", + "service-kpis": "" + }, + "publish_req": { + "service_api_id": "475efe88f362be86e6818967a1b1c2", + "publisher_apf_id": "APF69c4e696697fcd7815ccddb36cf730", + "publisher_aefs_ids": [ + "AEF295be601e3fad4886d0207f2371493", + "AEF6cc62d5779ca43df0e95c7908524f2" + ] + }, + "api_description_path": "./netapp-provider-api-spec.json" +} \ No newline at end of file diff --git a/test/netapp-provider-api-spec.json b/test/netapp-provider-api-spec.json new file mode 100755 index 0000000000000000000000000000000000000000..d41d9f8c77e80bb10b219869d4be8efa2af8ce60 --- /dev/null +++ b/test/netapp-provider-api-spec.json @@ -0,0 +1,155 @@ +{ + "apiName": "Test", + "aefProfiles": [ + { + "aefId": "AEF295be601e3fad4886d0207f2371493", + "versions": [ + { + "apiVersion": "v1", + "expiry": "2100-11-30T10:32:02.004Z", + "resources": [ + { + "resourceName": "MONITORING_SUBSCRIPTIONS", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/{scsAsId}/subscriptions", + "custOpName": "http_post", + "operations": [ + "GET", + "POST" + ], + "description": "Endpoint to manage monitoring subscriptions" + }, + { + "resourceName": "MONITORING_SUBSCRIPTION_SINGLE", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/{scsAsId}/subscriptions/{subscriptionId}", + "custOpName": "http_get", + "operations": [ + "GET", + "PUT", + "DELETE" + ], + "description": "Endpoint to manage single subscription" + } + ], + "custOperations": [ + { + "commType": "REQUEST_RESPONSE", + "custOpName": "string", + "operations": [ + "POST" + ], + "description": "string" + } + ] + } + ], + "protocol": "HTTP_1_1", + "dataFormat": "JSON", + "securityMethods": [ + "Oauth", + "PSK" + ], + "interfaceDescriptions": [ + { + "ipv4Addr": "127.0.0.1", + "port": 8888, + "securityMethods": [ + "Oauth" + ] + } + ] + }, + { + "aefId": "AEF6cc62d5779ca43df0e95c7908524f2", + "versions": [ + { + "apiVersion": "v1", + "expiry": "2100-11-30T10:32:02.004Z", + "resources": [ + { + "resourceName": "TSN_LIST_PROFILES", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/profile", + "custOpName": "http_get", + "operations": [ + "GET" + ], + "description": "Endpoint for retrieving the list of available TSN profiles" + }, + { + "resourceName": "TSN_DETAIL_PROFILE", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/profile?name={profileName}", + "custOpName": "http_get", + "operations": [ + "GET" + ], + "description": "Endpoint for retrieving information about a single TSN profile" + }, + { + "resourceName": "TSN_APPLY_CONFIGURATION", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/apply", + "custOpName": "http_post", + "operations": [ + "POST" + ], + "description": "Endpoint for configuring TSN connection parameters" + }, + { + "resourceName": "TSN_CLEAR_CONFIGURATION", + "commType": " SUBSCRIBE_NOTIFY", + "uri": "/clear", + "custOpName": "http_post", + "operations": [ + "POST" + ], + "description": "Endpoint for removing a previous TSN connection configuration" + } + ], + "custOperations": [ + { + "commType": "REQUEST_RESPONSE", + "custOpName": "string", + "operations": [ + "POST" + ], + "description": "string" + } + ] + } + ], + "protocol": "HTTP_1_1", + "dataFormat": "JSON", + "securityMethods": [ + "Oauth" + ], + "interfaceDescriptions": [ + { + "ipv4Addr": "127.0.0.1", + "port": 8899, + "securityMethods": [ + "Oauth" + ] + } + ] + } + ], + "description": "API of dummy netapp to test", + "supportedFeatures": "fffff", + "shareableInfo": { + "isShareable": true, + "capifProvDoms": [ + "string" + ] + }, + "serviceAPICategory": "string", + "apiSuppFeats": "fffff", + "pubApiPath": { + "ccfIds": [ + "string" + ] + }, + "ccfId": "string" +} \ No newline at end of file diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000000000000000000000000000000000000..708d62ef7643d07d2e35449c8aac8d399c0d68ba --- /dev/null +++ b/test/test.py @@ -0,0 +1,124 @@ +import sys +import os +import json + +# Añadir el directorio del SDK al PYTHONPATH usando una ruta relativa +script_dir = os.path.dirname(os.path.abspath(__file__)) # Directorio actual del script +sdk_path = os.path.join(script_dir, '..', 'sdk') # Subir dos niveles y apuntar a 'sdk' +sys.path.insert(0, sdk_path) +from sdk import CAPIFProviderConnector, CAPIFInvokerConnector, ServiceDiscoverer + +# capif_sdk_config_path = "/Users/dgs/Downloads/capif_sdk/invoker/config.json" + +capif_sdk_config_path = "./capif-sdk-config-sample-test.json" + +if __name__ == "__main__": + try: + # Inicialización del conector + capif_provider_connector = CAPIFProviderConnector(config_file=capif_sdk_config_path) + capif_provider_connector.onboard_provider() + print("PROVIDER ONBOARDING COMPLETED") + + # Obtención de los AEFs ids y APFs ids para publicar una API + with open(capif_sdk_config_path, 'r') as file: + config = json.load(file) + + provider_folder = config.get('provider_folder') + username_folder = config.get('capif_username') + if not provider_folder: + raise ValueError("El valor 'provider_folder' no está definido en el archivo de configuración.") + + detailspath = os.path.join(provider_folder, username_folder, "capif_provider_details.json") + if not os.path.exists(detailspath): + raise FileNotFoundError(f"No se encontró el archivo {detailspath}") + + with open(detailspath, 'r') as file: + details = json.load(file) + + APF = details.get('APF-1_api_prov_func_id') + AEF1 = details.get('AEF-1_api_prov_func_id') + AEF2 = details.get('AEF-2_api_prov_func_id') + + if not APF or not AEF1 or not AEF2: + raise ValueError("No se encontraron todos los valores necesarios en 'Capif_provider_details.json'") + + # Actualización del archivo de configuración + config['publish_req']['publisher_apf_id'] = APF + config['publish_req']['publisher_aefs_ids'] = [AEF1, AEF2] + + with open(capif_sdk_config_path, 'w') as file: + json.dump(config, file, indent=4) # Guarda el JSON con formato + + print("Archivo de configuración actualizado correctamente.") + # Volver a actualizar el constructor con los parametros nuevos de configuración + capif_provider_connector = CAPIFProviderConnector(config_file=capif_sdk_config_path) + + capif_provider_connector.publish_services() + + print("PROVIDER PUBLISH COMPLETED") + + PublishedApis = os.path.join(provider_folder, username_folder, "Published-Apis.json") + if not os.path.exists(PublishedApis): + raise FileNotFoundError(f"No se encontró el archivo {PublishedApis}") + + with open(PublishedApis, 'r') as file: + PublishedApis = json.load(file) + service_api_id = PublishedApis.get('Test') + + with open(capif_sdk_config_path, 'r') as file: + config = json.load(file) + + config['publish_req']['service_api_id'] = service_api_id + + with open(capif_sdk_config_path, 'w') as file: + json.dump(config, file, indent=4) # Guarda el JSON con formato + + capif_provider_connector = CAPIFProviderConnector(config_file=capif_sdk_config_path) + + capif_provider_connector.update_service() + + print("PROVIDER UPDATE COMPLETED") + + capif_provider_connector.get_all_services() + + print("PROVIDER GET ALL SERVICES COMPLETED") + + capif_provider_connector.get_service() + + print("PROVIDER GET SERVICE COMPLETED") + + capif_invoker_connector = CAPIFInvokerConnector(config_file=capif_sdk_config_path) + + capif_invoker_connector.onboard_invoker() + print("INVOKER ONBOARDING COMPLETED") + + discoverer = ServiceDiscoverer(config_file=capif_sdk_config_path) + + discoverer.discover() + + print("SERVICE DISCOVER COMPLETED") + + discoverer.get_tokens() + + print("SERVICE GET TOKENS COMPLETED") + + capif_invoker_connector.offboard_invoker() + + print("INVOKER OFFBOARD COMPLETED") + + capif_provider_connector.unpublish_service() + + print("PROVIDER UNPUBLISH SERVICE COMPLETED") + + # capif_provider_connector.update_service() + + capif_provider_connector.offboard_provider() + + print("PROVIDER OFFBOARDING COMPLETED") + + except FileNotFoundError as e: + print(f"Error: {e}") + except json.JSONDecodeError as e: + print(f"Error al leer el archivo JSON: {e}") + except Exception as e: + print(f"Error inesperado: {e}")