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