* YANG to TOSCA VNFFG Support
authorHashir Mohammed <hashir.mohammed@riftio.com>
Wed, 8 Mar 2017 06:25:18 +0000 (01:25 -0500)
committerHashir Mohammed <hashir.mohammed@riftio.com>
Mon, 20 Mar 2017 07:11:46 +0000 (03:11 -0400)
Signed-off-by: Hashir Mohammed <hashir.mohammed@riftio.com>
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_forwarding_graph.py
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_forwarding_path.py
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_network_network.py
common/python/rift/mano/yang_translator/riftiotypes.yaml
common/python/rift/mano/yang_translator/rwmano/syntax/tosca_resource.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_nsd.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_vdu.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_vnfd.py

index 715ddc3..7b8657d 100644 (file)
@@ -13,7 +13,7 @@ class ToscaForwardingGraph(ManoResource):
                                           type_="vnfgd",
                                           metadata=metadata)
                self.name = group.name
-               self.type_ = 'vnffg'
+               self.type_ = 'vnfgd'
                self.metadata = metadata
                self.group = group
                self.properties = {}
index 4e39236..12b7062 100644 (file)
@@ -18,6 +18,7 @@ class ToscaForwardingPath(ManoResource):
                self.properties = {}
 
        def handle_forwarding_path_dependencies(self, nodes, vnf_type_to_capability_substitution_mapping):
+
                def get_classifier(specs):
                        classifier_prop = {}
                        classifier_prop['name'] = 'VNFFG -' + str(self.name)
@@ -60,23 +61,27 @@ class ToscaForwardingPath(ManoResource):
                                fp_connection_point = []
                                vnf_index   = 1
                                order_index = 1
+                               visited_cps = []
                                for rsp_item in specs['path']:
                                        vnf_node_name       = rsp_item['forwarder']
                                        conn_forwarder      = rsp_item['capability']
-                                       vnf_node            = self.get_node_with_name(vnf_node_name, nodes)
+                                       vnf_node            = self.get_node_with_name(vnf_node_name, nodes)                                     
+
                                        for subs_mapping in vnf_type_to_capability_substitution_mapping[vnf_node.vnf_type]:
                                                prop = {}
                                                if conn_forwarder in subs_mapping:
                                                        fp_connection_point.append(subs_mapping[conn_forwarder])
                                                        cp_node_name = subs_mapping[conn_forwarder]
                                                        cp_node = self.get_node_with_name(cp_node_name, nodes)
-                                                       prop['vnfd_connection_point_ref'] = cp_node.cp_name
-                                                       prop['vnfd_id_ref'] = vnf_node.id
-                                                       prop['member_vnf_index_ref'] = vnf_index
-                                                       prop['order'] = order_index
-                                                       rsp['vnfd_connection_point_ref'].append(prop)
-                                                       vnf_index = vnf_index + 1
-                                                       order_index = order_index + 1
+                                                       if cp_node.cp_name not in visited_cps:
+                                                               prop['vnfd_connection_point_ref'] = cp_node.cp_name
+                                                               prop['vnfd_id_ref'] = vnf_node.id
+                                                               prop['member_vnf_index_ref'] = vnf_node.get_member_vnf_index()
+                                                               prop['order'] = order_index
+                                                               rsp['vnfd_connection_point_ref'].append(prop)
+                                                               vnf_index = vnf_index + 1
+                                                               order_index = order_index + 1
+                                                               visited_cps.append(cp_node.cp_name)
                                return rsp
 
                tosca_props = self.get_tosca_props()
index a94624d..a9f9c77 100644 (file)
@@ -89,7 +89,7 @@ class ToscaNetwork(ManoResource):
                 ip_profile_param['gateway-address'] = specs['gateway_ip']
             if 'ip_version' in specs:
                 ip_profile_param['ip-version'] = 'ipv' + str(specs['ip_version'])
-            if 'ip_version' in specs:
+            if 'cidr' in specs:
                 ip_profile_param['subnet-address'] = specs['cidr']
 
             ip_profile_prop['ip-profile-params'] = ip_profile_param
index 2fea0e3..18a0728 100644 (file)
@@ -250,10 +250,10 @@ data_types:
           - in_range: [ 1, 254 ]
         required: false
       destination_port_range:
-        type: string
+        type: integer
         required: false
       source_port_range:
-        type: string
+        type: integer
         required: false
       network_src_port_id:
         type: string
index 7143e67..57b0a31 100644 (file)
@@ -43,7 +43,7 @@ class ToscaResource(object):
                  MEM_VNF_INDEX_REF, VNFD_ID_REF,
                  MEM_VNF_INDEX, VNF_CONFIG, TYPE_Y,
                  USER_DEF_SCRIPT, SEQ, PARAM,
-                 VALUE, START_BY_DFLT,) = \
+                 VALUE, START_BY_DFLT, VNFFGD, ) = \
                 ('vld', 'nsd', 'vnfd', 'vdu', 'dashboard_params',
                  'config_attributes', 'config_template',
                  'config_type', 'config_details', 'external_interface',
@@ -51,7 +51,7 @@ class ToscaResource(object):
                  'member_vnf_index_ref', 'vnfd_id_ref',
                  'member_vnf_index', 'vnf_configuration', 'type_yang',
                  'user_defined_script', 'seq', 'parameter',
-                 'value', 'start_by_default',)
+                 'value', 'start_by_default', 'vnffgd',)
 
     TOSCA_FIELDS = (DERIVED_FROM, PROPERTIES, DEFAULT, REQUIRED,
                     NO, CONSTRAINTS, REALTIONSHIPS,
@@ -95,7 +95,9 @@ class ToscaResource(object):
         T_INITIAL_CFG,
         T_ARTF_CLOUD_INIT,
         T_PLACEMENT,
-        T_ELAN
+        T_ELAN,
+        T_VNFFG,
+        T_FP,
     ) = \
         ('tosca.policies.nfv.riftio.vnf_configuration',
          'tosca.capabilities.riftio.http_endpoint_type',
@@ -111,7 +113,9 @@ class ToscaResource(object):
          'tosca.policies.nfv.riftio.initial_config_primitive',
          'tosca.artifacts.Deployment.riftio.cloud_init_file',
          'tosca.policies.nfv.riftio.placement',
-         'tosca.nodes.nfv.riftio.ELAN'
+         'tosca.nodes.nfv.riftio.ELAN',
+         'tosca.groups.nfv.VNFFG',
+         'tosca.nodes.nfv.riftio.FP1',
         )
 
     SUPPORT_FILES = ( SRC, DEST, EXISTING) = \
index 4e421d1..d28b3e1 100644 (file)
@@ -21,6 +21,7 @@ from rift.mano.yang_translator.common.utils import _
 from rift.mano.yang_translator.rwmano.syntax.tosca_resource \
     import ToscaResource
 from rift.mano.yang_translator.rwmano.yang.yang_vld import YangVld
+from collections import OrderedDict
 
 TARGET_CLASS_NAME = 'YangNsd'
 
@@ -68,6 +69,10 @@ class YangNsd(ToscaResource):
         self.vld_to_vnf_map = {}
         self.vnf_to_vld_map = {}
         self._vnf_vld_conn_point_map = {}
+        self.vnffgds = {}
+        self.forwarding_paths = {}
+        self.substitution_mapping_forwarder = []
+        self.vnfd_sfc_map = None
 
     def handle_yang(self, vnfds):
         self.log.debug(_("Process NSD desc {0}: {1}").
@@ -182,7 +187,7 @@ class YangNsd(ToscaResource):
                         if ip_profile_name == ip_prof['name']:
                             ip_profile_vld = ip_prof
             if 'name' in vld:
-                vld_name = vld['name']
+                vld_name = vld['name'].replace('-','_').replace(' ','')
             if 'description' in vld:
                 vld_conf['description'] = vld['description']
             if 'vendor' in vld:
@@ -245,6 +250,168 @@ class YangNsd(ToscaResource):
                             }
                 self.placement_groups.append(placement)
 
+        def process_vnffgd(vnffgs, dic):
+            associated_cp_names = []
+            all_cp_names        = []
+            vnfd_sfc_map        = {}
+            
+            conn_point_to_conection_node = {}
+            conn_point_to_vnf_name_map = {}
+
+            unigue_id_forwarder_path_map = OrderedDict()
+            forwarder_name_to_constitent_vnf_map = OrderedDict()
+            unique_id_classifier_map = OrderedDict()
+            fp_path_count = 1
+            forwarder_count = 1
+
+            vnffg_to_unique_id_rsp_map = OrderedDict()
+            vnffg_to_unique_id_classifier_map = OrderedDict()
+            vnffg_to_associated_cp_names = OrderedDict()
+            rsp_associated_cp_names = OrderedDict()
+            vnffg_to_forwarder_map  = OrderedDict()
+            for vnffg in vnffgs:
+                unique_id_rsp_map = {}
+                for rs in vnffg['rsp']:
+                    unique_id_rsp_map[str(rs['id'])] = rs
+                for class_identifier in vnffg['classifier']:
+                    unique_id_classifier_map[str(class_identifier['rsp_id_ref'])] = class_identifier
+                    associated_cp_names.append(class_identifier['vnfd_connection_point_ref'])
+                    all_cp_names.append(class_identifier['vnfd_connection_point_ref'])
+                    conn_point_to_vnf_name_map[class_identifier['vnfd_connection_point_ref']] = self.vnf_id_to_vnf_map[class_identifier['vnfd_id_ref']]
+                    vnfd_sfc_map[self.vnf_id_to_vnf_map[class_identifier['vnfd_id_ref']]] = class_identifier['vnfd_connection_point_ref']
+
+                    rsp_associated_cp_names[str(class_identifier['rsp_id_ref'])] = class_identifier['vnfd_connection_point_ref']
+
+                vnffg_to_unique_id_rsp_map[vnffg['name']] = unique_id_rsp_map
+                vnffg_to_forwarder_map[vnffg['name']] = []
+    
+            for vnffg in vnffgs:
+                prop = {}
+                fp_members = []
+
+                
+                prop['type'] = self.T_VNFFG
+                prop[self.DESC] = "Test"
+                prop[self.PROPERTIES] = {}
+                if 'vendor' in vnffg:
+                    prop[self.PROPERTIES]['vendor'] = vnffg['vendor']
+                if 'name' in vnffg:
+                    self.vnffgds[vnffg['name']] = prop
+                
+                for rs_id, rs in vnffg_to_unique_id_rsp_map[vnffg['name']].items():
+                    associated_cp_node_names = []
+                    associated_vnf_names = []
+                    number_of_endpoints = 0
+                    if 'vnfd_connection_point_ref' in rs:
+                       number_of_endpoints = number_of_endpoints + len(rs['vnfd_connection_point_ref'])
+                       for vnf in rs['vnfd_connection_point_ref']:
+                            associated_vnf_names.append(str(self.vnf_id_to_vnf_map[vnf['vnfd_id_ref']]))
+                            associated_cp_names.append(vnf['vnfd_connection_point_ref'])
+                            all_cp_names.append(vnf['vnfd_connection_point_ref'])
+                            conn_point_to_vnf_name_map[vnf['vnfd_connection_point_ref']] = self.vnf_id_to_vnf_map[vnf['vnfd_id_ref']]
+                       if "forwarder{}".format(fp_path_count) not in  forwarder_name_to_constitent_vnf_map:
+                            forwarder_name_to_constitent_vnf_map["forwarder{}".format(fp_path_count)] = associated_vnf_names
+                            vnffg_to_forwarder_map[vnffg['name']].append("forwarder{}".format(fp_path_count))
+                    fp_path_count = fp_path_count + 1
+                    
+                    associated_cp_names = list(set(associated_cp_names))
+                    for cp_name in associated_cp_names:
+                            for idx, vnfd in self.vnfds.items():
+                                for vdu in vnfd.vdus:
+                                    if cp_name == rsp_associated_cp_names[rs_id]:
+                                        if cp_name in vdu.conn_point_to_conection_node:
+                                            associated_cp_node_names.append(vdu.conn_point_to_conection_node[cp_name])
+                                            #conn_point_to_conection_node[cp_name] = vdu.conn_point_to_conection_node[cp_name]
+
+                    for cp_name in all_cp_names:
+                        for idx, vnfd in self.vnfds.items():
+                            for vdu in vnfd.vdus:
+                                if cp_name in vdu.conn_point_to_conection_node:
+                                    conn_point_to_conection_node[cp_name] = vdu.conn_point_to_conection_node[cp_name]
+
+                    if len(associated_vnf_names) > 0:
+                        associated_vnf_names = list(set(associated_vnf_names))
+                        vnf_str = ", ".join(associated_vnf_names)
+                        prop[self.PROPERTIES]['constituent_vnfs'] = "[{}]".format(vnf_str)
+                    if len(associated_cp_node_names) > 0:
+                        associated_cp_node_names = list(set(associated_cp_node_names))
+                        connection_point_str = ", ".join(associated_cp_node_names)
+                        prop[self.PROPERTIES]['connection_point'] = "[{}]".format(", ".join(associated_cp_node_names))
+
+                    prop[self.PROPERTIES]['number_of_endpoints'] = number_of_endpoints
+                    fp_name = "Forwarding_path{}".format(forwarder_count)
+                    unigue_id_forwarder_path_map[fp_name] = rs_id
+                    fp_members.append(fp_name)
+                    forwarder_count = forwarder_count + 1
+
+                    if len(fp_members) > 0:
+                        prop['members'] = []
+                        for fp in fp_members:
+                            prop['members'].append(fp)
+
+            fp_count = 1
+            for fp, idx in unigue_id_forwarder_path_map.items():
+                for vnffg_name, unique_id_rsp_map in vnffg_to_unique_id_rsp_map.items():
+                    if idx in unique_id_rsp_map:
+                        prop = {}
+                        prop['type'] = self.T_FP
+                        prop[self.PROPERTIES] = {}
+                        prop[self.PROPERTIES][self.DESC] = "Forwarder"
+                        prop[self.PROPERTIES]['policy'] = {}
+                        prop[self.PROPERTIES]['policy']['type'] = 'ACL'
+                        prop[self.PROPERTIES]['policy']['criteria'] = []
+
+                        prop[self.PROPERTIES]['path'] = []
+
+                        rsp =  unique_id_rsp_map[idx]
+                        classifier = unique_id_classifier_map[idx]
+
+                        for match in classifier['match_attributes']:
+                            match_prop = {}
+                            if 'source_port' in match:
+                                port = "'{}'".format((match['source_port']))
+                                prop[self.PROPERTIES]['policy']['criteria'].append({'source_port_range': port})
+                            if 'destination_port' in match:
+                                port = "'f'{}''".format((match['destination_port']))
+                                prop[self.PROPERTIES]['policy']['criteria'].append({'destination_port_range': '5006'})
+                            if 'ip_proto' in match:
+                                port = match['ip_proto']
+                                prop[self.PROPERTIES]['policy']['criteria'].append({'ip_proto': port})
+                            if 'destination_ip_address' in match:
+                                port = "'{}'".format((match['destination_ip_address']))
+                                prop[self.PROPERTIES]['policy']['criteria'].append({'ip_dst_prefix': port})
+
+                        if 'vnfd_connection_point_ref' in classifier:
+                            if classifier['vnfd_connection_point_ref'] in conn_point_to_vnf_name_map:
+                                if 'cp' not in prop[self.PROPERTIES]:
+                                    prop[self.PROPERTIES]['cp'] = {}
+                                prop[self.PROPERTIES]['cp']['forwarder'] = conn_point_to_vnf_name_map[classifier['vnfd_connection_point_ref']]
+                                prop[self.PROPERTIES]['cp']['capability'] = conn_point_to_conection_node[classifier['vnfd_connection_point_ref']]
+
+                        for fp, vnf_list in forwarder_name_to_constitent_vnf_map.items():
+                            for vnf in vnf_list:
+                                for cp, vnf_name in conn_point_to_vnf_name_map.items():
+                                    if vnf == vnf_name:
+                                        self.substitution_mapping_forwarder.append((vnf, fp, conn_point_to_conection_node[cp]))
+
+                        visited_forwarder = []
+                        visited_path = None
+                        for path, vnfs in forwarder_name_to_constitent_vnf_map.items():
+                            for vnf in vnfs:
+                                if (vnf not in visited_forwarder) and (path in vnffg_to_forwarder_map[vnffg_name]):
+                                    path_prop = {}
+                                    path_prop['forwarder']  = vnf
+                                    path_prop['capability'] = path
+                                    prop[self.PROPERTIES]['path'].append(path_prop)
+                                    visited_forwarder.append(vnf)
+                                    visited_path = path
+                        forwarder_name_to_constitent_vnf_map.pop(visited_path)
+
+                        self.forwarding_paths["Forwarding_path{}".format(fp_count)] = prop
+                        fp_count = fp_count +1
+
+            self.vnfd_sfc_map = vnfd_sfc_map
+
         dic = deepcopy(self.yang)
         try:
             for key in self.REQUIRED_FIELDS:
@@ -263,10 +430,17 @@ class YangNsd(ToscaResource):
                     process_vld(vld_dic, dic)
                     #self.vlds.append(vld)
 
+            #Process VNFFG
+            if self.VNFFGD in dic:
+                process_vnffgd(dic[self.VNFFGD], dic)
+
+
+            #if self.
+
             # Process config primitives
             if self.CONF_PRIM in dic:
                 for cprim in dic.pop(self.CONF_PRIM):
-                    conf_prim = {self.NAME: cprim.pop(self.NAME)}
+                    conf_prim = {self.NAME: cprim.pop(self.NAME), self.DESC : 'TestDescription'}
                     if self.USER_DEF_SCRIPT in cprim:
                         conf_prim[self.USER_DEF_SCRIPT] = \
                                         cprim.pop(self.USER_DEF_SCRIPT)
@@ -427,12 +601,24 @@ class YangNsd(ToscaResource):
                         for vnf_vld in vnf_vld_list:
                             vnfd.generate_vld_link(vld_link_name, vnf_vld[1])
 
+            for sub_mapping in self.substitution_mapping_forwarder:
+                if sub_mapping[0] == vnfd.name:
+                    vnfd.generate_forwarder_sub_mapping(sub_mapping)
+
+            for vnfd_name, cp_name in self.vnfd_sfc_map.items():
+                if vnfd.name == vnfd_name:
+                    vnfd.generate_sfc_link(cp_name)
+
+
 
             tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vnfd.name] = node
 
         for vld_node_name in self.vlds:
             tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vld_node_name] = self.vlds[vld_node_name]
 
+        for fp_name, fp in self.forwarding_paths.items():
+            tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][fp_name] = fp
+
         # add the config primitives
         if len(self.conf_prims):
             if self.GROUPS not in tosca[self.TOPOLOGY_TMPL]:
@@ -451,8 +637,8 @@ class YangNsd(ToscaResource):
             conf_prims[self.PROPERTIES] = {
                 self.PRIMITIVES: prims
             }
-
-            tosca[self.TOPOLOGY_TMPL][self.GROUPS][self.CONF_PRIM] = conf_prims
+            conf_prims[self.DESC] = 'Test'
+            #tosca[self.TOPOLOGY_TMPL][self.GROUPS][self.CONF_PRIM] = conf_prims
 
 
         # Add the scale group
@@ -493,6 +679,13 @@ class YangNsd(ToscaResource):
             for placment_group in self.placement_groups:
                 tosca[self.TOPOLOGY_TMPL][self.POLICIES].append(placment_group)
 
+        if len(self.vnffgds) > 0:
+            if self.GROUPS not in tosca[self.TOPOLOGY_TMPL]:
+                tosca[self.TOPOLOGY_TMPL][self.GROUPS] = {}
+            for vnffgd_name in self.vnffgds:
+                tosca[self.TOPOLOGY_TMPL][self.GROUPS][vnffgd_name] = self.vnffgds[vnffgd_name]
+
+
         return tosca
 
     def get_supporting_files(self):
index 3786d86..2d82872 100644 (file)
@@ -87,6 +87,7 @@ class YangVdu(ToscaResource):
         self.cp_name_to_cp_node = {}
         self.pinning_epa_prop   = {}
         self.mem_page_guest_epa = None
