Fix two bugs in simulator & code cleaning
[sim/a1-interface.git] / near-rt-ric-simulator / src / OSC_2.1.0 / main.py
1 #  ============LICENSE_START===============================================
2 #  Copyright (C) 2020 Nordix Foundation. All rights reserved.
3 #  ========================================================================
4 #  Licensed under the Apache License, Version 2.0 (the "License");
5 #  you may not use this file except in compliance with the License.
6 #  You may obtain a copy of the License at
7 #
8 #       http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #  Unless required by applicable law or agreed to in writing, software
11 #  distributed under the License is distributed on an "AS IS" BASIS,
12 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 #  See the License for the specific language governing permissions and
14 #  limitations under the License.
15 #  ============LICENSE_END=================================================
16 #
17
18 import connexion
19 import json
20 import sys
21 import os
22 import requests
23
24 from pathlib import Path
25 from flask import Flask, escape, request, Response, jsonify
26 from jsonschema import validate
27 from var_declaration import policy_instances, policy_types, policy_status, policy_fingerprint, forced_settings, hosts_set
28 from maincommon import *
29 from time import sleep
30
31
32 check_apipath()
33
34 app = connexion.FlaskApp(__name__, specification_dir=apipath)
35
36 #Check alive function
37 @app.route('/', methods=['GET'])
38 def test():
39
40     return Response("OK", 200, mimetype='text/plain')
41
42 @app.route('/ip', methods=['GET'])
43 def get_ip():
44     if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
45         return jsonify({'ip': request.environ['REMOTE_ADDR']}), 200
46     else:
47         return jsonify({'ip': request.environ['HTTP_X_FORWARDED_FOR']}), 200
48
49 #Return the current and all supported yamls for the this container
50 @app.route('/container_interfaces', methods=['GET'])
51 def container_interfaces():
52
53     return get_supported_interfaces_response()
54
55 #Delete all created instances and status
56 @app.route('/deleteinstances', methods=['POST'])
57 def deleteinstances():
58
59   for i in policy_instances.keys():
60     policy_instances[i]={}
61
62   policy_status.clear()
63   forced_settings.clear()
64   forced_settings['code']=None
65   forced_settings['delay']=None
66   policy_fingerprint.clear()
67   return Response("All policy instances deleted", 200, mimetype='text/plain')
68
69 #Delete all - all reset
70 @app.route('/deleteall', methods=['POST'])
71 def deleteall():
72
73   policy_instances.clear()
74   policy_types.clear()
75   policy_status.clear()
76   forced_settings['code']=None
77   forced_settings['delay']=None
78   policy_fingerprint.clear()
79   return Response("All policy instances and types deleted", 200, mimetype='text/plain')
80
81 #Load a policy type
82 @app.route('/policytype', methods=['PUT'])
83 def policytype():
84
85   policyTypeId=request.args.get('id')
86   if (policyTypeId is None):
87     return Response('Parameter <id> missing in request', status=400, mimetype='text/plain')
88   try:
89     val=int(policyTypeId)
90   except:
91     return Response("The policy type id is not an int", 400, mimetype='text/plain')
92   try:
93     data = request.data
94     data = json.loads(data)
95   except:
96     return Response("The policy type is corrupt or missing", 400, mimetype='text/plain')
97
98   if ('name' not in data.keys() or 'description' not in data.keys() or 'policy_type_id' not in data.keys() or'create_schema' not in data.keys()):
99     return Response("The policy type missing atributes", 400, mimetype='text/plain')
100
101   retcode=201
102   if (policyTypeId in policy_types.keys()):
103     retcode=200
104     if (len(policy_instances[policyTypeId]) > 0):
105       return Response("The policy type already exists and instances exists", 400, mimetype='text/plain')
106
107   policy_types[policyTypeId]=data
108   policy_instances[policyTypeId]={}
109   return Response("Policy type " + policyTypeId + " is OK.", retcode, mimetype='text/plain')
110
111 #Delete a policy type
112 @app.route('/policytype', methods=['DELETE'])
113 def del_policytype():
114
115   policyTypeId=request.args.get('id')
116   if (policyTypeId is None):
117     return Response('Parameter <id> missing in request', status=400, mimetype='text/plain')
118   try:
119     val=int(policyTypeId)
120   except:
121     return Response("The policy type id is not an int", 400, mimetype='text/plain')
122
123   if (policyTypeId in policy_types.keys()):
124     if (len(policy_instances[policyTypeId]) > 0):
125       return Response("The policy type already exists and instances exists", 400, mimetype='text/plain')
126
127     del policy_types[policyTypeId]
128     del policy_instances[policyTypeId]
129     return Response("Policy type " + policyTypeId + " is OK.", 204, mimetype='text/plain')
130
131   return Response("Policy type " + policyTypeId + " not found.", 204, mimetype='text/plain')
132
133
134 # Get all policy type ids
135 @app.route('/policytypes', methods=['GET'])
136 def get_policytype_ids():
137
138   return (json.dumps(list(policy_instances.keys())), 200)
139
140 #Set force response for one A1 response
141 #/forceresponse?code=<responsecode>
142 @app.route('/forceresponse', methods=['POST'])
143 def forceresponse():
144
145   try:
146     forced_settings['code']=int(request.args.get('code'))
147   except:
148     forced_settings['code']=None
149   return Response("Force response code: " + str(forced_settings['code']) + " set for one single A1 response", 200, mimetype='text/plain')
150
151 #Set force delay response, in seconds, for all A1 responses
152 #/froceesponse?delay=<seconds>
153 @app.route('/forcedelay', methods=['POST'])
154 def forcedelay():
155
156   try:
157     forced_settings['delay']=int(request.args.get('delay'))
158   except:
159     forced_settings['delay']=None
160   return Response("Force delay: " + str(forced_settings['delay']) + " sec set for all A1 responses", 200, mimetype='text/plain')
161
162
163 #Set status and reason
164 #/status?policyid=<policyid>&status=<status>[&deleted=<boolean>][&created_at=<timestamp>]
165 @app.route('/status', methods=['PUT'])
166 def setstatus():
167
168   policyId=request.args.get('policyid')
169   if (policyId is None):
170     return Response('Parameter <policyid> missing in request', status=400, mimetype='text/plain')
171
172   if policyId not in policy_status.keys():
173     return Response('Policyid: '+policyId+' not found.', status=404, mimetype='text/plain')
174   status=request.args.get('status')
175   if (status is None):
176     return Response('Parameter <status> missing in request', status=400, mimetype='text/plain')
177   policy_status[policyId]["instance_status"]=status
178   msg = "Status set to "+status
179   deleted_policy=request.args.get('deleted')
180   if (deleted_policy is not None):
181     policy_status[policyId]["has_been_deleted"]=deleted_policy
182     msg = msg + " and has_been_deleted set to "+deleted_policy
183   created_at = request.args.get('created_at')
184   if (created_at is not None):
185     policy_status[policyId]["created_at"]=created_at
186     msg = msg + " and created_at set to "+created_at
187   msg=msg + " for policy: " + policyId
188   return Response(msg, 200, mimetype='text/plain')
189
190
191 #Metrics function
192 #Get a named counter
193 @app.route('/counter/<string:countername>', methods=['GET'])
194 def getCounter(countername):
195
196   if (countername == "num_instances"):
197     return Response(str(len(policy_fingerprint)), 200, mimetype='text/plain')
198   elif (countername == "num_types"):
199     return Response(str(len(policy_instances)),200, mimetype='text/plain')
200   elif (countername == "interface"):
201     p=Path(os.getcwd())
202     pp=p.parts
203     return Response(str(pp[len(pp)-1]),200, mimetype='text/plain')
204   elif (countername == "remote_hosts"):
205     hosts=",".join(hosts_set)
206     return str(hosts),200
207   else:
208     return Response("Counter name: "+countername+" not found.",404, mimetype='text/plain')
209
210 port_number = 2222
211 if len(sys.argv) >= 2:
212   if isinstance(sys.argv[1], int):
213     port_number = sys.argv[1]
214
215 app.add_api('openapi.yaml')
216
217 app.run(port=port_number, host="127.0.0.1", threaded=False)