From 7ae420b25aade14f12fb7c94a407f0f9fd6aff4e Mon Sep 17 00:00:00 2001 From: MD IRSHAD SHEIKH Date: Tue, 29 Sep 2020 21:01:51 +0530 Subject: Missing callback in NST selection Issue-ID: OPTFRA-852 Signed-off-by: MD IRSHAD SHEIKH Change-Id: I7e1d782d579fd5f4385802c6dfbdaa8bfaef7782 --- apps/nst/models/api/nstSelectionRequest.py | 25 +++--- apps/nst/optimizers/nst_select_processor.py | 133 +++++++++++++++++++--------- osdfapp.py | 9 +- 3 files changed, 105 insertions(+), 62 deletions(-) diff --git a/apps/nst/models/api/nstSelectionRequest.py b/apps/nst/models/api/nstSelectionRequest.py index dcc385e..99c5df6 100644 --- a/apps/nst/models/api/nstSelectionRequest.py +++ b/apps/nst/models/api/nstSelectionRequest.py @@ -16,14 +16,18 @@ # ------------------------------------------------------------------------- # -from schematics.types import BaseType, StringType, URLType, IntType -from schematics.types.compound import ModelType, ListType, DictType - from osdf.models.api.common import OSDFModel -from osdf.logging.osdf_logging import MH, audit_log +from schematics.types import BaseType +from schematics.types.compound import DictType +from schematics.types.compound import ModelType +from schematics.types import IntType +from schematics.types import StringType +from schematics.types import URLType + class RequestInfo(OSDFModel): """Info for northbound request from client such as SO""" + transactionId = StringType(required=True) requestId = StringType(required=True) callbackUrl = URLType(required=True) @@ -32,17 +36,8 @@ class RequestInfo(OSDFModel): timeout = IntType() -class ServiceProfile(OSDFModel): - """Information specific to ServiceProfile """ - # resourceName = StringType(required=True) - # resourceId = StringType(required=True) - serviceProfileParameters = DictType(BaseType) - - - - class NSTSelectionAPI(OSDFModel): """Request for NST selection """ - requestInfo = ModelType(RequestInfo, required=True) - serviceProfile = ModelType(ServiceProfile, required=True) + requestInfo = ModelType(RequestInfo, required=True) + serviceProfile = DictType(BaseType) diff --git a/apps/nst/optimizers/nst_select_processor.py b/apps/nst/optimizers/nst_select_processor.py index 04d5ba7..faab999 100644 --- a/apps/nst/optimizers/nst_select_processor.py +++ b/apps/nst/optimizers/nst_select_processor.py @@ -15,62 +15,107 @@ # # ------------------------------------------------------------------------- - -import json -import os -BASE_DIR = os.path.dirname(__file__) """ This application generates NST SELECTION API calls using the information received from SO """ +import json +import os +from osdf.logging.osdf_logging import error_log +from osdf.utils.interfaces import get_rest_client +from requests import RequestException +from threading import Thread +import traceback +BASE_DIR = os.path.dirname(__file__) + + +# This is the class for NST Selection + + +class NstSelection(Thread): + def __init__(self, osdf_config, request_json): + super().__init__() + self.osdf_config = osdf_config + self.request_json = request_json + self.request_info = self.request_json['requestInfo'] -def get_nst_solution(request_json): -# the file is in the same folder for now will move it to the conf folder of the has once its integrated there... - config_input_json = os.path.join(BASE_DIR, 'conf/configIinputs.json') - try: + def run(self): + self.process_nst_selection() + + def process_nst_selection(self): + """Process a PCI request from a Client (build config-db, policy and API call, make the call, return result) + + :param req_object: Request parameters from the client + :param osdf_config: Configuration specific to OSDF application (core + deployment) + :return: response from NST Opt + """ + 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())) + error_message = str(err) + solution = self.error_response(error_message) + + try: + rest_client.request(json=solution, noresponse=True) + except RequestException: + error_log.error("Error sending asynchronous notification for {} {}". + format(self.request_info['requestId'], traceback.format_exc())) + + def get_nst_solution(self): + """the file is in the same folder for now will move it to the conf folder of the has once its + + integrated there... + """ + + config_input_json = os.path.join(BASE_DIR, 'conf/configIinputs.json') with open(config_input_json, 'r') as openfile: - serviceProfile = request_json["serviceProfile"] - nstSolutionList = [] - resourceName = "NST" - serviceProfileParameters = serviceProfile["serviceProfileParameters"] + service_profile = self.request_json["serviceProfile"] + nst_solution_list = [] + resource_name = "NST" nst_object = json.load(openfile) - for nst in nst_object[resourceName]: - [(nstName, nstList)] = nst.items() + for nst in nst_object[resource_name]: + [(nst_name, nst_list)] = nst.items() individual_nst = dict() matchall = False - for constraint_name in serviceProfileParameters: - value = serviceProfileParameters[constraint_name] - constraint_value = nstList.get(constraint_name) - if (not constraint_value): + 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"] = nstList.get("name") - individual_nst["UUID"] = nstList.get("modeluuid") - individual_nst["invariantUUID"] = nstList.get("modelinvariantuuid") + 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 - nstSolutionList.append(individual_nst) - - return nstSolutionList - except Exception as err: - raise err - - -def process_nst_selection( request_json, osdf_config): - """ - Process a PCI request from a Client (build config-db, policy and API call, make the call, return result) - :param req_object: Request parameters from the client - :param osdf_config: Configuration specific to OSDF application (core + deployment) - :return: response from NST Opt - """ - solution = get_nst_solution(request_json) - - return { - "requestId" : request_json['requestInfo']['requestId'], - "transactionId" : request_json['requestInfo']['transactionId'], - "statusMessage" : " ", - "requestStatus" : "accepted", - "solutions" : solution - } \ No newline at end of file + nst_solution_list.append(individual_nst) + + return nst_solution_list + + def get_nst_selection_response(self, solutions): + """Get NST selection response from final solution + + :param solutions: final solutions + :return: NST selection response to send back as dictionary + """ + return {'requestId': self.request_info['requestId'], + 'transactionId': self.request_info['transactionId'], + 'requestStatus': 'completed', + 'statusMessage': '', + 'solutions': solutions} + + def error_response(self, error_message): + """Form response message from the error message + + :param error_message: error message while processing the request + :return: response json as dictionary + """ + return {'requestId': self.request_info['requestId'], + 'transactionId': self.request_info['transactionId'], + 'requestStatus': 'error', + 'statusMessage': error_message} diff --git a/osdfapp.py b/osdfapp.py index 8d40273..df85343 100755 --- a/osdfapp.py +++ b/osdfapp.py @@ -30,7 +30,7 @@ from flask import request, g from osdf.apps.baseapp import app, run_app from apps.nst.models.api.nstSelectionRequest import NSTSelectionAPI from apps.pci.models.api.pciOptimizationRequest import PCIOptimizationAPI -from apps.nst.optimizers.nst_select_processor import process_nst_selection +from apps.nst.optimizers.nst_select_processor import NstSelection from apps.pci.optimizers.pci_opt_processor import process_pci_optimation from apps.placement.models.api.placementRequest import PlacementAPI from apps.placement.optimizers.conductor.remote_opt_processor import process_placement_opt @@ -127,8 +127,11 @@ def do_nst_selection(): request_json = request.get_json() req_id = request_json['requestInfo']['requestId'] NSTSelectionAPI(request_json).validate() - response = process_nst_selection(request_json, osdf_config) - return response + nst_selection = NstSelection(osdf_config, request_json) + nst_selection.start() + return req_accept(request_id=req_id, + transaction_id=request_json['requestInfo']['transactionId'], + request_status="accepted", status_message="") @app.route("/api/oof/v1/pci", methods=["POST"]) -- cgit 1.2.3-korg