diff options
Diffstat (limited to 'app/toscalib/templates/node.py')
-rw-r--r-- | app/toscalib/templates/node.py | 389 |
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 |