7db215a0225f5f48b4b94e755739b3e5544af281
[sim/a1-interface.git] / near-rt-ric-simulator / src / STD_1.1.3 / main.py
1 #  ============LICENSE_START===============================================
2 #  Copyright (C) 2021 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
25 from pathlib import Path
26 from flask import Flask, escape, request, Response
27 from jsonschema import validate
28 from var_declaration import policy_instances, policy_status, callbacks, forced_settings, policy_fingerprint, hosts_set, app
29 from maincommon import check_apipath, apipath, get_supported_interfaces_response, extract_host_name
30
31 #Constants
32 TEXT_PLAIN='text/plain'
33
34 check_apipath()
35
36 # app is created in var_declarations
37
38 import payload_logging   # app var need to be initialized
39
40 #Check alive function
41 @app.route('/', methods=['GET'])
42 def test():
43
44   return Response("OK", 200, mimetype=TEXT_PLAIN)
45
46 #Return the current and all supported yamls for the this container
47 @app.route('/container_interfaces', methods=['GET'])
48 def container_interfaces():
49
50     return get_supported_interfaces_response()
51
52 #Delete all created instances and status
53 @app.route('/deleteinstances', methods=['POST'])
54 def delete_instances():
55
56   policy_instances.clear()
57   policy_status.clear()
58   callbacks.clear()
59   forced_settings['code']=None
60   forced_settings['delay']=None
61   policy_fingerprint.clear()
62   return Response("All policy instances deleted", 200, mimetype=TEXT_PLAIN)
63
64 #Delete all - all reset
65 #(same as delete_instances but kept to in order to use the same interface as other version of the simulator)
66 @app.route('/deleteall', methods=['POST'])
67 def delete_all():
68   return delete_instances()
69
70 #Set force response for one A1 response
71 #/forceresponse?code=<responsecode>
72 @app.route('/forceresponse', methods=['POST'])
73 def forceresponse():
74
75   try:
76     forced_settings['code']=request.args.get('code')
77   except Exception:
78     forced_settings['code']=None
79   return Response("Force response code: " + str(forced_settings['code']) + " set for one single A1 response", 200, mimetype=TEXT_PLAIN)
80
81 #Set force delay response, in seconds, for all A1 responses
82 #/froceesponse?delay=<seconds>
83 @app.route('/forcedelay', methods=['POST'])
84 def forcedelay():
85
86   try:
87     forced_settings['delay']=request.args.get('delay')
88   except Exception:
89     forced_settings['delay']=None
90   return Response("Force delay: " + str(forced_settings['delay']) + " sec set for all A1 responses", 200, mimetype=TEXT_PLAIN)
91
92
93 #Set status and reason
94 #/status?policyid=<policyid>&status=<status>[&reason=<reason>]
95 @app.route('/status', methods=['PUT'])
96 def setstatus():
97
98   policy_id=request.args.get('policyid')
99   if (policy_id is None):
100     return Response('Parameter <policyid> missing in request', status=400, mimetype=TEXT_PLAIN)
101   if policy_id not in policy_instances.keys():
102     return Response('Policyid: '+policy_id+' not found.', status=404, mimetype=TEXT_PLAIN)
103   status=request.args.get('status')
104   if (status is None):
105     return Response('Parameter <status> missing in request', status=400, mimetype=TEXT_PLAIN)
106   reason=request.args.get('reason')
107   ps = {}
108   ps["enforceStatus"] = status
109   msg="Status set to "+status
110   if (reason is not None):
111     ps["enforceReason"] = reason
112     msg=msg+" and "+reason
113   policy_status[policy_id] = ps
114   msg=msg+" for policy: " + policy_id
115   return Response(msg, 200, mimetype=TEXT_PLAIN)
116
117 #Send status
118 #/status?policyid=<policyid>
119 @app.route('/sendstatus', methods=['POST'])
120 def sendstatus():
121   policyid=request.args.get('policyid')
122   if (policyid is None):
123     return Response('Parameter <policyid> missing in request', status=400, mimetype=TEXT_PLAIN)
124
125   if (policyid not in policy_status.keys()):
126     return Response('Policyid: '+policyid+' not found.', status=404, mimetype=TEXT_PLAIN)
127
128   ps=policy_status[policyid]
129   cb=callbacks[policyid]
130   try:
131     resp=requests.post(cb,json=json.dumps(ps), verify=False) # NOSONAR
132   except Exception:
133     return Response('Post status failed, could not send to: '+str(cb), status=500, mimetype=TEXT_PLAIN)
134   if (resp.status_code<199 & resp.status_code > 299):
135     return Response('Post status failed with code: '+resp.status_code, status=500, mimetype=TEXT_PLAIN)
136
137   data = resp.json()
138   return Response(data, 200, mimetype='application/json')
139
140 #Receive status (only for testing callbacks)
141 #/statustest
142 @app.route('/statustest', methods=['POST', 'PUT'])
143 def statustest():
144   try:
145     data = request.data
146     data = json.loads(data)
147   except Exception:
148     return Response("The status data is corrupt or missing.", 400, mimetype=TEXT_PLAIN)
149
150   return Response(json.dumps(data), 200, mimetype='application/json')
151
152 #Metrics function
153 #Get a named counter
154 @app.route('/counter/<string:countername>', methods=['GET'])
155 def getcounter(countername):
156
157   if (countername == "num_instances"):
158     return Response(str(len(policy_instances)), 200, mimetype=TEXT_PLAIN)
159   elif (countername == "num_types"):
160     return Response("0",200, mimetype=TEXT_PLAIN)
161   elif (countername == "interface"):
162     p=Path(os.getcwd())
163     pp=p.parts
164     return Response(str(pp[len(pp)-1]),200, mimetype=TEXT_PLAIN)
165   elif (countername == "remote_hosts"):
166     hosts=",".join(hosts_set)
167     return str(hosts),200
168   elif (countername == "datadelivery"):
169     return Response(str(0),200, mimetype=TEXT_PLAIN)
170   else:
171     return Response("Counter name: "+countername+" not found.",404, mimetype=TEXT_PLAIN)
172
173 port_number = 2222
174 if len(sys.argv) >= 2:
175   if isinstance(sys.argv[1], int):
176     port_number = sys.argv[1]
177
178 app.add_api('STD_A1.yaml')
179
180 if __name__ == '__main__':
181   app.run(port=port_number, host="127.0.0.1", threaded=False)