Add support to process NSST Selection for HAS 00/132900/4
authoraleem.raja@t-systems.com <aleem.raja@t-systems.com>
Mon, 27 Feb 2023 15:14:17 +0000 (20:44 +0530)
committerAleem Raja <aleem.raja@t-systems.com>
Mon, 27 Feb 2023 16:00:38 +0000 (16:00 +0000)
Issue-ID: OPTFRA-1123
Signed-off-by: Aleem Raja <aleem.raja@t-systems.com>
Change-Id: Ib025bfe49948180a1808b5525dc1647ba04c3e0d

conductor/conductor/controller/translator_utils.py
conductor/conductor/data/plugins/inventory_provider/aai.py
conductor/conductor/data/plugins/inventory_provider/candidates/nsst_candidate.py [new file with mode: 0644]
conductor/conductor/data/plugins/inventory_provider/sdc.py
conductor/conductor/data/plugins/inventory_provider/utils/aai_utils.py
conductor/conductor/data/plugins/inventory_provider/utils/csar.py
conductor/conductor/data/service.py
conductor/conductor/solver/service.py

index e4aa4e1..0f6f4a0 100644 (file)
@@ -21,7 +21,7 @@ VERSIONS = {'BASE': ["2016-11-01", "2017-10-10", "2018-02-01"],
             'GENERIC': ["2020-08-13"]}
 LOCATION_KEYS = ['latitude', 'longitude', 'host_name', 'clli_code']
 INVENTORY_PROVIDERS = ['aai', 'generator', 'sdc']
-INVENTORY_TYPES = ['cloud', 'service', 'transport', 'vfmodule', 'nssi', 'nsi', 'slice_profiles', 'nst']
+INVENTORY_TYPES = ['cloud', 'service', 'transport', 'vfmodule', 'nssi', 'nsi', 'slice_profiles', 'nst', 'nsst']
 DEFAULT_INVENTORY_PROVIDER = INVENTORY_PROVIDERS[0]
 CANDIDATE_KEYS = ['candidate_id', 'cost', 'inventory_type', 'location_id',
                   'location_type']
index 7bbbe68..999c0ae 100644 (file)
@@ -27,7 +27,6 @@ import uuid
 from oslo_config import cfg
 from oslo_log import log
 
-
 from conductor.common import rest
 from conductor.data.plugins import constants
 from conductor.data.plugins.inventory_provider import base
@@ -765,7 +764,7 @@ class AAI(base.InventoryProviderBase):
             if match_type == 'any':
                 if attribute_key not in inventory_attributes or \
                         (len(attribute_values) > 0 and inventory_attributes[attribute_key] and
-                            inventory_attributes[attribute_key] not in attribute_values):
+                         inventory_attributes[attribute_key] not in attribute_values):
                     return False
             elif match_type == 'not':
                 # drop the candidate when
@@ -1677,6 +1676,17 @@ class AAI(base.InventoryProviderBase):
                                                                       inventory_type)
                         resolved_demands[name].extend(SDC().update_candidates(sdc_candidates_list))
 
+                elif inventory_type == 'nsst':
+                    if filtering_attributes:
+                        second_level_match = aai_utils.get_first_level_and_second_level_filter(filtering_attributes,
+                                                                                               "Nsst")
+                        aai_response = self.get_nsst_response(filtering_attributes)
+
+                        sdc_candidates_list = self.get_nsst_candidates(aai_response, second_level_match,
+                                                                       default_attributes, candidate_uniqueness,
+                                                                       inventory_type)
+                        resolved_demands[name].extend(SDC().update_candidates_nsst(sdc_candidates_list))
+
                 else:
                     LOG.error("Unknown inventory_type "
                               " {}".format(inventory_type))
@@ -1950,6 +1960,17 @@ class AAI(base.InventoryProviderBase):
         if aai_response.json():
             return aai_response.json()
 
+    def get_nsst_response(self, filtering_attributes):
+        raw_path = 'service-design-and-creation/models' + aai_utils.add_query_params_and_depth(filtering_attributes,
+                                                                                               "2")
+        path = self._aai_versioned_path(raw_path)
+        aai_response = self._request('get', path, data=None)
+
+        if aai_response is None or aai_response.status_code != 200:
+            return None
+        if aai_response.json():
+            return aai_response.json()
+
     def get_nst_candidates(self, response_body, filtering_attributes, default_attributes, candidate_uniqueness,
                            type):
         candidates = list()
