Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
"header: Date: Mon, 14 Oct 2024 05:16:12 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:16:24,765 - __main__ - DEBUG - >>> request_application_instance_id: sbx1urljfj\n",
"2024-10-14 07:16:24,767 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:16:24,815 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/sandboxAppInstances/sbx1urljfj HTTP/1.1\" 201 100\n",
"2024-10-14 07:16:24,816 DEBUG response body: b'{\"id\":\"ec9e33a5-c6f2-404d-a993-84e37aebf57c\",\"name\":\"JupyterMecApp\",\"nodeName\":\"mep1\",\"type\":\"USER\"}'\n",
"2024-10-14 07:16:24,817 - __main__ - DEBUG - request_application_instance_id: result: {'id': 'ec9e33a5-c6f2-404d-a993-84e37aebf57c',\n",
" 'name': 'JupyterMecApp',\n",
" 'node_name': 'mep1',\n",
" 'persist': None,\n",
" 'type': 'USER'}\n",
"2024-10-14 07:16:24,818 - __main__ - INFO - app_inst_id: <class 'swagger_client.models.application_info.ApplicationInfo'>\n",
"2024-10-14 07:16:24,819 - __main__ - INFO - app_inst_id: {'id': 'ec9e33a5-c6f2-404d-a993-84e37aebf57c',\n",
" 'name': 'JupyterMecApp',\n",
" 'node_name': 'mep1',\n",
" 'persist': None,\n",
" 'type': 'USER'}\n",
"2024-10-14 07:16:24,819 - __main__ - DEBUG - >>> get_applications_list: sbx1urljfj\n",
"2024-10-14 07:16:24,837 DEBUG https://mec-platform2.etsi.org:443 \"GET /sandbox-api/v1/sandboxAppInstances/sbx1urljfj HTTP/1.1\" 200 786\n",
"2024-10-14 07:16:24,839 DEBUG response body: b'[{\"id\":\"62cc2936-af22-4946-b3e5-5b9143d7203f\",\"name\":\"mec011-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"},{\"id\":\"b8a203be-ac81-45a6-8d88-fdb1f8f5393b\",\"name\":\"mec012-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"},{\"id\":\"298b2c0c-7efa-45d3-8b47-8ab3c009b845\",\"name\":\"mec013-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"},{\"id\":\"ec9e33a5-c6f2-404d-a993-84e37aebf57c\",\"name\":\"JupyterMecApp\",\"nodeName\":\"mep1\",\"type\":\"USER\"},{\"id\":\"f1e4d448-e277-496b-bf63-98391cfd20fb\",\"name\":\"mec015-1\",\"nodeName\":\"mep1\",\"type\":\"USER\"},{\"id\":\"fb4d3c6a-197e-4e3f-96ae-ab4d5ac663a9\",\"name\":\"mec016-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"},{\"id\":\"b8ae165a-a1e3-4d6c-86d9-52c59ad314b6\",\"name\":\"mec028-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"},{\"id\":\"5015e45f-be53-4e28-8f47-c107fd1dea8c\",\"name\":\"mec030-1\",\"nodeName\":\"mep1\",\"type\":\"SYSTEM\"}]'\n",
"2024-10-14 07:16:24,840 - __main__ - DEBUG - get_applications_list: result: [{'id': '62cc2936-af22-4946-b3e5-5b9143d7203f'}, {'id': 'b8a203be-ac81-45a6-8d88-fdb1f8f5393b'}, {'id': '298b2c0c-7efa-45d3-8b47-8ab3c009b845'}, {'id': 'ec9e33a5-c6f2-404d-a993-84e37aebf57c'}, {'id': 'f1e4d448-e277-496b-bf63-98391cfd20fb'}, {'id': 'fb4d3c6a-197e-4e3f-96ae-ab4d5ac663a9'}, {'id': 'b8ae165a-a1e3-4d6c-86d9-52c59ad314b6'}, {'id': '5015e45f-be53-4e28-8f47-c107fd1dea8c'}]\n",
"2024-10-14 07:16:24,842 - __main__ - INFO - app_list: <class 'list'>\n",
"2024-10-14 07:16:24,843 - __main__ - INFO - app_list: [{'id': '62cc2936-af22-4946-b3e5-5b9143d7203f'}, {'id': 'b8a203be-ac81-45a6-8d88-fdb1f8f5393b'}, {'id': '298b2c0c-7efa-45d3-8b47-8ab3c009b845'}, {'id': 'ec9e33a5-c6f2-404d-a993-84e37aebf57c'}, {'id': 'f1e4d448-e277-496b-bf63-98391cfd20fb'}, {'id': 'fb4d3c6a-197e-4e3f-96ae-ab4d5ac663a9'}, {'id': 'b8ae165a-a1e3-4d6c-86d9-52c59ad314b6'}, {'id': '5015e45f-be53-4e28-8f47-c107fd1dea8c'}]\n",
"2024-10-14 07:16:24,843 - __main__ - DEBUG - >>> delete_application_instance_id: sbx1urljfj\n",
"2024-10-14 07:16:24,844 - __main__ - DEBUG - >>> delete_application_instance_id: ec9e33a5-c6f2-404d-a993-84e37aebf57c\n",
"2024-10-14 07:16:24,880 DEBUG https://mec-platform2.etsi.org:443 \"DELETE /sandbox-api/v1/sandboxAppInstances/sbx1urljfj/ec9e33a5-c6f2-404d-a993-84e37aebf57c HTTP/1.1\" 204 0\n",
"2024-10-14 07:16:24,881 DEBUG response body: b''\n",
"2024-10-14 07:16:24,881 - __main__ - INFO - app_inst_id deleted: ec9e33a5-c6f2-404d-a993-84e37aebf57c\n",
"2024-10-14 07:16:24,882 - __main__ - DEBUG - >>> deactivate_network_scenario: sbx1urljfj\n",
"2024-10-14 07:16:24,916 DEBUG https://mec-platform2.etsi.org:443 \"DELETE /sandbox-api/v1/sandboxNetworkScenarios/sbx1urljfj/4g-5g-macro-v2x HTTP/1.1\" 204 0\n",
"2024-10-14 07:16:24,917 DEBUG response body: b''\n",
"2024-10-14 07:16:24,918 - __main__ - INFO - Network scenario deactivated: 4g-5g-macro-v2x\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/sandboxAppInstances/sbx1urljfj HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 107\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{\"id\": \"ec9e33a5-c6f2-404d-a993-84e37aebf57c\", \"name\": \"JupyterMecApp\", \"nodeName\": \"mep1\", \"type\": \"USER\"}'\n",
"reply: 'HTTP/1.1 201 Created\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:16:24 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 100\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'GET /sandbox-api/v1/sandboxAppInstances/sbx1urljfj HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"reply: 'HTTP/1.1 200 OK\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:16:24 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 786\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'DELETE /sandbox-api/v1/sandboxAppInstances/sbx1urljfj/ec9e33a5-c6f2-404d-a993-84e37aebf57c HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:16:24 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'DELETE /sandbox-api/v1/sandboxNetworkScenarios/sbx1urljfj/4g-5g-macro-v2x HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:16:24 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:16:36,931 - __main__ - DEBUG - >>> process_logout: sandbox=sbx1urljfj\n",
"2024-10-14 07:16:36,932 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:16:36,995 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/logout?sandbox_name=sbx1urljfj HTTP/1.1\" 204 0\n",
"2024-10-14 07:16:36,995 DEBUG response body: b''\n",
"2024-10-14 07:16:36,996 - __main__ - DEBUG - To check that logout is effective, verify on the MEC Sandbox server that the MEC Sandbox is removed (kubectl get pods -A)\n",
"2024-10-14 07:16:36,997 - __main__ - DEBUG - Stopped at 20241014-071636\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/logout?sandbox_name=sbx1urljfj HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:16:36 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
}
],
"source": [
"def process_main():\n",
" \"\"\"\n",
" This is the second sprint of our skeleton of our MEC application:\n",
" - Login\n",
" - Print sandbox identifier\n",
" - Print available network scenarios\n",
" - Activate a network scenario\n",
" - Request for a new application instance identifier\n",
" - Retrieve the list of the applications instance identifier\n",
" - Check the demo application is present in the list of applications\n",
" - Deactivate a network scenario\n",
" - Logout\n",
" - Check that logout is effective\n",
" \"\"\" \n",
" global logger, nw_scenarios\n",
" logger.debug('Starting at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" logger.debug('\\t pwd= ' + os.getcwd())\n",
"\n",
" # Login\n",
" sandbox = process_login()\n",
" if sandbox is None:\n",
" logger.error('Failed to instanciate a MEC Sandbox')\n",
" return\n",
"\n",
" # Print sandbox identifier\n",
" logger.info('Sandbox created: ' + sandbox)\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
"\n",
" # Print available network scenarios\n",
" nw_scenarios = get_network_scenarios(sandbox)\n",
" if nw_scenarios is None:\n",
" logger.error('Failed to retrieve the list of network scenarios')\n",
" logger.info('nw_scenarios: %s', str(type(nw_scenarios[0])))\n",
" logger.info('nw_scenarios: %s', str(nw_scenarios))\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
" logger.info('nw_scenarios: No scenario available')\n",
"\n",
" # Activate a network scenario based on a list of criterias (hard coded!!!)\n",
" if activate_network_scenario(sandbox) == -1:\n",
" logger.error('Failed to activate network scenario')\n",
" logger.info('Network scenario activated: ' + nw_scenarios[nw_scenario_idx].id)\n",
" time.sleep(2 * STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
" # Request for a new application instance identifier\n",
" app_inst_id = request_application_instance_id(sandbox)\n",
" if app_inst_id == None:\n",
" logger.error('Failed to request an application instance identifier')\n",
" logger.info('app_inst_id: %s', str(type(app_inst_id)))\n",
" logger.info('app_inst_id: %s', str(app_inst_id))\n",
" # Check the demo application is present in the list of applications\n",
" app_list = get_applications_list(sandbox)\n",
" if app_list is None:\n",
" logger.error('Failed to request the list of applications')\n",
" logger.info('app_list: %s', str(type(app_list)))\n",
" logger.info('app_list: %s', str(app_list))\n",
" # Check if our application is present in the list of applications\n",
" found = False\n",
" for item in app_list:\n",
" if item.id == app_inst_id.id:\n",
" found = True\n",
" break\n",
" if not found:\n",
" logger.error('Failed to retrieve our application instance identifier')\n",
" # Delete the application instance identifier\n",
" if delete_application_instance_id(sandbox, app_inst_id.id) == -1:\n",
" logger.error('Failed to delete the application instance identifier')\n",
" logger.info('app_inst_id deleted: ' + app_inst_id.id)\n",
"\n",
" # Deactivate a network scenario based on a list of criterias (hard coded!!!)\n",
" if deactivate_network_scenario(sandbox) == -1:\n",
" logger.error('Failed to deactivate network scenario')\n",
" logger.info('Network scenario deactivated: ' + nw_scenarios[nw_scenario_idx].id)\n",
" time.sleep(2 * STABLE_TIME_OUT)\n",
"\n",
" # Logout\n",
" process_logout(sandbox)\n",
"\n",
" # Check that logout is effective\n",
" logger.debug('To check that logout is effective, verify on the MEC Sandbox server that the MEC Sandbox is removed (kubectl get pods -A)')\n",
" logger.debug('Stopped at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" # End of function process_main\n",
"\n",
"if __name__ == '__main__':\n",
" process_main()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## MEC Registration and the READY confirmation\n",
"\n",
"Having an application instance identifier allows us to register with the MEC Sandbox and interact with it (e.g. to send service queries, to subscribe to events and to recieve notifications...).\n",
"\n",
"The standard MEC 011 Clause 5.2.2 MEC application start-up describes the start up process. Basically, our MEC application has to:\n",
"1. Indicates that it is running by sending a Confirm Ready message\n",
"2. Retrieve the list of MEC services \n",
"\n",
"To do so, a MEC application needs to be able to send requests but also to receive notifications (POST requests) and to reply to them."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Fifth step: Send the READY confirmation\n",
"\n",
"The MEC application instance confirms towards the MEC platform that it is up and running. It corresponds to step 4c described inETSI GS MEC 011 V3.2.1 (2024-04)11 Clause 5.2.2 MEC application start-up.\n"
"metadata": {},
"outputs": [],
"source": [
"def send_ready_confirmation(sandbox_name: str, app_inst_id: swagger_client.models.application_info.ApplicationInfo) -> int:\n",
" \"\"\"\n",
" Send the ready_confirmation to indicate that the MEC application is active.\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param app_inst_id: The MEC application instance identifier\n",
" :return: 0 on success, -1 otherwise\n",
" :see ETSI GS MEC 011 V3.2.1 (2024-04) Clause 5.2.2 MEC application start-up - Step 4c\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
" logger.debug('>>> send_ready_confirmation: ' + app_inst_id.id)\n",
" url = '/{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/confirm_ready'\n",
" logger.debug('send_ready_confirmation: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" path_params['app_inst_id'] = app_inst_id.id\n",
" header_params = {}\n",
" # HTTP header `Accept`\n",
" header_params['Accept'] = 'application/json' # noqa: E501\n",
" header_params['Content-Type'] = 'application/json' # noqa: E501\n",
" # JSON indication READY\n",
" dict_body = {}\n",
" dict_body['indication'] = 'READY'\n",
" service_api.call_api(url, 'POST', header_params=header_params, path_params = path_params, body=dict_body, async_req=False)\n",
" return 0\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" return -1\n",
" # End of function send_ready_confirmation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition, our MEC application is registering to AppTerminationNotificationSubscription and it needs to delete its subscription when terminating.\n",
"\n",
"At this stage, it is important to note that all subscription deletion use the same format: <subscription URL>/<subscription identifier> (see ETSI MEC GS 003 [16]). \n",
"In this case, it the AppTerminationNotificationSubscription is 'sub-1234', the URIs to do the susbscription and to delete it are:\n",
"- MEC_SANDBOX_URL + '/' + sandbox_name + '/' + MEC_PLTF + '/mec_app_support/v2/applications/' + app_inst_id + '/subscriptions'\n",
"- MEC_SANDBOX_URL + '/' + sandbox_name + '/' + MEC_PLTF + '/mec_app_support/v2/applications/' + app_inst_id + '/subscriptions/sub-1234'\n",
"\n",
"So, it will be usefull to create a small function to extract the subscription identifier from either the HTTP Location header or from the Link field found into the reponse body data structure. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Subscribing to application termination\n",
"\n",
"The purpose is to create a new subscription to \n",
"the MEC application termination notification as describe in ETSI GS MEC 011 V3.2.1 (2024-04) Clause 5.2.6b Receiving event notifications on MEC application instance \n",
"terminations"
"metadata": {},
"outputs": [],
"source": [
"def send_subscribe_termination(sandbox_name: str, app_inst_id: swagger_client.models.application_info.ApplicationInfo) -> object:\n",
" \"\"\"\n",
" Subscribe to the MEC application termination notifications.\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param app_inst_id: The MEC application instance identifier\n",
" :return: The HTTP respone, the subscription ID and the resource URL on success, None otherwise\n",
" :see ETSI GS MEC 011 V3.2.1 (2024-04) Clause 5.2.6b Receiving event notifications on MEC application instance termination\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
"\n",
" logger.debug('>>> send_subscribe_termination: ' + app_inst_id.id)\n",
" try:\n",
" url = '/{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/subscriptions'\n",
" logger.debug('send_subscribe_termination: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" path_params['app_inst_id'] = app_inst_id.id\n",
" header_params = {}\n",
" # HTTP header `Accept`\n",
" header_params['Accept'] = 'application/json' # noqa: E501\n",
" # HTTP header `Content-Type`\n",
" header_params['Content-Type'] = 'application/json' # noqa: E501\n",
" # Body\n",
" dict_body = {}\n",
" dict_body['subscriptionType'] = 'AppTerminationNotificationSubscription'\n",
" dict_body['callbackReference'] = 'http://yanngarcia.ddns.net/mec011/v2/termination' # FIXME To be parameterized\n",
" dict_body['appInstanceId'] = app_inst_id.id\n",
" (result, status, headers) = service_api.call_api(url, 'POST', header_params=header_params, path_params = path_params, body=dict_body, async_req=False)\n",
" return (result, extract_sub_id(headers['Location']), headers['Location'])\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" return None\n",
" # End of function send_subscribe_termination"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Extracting subscription identifier\n",
"\n",
"This helper function extracts the subscription identifier from any subscription URL."
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [],
"source": [
"def extract_sub_id(resource_url: str) -> str:\n",
" \"\"\"\n",
" Extract the subscription identifier from the specified subscription URL.\n",
" :param resource_url: The subscription URL\n",
" :return: The subscription identifier on success, None otherwise\n",
" \"\"\"\n",
" global logger\n",
"\n",
" logger.debug('>>> extract_sub_id: resource_url: ' + resource_url)\n",
"\n",
" res = urllib3.util.parse_url(resource_url)\n",
" if res is not None and res.path is not None and res.path != '':\n",
" id = res.path.rsplit('/', 1)[-1]\n",
" if id is not None:\n",
" return id\n",
" return None\n",
" # End of function extract_sub_id"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Delete subscription to application termination"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [],
"source": [
"def delete_subscribe_termination(sandbox_name: str, app_inst_id: swagger_client.models.application_info.ApplicationInfo, sub_id: str) -> int:\n",
" \"\"\"\n",
" Delete the subscrition to the AppTermination notification.\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param app_inst_id: The MEC application instance identifier\n",
" :param sub_id: The subscription identifier\n",
" :return: 0 on success, -1 otherwise\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
" logger.debug('>>> delete_subscribe_termination: ' + app_inst_id.id)\n",
" url = '/{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/subscriptions/{sub_id}'\n",
" logger.debug('delete_subscribe_termination: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" path_params['app_inst_id'] = app_inst_id.id\n",
" path_params['sub_id'] = sub_id\n",
" header_params = {}\n",
" # HTTP header `Accept`\n",
" header_params['Accept'] = 'application/json' # noqa: E501\n",
" # HTTP header `Content-Type`\n",
" header_params['Content-Type'] = 'application/json' # noqa: E501\n",
" service_api.call_api(url, 'DELETE', header_params=header_params, path_params = path_params, async_req=False)\n",
" return 0\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" # End of function delete_subscribe_termination"
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When the MEC application instance is notified to gracefully terminate, it provides to the MEC platform \n",
"that the application has completed its application level related terminate/stop actiono\n",
"\n",
"Reference: ETSI GS MEC 011 V3.2.1 (2024-04) Clause 5.2.3 MEC application graceful termination/stopp."
]
},
{
"cell_type": "code",
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
"metadata": {},
"outputs": [],
"source": [
"def send_termination_confirmation(sandbox_name: str, app_inst_id: swagger_client.models.application_info.ApplicationInfo) -> int:\n",
" \"\"\"\n",
" Send the confirm_termination to indicate that the MEC application is terminating gracefully.\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param app_inst_id: The MEC application instance identifier\n",
" :return: 0 on success, -1 otherwise\n",
" :see ETSI GS MEC 011 V3.2.1 (2024-04) Clause 5.2.3 MEC application graceful termination/stop\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
"\n",
" logger.debug('>>> send_termination_confirmation: ' + app_inst_id.id)\n",
" try:\n",
" url = '/{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/confirm_termination'\n",
" logger.debug('send_termination_confirmation: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" path_params['app_inst_id'] = app_inst_id.id\n",
" header_params = {}\n",
" # HTTP header `Accept`\n",
" header_params['Accept'] = 'application/json' # noqa: E501\n",
" # HTTP header `Content-Type`\n",
" header_params['Content-Type'] = 'application/json' # noqa: E501\n",
" # JSON indication READY\n",
" dict_body = {}\n",
" dict_body['operationAction'] = 'TERMINATING'\n",
" service_api.call_api(url, 'POST', header_params=header_params, path_params = path_params, body=dict_body, async_req=False)\n",
" return 0\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" return -1\n",
" # End of function send_termination_confirmation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, it is time now to create the our fifth iteration of our MEC application.\n",
"\n",
"The sequence is the following:\n",
"- Login\n",
"- Print sandbox identifier\n",
"- Print available network scenarios\n",
"- Activate a network scenario\n",
"- Request for a new application instance identifier\n",
"- Subscribe to AppTerminationNotificationSubscription\n",
"- Check list of services\n",
"- Delete AppTerminationNotification subscription\n",
"- Delete our application instance identifier\n",
"- Deactivate a network scenario\n",
"- Logout\n",
"- Check that logout is effective\n"
]
},
{
"cell_type": "code",
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:23,329 - __main__ - DEBUG - Starting at 20241014-075223\n",
"2024-10-14 07:52:23,331 - __main__ - DEBUG - \t pwd= /home/yanng/dev/etsi-mec-sandbox/examples/demo6/python/mecapp\n",
"2024-10-14 07:52:23,332 - __main__ - DEBUG - >>> process_login\n",
"2024-10-14 07:52:23,333 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:52:23,408 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/login?provider=Jupyter2024 HTTP/1.1\" 201 48\n",
"2024-10-14 07:52:23,409 DEBUG response body: b'{\"user_code\":\"sbxmd076gh\",\"verification_uri\":\"\"}'\n",
"2024-10-14 07:52:23,409 - __main__ - DEBUG - process_login (step1): oauth: {'user_code': 'sbxmd076gh', 'verification_uri': ''}\n",
"2024-10-14 07:52:23,410 - __main__ - DEBUG - =======================> DO AUTHORIZATION WITH CODE : sbxmd076gh\n",
"2024-10-14 07:52:23,410 - __main__ - DEBUG - =======================> DO AUTHORIZATION HERE : \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/login?provider=Jupyter2024 HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 201 Created\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:23 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 48\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:26,428 DEBUG https://mec-platform2.etsi.org:443 \"GET /sandbox-api/v1/namespace?user_code=sbxmd076gh HTTP/1.1\" 200 29\n",
"2024-10-14 07:52:26,429 DEBUG response body: b'{\"sandbox_name\":\"sbxmd076gh\"}'\n",
"2024-10-14 07:52:26,431 - __main__ - DEBUG - process_login (step2): result: {'sandbox_name': 'sbxmd076gh'}\n",
"2024-10-14 07:52:26,432 - __main__ - INFO - Sandbox created: sbxmd076gh\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'GET /sandbox-api/v1/namespace?user_code=sbxmd076gh HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"reply: 'HTTP/1.1 200 OK\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:26 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 29\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:32,439 - __main__ - DEBUG - >>> get_network_scenarios: sandbox=sbxmd076gh\n",
"2024-10-14 07:52:32,443 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:52:32,541 DEBUG https://mec-platform2.etsi.org:443 \"GET /sandbox-api/v1/sandboxNetworkScenarios?sandbox_name=sbxmd076gh HTTP/1.1\" 200 186\n",
"2024-10-14 07:52:32,544 DEBUG response body: b'[{\"id\":\"4g-5g-macro-v2x\"},{\"id\":\"4g-5g-macro-v2x-fed\"},{\"id\":\"4g-5g-wifi-macro\"},{\"id\":\"4g-macro\"},{\"id\":\"4g-wifi-macro\"},{\"id\":\"dual-mep-4g-5g-wifi-macro\"},{\"id\":\"dual-mep-short-path\"}]'\n",
"2024-10-14 07:52:32,545 - __main__ - DEBUG - get_network_scenarios: result: [{'id': '4g-5g-macro-v2x'}, {'id': '4g-5g-macro-v2x-fed'}, {'id': '4g-5g-wifi-macro'}, {'id': '4g-macro'}, {'id': '4g-wifi-macro'}, {'id': 'dual-mep-4g-5g-wifi-macro'}, {'id': 'dual-mep-short-path'}]\n",
"2024-10-14 07:52:32,546 - __main__ - INFO - nw_scenarios: <class 'swagger_client.models.sandbox_network_scenario.SandboxNetworkScenario'>\n",
"2024-10-14 07:52:32,547 - __main__ - INFO - nw_scenarios: [{'id': '4g-5g-macro-v2x'}, {'id': '4g-5g-macro-v2x-fed'}, {'id': '4g-5g-wifi-macro'}, {'id': '4g-macro'}, {'id': '4g-wifi-macro'}, {'id': 'dual-mep-4g-5g-wifi-macro'}, {'id': 'dual-mep-short-path'}]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'GET /sandbox-api/v1/sandboxNetworkScenarios?sandbox_name=sbxmd076gh HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"reply: 'HTTP/1.1 200 OK\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:32 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 186\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:38,554 - __main__ - DEBUG - >>> activate_network_scenario: sbxmd076gh\n",
"2024-10-14 07:52:38,596 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/sandboxNetworkScenarios/sbxmd076gh?network_scenario_id=4g-5g-macro-v2x HTTP/1.1\" 204 0\n",
"2024-10-14 07:52:38,597 DEBUG response body: b''\n",
"2024-10-14 07:52:38,597 - __main__ - INFO - Network scenario activated: 4g-5g-macro-v2x\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/sandboxNetworkScenarios/sbxmd076gh?network_scenario_id=4g-5g-macro-v2x HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:38 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:50,611 - __main__ - DEBUG - >>> request_application_instance_id: sbxmd076gh\n",
"2024-10-14 07:52:50,615 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:52:50,675 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/sandboxAppInstances/sbxmd076gh HTTP/1.1\" 201 100\n",
"2024-10-14 07:52:50,676 DEBUG response body: b'{\"id\":\"3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\",\"name\":\"JupyterMecApp\",\"nodeName\":\"mep1\",\"type\":\"USER\"}'\n",
"2024-10-14 07:52:50,677 - __main__ - DEBUG - request_application_instance_id: result: {'id': '3508cfe7-989a-4e88-84d6-8f1d6f25d2fe',\n",
" 'name': 'JupyterMecApp',\n",
" 'node_name': 'mep1',\n",
" 'persist': None,\n",
" 'type': 'USER'}\n",
"2024-10-14 07:52:50,677 - __main__ - INFO - app_inst_id: {'id': '3508cfe7-989a-4e88-84d6-8f1d6f25d2fe',\n",
" 'name': 'JupyterMecApp',\n",
" 'node_name': 'mep1',\n",
" 'persist': None,\n",
" 'type': 'USER'}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/sandboxAppInstances/sbxmd076gh HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 107\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{\"id\": \"3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\", \"name\": \"JupyterMecApp\", \"nodeName\": \"mep1\", \"type\": \"USER\"}'\n",
"reply: 'HTTP/1.1 201 Created\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:50 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 100\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:52:56,684 - __main__ - DEBUG - >>> send_ready_confirmation: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:52:56,685 - __main__ - DEBUG - send_ready_confirmation: url: /{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/confirm_ready\n",
"2024-10-14 07:52:56,686 DEBUG Starting new HTTPS connection (1): mec-platform2.etsi.org:443\n",
"2024-10-14 07:52:57,770 DEBUG https://mec-platform2.etsi.org:443 \"POST /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/confirm_ready HTTP/1.1\" 204 0\n",
"2024-10-14 07:52:57,772 DEBUG response body: b''\n",
"2024-10-14 07:52:57,773 - __main__ - DEBUG - >>> send_subscribe_termination: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:52:57,774 - __main__ - DEBUG - send_subscribe_termination: url: /{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/subscriptions\n",
"2024-10-14 07:52:57,786 DEBUG https://mec-platform2.etsi.org:443 \"POST /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions HTTP/1.1\" 201 367\n",
"2024-10-14 07:52:57,786 DEBUG response body: b'{\"subscriptionType\":\"AppTerminationNotificationSubscription\",\"callbackReference\":\"http://yanngarcia.ddns.net/mec011/v2/termination\",\"_links\":{\"self\":{\"href\":\"https://mec-platform2.etsi.org/sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm\"}},\"appInstanceId\":\"3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\"}'\n",
"2024-10-14 07:52:57,787 - __main__ - DEBUG - >>> extract_sub_id: resource_url: https://mec-platform2.etsi.org/sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm\n",
"2024-10-14 07:52:57,787 - __main__ - INFO - result: <swagger_client.rest.RESTResponse object at 0x7f23444781c0>\n",
"2024-10-14 07:52:57,788 - __main__ - INFO - sub_id: sub-giaY6RYhNCYb6tEm\n",
"2024-10-14 07:52:57,788 - __main__ - INFO - data: {'subscriptionType': 'AppTerminationNotificationSubscription', 'callbackReference': 'http://yanngarcia.ddns.net/mec011/v2/termination', '_links': {'self': {'href': 'https://mec-platform2.etsi.org/sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm'}}, 'appInstanceId': '3508cfe7-989a-4e88-84d6-8f1d6f25d2fe'}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/confirm_ready HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 23\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{\"indication\": \"READY\"}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:57 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'POST /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 192\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{\"subscriptionType\": \"AppTerminationNotificationSubscription\", \"callbackReference\": \"http://yanngarcia.ddns.net/mec011/v2/termination\", \"appInstanceId\": \"3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\"}'\n",
"reply: 'HTTP/1.1 201 Created\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:52:57 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Content-Length: 367\n",
"header: Connection: keep-alive\n",
"header: Location: https://mec-platform2.etsi.org/sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:53:03,795 - __main__ - DEBUG - >>> delete_subscribe_termination: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:53:03,797 - __main__ - DEBUG - delete_subscribe_termination: url: /{sandbox_name}/{mec_pltf}/mec_app_support/v2/applications/{app_inst_id}/subscriptions/{sub_id}\n",
"2024-10-14 07:53:03,810 DEBUG https://mec-platform2.etsi.org:443 \"DELETE /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm HTTP/1.1\" 204 0\n",
"2024-10-14 07:53:03,811 DEBUG response body: b''\n",
"2024-10-14 07:53:03,812 - __main__ - INFO - app_inst_id deleted: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:53:03,812 - __main__ - DEBUG - >>> delete_application_instance_id: sbxmd076gh\n",
"2024-10-14 07:53:03,813 - __main__ - DEBUG - >>> delete_application_instance_id: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:53:03,836 DEBUG https://mec-platform2.etsi.org:443 \"DELETE /sandbox-api/v1/sandboxAppInstances/sbxmd076gh/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe HTTP/1.1\" 204 0\n",
"2024-10-14 07:53:03,837 DEBUG response body: b''\n",
"2024-10-14 07:53:03,837 - __main__ - INFO - app_inst_id deleted: 3508cfe7-989a-4e88-84d6-8f1d6f25d2fe\n",
"2024-10-14 07:53:03,838 - __main__ - DEBUG - >>> deactivate_network_scenario: sbxmd076gh\n",
"2024-10-14 07:53:03,876 DEBUG https://mec-platform2.etsi.org:443 \"DELETE /sandbox-api/v1/sandboxNetworkScenarios/sbxmd076gh/4g-5g-macro-v2x HTTP/1.1\" 204 0\n",
"2024-10-14 07:53:03,877 DEBUG response body: b''\n",
"2024-10-14 07:53:03,878 - __main__ - INFO - Network scenario deactivated: 4g-5g-macro-v2x\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'DELETE /sbxmd076gh/mep1/mec_app_support/v2/applications/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe/subscriptions/sub-giaY6RYhNCYb6tEm HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nAccept: application/json\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:53:03 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'DELETE /sandbox-api/v1/sandboxAppInstances/sbxmd076gh/3508cfe7-989a-4e88-84d6-8f1d6f25d2fe HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:53:03 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n",
"send: b'DELETE /sandbox-api/v1/sandboxNetworkScenarios/sbxmd076gh/4g-5g-macro-v2x HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:53:03 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-10-14 07:53:15,891 - __main__ - DEBUG - >>> process_logout: sandbox=sbxmd076gh\n",
"2024-10-14 07:53:15,895 DEBUG Resetting dropped connection: mec-platform2.etsi.org\n",
"2024-10-14 07:53:15,967 DEBUG https://mec-platform2.etsi.org:443 \"POST /sandbox-api/v1/logout?sandbox_name=sbxmd076gh HTTP/1.1\" 204 0\n",
"2024-10-14 07:53:15,969 DEBUG response body: b''\n",
"2024-10-14 07:53:15,971 - __main__ - DEBUG - To check that logout is effective, verify on the MEC Sandbox server that the MEC Sandbox is removed (kubectl get pods -A)\n",
"2024-10-14 07:53:15,972 - __main__ - DEBUG - Stopped at 20241014-075315\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"send: b'POST /sandbox-api/v1/logout?sandbox_name=sbxmd076gh HTTP/1.1\\r\\nHost: mec-platform2.etsi.org\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 2\\r\\nContent-Type: application/json\\r\\nUser-Agent: Swagger-Codegen/1.0.0/python\\r\\n\\r\\n'\n",
"send: b'{}'\n",
"reply: 'HTTP/1.1 204 No Content\\r\\n'\n",
"header: Date: Mon, 14 Oct 2024 05:53:15 GMT\n",
"header: Content-Type: application/json; charset=UTF-8\n",
"header: Connection: keep-alive\n",
"header: Strict-Transport-Security: max-age=15724800; includeSubDomains\n"
]
}
],
"source": [
"def process_main():\n",
" \"\"\"\n",
" This is the second sprint of our skeleton of our MEC application:\n",
" - Login\n",
" - Print sandbox identifier\n",
" - Print available network scenarios\n",
" - Activate a network scenario\n",
" - Request for a new application instance identifier\n",
" \n",
" - Subscribe to AppTermination Notification\n",
" - Delete AppTerminationNotification subscription\n",
" - Delete our application instance identifier\n",
" - Deactivate a network scenario\n",
" - Logout\n",
" - Check that logout is effective\n",
" \"\"\" \n",
" global logger, nw_scenarios\n",
" logger.debug('Starting at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" logger.debug('\\t pwd= ' + os.getcwd())\n",
"\n",
" # Login\n",
" sandbox = process_login()\n",
" if sandbox is None:\n",
" logger.error('Failed to instanciate a MEC Sandbox')\n",
" return\n",
"\n",
" # Print sandbox identifier\n",
" logger.info('Sandbox created: ' + sandbox)\n",
" # Wait for the MEC Sandbox is running\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
"\n",
" # Print available network scenarios\n",
" nw_scenarios = get_network_scenarios(sandbox)\n",
" if nw_scenarios is None:\n",
" logger.error('Failed to retrieve the list of network scenarios')\n",
" logger.info('nw_scenarios: %s', str(type(nw_scenarios[0])))\n",
" logger.info('nw_scenarios: %s', str(nw_scenarios))\n",
" # Wait for the MEC Sandbox is running\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
" else:\n",
" logger.info('nw_scenarios: No scenario available')\n",
"\n",
" # Activate a network scenario based on a list of criterias (hard coded!!!)\n",
" if activate_network_scenario(sandbox) == -1:\n",
" logger.error('Failed to activate network scenario')\n",
" logger.info('Network scenario activated: ' + nw_scenarios[nw_scenario_idx].id)\n",
" time.sleep(2 * STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
" # Request for a new application instance identifier\n",
" app_inst_id = request_application_instance_id(sandbox)\n",
" if app_inst_id == None:\n",
" logger.error('Failed to request an application instance identifier')\n",
" logger.info('app_inst_id: %s', str(app_inst_id))\n",
" time.sleep(STABLE_TIME_OUT)\n",
" sub_id = None\n",
" if send_ready_confirmation(sandbox, app_inst_id) == -1:\n",
" logger.error('Failed to send confirm_ready')\n",
" else:\n",
" # Subscribe to AppTerminationNotificationSubscription\n",
" result, sub_id, res_url = send_subscribe_termination(sandbox, app_inst_id)\n",
" if sub_id == None:\n",
" logger.error('Failed to do the subscription')\n",
" else:\n",
" logger.info('sub_id: %s', sub_id)\n",
" data = json.loads(result.data)\n",
" logger.info('data: ' + str(data))\n",
"\n",
" # Any processing here\n",
" time.sleep(STABLE_TIME_OUT)\n",
"\n",
" # Delete AppTerminationNotification subscription\n",
" if sub_id is not None:\n",
" if delete_subscribe_termination(sandbox, app_inst_id, sub_id) == -1:\n",
" logger.error('Failed to delete the application instance identifier')\n",
" else:\n",
" logger.info('app_inst_id deleted: ' + app_inst_id.id)\n",
" # Delete the application instance identifier\n",
" if delete_application_instance_id(sandbox, app_inst_id.id) == -1:\n",
" logger.error('Failed to delete the application instance identifier')\n",
" logger.info('app_inst_id deleted: ' + app_inst_id.id)\n",
"\n",
" # Deactivate a network scenario based on a list of criterias (hard coded!!!)\n",
" if deactivate_network_scenario(sandbox) == -1:\n",
" logger.error('Failed to deactivate network scenario')\n",
" logger.info('Network scenario deactivated: ' + nw_scenarios[nw_scenario_idx].id)\n",
" time.sleep(2 * STABLE_TIME_OUT)\n",
"\n",
" # Logout\n",
" process_logout(sandbox)\n",
"\n",
" # Check that logout is effective\n",
" logger.debug('To check that logout is effective, verify on the MEC Sandbox server that the MEC Sandbox is removed (kubectl get pods -A)')\n",
" logger.debug('Stopped at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" # End of function process_main\n",
"\n",
"if __name__ == '__main__':\n",
"cell_type": "markdown",
"metadata": {},
"source": [
"### Conclusion: Create two procedures for the setup and the termination of our MEC application\n"
"cell_type": "markdown",
"metadata": {},
"source": [
"#### The procedure for the setup of a MEC application\n",
"This function provides the steps to setup a MEC application and to be ready to use the MEC service exposed by the created MEC Sandbox.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def mec_app_setup():\n",
" This function provides the steps to setup a MEC application:\n",
" - Login\n",
" - Print sandbox identifier\n",
" - Print available network scenarios\n",
" - Activate a network scenario\n",
" - Request for a new application instance identifier\n",
" - Send READY confirmation\n",
" - Subscribe to AppTermination Notification\n",
" :return The MEC Sandbox instance, the MEC application instance identifier and the subscription identifier on success, None otherwise\n",
" global logger\n",
"\n",
" # Login\n",
" sandbox = process_login()\n",
" if sandbox is None:\n",
" logger.error('Failed to instanciate a MEC Sandbox')\n",
" return None\n",
" # Wait for the MEC Sandbox is running\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
"\n",
" # Print available network scenarios\n",
" nw_scenarios = get_network_scenarios(sandbox)\n",
" if nw_scenarios is None:\n",
" logger.error('Failed to retrieve the list of network scenarios')\n",
" elif len(nw_scenarios) != 0:\n",
" # Wait for the MEC Sandbox is running\n",
" time.sleep(STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
" else:\n",
" logger.info('nw_scenarios: No scenario available')\n",
"\n",
" # Activate a network scenario based on a list of criterias (hard coded!!!)\n",
" if activate_network_scenario(sandbox) == -1:\n",
" logger.error('Failed to activate network scenario')\n",
" else:\n",
" # Wait for the MEC services are running\n",
" time.sleep(2 * STABLE_TIME_OUT) # Wait for k8s pods up and running\n",
"\n",
" # Request for a new application instance identifier\n",
" app_inst_id = request_application_instance_id(sandbox)\n",
" if app_inst_id == None:\n",
" logger.error('Failed to request an application instance identifier')\n",
" # Wait for the MEC services are terminated\n",
" time.sleep(STABLE_TIME_OUT)\n",
" # Send READY confirmation\n",
" sub_id = None\n",
" if send_ready_confirmation(sandbox, app_inst_id) == -1:\n",
" logger.error('Failed to send confirm_ready')\n",
" else:\n",
" # Subscribe to AppTerminationNotificationSubscription\n",
" result, sub_id, res_url = send_subscribe_termination(sandbox, app_inst_id)\n",
" if sub_id == None:\n",
" logger.error('Failed to do the subscription')\n",
"\n",
" return (sandbox, app_inst_id, sub_id)\n",
" # End of function mec_app_setup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### The procedure for the termination of a MEC application\n",
"\n",
"This function provides the steps to terminate a MEC application.\n",
"**Note:** All subscriptions done outside of the mec_app_setup function are not deleted."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def mec_app_termination(sandbox_name: str, app_inst_id:swagger_client.models.ApplicationInfo, sub_id: str):\n",
" \"\"\"\n",
" This function provides the steps to setup a MEC application:\n",
" - Login\n",
" - Print sandbox identifier\n",
" - Print available network scenarios\n",
" - Activate a network scenario\n",
" - Request for a new application instance identifier\n",
" - Send READY confirmation\n",
" - Subscribe to AppTermination Notification\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param app_inst_id: The MEC application instance identifier\n",
" :param sub_id: The subscription identifier\n",
" global logger\n",
"\n",
" # Delete AppTerminationNotification subscription\n",
" if sub_id is not None:\n",
" if delete_subscribe_termination(sandbox_name, app_inst_id, sub_id) == -1:\n",
" logger.error('Failed to delete the application instance identifier')\n",
"\n",
" # Delete the application instance identifier\n",
" if delete_application_instance_id(sandbox_name, app_inst_id.id) == -1:\n",
" logger.error('Failed to delete the application instance identifier')\n",
" # Wait for the MEC services are terminated\n",
" time.sleep(STABLE_TIME_OUT)\n",
"\n",
" # Deactivate a network scenario based on a list of criterias (hard coded!!!)\n",
" if deactivate_network_scenario(sandbox_name) == -1:\n",
" logger.error('Failed to deactivate network scenario')\n",
" else:\n",
" # Wait for the MEC services are terminated\n",
" time.sleep(2 * STABLE_TIME_OUT)\n",
" process_logout(sandbox_name)\n",
" # End of function mec_app_termination"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [