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