d234327a562bc180e248cc215d04d287527e16b7
[sim/a1-interface.git] / near-rt-ric-simulator / src / STD_1.1.3 / a1.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 copy
19 import datetime
20 import json
21 import logging
22 import collections
23 import time
24
25 from connexion import NoContent
26 from flask import Flask, escape, request, Response, make_response
27 from var_declaration import policy_instances, policy_status, callbacks, forced_settings, policy_fingerprint, hosts_set
28 from utils import calcFingerprint
29 from maincommon import *
30
31 # API Function: Get all policy ids
32 def get_all_policy_identities():
33
34
35   if ((r := check_modified_response()) is not None):
36     return r
37
38   return (list(policy_instances.keys()), 200)
39
40 # API Function: Create or update a policy
41 def put_policy(policyId):
42
43   extract_host_name(hosts_set, request)
44
45   if ((r := check_modified_response()) is not None):
46     return r
47
48   try:
49     data = request.data
50     data = json.loads(data)
51   except:
52     pjson=create_problem_json(None, "The policy is corrupt or missing.", 400, None, policyId)
53     return Response(json.dumps(pjson), 400, mimetype='application/problem+json')
54
55   fpPrevious=None
56   retcode=201
57   if policyId in policy_instances.keys():
58     retcode=200
59     fpPrevious=calcFingerprint(policy_instances[policyId])
60
61   fp=calcFingerprint(data)
62   if (fp in policy_fingerprint.keys()):
63     id=policy_fingerprint[fp]
64     if (id != policyId):
65       pjson=create_problem_json(None, "The policy json already exists.", 400, None, policyId)
66       return Response(json.dumps(pjson), 400, mimetype='application/problem+json')
67
68   if (fpPrevious is not None):
69     del policy_fingerprint[fpPrevious]
70
71   policy_fingerprint[fp]=policyId
72
73   noti=request.args.get('notificationDestination')
74   callbacks[policyId]=noti
75
76   policy_instances[policyId]=data
77   ps={}
78   ps["enforceStatus"] = "UNDEFINED"
79   policy_status[policyId]=ps
80
81   if (retcode == 200):
82     return Response(json.dumps(data), 200, mimetype='application/json')
83   else:
84     headers={}
85     headers['Location']='/A1-P/v1/policies/' + policyId
86     return Response(json.dumps(data), 201, headers=headers, mimetype='application/json')
87
88 # API Function: Get a policy
89 def get_policy(policyId):
90
91   extract_host_name(hosts_set, request)
92
93   if ((r := check_modified_response()) is not None):
94     return r
95
96   if policyId in policy_instances.keys():
97     return Response(json.dumps(policy_instances[policyId]), 200, mimetype='application/json')
98
99   pjson=create_problem_json(None, "The requested policy does not exist.", 404, None, policyId)
100   return Response(json.dumps(pjson), 404, mimetype='application/problem+json')
101
102 # API Function: Delete a policy
103 def delete_policy(policyId):
104
105   extract_host_name(hosts_set, request)
106
107   if ((r := check_modified_response()) is not None):
108     return r
109
110   if policyId in policy_instances.keys():
111     fpPrevious=calcFingerprint(policy_instances[policyId])
112     policy_fingerprint.pop(fpPrevious)
113     policy_instances.pop(policyId)
114     policy_status.pop(policyId)
115     callbacks.pop(policyId)
116     return Response('', 204, mimetype='application/json')
117
118   pjson=create_problem_json(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", policyId)
119   return Response(json.dumps(pjson), 404, mimetype='application/problem+json')
120
121 # API Function: Get status for a policy
122 def get_policy_status(policyId):
123
124   extract_host_name(hosts_set, request)
125
126   if ((r := check_modified_response()) is not None):
127     return r
128
129   if policyId in policy_instances.keys():
130     return Response(json.dumps(policy_status[policyId]), status=200, mimetype='application/json')
131
132   pjson=create_problem_json(None, "The policy identity does not exist.", 404, "There is no existing policy instance with the identity: " + policyId, policyId)
133   return Response(json.dumps(pjson), 404, mimetype='application/problem+json')
134
135 # Helper: Create a response object if forced http response code is set
136 def get_forced_response():
137   if (forced_settings['code'] is not None):
138     pjson=create_error_response(forced_settings['code'])
139     forced_settings['code']=None
140     return Response(json.dumps(pjson), pjson['status'], mimetype='application/problem+json')
141   return None
142
143 # Helper: Delay if delayed response code is set
144 def do_delay():
145   if (forced_settings['delay'] is not None):
146     try:
147       val=int(forced_settings['delay'])
148       time.sleep(val)
149     except:
150       return
151   return
152
153 # Helper: Check if response shall be delayed or a forced response shall be sent
154 def check_modified_response():
155   do_delay()
156   return get_forced_response()
157
158 # Helper: Create a problem json object
159 def create_problem_json(type_of, title, status, detail, instance):
160
161   error = {}
162   if type_of is not None:
163     error["type"] = type_of
164   if title is not None:
165     error["title"] = title
166   if status is not None:
167     error["status"] = status
168   if detail is not None:
169     error["detail"] = detail
170   if instance is not None:
171     error["instance"] = instance
172   return error
173
174 # Helper: Create a problem json based on a generic http response code
175 def create_error_response(code):
176
177     if code == '400':
178       return(create_problem_json(None, "Bad request", 400, "Object in payload not properly formulated or not related to the method", None))
179     elif code == '404':
180       return(create_problem_json(None, "Not found", 404, "No resource found at the URI", None))
181     elif code == '405':
182       return(create_problem_json(None, "Method not allowed", 405, "Method not allowed for the URI", None))
183     elif code == '409':
184       return(create_problem_json(None, "Conflict", 409, "Request could not be processed in the current state of the resource", None))
185     elif code == '429':
186       return(create_problem_json(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None))
187     elif code == '507':
188       return(create_problem_json(None, "Insufficient storage", 507, "The method could not be performed on the resource because the provider is unable to store the representation needed to successfully complete the request", None))
189     elif code == '503':
190       return(create_problem_json(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None))
191     else:
192       return(create_problem_json(None, "Unknown", code, "Not implemented response code", None))