Catalog parses ETSI standard NS model via EtsiNsModel.
Change-Id: Ia6f87bfffdf8e19e024cd7dba06252158f6290ac
Issue-ID: VFC-1179
Signed-off-by: maopengzhang <zhang.maopeng1@zte.com.cn>
                 pnfd_id = pnf["properties"].get("id", "undefined")
             pkg = PnfPackageModel.objects.filter(pnfdId=pnfd_id)
             if not pkg:
-                pnfd_name = pnf.get("vnf_id", "undefined")
+                pnfd_name = pnf.get("pnf_id", "undefined")
                 logger.error("[%s] is not distributed.", pnfd_name)
-                raise CatalogException("VNF package(%s) is not distributed." % pnfd_name)
+                raise CatalogException("PNF package(%s) is not distributed." % pnfd_name)
 
         ns_pkgs.update(
             nsdId=nsd_id,
 
         if not ns_pkg:
             raise CatalogException("NS CSAR(%s) does not exist." % csar_id)
         csar_path = ns_pkg[0].localFilePath
-        ret = {"model": toscaparser.parse_nsd(csar_path, inputs, False)}
+        ret = {"model": toscaparser.parse_nsd(csar_path, inputs)}
     except CatalogException as e:
         return [1, e.message]
     except Exception as e:
 
 
 import json
 
-from catalog.pub.utils.toscaparser.nsdmodel import EtsiNsdInfoModel
+from catalog.pub.utils.toscaparser.nsdmodel import NsdInfoModel
 from catalog.pub.utils.toscaparser.vnfdmodel import EtsiVnfdInfoModel
 from catalog.pub.utils.toscaparser.pnfmodel import PnfdInfoModel
-from catalog.pub.utils.toscaparser.servicemodel import SdcServiceModel
 
 
-def parse_nsd(path, input_parameters=[], isETSI=True):
-    if isETSI:
-        tosca_obj = EtsiNsdInfoModel(path, input_parameters)
-    else:
-        tosca_obj = SdcServiceModel(path, input_parameters)
+def parse_nsd(path, input_parameters=[]):
+    tosca_obj = NsdInfoModel(path, input_parameters).model
     strResponse = json.dumps(tosca_obj, default=lambda obj: obj.__dict__)
     strResponse = strResponse.replace(': null', ': ""')
     return strResponse
 
 
 class BaseInfoModel(object):
 
-    def __init__(self, path, params):
-        tosca = self.buildToscaTemplate(path, params)
-        self.description = tosca.description
-        self.parseModel(tosca)
+    def __init__(self, path=None, params=None, tosca=None):
+        if tosca:
+            _tosca = tosca
+        else:
+            _tosca = self.buildToscaTemplate(path, params)
+        self.description = _tosca.description
+        self.parseModel(_tosca)
 
     def parseModel(self, tosca):
         pass
 
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-NS_METADATA_SECTIONS = (NS_UUID, NS_INVARIANTUUID, NS_NAME, NS_VERSION, NS_DESIGNER, NS_DESCRIPTION) =\
-    ("id", "invariant_id", "name", "version", "designer", "description")
+NS_METADATA_SECTIONS = (NS_UUID, NS_INVARIANTUUID, NS_NAME, NS_VERSION, NS_DESIGNER, NSD_RELEASE_DATE) =\
+    ("nsd_id", "nsd_invariant_id", "nsd_name", "nsd_file_structure_version", "nsd_designer", "nsd_release_date_time")
+# ("id", "invariant_id", "name", "version", "designer", "description")
+
+SDC_SERVICE_METADATA_SECTIONS = (SRV_UUID, SRV_INVARIANTUUID, SRV_NAME) = ('UUID', 'invariantUUID', 'name')
 
 PNF_METADATA_SECTIONS = (PNF_UUID, PNF_INVARIANTUUID, PNF_NAME, PNF_METADATA_DESCRIPTION, PNF_VERSION, PNF_PROVIDER) = \
     ("descriptor_id", "descriptor_invariant_id", "name", "description", "version", "provider")
 
 import functools
 import logging
 from catalog.pub.utils.toscaparser.basemodel import BaseInfoModel
+from catalog.pub.utils.toscaparser.const import SDC_SERVICE_METADATA_SECTIONS
+from catalog.pub.utils.toscaparser.servicemodel import SdcServiceModel
 
 logger = logging.getLogger(__name__)
 
 NFV_NS_RELATIONSHIPS = [["tosca.relationships.nfv.VirtualLinksTo", "tosca.relationships.DependsOn"], []]
 
 
+class NsdInfoModel(BaseInfoModel):
+    def __init__(self, path, params):
+        super(NsdInfoModel, self).__init__(path, params)
+
+    def parseModel(self, tosca):
+        metadata = self.buildMetadata(tosca)
+        self.model = {}
+        if self._is_etsi(metadata):
+            self.model = EtsiNsdInfoModel(tosca)
+        elif self._is_ecomp(metadata):
+            self.model = SdcServiceModel(tosca)
+
+    def _is_etsi(self, metadata):
+        NS_METADATA_MUST = ["nsd_invariant_id", "nsd_name", "nsd_file_structure_version", "nsd_designer", "nsd_release_date_time"]
+        return True if len([1 for key in NS_METADATA_MUST if key in metadata]) == len(NS_METADATA_MUST) else False
+
+    def _is_ecomp(self, metadata):
+        return True if len([1 for key in SDC_SERVICE_METADATA_SECTIONS if key in metadata]) == len(SDC_SERVICE_METADATA_SECTIONS) else False
+
+
 class EtsiNsdInfoModel(BaseInfoModel):
 
-    def __init__(self, path, params):
-        super(EtsiNsdInfoModel, self).__init__(path, params)
+    def __init__(self, tosca):
+        super(EtsiNsdInfoModel, self).__init__(tosca=tosca)
 
     def parseModel(self, tosca):
         self.metadata = self.buildMetadata(tosca)
                 vnf['properties'] = node['properties']
                 if not vnf['properties'].get('id', None):
                     vnf['properties']['id'] = vnf['properties'].get('descriptor_id', None)
-                if not vnf['properties'].get('id', None) and node['metadata']:
-                    vnf['properties']['id'] = node['metadata'].get('UUID', None)
                 vnf['dependencies'] = self._get_networks(node, node_types)
                 vnf['networks'] = self._get_networks(node, node_types)
                 vnfs.append(vnf)
         properties = ns.get("properties", {})
         metadata = ns.get("metadata", {})
         if properties.get("descriptor_id", "") == "":
-            descriptor_id = metadata.get("descriptor_id", "")
-            if descriptor_id == "":
-                descriptor_id = metadata.get("id", "")
-            if descriptor_id == "":
-                descriptor_id = metadata.get("UUID", "")
+            descriptor_id = metadata.get("nsd_id", "")
             properties["descriptor_id"] = descriptor_id
         if properties.get("verison", "") == "":
-            version = metadata.get("template_version", "")
-            if version == "":
-                version = metadata.get("version", "")
+            version = metadata.get("nsd_file_structure_version", "")
             properties["verison"] = version
         if properties.get("designer", "") == "":
-            author = metadata.get("template_author", "")
+            author = metadata.get("nsd_designer", "")
             properties["designer"] = author
         if properties.get("name", "") == "":
-            template_name = metadata.get("template_name", "")
-            if template_name == "":
-                template_name = metadata.get("name", "")
+            template_name = metadata.get("nsd_name", "")
             properties["name"] = template_name
+        if properties.get("invariant_id", "") == "":
+            nsd_invariant_id = metadata.get("nsd_invariant_id", "")
+            properties["invariant_id"] = nsd_invariant_id
         return ns
 
 import logging
 from catalog.pub.utils.toscaparser.const import NS_METADATA_SECTIONS, PNF_METADATA_SECTIONS, VNF_SECTIONS, PNF_SECTIONS, VL_SECTIONS
 from catalog.pub.utils.toscaparser.basemodel import BaseInfoModel
+
 logger = logging.getLogger(__name__)
 
 SDC_SERVICE_SECTIONS = (SERVICE_TYPE, SRV_DESCRIPTION) = (
 
 class SdcServiceModel(BaseInfoModel):
 
-    def __init__(self, path, params):
-        super(SdcServiceModel, self).__init__(path, params)
+    def __init__(self, tosca):
+        super(SdcServiceModel, self).__init__(tosca=tosca)
 
     def parseModel(self, tosca):
         self.metadata = self._buildServiceMetadata(tosca)
+        self.ns = self._build_ns(tosca)
         self.inputs = self.buildInputs(tosca)
         if hasattr(tosca, 'nodetemplates'):
             nodeTemplates = map(functools.partial(self.buildNode, tosca=tosca), tosca.nodetemplates)
             if self.isNodeTypeX(node, node_types, VF_TYPE):
                 vnf = {}
                 self.setTargetValues(vnf, VNF_SECTIONS, node, SDC_VF_SECTIONS)
-                if not vnf['properties'].get('id', None):
-                    vnf['properties']['id'] = vnf['properties'].get('descriptor_id', None)
                 if not vnf['properties'].get('id', None) and node['metadata']:
                     vnf['properties']['id'] = node['metadata'].get('UUID', None)
+                vnf['properties']['vnfm_info'] = vnf['properties'].get('nf_type', None)
                 vnf['dependencies'] = self._get_networks(node, node_types)
                 vnf['networks'] = self._get_networks(node, node_types)
                 vnfs.append(vnf)
                 for key, value in item.items():
                     rets.append({"key_name": key, "vl_id": self.get_requirement_node_name(value)})
         return rets
+
+    def _build_ns(self, tosca):
+        ns = self.get_substitution_mappings(tosca)
+        properties = ns.get("properties", {})
+        metadata = ns.get("metadata", {})
+        if properties.get("descriptor_id", "") == "":
+            descriptor_id = metadata.get(SRV_UUID, "")
+            properties["descriptor_id"] = descriptor_id
+        properties["verison"] = ""
+        properties["designer"] = ""
+        if properties.get("name", "") == "":
+            template_name = metadata.get(SRV_NAME, "")
+            properties["name"] = template_name
+        if properties.get("invariant_id", "") == "":
+            nsd_invariant_id = metadata.get(SRV_INVARIANTUUID, "")
+            properties["invariant_id"] = nsd_invariant_id
+        return ns
 
     def test_nsd_parse(self):
         self.remove_temp_dir()
         # ran_csar = os.path.dirname(os.path.abspath(__file__)) + "/testdata/ns/ran.csar"
-        # nsd_json = parse_nsd(ran_csar)
+        # nsd_json = parse_nsd(ran_csar, [])
+        # logger.debug("NS ran json: %s" % nsd_json)
         # metadata = json.loads(nsd_json).get("metadata")
-        # self.assertEqual("RAN-NS", metadata.get("template_name", ""))
+        # self.assertEqual("RAN-NS", metadata.get("nsd_name", ""))
 
     def test_service_descriptor_parse(self):
         self.remove_temp_dir()
         service_test_csar = os.path.dirname(os.path.abspath(__file__)) + "/testdata/ns/service-vIMS.csar"
-        test_json = parse_nsd(service_test_csar, [], False)
+        test_json = parse_nsd(service_test_csar, [])
+        logger.debug("service-vIMS json: %s" % test_json)
         metadata = json.loads(test_json).get("metadata")
-        self.assertEqual("vIMS_v2", metadata.get("name", ""))
+        self.assertEqual("vIMS_v2", metadata.get("nsd_name", ""))
 
     def remove_temp_dir(self):
         tempdir = tempfile.gettempdir()