--- /dev/null
+# Copyright (c) 2019 AT&T Intellectual Property. #\r
+# #\r
+# Licensed under the Apache License, Version 2.0 (the "License"); #\r
+# you may not use this file except in compliance with the License. #\r
+# You may obtain a copy of the License at #\r
+# #\r
+# http://www.apache.org/licenses/LICENSE-2.0 #\r
+# #\r
+# Unless required by applicable law or agreed to in writing, software #\r
+# distributed under the License is distributed on an "AS IS" BASIS, #\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #\r
+# See the License for the specific language governing permissions and #\r
+# limitations under the License. #\r
+################################################################################\r
+# File name: a1-mediator-vth.py #\r
+# Description: vth for a1-mediator-vth service #\r
+# Date created: 08/22/2019 #\r
+# Last modified: 04/02/2020 #\r
+# Python Version: 3.7.4 #\r
+# Author: Jackie Chen (jv246a) #\r
+# Email: jv246a@att.com #\r
+################################################################################\r
+import datetime\r
+import json\r
+import logging\r
+from logging import FileHandler\r
+import os\r
+\r
+import requests\r
+from flask import Flask, request, jsonify\r
+\r
+# redirect http to https\r
+app = Flask(__name__)\r
+\r
+# Prevents print statement every time an endpoint is triggered.\r
+logging.getLogger("werkzeug").setLevel(logging.WARNING)\r
+\r
+\r
+def sendCallback(url, data):\r
+ try:\r
+ if type(data) is not dict:\r
+ data = {"msg": data}\r
+ app.logger.info("sending callback")\r
+ requests.post(url, json=data)\r
+ except Exception as e:\r
+ app.logger.info(e)\r
+ return\r
+\r
+def unix_time_millis(dt):\r
+ epoch = datetime.datetime.utcfromtimestamp(0)\r
+ return (dt - epoch).total_seconds() * 1000.0\r
+\r
+\r
+@app.route("/otf/vth/oran/a1/v1/health", methods=['GET'])\r
+def getHealth():\r
+ return "UP"\r
+\r
+\r
+@app.route("/otf/vth/oran/a1/v1", methods=['POST'])\r
+def executeRicRequest():\r
+ response_data = {\r
+ 'vthResponse': {\r
+ 'testDuration': '',\r
+ 'dateTimeUTC': str(datetime.datetime.now()),\r
+ 'abstractMessage': '',\r
+ 'resultData': {}\r
+ }\r
+ }\r
+\r
+ startTime = unix_time_millis(datetime.datetime.now())\r
+ ret_url = request.args.get('retURL')\r
+ try:\r
+ if not request.is_json:\r
+ raise ValueError("request must be json")\r
+\r
+ requestData = request.get_json()\r
+\r
+ app.logger.info("A1 requestData:" + str(requestData))\r
+\r
+ action = requestData['action'].lower()\r
+ _check_incoming_request(requestData)\r
+\r
+ os.environ['NO_PROXY'] = '127.0.0.1' # TODO testing purpose w/ mock server. Needs to remove on final version\r
+ with open('config.json') as configFile:\r
+ config = json.load(configFile)\r
+\r
+ baseAddress = config['base_address']\r
+ if action == 'health_check' or action == 'list_policy':\r
+ res = requests.get(baseAddress + config['actions_path'][action])\r
+ response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+ if action == 'health_check':\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+ else:\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+ elif action == 'list_policy_instance':\r
+ res = requests.get(baseAddress + config['actions_path'][action]\r
+ .format(policy_type_id=requestData['policy_type_id']))\r
+ response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+ elif action == 'get_policy_instance_status':\r
+ res = requests.get(baseAddress + config['actions_path'][action]\r
+ .format(policy_type_id=requestData['policy_type_id'],\r
+ policy_instance_id=requestData['policy_instance_id']))\r
+ response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+ elif action == 'edit_policy':\r
+ res = _send_edit_request(requestData, config)\r
+ response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+ if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+ else:\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+ elif action == 'edit_policy_instance':\r
+ res = _send_edit_request(requestData, config)\r
+ response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
+ if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
+ else:\r
+ response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
+\r
+ except Exception as ex:\r
+ endTime = unix_time_millis(datetime.datetime.now())\r
+ totalTime = endTime - startTime\r
+ response_data['vthResponse']['testDuration'] = totalTime\r
+ response_data['vthResponse']['abstractMessage'] = str(ex)\r
+ return jsonify(response_data)\r
+\r
+ endTime = unix_time_millis(datetime.datetime.now())\r
+ totalTime = endTime - startTime\r
+\r
+ response_data['vthResponse']['testDuration'] = totalTime\r
+\r
+ if ret_url is not None:\r
+ sendCallback(ret_url, response_data)\r
+ return '', 200\r
+\r
+ return jsonify(response_data), 200\r
+\r
+\r
+def _send_edit_request(request_data, config):\r
+ baseAddress = config['base_address']\r
+ path = ''\r
+ action = request_data['action']\r
+ policy_type_id = request_data['policy_type_id']\r
+ request_type = request_data['request_type']\r
+ if action == "edit_policy":\r
+ path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id)\r
+ if action == 'edit_policy_instance':\r
+ instance_id = request_data['policy_instance_id']\r
+ path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id,\r
+ policy_instance_id=instance_id)\r
+ if request_type == 'get':\r
+ return requests.get(path)\r
+ if request_type == 'put':\r
+ payload = request_data['payload']\r
+ return requests.put(path, payload)\r
+ if request_type == 'delete':\r
+ return requests.delete(path)\r
+\r
+\r
+def _check_incoming_request(requestData): # check if the request is valid\r
+ if 'action' not in requestData:\r
+ raise KeyError('no action was specify')\r
+\r
+ action = requestData['action'].lower()\r
+ edit_actions = ['edit_policy', 'edit_policy_instance']\r
+ requires_policy_id = ['edit_policy', 'list_policy_instance'\r
+ , 'edit_policy_instance', 'get_policy_instance_status']\r
+ requires_policy_instance_id = ['edit_policy_instance', 'get_policy_instance_status']\r
+ possible_actions = ['health_check', 'list_policy', 'edit_policy', 'list_policy_instance'\r
+ , 'edit_policy_instance', 'get_policy_instance_status']\r
+ possible_request_type = ['get', 'put', 'delete']\r
+\r
+ if action not in possible_actions:\r
+ raise KeyError("invalid action")\r
+ if action in edit_actions: # request type is required\r
+ if 'request_type' not in requestData:\r
+ raise KeyError('this action: ' + action + ' requires a request type')\r
+ if requestData['request_type'] not in possible_request_type:\r
+ raise KeyError('this request_type: ' + requestData['request_type'] + ' is not valid')\r
+ if requestData['request_type'] == 'put' and 'payload' not in requestData:\r
+ raise KeyError('put request requires a payload')\r
+ if action in requires_policy_id:\r
+ if 'policy_type_id' not in requestData:\r
+ raise KeyError('this action: ' + action + ' requires a policy_type_id')\r
+ if action in requires_policy_instance_id:\r
+ if 'policy_instance_id' not in requestData:\r
+ raise KeyError('this action: ' + action + ' requires a policy_instance_id')\r
+\r
+\r
+if __name__ == '__main__':\r
+ logHandler = FileHandler('a1-mediator-vth.log', mode='a')\r
+ logHandler.setLevel(logging.INFO)\r
+ app.logger.setLevel(logging.INFO)\r
+ app.logger.addHandler(logHandler)\r
+ # context = ('opt/cert/otf.pem', 'opt/cert/privateKey.pem')\r
+ # app.run(debug = False, host = '0.0.0.0', port = 5000, ssl_context = context)\r
+ app.run(debug=False, host='0.0.0.0', port=5000)\r