Skip to content
MEC application.ipynb 208 KiB
Newer Older
Yann Garcia's avatar
Yann Garcia committed
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to develop a MEC application using the MEC Sandbox HTTP REST API\n",
Yann Garcia's avatar
Yann Garcia committed
    "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",
    "<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>"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "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",
Yann Garcia's avatar
Yann Garcia committed
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "    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",
Yann Garcia's avatar
Yann Garcia committed
    "## 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",
Yann Garcia's avatar
Yann Garcia committed
    "\n",
Yann Garcia's avatar
Yann Garcia committed
    "The project architecture is describe [here](images/project_arch.jpg).\n",
Yann Garcia's avatar
Yann Garcia committed
    "\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"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before going to create our MEC application skeleton, the following steps shall be done:\n",
Yann Garcia's avatar
Yann Garcia committed
    "1) Change the working directory (see the project architecture)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
Yann Garcia's avatar
Yann Garcia committed
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
Yann Garcia's avatar
Yann Garcia committed
   "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"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
Yann Garcia's avatar
Yann Garcia committed
   "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",
Yann Garcia's avatar
Yann Garcia committed
    "import logging\n",
    "import threading\n",
Yann Garcia's avatar
Yann Garcia committed
    "import time\n",
    "import json\n",
    "import uuid\n",
    "\n",
    "import pprint\n",
    "\n",
    "import six\n",
Yann Garcia's avatar
Yann Garcia committed
    "\n",
    "import swagger_client\n",
Yann Garcia's avatar
Yann Garcia committed
    "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"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3) Initialize of the global constants (cell 3)"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
Yann Garcia's avatar
Yann Garcia committed
   "metadata": {},
   "outputs": [],
   "source": [
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "                                                                             #'https://yanngarcia.ddns.net:' + str(LISTENER_PORT) + '/jupyter/sandbox/demo6/v1/'"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4) Setup the logger instance and the HTTP REST API (cell 4)"
Yann Garcia's avatar
Yann Garcia committed
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
Yann Garcia's avatar
Yann Garcia committed
   "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",
Yann Garcia's avatar
Yann Garcia committed
    "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",
Yann Garcia's avatar
Yann Garcia committed
    "configuration               = swagger_client.Configuration()\n",
Yann Garcia's avatar
Yann Garcia committed
    "configuration.host          = MEC_SANDBOX_API_URL\n",
    "configuration.verify_ssl    = True\n",
Yann Garcia's avatar
Yann Garcia committed
    "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…