+        self.conn_point_to_conection_node = {}
 
     def process_vdu(self):
         self.log.debug(_("Process VDU desc {0}: {1}").format(self.name,
@@ -223,6 +224,11 @@ class YangVdu(ToscaResource):
 
         self.remove_ignored_fields(vdu_dic)
 
+        for cp in self.ext_cp:
+            cp_name = cp[self.NAME].replace('/', '_')
+            self.conn_point_to_conection_node[cp[self.NAME]] = cp_name
+
+
         if len(vdu_dic):
             self.log.warn(_("{0}, Did not process the following in "
                             "VDU: {1}").
index 1094c14..ec21e3c 100644 (file)
@@ -56,6 +56,7 @@ class YangVnfd(ToscaResource):
         self.vnf_type = None
         self.tosca = None
         self.script_files = []
+        self.service_function_type = None
 
     def handle_yang(self):
         self.log.debug(_("Process VNFD desc {0}: {1}").format(self.name,
@@ -197,6 +198,9 @@ class YangVnfd(ToscaResource):
                                     "connection-point {1}: {2}").
                                   format(self, name, cp_dic))
 
+        def process_service_type(dic):
+            self.service_function_type = dic['service_function_type']
+
         ENDPOINTS_MAP = {
             self.MGMT_INTF: process_mgmt_intf,
             self.HTTP_EP:  process_http_ep,
@@ -224,6 +228,9 @@ class YangVnfd(ToscaResource):
             if self.VNF_CONFIG in dic:
                 process_vnf_config(dic.pop(self.VNF_CONFIG))
 
+            if 'service_function_type' in dic:
+                process_service_type(dic)
+
             self.remove_ignored_fields(dic)
             if len(dic):
                 self.log.warn(_("{0}, Did not process the following for "
@@ -243,7 +250,8 @@ class YangVnfd(ToscaResource):
                 vdu.set_vld(cp_name, vld_name)
                 break
     def _generate_vnf_type(self, tosca):
-        name = self.name.split('_', 1)[0]
+        name = self.name.replace("_","")
+        name = name.split('_', 1)[0]
         self.vnf_type = "{0}{1}{2}".format(self.vnf_prefix_type, name, 'VNF')
         if self.NODE_TYPES not in tosca and self.vnf_type:
             tosca[self.NODE_TYPES] = {}
@@ -362,7 +370,28 @@ class YangVnfd(ToscaResource):
             self.tosca[self.NODE_TYPES][self.vnf_type][self.REQUIREMENTS] = []
         self.tosca[self.NODE_TYPES][self.vnf_type][self.REQUIREMENTS].append({virtualLink : {
                                                                         "type": "tosca.nodes.nfv.VL"}})
+    def generate_forwarder_sub_mapping(self, sub_link):
+        if self.CAPABILITIES not in self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]:
+            self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING][self.CAPABILITIES] = {}
+            self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING][self.CAPABILITIES]
 
+        self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING][self.CAPABILITIES][sub_link[1]] = \
+                            "[{}, forwarder]".format(sub_link[2])
+
+    def generate_sfc_link(self, sfs_conn_point_name):
+        for vdu in self.vdus:
+            if sfs_conn_point_name in vdu.cp_name_to_cp_node:
+                 conn_point_node_name = vdu.cp_name_to_cp_node[sfs_conn_point_name]
+                 if conn_point_node_name in self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL]:
+                    if self.CAPABILITIES not in  self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL]:
+                        self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][conn_point_node_name][self.CAPABILITIES] = {}
+                    self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][conn_point_node_name][self.CAPABILITIES]['sfc'] =  {self.PROPERTIES: {}}
+                    self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][conn_point_node_name] \
+                            [self.CAPABILITIES]['sfc'][self.PROPERTIES]['sfc_type'] = 'sf'
+
+                    if self.service_function_type:
+                        self.tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][conn_point_node_name] \
+                                [self.CAPABILITIES]['sfc'][self.PROPERTIES]['sf_type'] = self.service_function_type
 
     def generate_tosca(self):
         tosca = {}