Missing callback in NST selection 27/113327/2
authorMD IRSHAD SHEIKH <md.irshad.sheikh@huawei.com>
Tue, 29 Sep 2020 15:31:51 +0000 (21:01 +0530)
committerMD IRSHAD SHEIKH <md.irshad.sheikh@huawei.com>
Tue, 29 Sep 2020 16:50:08 +0000 (22:20 +0530)
Issue-ID: OPTFRA-852
Signed-off-by: MD IRSHAD SHEIKH <md.irshad.sheikh@huawei.com>
Change-Id: I7e1d782d579fd5f4385802c6dfbdaa8bfaef7782

apps/nst/models/api/nstSelectionRequest.py
apps/nst/optimizers/nst_select_processor.py
osdfapp.py

index dcc385e..99c5df6 100644 (file)
 # -------------------------------------------------------------------------
 #
 
-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)
index 04d5ba7..faab999 100644 (file)
 #
 # -------------------------------------------------------------------------
 
-
-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}
index 8d40273..df85343 100755 (executable)
@@ -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"])