Newer
Older
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class SecurityInfoOAuth2Info(object):\n",
" swagger_types = {'grant_types': 'list[str]','token_endpoint': 'str'}\n",
" attribute_map = {'grant_types': 'grantTypes','token_endpoint': 'tokenEndpoint'}\n",
" def __init__(self, grant_types=None, token_endpoint=None): # noqa: E501\n",
" self._grant_types = None\n",
" self._token_endpoint = None\n",
" self.discriminator = None\n",
" self.grant_types = grant_types\n",
" self.token_endpoint = token_endpoint\n",
" def grant_types(self):\n",
" return self._grant_types\n",
" @grant_types.setter\n",
" def grant_types(self, grant_types):\n",
" if grant_types is None:\n",
" raise ValueError(\"Invalid value for `grant_types`, must not be `None`\") # noqa: E501\n",
" self._grant_types = grant_types\n",
" def token_endpoint(self):\n",
" return self._token_endpoint\n",
" @token_endpoint.setter\n",
" def token_endpoint(self, token_endpoint):\n",
" if token_endpoint is None:\n",
" raise ValueError(\"Invalid value for `token_endpoint`, must not be `None`\") # noqa: E501\n",
" self._token_endpoint = token_endpoint\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(\n",
" lambda x: x.to_dict() if hasattr(x, \"to_dict\") else x,\n",
" value\n",
" ))\n",
" elif hasattr(value, \"to_dict\"):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class OneOfTransportInfoEndpoint(object):\n",
" swagger_types = {}\n",
" attribute_map = {}\n",
" def __init__(self): # noqa: E501\n",
" self.discriminator = None\n",
" def uris(self):\n",
" return self._uris\n",
" @uris.setter\n",
" def uris(self, uris):\n",
" self._uris = uris\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(\n",
" lambda x: x.to_dict() if hasattr(x, \"to_dict\") else x,\n",
" value\n",
" ))\n",
" elif hasattr(value, \"to_dict\"):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" if not isinstance(other, OneOfTransportInfoEndpoint):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class EndPointInfoUris(object):\n",
" swagger_types = {'_uris': 'list[str]'}\n",
" attribute_map = {'_uris': 'uris'}\n",
" def __init__(self, uris:list): # noqa: E501\n",
" self._uris = None\n",
" self.uris = uris\n",
" def uris(self):\n",
" return self._uris\n",
" @uris.setter\n",
" def uris(self, uris):\n",
" self._uris = uris\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(lambda x: x.to_dict() if hasattr(x, 'to_dict') else x,value))\n",
" elif hasattr(value, 'to_dict'):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" if hasattr(item[1], 'to_dict') else item,\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class EndPointInfoFqdn(object):\n",
" swagger_types = {'_fqdn': 'list[str]'}\n",
" attribute_map = {'_fqdn': 'fqdn'}\n",
" def __init__(self, fqdn:list): # noqa: E501\n",
" self._fqdn = None\n",
" self.fqdn = fqdn\n",
" def fqdn(self):\n",
" return self._fqdn\n",
" @fqdn.setter\n",
" def fqdn(self, fqdn):\n",
" self._fqdn = fqdn\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(lambda x: x.to_dict() if hasattr(x, 'to_dict') else x,value))\n",
" elif hasattr(value, 'to_dict'):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" if hasattr(item[1], 'to_dict') else item,\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class EndPointInfoAddress(object):\n",
" swagger_types = {'_host': 'str', '_port': 'int'}\n",
" attribute_map = {'_host': 'host', '_port': 'port'}\n",
" def __init__(self, host:str, port:list): # noqa: E501\n",
" self._host = None\n",
" self._port = None\n",
" self.host = host\n",
" self.port = port\n",
" def host(self):\n",
" return self.host\n",
" @host.setter\n",
" def host(self, host):\n",
" self._host = host\n",
" def port(self):\n",
" return self._port\n",
" @port.setter\n",
" def port(self, port):\n",
" self._port = qosport_kpi\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(\n",
" lambda x: x.to_dict() if hasattr(x, 'to_dict') else x,\n",
" value\n",
" ))\n",
" elif hasattr(value, 'to_dict'):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" if hasattr(item[1], 'to_dict') else item,\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class EndPointInfoAddresses(object):\n",
" swagger_types = {'_addresses': 'list[EndPointInfoAddress]'}\n",
" attribute_map = {'_addresses': 'addresses'}\n",
" def __init__(self, addresses:list): # noqa: E501\n",
" self._addresses = None\n",
" self.addresses = addresses\n",
" def addresses(self):\n",
" return self._addresses\n",
" @addresses.setter\n",
" def addresses(self, addresses):\n",
" self._addresses = addresses\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(lambda x: x.to_dict() if hasattr(x, 'to_dict') else x,value))\n",
" elif hasattr(value, 'to_dict'):\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" if hasattr(item[1], 'to_dict') else item,\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n",
"\n",
"class EndPointInfoAlternative(object):\n",
" swagger_types = {'alternative': 'object'}\n",
" attribute_map = {'alternative': 'alternative'}\n",
" def __init__(self, alternative=None): # noqa: E501\n",
" self._alternative = None\n",
" self.discriminator = None\n",
" self.alternative = alternative\n",
" def alternative(self):\n",
" return self._alternative\n",
" @alternative.setter\n",
" def alternative(self, alternative):\n",
" if alternative is None:\n",
" raise ValueError(\"Invalid value for `alternative`, must not be `None`\") # noqa: E501\n",
" self._alternative = alternative\n",
" def to_dict(self):\n",
" result = {}\n",
" for attr, _ in six.iteritems(self.swagger_types):\n",
" value = getattr(self, attr)\n",
" if isinstance(value, list):\n",
" result[attr] = list(map(\n",
" lambda x: x.to_dict() if hasattr(x, \"to_dict\") else x,\n",
" result[attr] = value.to_dict()\n",
" elif isinstance(value, dict):\n",
" result[attr] = dict(map(\n",
" lambda item: (item[0], item[1].to_dict())\n",
" value.items()\n",
" ))\n",
" else:\n",
" result[attr] = value\n",
" for key, value in self.items():\n",
" result[key] = value\n",
" return result\n",
" def to_str(self):\n",
" return pprint.pformat(self.to_dict())\n",
" def __repr__(self):\n",
" return self.to_str()\n",
" def __eq__(self, other):\n",
" return False\n",
" return self.__dict__ == other.__dict__\n",
" def __ne__(self, other):\n",
" return not self == other\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create an application MEC service\n",
"\n",
"The function below is creating an application MEC services\n",
"\n",
"**Note:** This is call application MEC service in opposition of a standardized MEC service exposed by the MEC Sanbox such as MEC 013, MEC 030...\n",
"\n",
"**Reference:** ETSI GS MEC 011 V3.2.1 (2024-04) Clause 8.2.6.3.4 POST"
]
},
"metadata": {},
"outputs": [],
"source": [
"def create_mec_service(sandbox_name: str, app_inst_id: swagger_client.models.application_info.ApplicationInfo) -> object:\n",
" \"\"\"\n",
" Request to create a new application MEC service\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 The HTTP response, the response status and the headers on success, None otherwise\n",
" :see ETSI GS MEC 011 V3.2.1 (2024-04) Clause 8.2.6.3.4 POST\n",
" \"\"\"\n",
" global MEC_PLTF, CALLBACK_URI, logger, service_api\n",
" url = '/{sandbox_name}/{mec_pltf}/mec_service_mgmt/v1/applications/{app_inst_id}/services'\n",
" logger.debug('create_mec_service: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" header_params['Accept'] = 'application/json' # noqa: E501\n",
" # HTTP header `Content-Type`\n",
" header_params['Content-Type'] = 'application/json' # noqa: E501\n",
" # Body request\n",
" callback = CALLBACK_URI + '/statistic/v1/quantity'\n",
" transport_info = TransportInfo(id=str(uuid.uuid4()), name='HTTP REST API', type='REST_HTTP', protocol='HTTP', version='2.0', security=SecurityInfo(), endpoint=OneOfTransportInfoEndpoint())\n",
" transport_info.endpoint.uris=[EndPointInfoUris(callback)]\n",
" category_ref = CategoryRef(href=callback, id=str(uuid.uuid4()), name='Demo', version='1.0.0')\n",
" appServiceInfo = ServiceInfo(ser_name='demo6 MEC Service', ser_category=category_ref, version='1.0.0', state='ACTIVE',transport_info=transport_info, serializer='JSON')\n",
" (result, status, headers) = service_api.call_api(url, 'POST', header_params=header_params, path_params=path_params, body=appServiceInfo, async_req=False)\n",
" return (result, status, headers['Location'])\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Delete an application MEC service\n",
"\n",
"The function below is deleting an application MEC services.\n",
"\n",
"**Reference:** ETSI GS MEC 011 V3.2.1 (2024-04) Clause 8.2.7.3.5 DELETE"
]
},
" \"\"\"\n",
" Request to create a new application MEC service\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",
" :see ETSI GS MEC 011 V3.2.1 (2024-04) Clause 8.2.7.3.5 DELETE\n",
" \"\"\"\n",
" logger.debug('>>> delete_mec_subscription: resource_url: ' + resource_url)\n",
" try:\n",
" res = urllib3.util.parse_url(resource_url)\n",
" if res is None:\n",
" logger.error('delete_mec_subscription: Failed to paerse URL')\n",
" return -1\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(res.path, 'DELETE', header_params=header_params, 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 delete_mec_service"
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Putting everything together\n",
"\n",
"The sequence is the following:\n",
"- Mec application setup\n",
"- Create new MEC service\n",
"- Send a request to our MEC service\n",
"- Delete newly created MEC service\n",
"- Mec application termination\n"
]
},
"#%%script echo skipping\n",
"# Uncomment the ;line above to skip execution of this cell\n",
" This is the fith sprint of our skeleton of our MEC application:\n",
" - Create new MEC service\n",
" - Send a request to our MEC service\n",
" - Delete newly created MEC service\n",
" - Mec application termination\n",
" \"\"\" \n",
" global LISTENER_IP, LISTENER_PORT, CALLBACK_URI, logger\n",
"\n",
" logger.debug('Starting at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" logger.debug('\\t pwd= ' + os.getcwd())\n",
"\n",
" # Start notification server in a daemonized thread\n",
" httpd = start_notification_server()\n",
"\n",
" # Create the MEC service\n",
" result, status, mec_service_resource = create_mec_service(sandbox_name, app_inst_id)\n",
" if status != 201:\n",
" logger.error('Failed to create MEC service')\n",
" logger.info('mec_service_resource: %s', mec_service_resource)\n",
"\n",
" # Send a request to our MEC service\n",
" logger.info('body: ' + str(result.data))\n",
" data = json.loads(result.data)\n",
" logger.info('data: %s', str(data))\n",
" logger.info('=============> Execute the command: curl --request GET %s/statistic/v1/quantity --header \"Accept: application/json\" --data \\'{\"time\":20180124,\"data1\":\"[1516752000,11590.6,11616.9,11590.4,11616.9,0.25202387,1516752060,11622.4,11651.7,11622.4,11644.6,1.03977764]\"}\\'', CALLBACK_URI)\n",
"\n",
" # Stop notification server\n",
" stop_notification_server(httpd)\n",
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
" # Delete the MEC servce\n",
" delete_mec_service(mec_service_resource)\n",
"\n",
" # Terminate the MEC application\n",
" mec_app_termination(sandbox_name, app_inst_id, sub_id)\n",
"\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": [
"# Support of CAPIF (3GPP TS 29.222: 3rd Generation Partnership Project; Technical Specification Group Core Network and Terminals; Common API Framework for 3GPP Northbound APIs)\n",
"\n",
"MEC-CAPIF support is described in ETSI GS MEC 011 (V3.2.1) Clause 9 [4]\n",
"\n",
"The sample code below illustrates the usage of MEC-CAPI endpoints:\n",
"- /service-apis/v1/allServiceAPIs\n",
"- /published-apis/v1/{apfId}/service-apis\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Getting all MEC services\n",
"The code below illustrates how to use CAPIF '/service-apis/v1/allServiceAPIs' endpoint to retrieve the complete list of available MEC services.\n",
"**Reference:** ETSI GS MEC 011 (V3.2.1) Clause 9.2.3 Resource: All published service APIs"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
"def capif_get_all_mec_services(sandbox_name: str):\n",
" \"\"\"\n",
" To retrieves the MEC services using CAPIF endpoint\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :return The HTTP response and the response status on success, None otherwise\n",
" :see ETSI GS MEC 011 (V3.2.1) Clause 9\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
"\n",
" logger.debug('>>> capif_get_all_mec_services: ' + sandbox_name)\n",
" try:\n",
" url = '/{sandbox_name}/{mec_pltf}/service-apis/v1/allServiceAPIs'\n",
" logger.debug('capif_get_all_mec_services: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\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",
" (result, status, headers) = service_api.call_api(url, 'GET', header_params=header_params, path_params=path_params, async_req=False)\n",
" return (result, status)\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" return (None, status)\n",
" # End of capif_get_all_mec_services function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Getting MEC services for a specified MEC application instance ID\n",
"\n",
"The code below illustrates how to use CAPIF '/published-apis/v1/{apfId}/service-apis' endpoint to retrieve the complete list of MEC services for a specified MEC application instance ID (apfid).\n",
"\n",
"**Reference:** ETSI GS MEC 011 (V3.2.1) Table 9.2.4.2-1: Profiling of the URI variables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def capif_get_mec_services(sandbox_name: str, apfId: str):\n",
" \"\"\"\n",
" To retrieves the MEC services using CAPIF endpoint\n",
" :param sandbox_name: The MEC Sandbox instance to use\n",
" :param apfId: The identifier of the entity that registers the service API\n",
" :return The HTTP response and the response status on success, None otherwise\n",
" :see ETSI GS MEC 011 (V3.2.1) Clause 9\n",
" \"\"\"\n",
" global MEC_PLTF, logger, service_api\n",
"\n",
" logger.debug('>>> capif_get_all_mec_services: ' + sandbox_name)\n",
" try:\n",
" url = '/{sandbox_name}/{mec_pltf}/published-apis/v1/{apfId}/service-apis'\n",
" logger.debug('capif_get_mec_services: url: ' + url)\n",
" path_params = {}\n",
" path_params['sandbox_name'] = sandbox_name\n",
" path_params['mec_pltf'] = MEC_PLTF\n",
" path_params['apfId'] = apfId\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",
" (result, status, headers) = service_api.call_api(url, 'GET', header_params=header_params, path_params=path_params, async_req=False)\n",
" return (result, status)\n",
" except ApiException as e:\n",
" logger.error('Exception when calling call_api: %s\\n' % e)\n",
" return (None, status)\n",
" # End of capif_get_mec_services function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Putting evrythong together\n",
"\n",
"It is time now to create the our third iteration of our MEC application.\n",
"\n",
"The sequence is the following:\n",
"\n",
"- Login\n",
"- Activate a network scenario\n",
"- Create an application instance identifier\n",
"- Retrieve all MEC services (/service-apis/v1/allServiceAPIs)\n",
"- Retrieve MEC services for the newly created application instance identifier\n",
"- Delete our application instance identifier\n",
"- Deactivate a network scenario\n",
"- Logout"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Uncomment the ;line above to skip execution of this cell\n",
"def process_main():\n",
" \"\"\"\n",
" This code illustrates the usage of MEC-CAPI endpoints:\n",
" - Login\n",
" - Activate a network scenario\n",
" - Create an application instance identifier\n",
" - Retrieve all MEC services (/service-apis/v1/allServiceAPIs)\n",
" - Retrieve MEC services for the newly created application instance identifier\n",
" - Delete our application instance identifier\n",
" - Deactivate a network scenario\n",
" - Logout\n",
" \"\"\" \n",
" global LISTENER_IP, LISTENER_PORT, CALLBACK_URI, logger\n",
"\n",
" logger.debug('Starting at ' + time.strftime('%Y%m%d-%H%M%S'))\n",
" logger.debug('\\t pwd= ' + os.getcwd())\n",
"\n",
" # Setup the MEC application\n",
" sandbox_name, app_inst_id, sub_id = mec_app_setup()\n",
"\n",
" # Get the list of the MEC sevices using CAPIF endpoints\n",
" result, status = capif_get_all_mec_services(sandbox_name)\n",
" if status != 200:\n",
" logger.error('Failed to get the list of MEC services using CAPIF endpoint')\n",
" else:\n",
" logger.info('capif_get_all_mec_services: ' + str(result.data))\n",
"\n",
" # Get the list of the MEC sevices for our AppInstanceId using CAPIF endpoints\n",
" result, status = capif_get_mec_services(sandbox_name, app_inst_id.id)\n",
" if status != 200:\n",
" logger.error('Failed to get the list of MEC services for our AppInstanceId using CAPIF endpoint')\n",
" else:\n",
" logger.info('capif_get_mec_services: ' + str(result.data))\n",
"\n",
" # In the previous request, the list of services for our AppInstanceId is empty.\n",
" # Let's create a new MEC service\n",
" result, status, mec_service_resource = create_mec_service(sandbox_name, app_inst_id)\n",
" if status != 201:\n",
" logger.error('Failed to create MEC service')\n",
" else:\n",
" logger.info('mec_service_resource: %s', mec_service_resource)\n",
"\n",
" # Now, we can send a new request for services for our MEC application\n",
" # Get the list of the MEC sevices for our AppInstanceId using CAPIF endpoints\n",
" result, status = capif_get_mec_services(sandbox_name, app_inst_id.id)\n",
" if status != 200:\n",
" logger.error('Failed to get the list of MEC services for our AppInstanceId using CAPIF endpoint')\n",
" else:\n",
" logger.info('capif_get_mec_services: ' + str(result.data))\n",
" data = json.loads(result.data)\n",
" logger.info('serviceAPIDescriptions: ' + str(data))\n",
" # b'{\"serviceAPIDescriptions\":[{\"apiName\":\"demo6 MEC Service\",\"apiId\":\"6172de7d-ed42-4ba2-947a-a0db7cc8915e\",\"aefProfiles\":[{\"aefId\":\"3daa9b79-ba81-4a74-9668-df710dc68020\",\"versions\":[\"1.0.0\"],\"interfaceDescriptions\":{\"uris\":null,\"fqdn\":null,\"addresses\":null,\"alternative\":null},\"vendorSpecific-urn:etsi:mec:capifext:transport-info\":{\"name\":\"HTTP REST API\",\"type\":\"REST_HTTP\",\"protocol\":\"HTTP\",\"version\":\"2.0\",\"security\":{}}}],\"vendorSpecific-urn:etsi:mec:capifext:service-info\":{\"serializer\":\"JSON\",\"state\":\"ACTIVE\",\"scopeOfLocality\":\"MEC_HOST\",\"consumedLocalOnly\":true,\"isLocal\":true,\"category\":{\"href\":\"http://mec-platform2.etsi.org:31111/sandbox/v1/statistic/v1/quantity\",\"id\":\"98a5039d-2b7c-49b1-b3b1-45a6ebad2ea4\",\"name\":\"Demo\",\"version\":\"1.0.0\"}}}]}'\n",
" logger.info('apiId: ' + str(data['serviceAPIDescriptions'][0]['apiId'] + ' matching MEC serInstanceID'))\n",
" logger.info('aefId: ' + str(data['serviceAPIDescriptions'][0]['aefProfiles'][0]['aefId'] + ' matching MEC TransportInfo.Id\"'))\n",
"\n",
" # Delete the MEC servce\n",
" delete_mec_service(mec_service_resource)\n",
"\n",
" # Terminate the MEC application\n",
" mec_app_termination(sandbox_name, app_inst_id, sub_id)\n",
"\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": [
"# Annexes\n",
"\n",
"## Annex A: How to use an existing MEC sandbox instance\n",
"\n",
"This case is used when the MEC Sandbox API is not used. The procedure is the following:\n",
"- Log to the MEC Sandbox using a WEB browser\n",
"- Select a network scenario\n",
"- Create a new application instance\n",
"\n",
"When it is done, the newly created application instance is used by your application when required. This application instance is usually passed to your application in the command line or using a configuration file\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"1. ETSI GS MEC 002 (V2.2.1) (01-2022): \"Multi-access Edge Computing (MEC); Phase 2: Use Cases and Requirements\".\n",
"2. ETSI GS MEC 010-1 (V1.1.1) (10-2017): \"Mobile Edge Computing (MEC); Mobile Edge Management; Part 1: System, host and platform management\".\n",
"3. ETSI GS MEC 010-2 (V2.2.1) (02-2022): \"Multi-access Edge Computing (MEC); MEC Management; Part 2: Application lifecycle, rules and requirements management\".\n",
"4. ETSI GS MEC 011 (V3.2.1) (09-2022): \"Multi-access Edge Computing (MEC); Edge Platform Application Enablement\".\n",
"5. ETSI GS MEC 012 (V2.2.1) (02-2022): \"Multi-access Edge Computing (MEC); Radio Network Information API\".\n",
"6. ETSI GS MEC 013 (V2.2.1) (01-2022): \"Multi-access Edge Computing (MEC); Location API\".\n",
"7. ETSI GS MEC 014 (V2.1.1) (03-2021): \"Multi-access Edge Computing (MEC); UE Identity API\".\n",
"8. ETSI GS MEC 015 (V2.1.1) (06-2020): \"Multi-Access Edge Computing (MEC); Traffic Management APIs\".\n",
"9. ETSI GS MEC 016 (V2.2.1) (04-2020): \"Multi-access Edge Computing (MEC); Device application interface\".\n",
"10. ETSI GS MEC 021 (V2.2.1) (02-2022): \"Multi-access Edge Computing (MEC); Application Mobility Service API\".\n",
"11. ETSI GS MEC 028 (V2.3.1) (07-2022): \"Multi-access Edge Computing (MEC); WLAN Access Information API\".\n",
"12. ETSI GS MEC 029 (V2.2.1) (01-2022): \"Multi-access Edge Computing (MEC); Fixed Access Information API\".\n",
"13. ETSI GS MEC 030 (V3.2.1) (05-2022): \"Multi-access Edge Computing (MEC); V2X Information Service API\".\n",
"14. ETSI GR MEC-DEC 025 (V2.1.1) (06-2019): \"Multi-access Edge Computing (MEC); MEC Testing Framework\".\n",
"15. ETSI GR MEC 001 (V3.1.1) (01-2022): \"Multi-access Edge Computing (MEC); Terminology\".\n",
"16. ETSI GR MEC 003 (V3.1.1): Multi-access Edge Computing (MEC);\n",
"17. 3GPP TS 29.222: 3rd Generation Partnership Project; Technical Specification Group Core Network and Terminals; Common API Framework for 3GPP Northbound APIs\n",
"Framework and Reference Architecture\n",
"18. [The Wiki MEC web site](https://www.etsi.org/technologies/multi-access-edge-computing)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
}
},
"nbformat": 4,
"nbformat_minor": 4
}