From d9a9520bd7efe2f022c0ad3de37b0c4ada4789df Mon Sep 17 00:00:00 2001 From: MD IRSHAD SHEIKH Date: Thu, 18 Feb 2021 18:31:25 +0530 Subject: Add support to process NST Selection for HAS Issue-ID: OPTFRA-911 Signed-off-by: MD IRSHAD SHEIKH Change-Id: I809857348b00fe415d416954b1cfbedd404bdffc --- apps/nst/optimizers/nst_select_processor.py | 90 ++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 28 deletions(-) (limited to 'apps/nst') diff --git a/apps/nst/optimizers/nst_select_processor.py b/apps/nst/optimizers/nst_select_processor.py index faab999..5b31f73 100644 --- a/apps/nst/optimizers/nst_select_processor.py +++ b/apps/nst/optimizers/nst_select_processor.py @@ -18,8 +18,10 @@ """ This application generates NST SELECTION API calls using the information received from SO """ -import json import os +from osdf.adapters.conductor import conductor +from osdf.adapters.policy.interface import get_policies +from osdf.logging.osdf_logging import debug_log from osdf.logging.osdf_logging import error_log from osdf.utils.interfaces import get_rest_client from requests import RequestException @@ -38,6 +40,7 @@ class NstSelection(Thread): self.osdf_config = osdf_config self.request_json = request_json self.request_info = self.request_json['requestInfo'] + self.request_info['numSolutions'] = 1 def run(self): self.process_nst_selection() @@ -52,7 +55,6 @@ class NstSelection(Thread): try: rest_client = get_rest_client(self.request_json, service='so') solution = self.get_nst_solution() - solution = self.get_nst_selection_response(solution) except Exception as err: error_log.error("Error for {} {}".format(self.request_info.get('requestId'), traceback.format_exc())) @@ -70,32 +72,12 @@ class NstSelection(Thread): integrated there... """ - - config_input_json = os.path.join(BASE_DIR, 'conf/configIinputs.json') - with open(config_input_json, 'r') as openfile: - service_profile = self.request_json["serviceProfile"] - nst_solution_list = [] - resource_name = "NST" - nst_object = json.load(openfile) - for nst in nst_object[resource_name]: - [(nst_name, nst_list)] = nst.items() - individual_nst = dict() - matchall = False - for constraint_name in service_profile: - constraint_value = nst_list.get(constraint_name) - if not constraint_value: - matchall = False - break - else: - matchall = True - if matchall: - individual_nst["NSTName"] = nst_list.get("name") - individual_nst["UUID"] = nst_list.get("modeluuid") - individual_nst["invariantUUID"] = nst_list.get("modelinvariantuuid") - individual_nst["individual_nst"] = 1 - nst_solution_list.append(individual_nst) - - return nst_solution_list + req_info = self.request_json['requestInfo'] + requirements = self.request_json['serviceProfile'] + model_name = "nst" + policies = self.get_app_policies(model_name, "nst_selection") + conductor_response = self.get_conductor(req_info, requirements, policies, model_name) + return conductor_response def get_nst_selection_response(self, solutions): """Get NST selection response from final solution @@ -119,3 +101,55 @@ class NstSelection(Thread): 'transactionId': self.request_info['transactionId'], 'requestStatus': 'error', 'statusMessage': error_message} + + def get_app_policies(self, model_name, app_name): + policy_request_json = self.request_json.copy() + policy_request_json['serviceInfo'] = {'serviceName': model_name} + debug_log.debug("policy_request_json {}".format(str(policy_request_json))) + return get_policies(policy_request_json, app_name) # app_name: nst_selection + + def get_conductor(self, req_info, request_parameters, policies, model_name): + demands = [ + { + "resourceModuleName": model_name, + "resourceModelInfo": {} + } + ] + + try: + template_fields = { + 'location_enabled': False, + 'version': '2020-08-13' + } + resp = conductor.request(req_info, demands, request_parameters, {}, template_fields, + self.osdf_config, policies) + except RequestException as e: + resp = e.response.json() + error = resp['plans'][0]['message'] + if "Unable to find any" in error: + return self.get_nst_selection_response([]) + error_log.error('Error from conductor {}'.format(error)) + return self.error_response(error) + debug_log.debug("Response from conductor in get_conductor method {}".format(str(resp))) + recommendations = resp["plans"][0].get("recommendations") + return self.process_response(recommendations, model_name) + + def process_response(self, recommendations, model_name): + """Process conductor response to form the response for the API request + + :param recommendations: recommendations from conductor + :return: response json as a dictionary + """ + if not recommendations: + return self.get_nst_selection_response([]) + solutions = [self.get_solution_from_candidate(rec[model_name]['candidate']) + for rec in recommendations] + return self.get_nst_selection_response(solutions) + + def get_solution_from_candidate(self, candidate): + if candidate['inventory_type'] == 'nst': + return { + 'UUID': candidate['model_version_id'], + 'invariantUUID': candidate['model_invariant_id'], + 'NSTName': candidate['name'], + } -- cgit 1.2.3-korg