b326d105eb7e0844d0f504ca3791ceb40c8ee51d
[sim/a1-interface.git] / near-rt-ric-simulator / src / 1.1.x-alpha.2 / 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
23 from connexion import NoContent
24 from flask import Flask, escape, request, make_response
25 from jsonschema import validate
26 from random import random, choice
27 from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance, hosts_set
28 from maincommon import *
29
30 def get_all_policy_identities():
31   extract_host_name(hosts_set, request)
32   if len(request.args) == 0:
33     return(list(policy_instances.keys()), 200)
34   elif 'policyTypeId' in request.args:
35     policyTypeId = request.args.get('policyTypeId')
36     if policyTypeId not in list(policy_types.keys()):
37       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))
38     else:
39       return(list({key for key in policy_instances.keys() if policy_type_per_instance[key]==policyTypeId}), 200)
40   else:
41     return(send_error_code(request.args))
42
43 def put_policy(policyId):
44   extract_host_name(hosts_set, request)
45   data = request.data.decode("utf-8")
46   data = data.replace("'", "\"")
47   data = json.loads(data)
48   ps = {}
49   if 'policyTypeId' in request.args:
50     policyTypeId = request.args.get('policyTypeId')
51
52     if policyTypeId not in list(policy_types.keys()):
53       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))
54
55     policy_schema = policy_types[policyTypeId]["policySchema"]
56     try:
57       validate(instance=data, schema=policy_schema)
58     except:
59       return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None, None))
60
61     for i in list(policy_instances.keys()):
62       if policyId != i and \
63          data == policy_instances[i] and \
64          policyTypeId == policy_type_per_instance[i]:
65         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))
66
67   if policyId in list(policy_instances.keys()):
68     if data["scope"] != policy_instances[policyId]["scope"]:
69       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))
70
71   if 'code' in request.args:
72     return(send_error_code(request.args))
73
74   if policyId in policy_instances.keys():
75     code = 201
76   else:
77     code = 200
78
79   policy_instances[policyId] = data
80   policy_status[policyId] = set_status("UNDEFINED")
81   if 'policyTypeId' in request.args:
82     status_schema = policy_types[policyTypeId]["statusSchema"]
83     try:
84       validate(instance=policy_status[policyId], schema=status_schema)
85     except:
86       return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
87     policy_type_per_instance[policyId] = policyTypeId
88   else:
89     policy_type_per_instance[policyId] = "UNDEFINED"
90
91   response = make_response(policy_instances[policyId], code)
92   if code == 201:
93     response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
94   return response
95
96 def set_status(*args):
97   ps = {}
98   ps["enforceStatus"] = args[0]
99   if len(args) == 2:
100     ps["enforceReason"] = args[1]
101   if len(args) > 2:
102     return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
103   return ps
104
105 def get_policy(policyId):
106   extract_host_name(hosts_set, request)
107   if len(request.args) == 0:
108     if policyId in policy_instances.keys():
109       res = policy_instances[policyId]
110       res["enforceStatus"] = policy_status[policyId]["enforceStatus"]
111       return(res, 200)
112     else:
113       return(set_error(None, "The requested policy does not exist.", 404, None, None, None, "policyId", None))
114   else:
115     return(send_error_code(request.args))
116
117 def delete_policy(policyId):
118   extract_host_name(hosts_set, request)
119   if len(request.args) == 0:
120     if policyId in policy_instances.keys():
121       policy_instances.pop(policyId)
122       policy_status.pop(policyId)
123       policy_type_per_instance.pop(policyId)
124       return(None, 204)
125     else:
126       return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
127   else:
128     return(send_error_code(request.args))
129
130 def get_policy_status(policyId):
131   extract_host_name(hosts_set, request)
132   if len(request.args) == 0:
133     if policyId in policy_instances.keys():
134       return(policy_status[policyId], 200)
135     else:
136       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))
137   else:
138     return(send_error_code(request.args))
139
140 def get_all_policytypes_identities():
141   extract_host_name(hosts_set, request)
142   if len(request.args) == 0:
143     return(list(policy_types.keys()), 200)
144   else:
145     return(send_error_code(request.args))
146
147 def get_policytypes(policyTypeId):
148   extract_host_name(hosts_set, request)
149   if len(request.args) == 0:
150     if policyTypeId in policy_types.keys():
151       return(policy_types[policyTypeId], 200)
152     else:
153       return(set_error(None, "The requested policy type does not exist.", 404, None, None, None, "policyTypeId", None))
154   else:
155     return(send_error_code(request.args))
156
157 def set_error(type_of, title, status, detail, instance, cause, param, reason):
158   error = {}
159   params = {}
160   if type_of is not None:
161     error["type"] = type_of
162   if title is not None:
163     error["title"] = title
164   if status is not None:
165     error["status"] = status
166   if detail is not None:
167     error["detail"] = detail
168   if instance is not None:
169     error["instance"] = instance
170   if cause is not None:
171     error["cause"] = cause
172   if param is not None:
173     params["param"] = param
174   if reason is not None:
175     params["reason"] = reason
176   if params:
177     error["invalidParams"] = params
178   return(error, error["status"])
179
180 def send_error_code(args):
181   if 'code' in args.keys():
182     code = args['code']
183     if code == '405':
184       return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
185     elif code == '429':
186       return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
187     elif code == '507':
188       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))
189     elif code == '503':
190       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))
191     else:
192       return(set_error(None, "Not found", 400, "Object in payload not properly formulated or not related to the method", None, None, None, None))
193   else:
194     return(set_error(None, "Not found", 404, "No resource found at the URI", None, None, None, None))