1 # ============LICENSE_START===============================================
2 # Copyright (C) 2022 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
8 # http://www.apache.org/licenses/LICENSE-2.0
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=================================================
21 from flask import request, Response
22 from jsonschema import validate
23 from var_declaration import rapp_registry
24 from zipfile import ZipFile
25 from io import TextIOWrapper
26 from util import ToscametaFormatChecker
29 APPL_JSON='application/json'
30 TEXT_PLAIN='text/plain'
31 APPL_PROB_JSON='application/problem+json'
33 # API Function: Query for all rapp identifiers
34 def query_all_rapp_ids():
36 res = list(rapp_registry.keys())
40 # API Function: Get a rapp definition
41 def query_rapp_by_id(rappid):
45 if (rapp_id not in rapp_registry.keys()):
46 pjson=create_problem_json(None, "The rapp does not exist.", 404, None, rapp_id)
47 return Response(json.dumps(pjson), 404, mimetype=APPL_PROB_JSON)
49 return Response(json.dumps(rapp_registry[rapp_id]), 200, mimetype=APPL_JSON)
52 # API Function: Register, or update, a rapp definition
53 def register_rapp(rappid):
59 data = json.loads(data)
61 pjson=create_problem_json(None, "The rapp definition is corrupt or missing.", 400, None, rapp_id)
62 return Response(json.dumps(pjson), 400, mimetype=APPL_PROB_JSON)
65 if rapp_id in rapp_registry.keys():
68 # Register or update rapp definition
69 rapp_registry[rapp_id] = data
71 return Response(json.dumps(data), return_code, mimetype=APPL_JSON)
74 # API Function: Unregister a rapp from catalogue
75 def unregister_rapp(rappid):
79 if (rapp_id not in rapp_registry.keys()):
80 pjson = create_problem_json(None, "The rapp definition does not exist.", 404, None, rapp_id)
81 return Response(json.dumps(pjson), 404, mimetype=APPL_PROB_JSON)
83 # Delete rapp definition
84 del rapp_registry[rapp_id]
86 return Response('', 204, mimetype=APPL_JSON)
88 # API Function: Query api list by rapp_id and service_type: produced or consumed
89 def query_api_list_by_rapp_id_and_service_type(rappid, servicetype):
92 service_type = str(servicetype)
94 if (rapp_id in rapp_registry.keys()):
96 rapp_definition = rapp_registry[rapp_id]
98 arr_api_list = rapp_definition['apiList']
99 arr_filtered_api_list = [arr_item for arr_item in arr_api_list if arr_item['serviceType'] == service_type]
100 return (arr_filtered_api_list, 200)
101 except Exception as err:
102 print('An error occured:', err)
103 pjson=create_problem_json(None, "The rapp definition is corrupt or missing.", 400, None, rapp_id)
104 return Response(json.dumps(pjson), 400, mimetype=APPL_PROB_JSON)
108 # API Function: Validate and return TOSCA.meta file content
109 def query_tosca_meta_content_by_rapp_id(rappid):
111 rapp_id = str(rappid)
113 if (rapp_id not in rapp_registry.keys()):
114 pjson=create_problem_json(None, "The rapp does not exist.", 404, None, rapp_id)
115 return Response(json.dumps(pjson), 404, mimetype=APPL_PROB_JSON)
117 with open_zip_and_filter('/usr/src/app/csar/rapp1/rapp1.csar') as tosca_file:
120 line = tosca_file.readline() # Get next line from file
121 if not line: # end of file is reached
124 tosca_meta.append(line.strip())
126 print('TOSCA.meta content:', tosca_meta)
127 is_valid = validate_tosca_meta_format(tosca_meta)
131 return Response(json.dumps(content), 200, mimetype=APPL_JSON)
135 # Helper: Open CSAR zip file and returns TOSCA.meta
136 def validate_tosca_meta_format(toscameta):
138 if len(toscameta) >= 3:
139 file_tag = split_and_strip(toscameta[0])
140 csar_tag = split_and_strip(toscameta[1])
141 crby_tag = split_and_strip(toscameta[2])
143 checker = ToscametaFormatChecker(file_tag, csar_tag, crby_tag) # util.py: validater
144 result = checker.validate()
146 if result == True: # Log: Validated or NOT
147 print('Validated:', checker)
149 print('NOT Validated:', checker)
154 # Helper: Splits given string by colon and strip
155 def split_and_strip(string):
156 result = [x.strip() for x in string.split(':')]
159 # Helper: Open CSAR zip file and returns TOSCA.meta file
160 def open_zip_and_filter(filename):
163 with ZipFile(filename, 'r') as zip_object:
164 file_names = zip_object.namelist()
165 for file_name in file_names:
166 if file_name.endswith('TOSCA.meta'):
167 return TextIOWrapper(zip_object.open(file_name)) # TextIOWrapper: provides buffered text stream
169 pjson=create_problem_json(None, "TOSCA.meta file is corrupt or missing.", 400, None, rapp_id)
170 return Response(json.dumps(pjson), 400, mimetype=APPL_PROB_JSON)
171 except Exception as err:
172 print('An error occured:', err)
173 pjson=create_problem_json(None, "The CSAR zip content is corrupt or missing.", 400, None, rapp_id)
174 return Response(json.dumps(pjson), 400, mimetype=APPL_PROB_JSON)
178 # Helper: Create a problem json object
179 def create_problem_json(type_of, title, status, detail, instance):
182 if type_of is not None:
183 error["type"] = type_of
184 if title is not None:
185 error["title"] = title
186 if status is not None:
187 error["status"] = status
188 if detail is not None:
189 error["detail"] = detail
190 if instance is not None:
191 error["instance"] = instance
195 # Helper: Create a problem json based on a generic http response code
196 def create_error_response(code):
199 return(create_problem_json(None, "Bad request", 400, "Object in payload not properly formulated or not related to the method", None))
201 return(create_problem_json(None, "Not found", 404, "No resource found at the URI", None))
203 return(create_problem_json(None, "Method not allowed", 405, "Method not allowed for the URI", None))
205 return(create_problem_json(None, "Request timeout", 408, "Request timeout", None))
207 return(create_problem_json(None, "Conflict", 409, "Request could not be processed in the current state of the resource", None))
209 return(create_problem_json(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None))
211 return(create_problem_json(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None))
213 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))
215 return(create_problem_json(None, "Unknown", code, "Not implemented response code", None))