Merge "Remove dashboard"
[nonrtric.git] / near-rt-ric-simulator / ric-plt / a1 / a1.py
1 #!/u:sr/bin/env python3
2 import copy
3 import datetime
4 import json
5 import logging
6 #import requests
7
8 from connexion import NoContent
9 from flask import Flask, escape, request, make_response
10 from jsonschema import validate
11 from random import random, choice
12 from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance
13
14 def get_all_policy_identities():
15   if len(request.args) == 0:
16     return(list(policy_instances.keys()), 200)
17   elif 'policyTypeId' in request.args:
18     policyTypeId = request.args.get('policyTypeId')
19     if policyTypeId not in list(policy_types.keys()):
20       return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + data["policyTypeId"] + " is not defined as a policy type.", None, None, "policyTypeId", None))
21     else:
22       return(list({key for key in policy_instances.keys() if policy_type_per_instance[key]==policyTypeId}), 200)
23   else:
24     return(send_error_code(request.args))
25
26 def put_policy(policyId):
27   data = request.data.decode("utf-8")
28   data = data.replace("'", "\"")
29   data = json.loads(data)
30   ps = {}
31   if 'policyTypeId' in request.args:
32     policyTypeId = request.args.get('policyTypeId')
33
34     if policyTypeId not in list(policy_types.keys()):
35       return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + policyTypeId + " is not defined as a policy type.", None, None, "policyTypeId", None))
36
37     policy_schema = policy_types[policyTypeId]["policySchema"]
38     try:
39       validate(instance=data, schema=policy_schema)
40     except:
41       return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None, None))
42
43     for i in list(policy_instances.keys()):
44       if policyId != i and \
45          data == policy_instances[i] and \
46          policyTypeId == policy_type_per_instance[i]:
47         return(set_error(None, "The policy already exists with a different id.", 400, "No action has been taken. The id of the existing policy instance is: " + i + ".", None, None, None, None))
48
49   if policyId in list(policy_instances.keys()):
50     if data["scope"] != policy_instances[policyId]["scope"]:
51       return(set_error(None, "The policy already exists with a different scope.", 400, "The policy put involves a modification of the existing scope, which is not allowed.", None, None, "scope", None))
52
53   if 'code' in request.args:
54     return(send_error_code(request.args))
55
56   if policyId in policy_instances.keys():
57     code = 201
58   else:
59     code = 200
60
61   policy_instances[policyId] = data
62   policy_status[policyId] = set_status("UNDEFINED")
63   if 'policyTypeId' in request.args:
64     status_schema = policy_types[policyTypeId]["statusSchema"]
65     try:
66       validate(instance=policy_status[policyId], schema=status_schema)
67     except:
68       return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
69     policy_type_per_instance[policyId] = policyTypeId
70   else:
71     policy_type_per_instance[policyId] = "UNDEFINED"
72
73   response = make_response(policy_instances[policyId], code)
74   if code == 201:
75     response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
76   return response
77
78 def set_status(*args):
79   ps = {}
80   ps["enforceStatus"] = args[0]
81   if len(args) == 2:
82     ps["enforceReason"] = args[1]
83   if len(args) > 2:
84     return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
85   return ps
86
87 def get_policy(policyId):
88   if len(request.args) == 0:
89     if policyId in policy_instances.keys():
90       res = policy_instances[policyId]
91       res["enforceStatus"] = policy_status[policyId]["enforceStatus"]
92       return(res, 200)
93     else:
94       return(set_error(None, "The requested policy does not exist.", 404, None, None, None, "policyId", None))
95   else:
96     return(send_error_code(request.args))
97
98 def delete_policy(policyId):
99   if len(request.args) == 0:
100     if policyId in policy_instances.keys():
101       policy_instances.pop(policyId)
102       policy_status.pop(policyId)
103       policy_type_per_instance.pop(policyId)
104       return(None, 204)
105     else:
106       return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
107   else:
108     return(send_error_code(request.args))
109
110 def get_policy_status(policyId):
111   if len(request.args) == 0:
112     if policyId in policy_instances.keys():
113       return(policy_status[policyId], 200)
114     else:
115       return(set_error(None, "The policy identity does not exist.", 404, "There is no existing policy instance with the identity: " + policyId, None, None, "policyId", None))
116   else:
117     return(send_error_code(request.args))
118
119 def get_all_policytypes_identities():
120   if len(request.args) == 0:
121     return(list(policy_types.keys()), 200)
122   else:
123     return(send_error_code(request.args))
124
125 def get_policytypes(policyTypeId):
126   if len(request.args) == 0:
127     if policyTypeId in policy_types.keys():
128       return(policy_types[policyTypeId], 200)
129     else:
130       return(set_error(None, "The requested policy type does not exist.", 404, None, None, None, "policyTypeId", None))
131   else:
132     return(send_error_code(request.args))
133
134 def set_error(type_of, title, status, detail, instance, cause, param, reason):
135   error = {}
136   params = {}
137   if type_of is not None:
138     error["type"] = type_of
139   if title is not None:
140     error["title"] = title
141   if status is not None:
142     error["status"] = status
143   if detail is not None:
144     error["detail"] = detail
145   if instance is not None:
146     error["instance"] = instance
147   if cause is not None:
148     error["cause"] = cause
149   if param is not None:
150     params["param"] = param
151   if reason is not None:
152     params["reason"] = reason
153   if params:
154     error["invalidParams"] = params
155   return(error, error["status"])
156
157 def send_error_code(args):
158   if 'code' in args.keys():
159     code = args['code']
160     if code == '405':
161       return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
162     elif code == '429':
163       return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
164     elif code == '507':
165       return(set_error(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, None, None, None))
166     elif code == '503':
167       return(set_error(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None, None, None, None))
168     else:
169       return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))
170   else:
171     return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))