@@ -1970,3 +1991,24 @@ class AAI(base.InventoryProviderBase):
                                         profile_info=None)
                     candidates.append(nst_candidate)
         return candidates
+
+    def get_nsst_candidates(self, response_body, filtering_attributes, default_attributes, candidate_uniqueness,
+                            type):
+        candidates = list()
+        if response_body is not None:
+            nsst_metadatas = response_body.get("model", [])
+
+            for nsst_metadata in nsst_metadatas:
+                nsst_info = aai_utils.get_nsst_info(nsst_metadata)
+                model_vers = nsst_metadata.get('model-vers').get('model-ver')
+                for model_ver in model_vers:
+                    model_version_id = model_ver.get('model-version-id')
+                    cost = self.conf.data.nsst_candidate_cost
+                    info = Candidate.build_candidate_info('aai', type, cost, candidate_uniqueness, model_version_id)
+                    model_version_obj = aai_utils.get_model_ver_info(model_ver)
+                    model_ver_info = aai_utils.convert_hyphen_to_under_score(model_version_obj)
+                    nst_candidate = NST(model_info=nsst_info, model_ver=model_ver_info, info=info,
+                                        default_fields=aai_utils.convert_hyphen_to_under_score(default_attributes),
+                                        profile_info=None)
+                    candidates.append(nst_candidate)
+        return candidates
diff --git a/conductor/conductor/data/plugins/inventory_provider/candidates/nsst_candidate.py b/conductor/conductor/data/plugins/inventory_provider/candidates/nsst_candidate.py
new file mode 100644 (file)
index 0000000..56eb0ca
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# -------------------------------------------------------------------------
+#   Copyright (C) 2020 Wipro Limited.
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+
+from conductor.data.plugins.inventory_provider.candidates.candidate import Candidate
+
+
+class NSST(Candidate):
+    def __init__(self, **kwargs):
+        super().__init__(kwargs['info'])
+        self.nsst_info = kwargs['model_info']
+        self.model_ver_info = kwargs['model_ver']
+        self.profile_info = kwargs['profile_info']
+        self.other = kwargs['default_fields']
index c69d7b0..f7fc1d6 100644 (file)
@@ -172,6 +172,28 @@ class SDC(object):
             candidateslist.append(finalcandidate)
         return candidateslist
 
+    def update_candidates_nsst(self, candidates):
+        absfilepath = self.conf.sdc.temp_path
+        candidateslist = []
+        for candidate in candidates:
+            model_ver_obj = candidate.model_ver_info
+            model_name = model_ver_obj['model_name']
+            self.model_version_id = candidate.candidate_id
+            response = self.get_nsst_template(self.model_version_id)
+            filepath = os.path.join(absfilepath, "{}.csar".format(self.model_version_id))
+            if not os.path.exists(absfilepath):
+                os.makedirs(absfilepath)
+            f = open(filepath, "wb")
+            file_res = response.content
+            f.write(file_res)
+            obj = csar.SDCCSAR(filepath, model_name)
+            nsst_temp_prop = obj.validate()
+            nsst_properties = self.get_nsst_prop_dict(nsst_temp_prop)
+            candidate.profile_info = nsst_properties
+            finalcandidate = candidate.convert_nested_dict_to_dict()
+            candidateslist.append(finalcandidate)
+        return candidateslist
+
     def get_nst_prop_dict(self, nst_properties):
         properties_dict = dict()
         for key in list(nst_properties):
@@ -181,6 +203,15 @@ class SDC(object):
                     properties_dict[key] = temp_dict[temp_key]
         return properties_dict
 
+    def get_nsst_prop_dict(self, nsst_properties):
+        properties_dict = dict()
+        for key in list(nsst_properties):
+            temp_dict = nsst_properties[key]
+            for temp_key in list(temp_dict):
+                if "default" in temp_key:
+                    properties_dict[key] = temp_dict[temp_key]
+        return properties_dict
+
     def get_nst_template(self, ver_id):
         raw_path = "/catalog/services/{}/toscaModel".format(ver_id)
         path = self._sdc_versioned_path(raw_path)
