summaryrefslogtreecommitdiffstats
path: root/app/toscalib/templates/node.py
diff options
context:
space:
mode:
authorStone, Avi (as206k) <as206k@att.com>2018-04-12 16:41:45 +0300
committerStone, Avi (as206k) <as206k@att.com>2018-04-12 16:41:45 +0300
commit879e94b78193798e8b170fca9b924d2c3881f7ba (patch)
tree150de697138a7593869eaae455add025b06a6e04 /app/toscalib/templates/node.py
parent7e02c7aaab14828ef8baaef98865f26d98e3b795 (diff)
DCAE-D tosca-lab initial commit
DCAE-D tosca-lab initial commit Change-Id: Ia42934ce7c75abe05fa106585c9334c8b048ee36 Issue-ID: SDC-1218 Signed-off-by: Stone, Avi (as206k) <as206k@att.com>
Diffstat (limited to 'app/toscalib/templates/node.py')
-rw-r--r--app/toscalib/templates/node.py389
1 files changed, 389 insertions, 0 deletions
diff --git a/app/toscalib/templates/node.py b/app/toscalib/templates/node.py
new file mode 100644
index 0000000..8a07a49
--- /dev/null
+++ b/app/toscalib/templates/node.py
@@ -0,0 +1,389 @@
+from toscalib.templates.constant import *
+from toscalib.types.node import NodeType
+from toscalib.templates.requirement_item import RequirementItem
+from toscalib.templates.property_item import PropertyItem
+from toscalib.templates.capability_item import CapabilityItem
+from toscalib.utils import tosca_import, tosca_heat
+
+import copy, re, logging
+from toscalib.templates.interface_item import InterfaceItem
+#Author: Shu Shi
+#emaiL: shushi@research.att.com
+
+
+
+class Node(object):
+ def __init__(self, template, node_name, node_type):
+ self.template = template
+ self.name = node_name
+ self.id = PropertyItem(node_type.id)
+ self_id_str = {}
+ self_id_str['get_attribute']= [node_name, 'id']
+ self.id._assign(self_id_str)
+
+ self.mapping_template = None
+ self.tran_template = None
+
+ self.fe_json = None
+ self.fe_nid = None
+
+ if node_type is None:
+ logging.warning( 'Empty node type')
+ return
+ elif isinstance(node_type, NodeType) is False:
+ logging.warning( 'Invalid NodeType passed to Node: '+ node_name+ 'construction')
+ return
+ else:
+ self._instatiateWithType(node_type)
+
+#Instantiate the node type, when substitution mapping is attached, create the new template for it
+ def _instatiateWithType(self, node_type):
+ self.type = node_type.name
+ self.type_obj = node_type
+
+ self.properties = {}
+ for prop in node_type.properties.keys():
+ self.properties[prop] = PropertyItem(node_type.properties[prop])
+
+ self.attributes = {}
+ for attr in node_type.attributes.keys():
+ self.attributes[attr] = PropertyItem(node_type.attributes[attr])
+
+ self.requirements = []
+ for req in node_type.requirements:
+ self.requirements.append(RequirementItem(req))
+
+ self.capabilities = {}
+ for cap in node_type.capabilities.keys():
+ self.capabilities[cap] = CapabilityItem(node_type.capabilities[cap])
+
+ self.interfaces = {}
+ for intf in node_type.interfaces.keys():
+ self.interfaces[intf] = InterfaceItem(node_type.interfaces[intf])
+
+ if node_type.mapping_template is not None:
+ from toscalib.templates.topology import ToscaTopology
+ self.mapping_template = copy.deepcopy(node_type.mapping_template)
+ self.mapping_template._update_prefix(self.name + '_')
+ self.mapping_template._verify_substitution(self)
+# for sub_rule in node_type.mapping_template.sub_rules:
+# sub_rule._update_pointer(self, self.mapping_template)
+
+ self._update_parent_node()
+
+#used to parse node template structure written in a template
+#Assign values if needed
+#For requirement fulfillment, add pending mode to check whether the value is a node template or type
+ def _parse_pre_defined_content(self, content):
+# if content.has_key(NOD_PROPERTIES):
+ if NOD_PROPERTIES in content:
+ prop_sec = content[NOD_PROPERTIES]
+ if prop_sec is not None:
+ for prop_name in prop_sec.keys():
+ prop_item = self._get_property_item(prop_name)
+ if prop_item is not None:
+ prop_item._assign(prop_sec[prop_name])
+ if prop_sec[prop_name] == '__GET_NODE_NAME__':
+ prop_item._assign(self.name)
+
+# if content.has_key(NOD_REQUIREMENTS):
+ if NOD_REQUIREMENTS in content:
+ req_sec = content[NOD_REQUIREMENTS]
+ if req_sec is not None:
+ for req in req_sec:
+ req_item_name, req_item_value = tosca_import._parse_requirement_name_and_value(req)
+#TODO: the same requirement name can only appear once!!
+ req_item = self._get_requirement_item_first(req_item_name)
+ if req_item is not None:
+ req_item._parse_pre_defined_content(req_item_value)
+ else:
+ logging.warning( 'Requirement '+ req_item_name +'not defined in Node '+ self.name + ' of type '+ self.type)
+
+# if content.has_key(NOD_CAPABILITIES):
+ if NOD_CAPABILITIES in content:
+ cap_sec = content[NOD_CAPABILITIES]
+ if cap_sec is not None:
+ for cap_name in cap_sec.keys():
+ cap_item = self._get_capability_item(cap_name)
+ if cap_item is not None:
+ cap_item._parse_pre_defined_content(cap_sec[cap_name])
+
+# if content.has_key(NOD_INTERFACES):
+ if NOD_INTERFACES in content:
+ interface_sec = content[NOD_INTERFACES]
+ if interface_sec is not None:
+ for interface_name in interface_sec.keys():
+ interface_item = self._get_interface_item(interface_name)
+ if interface_item is not None:
+ interface_item._parse_pre_defined_content(interface_sec[interface_name])
+ else:
+ self.interfaces[interface_name] = InterfaceItem(None, interface_name, interface_sec[interface_name])
+
+ self._update_parent_node()
+
+ def _get_property_item(self, prop_name):
+# if self.properties.has_key(prop_name):
+ if prop_name in self.properties:
+ return self.properties[prop_name]
+ else:
+ logging.warning('Node: '+ self.name+ ' of type: '+ self.type+ ' has no property: '+ prop_name)
+ return None
+
+ def _get_attribute_item(self, attr_name):
+# if self.attributes.has_key(attr_name):
+ if attr_name in self.attributes:
+ return self.attributes[attr_name]
+ else:
+ logging.warning('Node: '+ self.name+ ' of type: '+ self.type+ ' has no attribute: '+ attr_name)
+ return None
+
+ def _get_interface_item(self, interface_name):
+# if self.interfaces.has_key(interface_name):
+ if interface_name in self.interfaces:
+ return self.interfaces[interface_name]
+ else:
+ logging.warning( 'Node: '+ self.name+ ' of type: '+ self.type+ ' has no interface: '+ interface_name)
+ return None
+
+ def _get_capability_item(self, cap_name):
+# if self.capabilities.has_key(cap_name):
+ if cap_name in self.capabilities:
+ return self.capabilities[cap_name]
+ else:
+ #logging.debug('Node: '+ self.name+ ' of type: '+ self.type+ ' has no capability: '+ cap_name)
+ return None
+
+ def _get_capability_property(self, cap_name, prop_name):
+ cap_item = self._get_capability_item(cap_name)
+ if cap_item is not None:
+ return cap_item._get_property_item(prop_name)
+ else:
+ #logging.debug( 'Node: '+ self.name+ ' of type: '+ self.type+ ' has no capability: '+ cap_name)
+ return None
+
+ def _get_requirement_item_first(self, req_name):
+ for req_item in self.requirements:
+ if req_item.name == req_name:
+ return req_item
+ logging.warning( 'Node: '+ self.name+ ' of type: '+ self.type+ ' has no requirement: '+ req_name)
+ return None
+
+ def _verify_requirements(self, node_dict):
+ for req in self.requirements:
+ req._verify_requirement(node_dict)
+
+ def _verify_functions(self):
+ if self.id.value is not None:
+ self.id.value._update_function_reference(self.template, self, self.id)
+ for prop_item in iter(self.properties.values()):
+ if prop_item.value is not None:
+ prop_item.value._update_function_reference(self.template, self, prop_item)
+ for cap_item in iter(self.capabilities.values()):
+ for cap_item_prop in iter(cap_item.properties.values()):
+ if cap_item_prop.value is not None:
+ cap_item_prop.value._update_function_reference(self.template, self, cap_item_prop)
+ for interface_item in iter(self.interfaces.values()):
+ for interface_item_input in iter(interface_item.inputs.values()):
+ if interface_item_input.value is not None:
+ interface_item_input.value._update_function_reference(self.template, self, interface_item_input)
+ for operation_item in iter(interface_item.operations.values()):
+ for input_item in iter(operation_item.inputs.values()):
+ if input_item.value is not None:
+ input_item.value._update_function_reference(self.template, self, input_item)
+
+ def _update_parent_node(self):
+ for prop in iter(self.properties.values()):
+ prop._update_parent_node(self)
+ for cap in iter(self.capabilities.values()):
+ cap._update_parent_node(self)
+ for req in self.requirements:
+ req._update_parent_node(self)
+ for interface in iter(self.interfaces.values()):
+ interface._update_parent_node(self)
+
+
+ def _update_prefix(self, prefix):
+ if self.name == 'NO_PREFIX':
+ self.name = prefix[:len(prefix)-1]
+ else:
+ self.name = prefix + self.name
+ self.id.value._update_prefix(prefix)
+
+ for prop_item in iter(self.properties.values()):
+ if prop_item.value is not None:
+ prop_item.value._update_prefix(prefix)
+ for cap_item in iter(self.capabilities.values()):
+ for cap_item_prop in iter(cap_item.properties.values()):
+ if cap_item_prop.value is not None:
+ cap_item_prop.value._update_prefix(prefix)
+ for interface_item in iter(self.interfaces.values()):
+ for interface_item_input in iter(interface_item.inputs.values()):
+ if interface_item_input.value is not None:
+ interface_item_input.value._update_prefix(prefix)
+ for operation_item in iter(interface_item.operations.values()):
+ for input_item in iter(operation_item.inputs.values()):
+ if input_item.value is not None:
+ input_item.value._update_prefix(prefix)
+
+ for req in self.requirements:
+ req._update_prefix(prefix)
+
+ self._update_parent_node()
+
+ def _verify_req_node(self, req_type, req_cap, req_filter):
+ if req_type is not None and self.type_obj._verify_req_type(req_type) is False:
+ logging.warning( 'Type matching failed')
+ return False
+
+ if req_cap is not None:
+ cap_found = None
+ for cap_item in iter(self.capabilities.values()):
+ if cap_item._validate_capability(req_cap) is True:
+ cap_found = cap_item
+ break
+ if cap_found is None:
+ logging.warning( 'Capability matching failed')
+ return False
+
+ return self._verify_node_filter(req_filter)
+
+ def _verify_node_filter(self, req_filter):
+ return True
+
+ def _propagate_substitution_value(self):
+ converge = True
+ for prop_item in iter(self.properties.values()):
+ converge = converge and prop_item._propagate_substitution_value()
+ for req_item in self.requirements:
+ converge = converge and req_item._propagate_substitution_value()
+ for cap_item in iter(self.capabilities.values()):
+ converge = converge and cap_item._propagate_substitution_value()
+ for attr_item in iter(self.attributes.values()):
+ converge = converge and attr_item._propagate_attr_substitution_value()
+
+
+ if self.mapping_template is not None:
+ self.mapping_template._propagate_substitution_value()
+ if self.tran_template is not None:
+ self.tran_template._propagate_substitution_value()
+
+ return converge
+
+ def _prepare_extra_imports(self, tags = ''):
+ if 'noexpand' in tags:
+ return []
+ if self.tran_template is not None:
+ return self.tran_template._prepare_extra_imports(tags)
+ if self.mapping_template is not None:
+ return self.mapping_template._prepare_extra_imports(tags)
+ return []
+
+ def _prepare_output(self, tags=''):
+ if 'noexpand' not in tags:
+ newtags = tags.replace('main', 'part')
+ if self.tran_template is not None:
+ return self.tran_template._prepare_output(newtags)
+ if self.mapping_template is not None:
+ return self.mapping_template._prepare_output(newtags)
+ output = {}
+ if 'heat' in tags:
+ heat_type = re.sub('tosca.heat.', '', self.type)
+ heat_type = re.sub('\.', '::', heat_type)
+ output[YMO_NOD_TYPE] = heat_type
+ else:
+ output[YMO_NOD_TYPE] = self.type
+ prop_out = {}
+ for prop in self.properties.keys():
+ prop_item = self.properties[prop]
+# if prop_item.required is False and prop_item.used is not True and prop_item.filled is not True:
+ if prop_item.required is False and prop_item.filled is not True:
+ continue
+ if prop_item.filled is not True or prop_item.value is None:
+ prop_value = None
+ else:
+ prop_value = prop_item.value._get_value(tags)[0]
+ if prop_item.required is False and prop_value in [None, [], {}]:
+ continue
+ else:
+ prop_out[prop] = prop_value
+ cap_out={}
+ for cap in iter(self.capabilities.values()):
+ cap_item = {}
+ for cap_prop in iter(cap.properties.values()):
+ if cap_prop.filled is True:
+ cap_item[cap_prop.name] = cap_prop.value._get_value(tags)[0]
+ if len(cap_item) > 0:
+ cap_out[cap.name] = {'properties': cap_item}
+
+ req_out = []
+ for req in self.requirements:
+ if req.filled is True:
+ req_item = dict()
+ if 'cloudify' in tags:
+ if req.relationship is not None :
+ req_item['type'] = req.relationship
+ else:
+ req_item['type'] = 'cloudify.relationships.connected_to'
+ req_item['target'] = req.str_value
+ else:
+ req_item[req.name] = req.str_value
+ req_out.append(req_item)
+ elif req.filter is not None and 'cloudify' not in tags:
+ req_item = {}
+ if req.req_capability is not None:
+ req_item[YMO_REQ_CAPABILITY] = req.req_capability
+ if req.req_type is not None:
+ req_item[YMO_REQ_NODE] = req.req_type
+ if req.relationship is not None:
+ req_item[YMO_REQ_RELATIONSHIP] = req.relationship
+ req_item[YMO_REQ_FILTER] = req.filter
+ req_out.append({req.name:req_item})
+ int_out = {}
+ for interface_name in self.interfaces.keys():
+ int_out[interface_name] = self.interfaces[interface_name]._prepare_output(tags)
+
+ if len(prop_out) > 0:
+ output[YMO_NOD_PROPERTIES]=prop_out
+ if len(req_out) > 0 and 'java_sim' not in tags:
+ if 'cloudify' in tags:
+ output[YMO_NOD_RELATIONSHIPS] = req_out
+ else:
+ output[YMO_NOD_REQUIREMENTS] = req_out
+ if len(cap_out) > 0 and 'cloudify' not in tags:
+ output[YMO_NOD_CAPABILITIES] = cap_out
+ if len(int_out) > 0 :
+ output[YMO_NOD_INTERFACES] = int_out
+ final_out = {}
+ final_out[self.name] = output
+ return final_out
+
+ def _prepare_heat_output(self, parameters_type, parameters_val):
+ if self.mapping_template is not None:
+ return self.mapping_template._prepare_heat_output(parameters_type, parameters_val, True)
+ else:
+ if tosca_heat._type_validate(self.type) is not True:
+ return None
+ output = {}
+ output[YMO_NOD_TYPE] = tosca_heat._type_translate(self.type)
+ prop_out = {}
+ for prop_item in iter(self.properties.values()):
+ if prop_item.filled:
+ prop_out[prop_item.name] = prop_item.value
+ else:
+ input_name = self.name + '_' + prop_item.name
+ prop_out[prop_item.name] = '{ get_param: ' + input_name + ' }'
+ input_type = {}
+ input_type[input_name] = prop_item.type
+ input_val = {}
+ input_val[input_name] = prop_item.value
+ parameters_type.update(input_type)
+ parameters_val.udpate(input_val)
+ if len(prop_out) > 0:
+ output[YMO_NOD_PROPERTIES] = prop_out
+ final_out = {}
+ final_out[self.name] = output
+ return final_out
+
+
+ def toJson(self):
+ return self.fe_json \ No newline at end of file