added new vths(smo,a1-mediator,dmaap)
[it/otf.git] / a1-mediator-vth / a1-mediator-vth.py
1 #   Copyright (c) 2019 AT&T Intellectual Property.                             #\r
2 #                                                                              #\r
3 #   Licensed under the Apache License, Version 2.0 (the "License");            #\r
4 #   you may not use this file except in compliance with the License.           #\r
5 #   You may obtain a copy of the License at                                    #\r
6 #                                                                              #\r
7 #       http://www.apache.org/licenses/LICENSE-2.0                             #\r
8 #                                                                              #\r
9 #   Unless required by applicable law or agreed to in writing, software        #\r
10 #   distributed under the License is distributed on an "AS IS" BASIS,          #\r
11 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
12 #   See the License for the specific language governing permissions and        #\r
13 #   limitations under the License.                                             #\r
14 ################################################################################\r
15 # File name: a1-mediator-vth.py                                                         #\r
16 # Description: vth for a1-mediator-vth service                                              #\r
17 # Date created: 08/22/2019                                                     #\r
18 # Last modified: 04/02/2020                                                    #\r
19 # Python Version: 3.7.4                                                        #\r
20 # Author: Jackie Chen (jv246a)                                                 #\r
21 # Email: jv246a@att.com                                                        #\r
22 ################################################################################\r
23 import datetime\r
24 import json\r
25 import logging\r
26 from logging import FileHandler\r
27 import os\r
28 \r
29 import requests\r
30 from flask import Flask, request, jsonify\r
31 \r
32 # redirect http to https\r
33 app = Flask(__name__)\r
34 \r
35 # Prevents print statement every time an endpoint is triggered.\r
36 logging.getLogger("werkzeug").setLevel(logging.WARNING)\r
37 \r
38 \r
39 def sendCallback(url, data):\r
40     try:\r
41         if type(data) is not dict:\r
42             data = {"msg": data}\r
43         app.logger.info("sending callback")\r
44         requests.post(url, json=data)\r
45     except Exception as e:\r
46         app.logger.info(e)\r
47     return\r
48 \r
49 def unix_time_millis(dt):\r
50     epoch = datetime.datetime.utcfromtimestamp(0)\r
51     return (dt - epoch).total_seconds() * 1000.0\r
52 \r
53 \r
54 @app.route("/otf/vth/oran/a1/v1/health", methods=['GET'])\r
55 def getHealth():\r
56     return "UP"\r
57 \r
58 \r
59 @app.route("/otf/vth/oran/a1/v1", methods=['POST'])\r
60 def executeRicRequest():\r
61     response_data = {\r
62         'vthResponse': {\r
63             'testDuration': '',\r
64             'dateTimeUTC': str(datetime.datetime.now()),\r
65             'abstractMessage': '',\r
66             'resultData': {}\r
67         }\r
68     }\r
69 \r
70     startTime = unix_time_millis(datetime.datetime.now())\r
71     ret_url = request.args.get('retURL')\r
72     try:\r
73         if not request.is_json:\r
74             raise ValueError("request must be json")\r
75 \r
76         requestData = request.get_json()\r
77 \r
78         app.logger.info("A1 requestData:" + str(requestData))\r
79 \r
80         action = requestData['action'].lower()\r
81         _check_incoming_request(requestData)\r
82 \r
83         os.environ['NO_PROXY'] = '127.0.0.1'  # TODO testing purpose w/ mock server. Needs to remove on final version\r
84         with open('config.json') as configFile:\r
85             config = json.load(configFile)\r
86 \r
87         baseAddress = config['base_address']\r
88         if action == 'health_check' or action == 'list_policy':\r
89             res = requests.get(baseAddress + config['actions_path'][action])\r
90             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
91             if action == 'health_check':\r
92                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
93             else:\r
94                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
95         elif action == 'list_policy_instance':\r
96             res = requests.get(baseAddress + config['actions_path'][action]\r
97                                .format(policy_type_id=requestData['policy_type_id']))\r
98             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
99             response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
100         elif action == 'get_policy_instance_status':\r
101             res = requests.get(baseAddress + config['actions_path'][action]\r
102                                .format(policy_type_id=requestData['policy_type_id'],\r
103                                        policy_instance_id=requestData['policy_instance_id']))\r
104             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
105             response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
106         elif action == 'edit_policy':\r
107             res = _send_edit_request(requestData, config)\r
108             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
109             if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
110                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
111             else:\r
112                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
113         elif action == 'edit_policy_instance':\r
114             res = _send_edit_request(requestData, config)\r
115             response_data['vthResponse']['resultData']['statusCode'] = res.status_code\r
116             if requestData['request_type'].lower() == 'get' and res.status_code == 200:\r
117                 response_data['vthResponse']['resultData']['resultOutput'] = res.json()\r
118             else:\r
119                 response_data['vthResponse']['resultData']['resultOutput'] = res.text\r
120 \r
121     except Exception as ex:\r
122         endTime = unix_time_millis(datetime.datetime.now())\r
123         totalTime = endTime - startTime\r
124         response_data['vthResponse']['testDuration'] = totalTime\r
125         response_data['vthResponse']['abstractMessage'] = str(ex)\r
126         return jsonify(response_data)\r
127 \r
128     endTime = unix_time_millis(datetime.datetime.now())\r
129     totalTime = endTime - startTime\r
130 \r
131     response_data['vthResponse']['testDuration'] = totalTime\r
132 \r
133     if ret_url is not None:\r
134         sendCallback(ret_url, response_data)\r
135         return '', 200\r
136 \r
137     return jsonify(response_data), 200\r
138 \r
139 \r
140 def _send_edit_request(request_data, config):\r
141     baseAddress = config['base_address']\r
142     path = ''\r
143     action = request_data['action']\r
144     policy_type_id = request_data['policy_type_id']\r
145     request_type = request_data['request_type']\r
146     if action == "edit_policy":\r
147         path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id)\r
148     if action == 'edit_policy_instance':\r
149         instance_id = request_data['policy_instance_id']\r
150         path = baseAddress + config['actions_path'][action].format(policy_type_id=policy_type_id,\r
151                                                                    policy_instance_id=instance_id)\r
152     if request_type == 'get':\r
153         return requests.get(path)\r
154     if request_type == 'put':\r
155         payload = request_data['payload']\r
156         return requests.put(path, payload)\r
157     if request_type == 'delete':\r
158         return requests.delete(path)\r
159 \r
160 \r
161 def _check_incoming_request(requestData):  # check if the request is valid\r
162     if 'action' not in requestData:\r
163         raise KeyError('no action was specify')\r
164 \r
165     action = requestData['action'].lower()\r
166     edit_actions = ['edit_policy', 'edit_policy_instance']\r
167     requires_policy_id = ['edit_policy', 'list_policy_instance'\r
168         , 'edit_policy_instance', 'get_policy_instance_status']\r
169     requires_policy_instance_id = ['edit_policy_instance', 'get_policy_instance_status']\r
170     possible_actions = ['health_check', 'list_policy', 'edit_policy', 'list_policy_instance'\r
171         , 'edit_policy_instance', 'get_policy_instance_status']\r
172     possible_request_type = ['get', 'put', 'delete']\r
173 \r
174     if action not in possible_actions:\r
175         raise KeyError("invalid action")\r
176     if action in edit_actions:  # request type is required\r
177         if 'request_type' not in requestData:\r
178             raise KeyError('this action: ' + action + ' requires a request type')\r
179         if requestData['request_type'] not in possible_request_type:\r
180             raise KeyError('this request_type: ' + requestData['request_type'] + ' is not valid')\r
181         if requestData['request_type'] == 'put' and 'payload' not in requestData:\r
182             raise KeyError('put request requires a payload')\r
183     if action in requires_policy_id:\r
184         if 'policy_type_id' not in requestData:\r
185             raise KeyError('this action: ' + action + ' requires a policy_type_id')\r
186     if action in requires_policy_instance_id:\r
187         if 'policy_instance_id' not in requestData:\r
188             raise KeyError('this action: ' + action + ' requires a policy_instance_id')\r
189 \r
190 \r
191 if __name__ == '__main__':\r
192     logHandler = FileHandler('a1-mediator-vth.log', mode='a')\r
193     logHandler.setLevel(logging.INFO)\r
194     app.logger.setLevel(logging.INFO)\r
195     app.logger.addHandler(logHandler)\r
196     # context = ('opt/cert/otf.pem', 'opt/cert/privateKey.pem')\r
197     # app.run(debug = False, host = '0.0.0.0', port = 5000, ssl_context = context)\r
198     app.run(debug=False, host='0.0.0.0', port=5000)\r