@@ -189,3 +220,12 @@ class SDC(object):
             return None
         if sdc_response:
             return sdc_response
+
+    def get_nsst_template(self, ver_id):
+        raw_path = "/catalog/services/{}/toscaModel".format(ver_id)
+        path = self._sdc_versioned_path(raw_path)
+        sdc_response = self._request('get', path, data=None)
+        if sdc_response is None or sdc_response.status_code != 200:
+            return None
+        if sdc_response:
+            return sdc_response
index c88b459..5191c91 100644 (file)
@@ -20,7 +20,7 @@
 QUERY_PARAMS = {'service_instance': ["service-instance-id", "service-instance-name", "environment-context",
                                      "workload-context", "model-invariant-id", "model-version-id", "widget-model-id",
                                      "widget-model-version", "service-instance-location-id", "orchestration-status"],
-                'nst': ["model-role"]
+                'nst': ["model-role"], 'Nsst': ["model-role"]
                 }
 
 
@@ -90,6 +90,14 @@ def get_nst_info(nst_instance):
     return nst_dict
 
 
+def get_nsst_info(nsst_instance):
+    nsst_dict = {}
+    nsst_dict['model_invariant_id'] = nsst_instance.get('model-invariant-id')
+    nsst_dict['model_type'] = nsst_instance.get('model-type')
+    nsst_dict['model_role'] = nsst_instance.get('model-role')
+    return nsst_dict
+
+
 def get_model_ver_info(model_version):
     for key in list(model_version):
         if "model-elements" in key:
index 0caccac..dc0977c 100644 (file)
@@ -1,5 +1,3 @@
-
-
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
 #    not use this file except in compliance with the License. You may obtain
 #    a copy of the License at
@@ -22,7 +20,6 @@ from toscaparser.utils.urlutils import UrlUtils
 from toscaparser.utils import yamlparser
 import zipfile
 
-
 try:  # Python 2.x
     from BytesIO import BytesIO
 except ImportError:  # Python 3.x
@@ -82,6 +79,12 @@ class SDCCSAR(CSAR):
             print("nst properties", nst_properies_res)
         return nst_properies_res
 
+        if is_validated:
+            main_tpl = self._read_template_yaml(self.main_template_file_name)
+            nsst_properies_res = self.get_nsst_properties(main_tpl)
+            print("nsst properties", nsst_properies_res)
+        return nsst_properies_res
+
     def get_nst_properties(self, main_tpl):
         importsarr = main_tpl.get('imports')
         for imports in importsarr:
@@ -96,3 +99,18 @@ class SDCCSAR(CSAR):
                 nodedata = node_types[key]
         nst_properties = nodedata.get("properties")
         return nst_properties
+
+    def get_nsst_properties(self, main_tpl):
+        importsarr = main_tpl.get('imports')
+        for imports in importsarr:
+            for key in imports:
+                if "service-{}-interface".format(self.model_name) in key:
+                    val = imports[key]
+        filename = val.get("file")
+        datanew = self._read_template_yaml("Definitions/" + filename)
+        node_types = datanew.get("node_types")
+        for key in list(node_types):
+            if "org.openecomp" in key:
+                nodedata = node_types[key]
+        nsst_properties = nodedata.get("properties")
+        return nsst_properties
index 69f6945..3f0ec13 100644 (file)
@@ -68,6 +68,8 @@ DATA_OPTS = [
                  default=1.0),
     cfg.FloatOpt('nst_candidate_cost',
                  default=1.0),
+    cfg.FloatOpt('nsst_candidate_cost',
+                 default=1.0),
 ]
 
 CONF.register_opts(DATA_OPTS, group='data')
index f0bb14b..a6fa2a0 100644 (file)
@@ -486,7 +486,7 @@ class SolverService(cotyledon.Service):
                                 'aic_version': resource.get("cloud_region_version")},
                         }
 
-                        if rec["candidate"]["inventory_type"] in ["nssi", "nsi", "slice_profiles", "nst"]:
+                        if rec["candidate"]["inventory_type"] in ["nssi", "nsi", "slice_profiles", "nst", "nsst"]:
                             rec["candidate"] = resource
 
                         if resource.get('vim-id'):