Newer
Older
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# How to develop a MEC application using the MEC Sandbox HTTP REST API\n",
"This tutorial introduces the step by step procedure to create a basic MEC application following ETSI MEC standards.\n",
"It uses the ETSI MEC Sandbox simulator.\n",
"\n",
"<div class=\"alert alert-block alert-danger\">\n",
" <b>Note:</b> These source code examples are simplified and ignore return codes and error checks to a large extent. We do this to highlight how to use the MEC Sandbox API and the different MEC satndards and reduce unrelated code.\n",
"A real-world application will of course properly check every return value and exit correctly at the first serious error.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What is a MEC application\n",
"\n",
"See [The Wiki MEC web site](https://www.etsi.org/technologies/multi-access-edge-computing)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The basics of developing a MEC application\n",
"\n",
"The developement of a MEC application follows a strict process in order to access the ETSI MEC services and provides valuable services to the customers.\n",
"Mainly, this process can be split in several steps:\n",
"1. Global initializations (constant, variables...)\n",
"2. Create a new instance of a MEC Sandbox (Note that using an existing one could be a solution too (see Annex A))\n",
"3. Activate a network scenario in order to access the ETSI MEC services\n",
"4. Create a new application identifier\n",
"5. Register our MEC application and subscribe to service termination (see MEC 011)\n",
"6. Use MEC services in order to provide valuable services to the customers\n",
" 6.1. Apply MEC services required subscriptions (e.g. MEC 013 location subscription)\n",
"7. Terminate the MEC application\n",
" 7.1. Remove MEC services subscriptions\n",
" 7.2. Deactivate the current network scenario\n",
" 7.3. Delete the instance of the MEC Sandbox\n",
"8. Release all the MEC application resources\n",
"\n",
"**Note:** Several application identifier can be created to address several MEC application.\n",
"\n",
"## Use the MEC Sandbox HTTP REST API models and code\n",
"\n",
"The MEC sandbox provides a piece of code (the python sub) that shall be used to develop the MEC application and interact with the MEC Sandbox. This piece of code mainly contains swagger models to serialize/deserialize JSON data structures and HTTP REST API call functions.\n",
"The openApi file is availabe [here](https://labs.etsi.org/rep/mec/etsi-mec-sandbox/-/blob/STF678_Task1_2_3_4/go-apps/meep-sandbox-api/api/swagger.yaml) and the [Swagger editor](https://editor-next.swagger.io/) is used to generate the python stub.\n",
"The project architecture is describe [here](images/project_arch.jpg).\n",
"The sandbox_api folder contains the python implementation of the HTTP REST API definitions introduced by the openApi [file](https://labs.etsi.org/rep/mec/etsi-mec-sandbox/-/blob/STF678_Task1_2_3_4/go-apps/meep-sandbox-api/api/swagger.yaml).\n",
"The model folder contains the python implementation of the data type definitions introduced by the openApi [file](https://labs.etsi.org/rep/mec/etsi-mec-sandbox/-/blob/STF678_Task1_2_3_4/go-apps/meep-sandbox-api/api/swagger.yaml).\n",
"\n",
"<div class=\"alert alert-warning\" role=\"alert\">\n",
" <b>Note:</b> The sub-paragraph 'Putting everything together' is a specific paragraph where all the newly features introduced in the main paragraph are put together to create an executable block of code. It is possible to skip this block of code by removing the comment character (#) on first line of this block of code.\n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Before going to create our MEC application skeleton, the following steps shall be done:\n",
"1) Change the working directory (see the project architecture)"
]
},
{
"cell_type": "code",
"source": [
"import os\n",
"os.chdir(os.path.join(os.getcwd(), '../mecapp'))\n",
"print(os.getcwd())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2) Apply the python imports"
"metadata": {},
"outputs": [],
"source": [
"from __future__ import division # Import floating-point division (1/4=0.25) instead of Euclidian division (1/4=0)\n",
"\n",
"import os\n",
"import sys\n",
"import threading\n",
"import time\n",
"import json\n",
"import uuid\n",
"\n",
"import pprint\n",
"\n",
"import six\n",
"from swagger_client.rest import ApiException\n",
"\n",
"from http import HTTPStatus\n",
"from http.server import BaseHTTPRequestHandler, HTTPServer\n",
"\n",
"try:\n",
" import urllib3\n",
"except ImportError:\n",
" raise ImportError('Swagger python client requires urllib3.')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3) Initialize of the global constants (cell 3)"
"MEC_SANDBOX_URL = 'https://mec-platform2.etsi.org' # MEC Sandbox host/base URL\n",
"MEC_SANDBOX_API_URL = 'https://mec-platform2.etsi.org/sandbox-api/v1' # MEC Sandbox API host/base URL\n",
"PROVIDER = 'Jupyter2024' # Login provider value - To skip authorization: 'github'\n",
"MEC_PLTF = 'mep1' # MEC plateform name. Linked to the network scenario\n",
"LOGGER_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' # Logging format\n",
"STABLE_TIME_OUT = 10 # Timer to wait for MEC Sndbox reaches its stable state (K8S pods in running state)\n",
"LOGIN_TIMEOUT = 3 #30 # Timer to wait for user to authorize from GITHUB\n",
"LISTENER_IP = '0.0.0.0' # Listener IPv4 address for notification callback calls\n",
"LISTENER_PORT = 31111 # Listener IPv4 port for notification callback calls. Default: 36001\n",
"CALLBACK_URI = 'http://mec-platform2.etsi.org:31111/sandbox/v1'\n",
" #'https://yanngarcia.ddns.net:' + str(LISTENER_PORT) + '/jupyter/sandbox/demo6/v1/'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4) Setup the logger instance and the HTTP REST API (cell 4)"
"metadata": {},
"outputs": [],
"source": [
"# Initialize the logger\n",
"logger = logging.getLogger(__name__)\n",
"logger.setLevel(logging.DEBUG)\n",
"logging.basicConfig(filename='/tmp/' + time.strftime('%Y%m%d-%H%M%S') + '.log')\n",
"l = logging.StreamHandler()\n",
"l.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))\n",
"logger.addHandler(l)\n",
"\n",
"# Setup the HTTP REST API configuration to be used to send request to MEC Sandbox API \n",
"configuration.verify_ssl = True\n",
"configuration.debug = True\n",
"configuration.logger_format = LOGGER_FORMAT\n",
"# Create an instance of ApiClient\n",
"sandbox_api = swagger_client.ApiClient(configuration, 'Content-Type', 'application/json')\n",
"\n",
"# Setup the HTTP REST API configuration to be used to send request to MEC Services\n",
"configuration1 = swagger_client.Configuration()\n",
"configuration1.host = MEC_SANDBOX_URL\n",
"configuration1.verify_ssl = True\n",
"configuration1.debug = True\n",
"configuration1.logger_format = LOGGER_FORMAT\n",
"# Create an instance of ApiClient\n",
"service_api = swagger_client.ApiClient(configuration1, 'Content-Type', 'application/json')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"5) Setup the global variables (cell 5)"
]
},
{
"cell_type": "code",
Loading
Loading full blame…