You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by mx...@apache.org on 2017/07/25 12:34:47 UTC
[1/2] incubator-ariatosca git commit: removed all unnecessary method
from models into the topology package
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-174-Refactor-instantiation-phase a9640765a -> 4ae0e5f99
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/orchestrator/topology/template.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/template.py b/aria/orchestrator/topology/template.py
index 86619a9..8b78c7a 100644
--- a/aria/orchestrator/topology/template.py
+++ b/aria/orchestrator/topology/template.py
@@ -21,30 +21,30 @@ from . import utils, common
class ServiceTemplate(common._TemplateHandler):
def dump(self, context):
- if self._template.description is not None:
- context.write(context.style.meta(self._template.description))
- self._topology.dump(self._template.meta_data, context, 'Metadata')
- for node_template in self._template.node_templates.itervalues():
+ if self._model.description is not None:
+ context.write(context.style.meta(self._model.description))
+ self._topology.dump(self._model.meta_data, context, 'Metadata')
+ for node_template in self._model.node_templates.itervalues():
node_template.dump()
- for group_template in self._template.group_templates.itervalues():
+ for group_template in self._model.group_templates.itervalues():
group_template.dump()
- for policy_template in self._template.policy_templates.itervalues():
+ for policy_template in self._model.policy_templates.itervalues():
policy_template.dump()
- if self._template.substitution_template is not None:
- self._template.substitution_template.dump()
- self._topology.dump(self._template.inputs, context, 'Inputs')
- self._topology.dump(self._template.outputs, context, 'Outputs')
- self._topology.dump(self._template.workflow_templates, context, 'Workflow templates')
+ if self._model.substitution_template is not None:
+ self._model.substitution_template.dump()
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ self._topology.dump(self._model.outputs, context, 'Outputs')
+ self._topology.dump(self._model.workflow_templates, context, 'Workflow templates')
def coerce(self, **kwargs):
- self._coerce(self._template.meta_data,
- self._template.node_templates,
- self._template.group_templates,
- self._template.policy_templates,
- self._template.substitution_template,
- self._template.inputs,
- self._template.outputs,
- self._template.workflow_templates,
+ self._coerce(self._model.meta_data,
+ self._model.node_templates,
+ self._model.group_templates,
+ self._model.policy_templates,
+ self._model.substitution_template,
+ self._model.inputs,
+ self._model.outputs,
+ self._model.workflow_templates,
**kwargs)
def instantiate(self, instance_cls, inputs=None):
@@ -52,12 +52,12 @@ class ServiceTemplate(common._TemplateHandler):
service = instance_cls(
created_at=now,
updated_at=now,
- description=utils.deepcopy_with_locators(self._template.description),
- service_template=self._template,
- inputs=modeling_utils.merge_parameter_values(inputs, self._template.inputs)
+ description=utils.deepcopy_with_locators(self._model.description),
+ service_template=self._model,
+ inputs=modeling_utils.merge_parameter_values(inputs, self._model.inputs)
)
- for plugin_specification in self._template.plugin_specifications.itervalues():
+ for plugin_specification in self._model.plugin_specifications.itervalues():
if plugin_specification.enabled and self._topology._model_storage:
if utils.resolve_plugin_specification(plugin_specification,
self._topology.model_storage.plugin.list()):
@@ -68,262 +68,320 @@ class ServiceTemplate(common._TemplateHandler):
pass
# self._context.validation.report('specified plugin not found: {0}'.format(
# plugin_specification.name), level=validation.Issue.EXTERNAL)
- service.meta_data = self._topology.instantiate(self._template.meta_data)
+ service.meta_data = self._topology.instantiate(self._model.meta_data)
- for node_template in self._template.node_templates.itervalues():
- for _ in range(node_template.scaling['default_instances']):
+ for node_template in self._model.node_templates.itervalues():
+ for _ in range(self._scaling(node_template)['default_instances']):
node = self._topology.instantiate(node_template)
service.nodes[node.name] = node
- service.groups = self._topology.instantiate(self._template.group_templates)
- service.policies = self._topology.instantiate(self._template.policy_templates)
- service.workflows = self._topology.instantiate(self._template.workflow_templates)
+ service.groups = self._topology.instantiate(self._model.group_templates)
+ service.policies = self._topology.instantiate(self._model.policy_templates)
+ service.workflows = self._topology.instantiate(self._model.workflow_templates)
- if self._template.substitution_template is not None:
- service.substitution = self._topology.instantiate(self._template.substitution_template)
- service.outputs = self._topology.instantiate(self._template.outputs)
+ if self._model.substitution_template is not None:
+ service.substitution = self._topology.instantiate(self._model.substitution_template)
+ service.outputs = self._topology.instantiate(self._model.outputs)
return service
+ @staticmethod
+ def _scaling(node_template):
+ scaling = {}
+
+ def extract_property(properties, name):
+ if name in scaling:
+ return
+ prop = properties.get(name)
+ if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
+ scaling[name] = prop.value
+
+ def extract_properties(properties):
+ extract_property(properties, 'min_instances')
+ extract_property(properties, 'max_instances')
+ extract_property(properties, 'default_instances')
+
+ def default_property(name, value):
+ if name not in scaling:
+ scaling[name] = value
+
+ # From our scaling capabilities
+ for capability_template in node_template.capability_templates.itervalues():
+ if capability_template.type.role == 'scaling':
+ extract_properties(capability_template.properties)
+
+ # From service scaling policies
+ for policy_template in node_template.service_template.policy_templates.itervalues():
+ if policy_template.type.role == 'scaling':
+ if policy_template.is_for_node_template(node_template.name):
+ extract_properties(policy_template.properties)
+
+ # Defaults
+ default_property('min_instances', 0)
+ default_property('max_instances', 1)
+ default_property('default_instances', 1)
+
+ # Validate
+ # pylint: disable=too-many-boolean-expressions
+ if (scaling['min_instances'] < 0 or
+ scaling['max_instances'] < 0 or
+ scaling['default_instances'] < 0 or
+ scaling['max_instances'] < scaling['min_instances'] or
+ scaling['default_instances'] < scaling['min_instances'] or
+ scaling['default_instances'] > scaling['max_instances']):
+ pass
+ # TODO: fix this
+ # context = ConsumptionContext.get_thread_local()
+ # context.validation.report('invalid scaling parameters for node template "{0}": '
+ # 'min={1}, max={2}, default={3}'.format(
+ # self.name,
+ # scaling['min_instances'],
+ # scaling['max_instances'],
+ # scaling['default_instances']),
+ # level=validation.Issue.BETWEEN_TYPES)
+
+ return scaling
+
+
def validate(self):
- self._topology.validate(self._template.meta_data)
- self._topology.validate(self._template.node_templates)
- self._topology.validate(self._template.group_templates)
- self._topology.validate(self._template.policy_templates)
- self._topology.validate(self._template.substitution_template)
- self._topology.validate(self._template.inputs)
- self._topology.validate(self._template.outputs)
- self._topology.validate(self._template.workflow_templates)
- self._topology.validate(self._template.node_types)
- self._topology.validate(self._template.group_types)
- self._topology.validate(self._template.policy_types)
- self._topology.validate(self._template.relationship_types)
- self._topology.validate(self._template.capability_types)
- self._topology.validate(self._template.interface_types)
- self._topology.validate(self._template.artifact_types)
+ self._topology.validate(self._model.meta_data)
+ self._topology.validate(self._model.node_templates)
+ self._topology.validate(self._model.group_templates)
+ self._topology.validate(self._model.policy_templates)
+ self._topology.validate(self._model.substitution_template)
+ self._topology.validate(self._model.inputs)
+ self._topology.validate(self._model.outputs)
+ self._topology.validate(self._model.workflow_templates)
+ self._topology.validate(self._model.node_types)
+ self._topology.validate(self._model.group_types)
+ self._topology.validate(self._model.policy_types)
+ self._topology.validate(self._model.relationship_types)
+ self._topology.validate(self._model.capability_types)
+ self._topology.validate(self._model.interface_types)
+ self._topology.validate(self._model.artifact_types)
class ArtifactTemplate(common._TemplateHandler):
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Artifact type: {0}'.format(context.style.type(self._template.type.name)))
- context.write('Source path: {0}'.format(context.style.literal(self._template.source_path)))
- if self._template.target_path is not None:
- context.write('Target path: {0}'.format(context.style.literal(self._template.target_path)))
- if self._template.repository_url is not None:
+ context.write('Artifact type: {0}'.format(context.style.type(self._model.type.name)))
+ context.write('Source path: {0}'.format(context.style.literal(self._model.source_path)))
+ if self._model.target_path is not None:
+ context.write('Target path: {0}'.format(context.style.literal(self._model.target_path)))
+ if self._model.repository_url is not None:
context.write('Repository URL: {0}'.format(
- context.style.literal(self._template.repository_url)))
- if self._template.repository_credential:
+ context.style.literal(self._model.repository_url)))
+ if self._model.repository_credential:
context.write('Repository credential: {0}'.format(
- context.style.literal(self._template.repository_credential)))
- self._topology.dump(self._template.properties, context, 'Properties')
+ context.style.literal(self._model.repository_credential)))
+ self._topology.dump(self._model.properties, context, 'Properties')
def coerce(self, **kwargs):
- self._topology.coerce(self._template.properties, **kwargs)
+ self._topology.coerce(self._model.properties, **kwargs)
def instantiate(self, instance_cls):
return instance_cls(
- name=self._template.name,
- type=self._template.type,
- description=utils.deepcopy_with_locators(self._template.description),
- source_path=self._template.source_path,
- target_path=self._template.target_path,
- repository_url=self._template.repository_url,
- repository_credential=self._template.repository_credential,
- artifact_template=self._template)
+ name=self._model.name,
+ type=self._model.type,
+ description=utils.deepcopy_with_locators(self._model.description),
+ source_path=self._model.source_path,
+ target_path=self._model.target_path,
+ repository_url=self._model.repository_url,
+ repository_credential=self._model.repository_credential,
+ artifact_template=self._model)
def validate(self):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
class CapabilityTemplate(common._TemplateHandler):
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
context.write(
'Occurrences: {0:d}{1}'.format(
- self._template.min_occurrences or 0,
- ' to {0:d}'.format(self._template.max_occurrences)
- if self._template.max_occurrences is not None
+ self._model.min_occurrences or 0,
+ ' to {0:d}'.format(self._model.max_occurrences)
+ if self._model.max_occurrences is not None
else ' or more'))
- if self._template.valid_source_node_types:
+ if self._model.valid_source_node_types:
context.write('Valid source node types: {0}'.format(
', '.join((str(context.style.type(v.name))
- for v in self._template.valid_source_node_types))))
- self._topology.dump(self._template.properties, context, 'Properties')
+ for v in self._model.valid_source_node_types))))
+ self._topology.dump(self._model.properties, context, 'Properties')
def coerce(self):
- self._topology.coerce(self._template.properties)
+ self._topology.coerce(self._model.properties)
def instantiate(self, instance_cls):
- return instance_cls(name=self._template.name,
- type=self._template.type,
- min_occurrences=self._template.min_occurrences,
- max_occurrences=self._template.max_occurrences,
+ return instance_cls(name=self._model.name,
+ type=self._model.type,
+ min_occurrences=self._model.min_occurrences,
+ max_occurrences=self._model.max_occurrences,
occurrences=0,
- capability_template=self._template)
+ capability_template=self._model)
def validate(self):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
class RequirementTemplate(common._TemplateHandler):
def dump(self, context):
- if self._template.name:
- context.write(context.style.node(self._template.name))
+ if self._model.name:
+ context.write(context.style.node(self._model.name))
else:
context.write('Requirement:')
with context.style.indent:
- if self._template.target_node_type is not None:
+ if self._model.target_node_type is not None:
context.write('Target node type: {0}'.format(
- context.style.type(self._template.target_node_type.name)))
- elif self._template.target_node_template is not None:
+ context.style.type(self._model.target_node_type.name)))
+ elif self._model.target_node_template is not None:
context.write('Target node template: {0}'.format(
- context.style.node(self._template.target_node_template.name)))
- if self._template.target_capability_type is not None:
+ context.style.node(self._model.target_node_template.name)))
+ if self._model.target_capability_type is not None:
context.write('Target capability type: {0}'.format(
- context.style.type(self._template.target_capability_type.name)))
- elif self._template.target_capability_name is not None:
+ context.style.type(self._model.target_capability_type.name)))
+ elif self._model.target_capability_name is not None:
context.write('Target capability name: {0}'.format(
- context.style.node(self._template.target_capability_name)))
- if self._template.target_node_template_constraints:
+ context.style.node(self._model.target_capability_name)))
+ if self._model.target_node_template_constraints:
context.write('Target node template constraints:')
with context.style.indent:
- for constraint in self._template.target_node_template_constraints:
+ for constraint in self._model.target_node_template_constraints:
context.write(context.style.literal(constraint))
- if self._template.relationship_template:
+ if self._model.relationship_template:
context.write('Relationship:')
with context.style.indent:
- self._template.relationship_template.dump()
+ self._model.relationship_template.dump()
def coerce(self, **kwargs):
- self._topology.coerce(self._template.relationship_template, **kwargs)
+ self._topology.coerce(self._model.relationship_template, **kwargs)
def instantiate(self, instance_cls):
- return instance_cls(name=self._template.name,
- type=self._template.type,
- min_occurrences=self._template.min_occurrences,
- max_occurrences=self._template.max_occurrences,
+ return instance_cls(name=self._model.name,
+ type=self._model.type,
+ min_occurrences=self._model.min_occurrences,
+ max_occurrences=self._model.max_occurrences,
occurrences=0,
- capability_template=self._template)
+ capability_template=self._model)
def validate(self):
- self._topology.validate(self._template.relationship_template)
+ self._topology.validate(self._model.relationship_template)
class GroupTemplate(common._TemplateHandler):
def dump(self, context):
- context.write('Group template: {0}'.format(context.style.node(self._template.name)))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write('Group template: {0}'.format(context.style.node(self._model.name)))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
- if self._template.node_templates:
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.interface_templates, context, 'Interface Templates')
+ if self._model.node_templates:
context.write('Member node templates: {0}'.format(', '.join(
- (str(context.style.node(v.name)) for v in self._template.node_templates))))
+ (str(context.style.node(v.name)) for v in self._model.node_templates))))
def coerce(self, **kwargs):
- self._coerce(self._template.properties,
- self._template.interface_templates,
+ self._coerce(self._model.properties,
+ self._model.interface_templates,
**kwargs)
def instantiate(self, instance_cls):
group = instance_cls(
- name=self._template.name,
- type=self._template.type,
- description=utils.deepcopy_with_locators(self._template.description),
- group_template=self._template)
- group.properties = self._topology.instantiate(self._template.properties)
- group.interfaces = self._topology.instantiate(self._template.interface_templates)
- if self._template.node_templates:
- for node_template in self._template.node_templates:
+ name=self._model.name,
+ type=self._model.type,
+ description=utils.deepcopy_with_locators(self._model.description),
+ group_template=self._model)
+ group.properties = self._topology.instantiate(self._model.properties)
+ group.interfaces = self._topology.instantiate(self._model.interface_templates)
+ if self._model.node_templates:
+ for node_template in self._model.node_templates:
group.nodes += node_template.nodes
return group
def validate(self):
- self._validate(self._template.properties,
- self._template.interface_templates)
+ self._validate(self._model.properties,
+ self._model.interface_templates)
class InterfaceTemplate(common._TemplateHandler):
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Interface type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.inputs, context, 'Inputs')
- self._topology.dump(self._template.operation_templates, context, 'Operation templates')
+ context.write('Interface type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ self._topology.dump(self._model.operation_templates, context, 'Operation templates')
def coerce(self, **kwargs):
- self._coerce(self._template.inputs,
- self._template.operation_templates,
+ self._coerce(self._model.inputs,
+ self._model.operation_templates,
**kwargs)
def instantiate(self, instance_cls):
interface = instance_cls(
- name=self._template.name,
- type=self._template.type,
- description=utils.deepcopy_with_locators(self._template.description),
- interface_template=self._template)
- interface.inputs = self._topology.instantiate(self._template.inputs)
- interface.operations = self._topology.instantiate(self._template.operation_templates)
+ name=self._model.name,
+ type=self._model.type,
+ description=utils.deepcopy_with_locators(self._model.description),
+ interface_template=self._model)
+ interface.inputs = self._topology.instantiate(self._model.inputs)
+ interface.operations = self._topology.instantiate(self._model.operation_templates)
return interface
def validate(self):
- self._validate(self._template.inputs,
- self._template.operation_templates)
+ self._validate(self._model.inputs,
+ self._model.operation_templates)
class NodeTemplate(common._TemplateHandler):
def dump(self, context):
- context.write('Node template: {0}'.format(context.style.node(self._template.name)))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write('Node template: {0}'.format(context.style.node(self._model.name)))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.attributes, context, 'Attributes')
- self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
- self._topology.dump(self._template.artifact_templates, context, 'Artifact templates')
- self._topology.dump(self._template.capability_templates, context, 'Capability templates')
- self._topology.dump(self._template.requirement_templates, context, 'Requirement templates')
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.attributes, context, 'Attributes')
+ self._topology.dump(self._model.interface_templates, context, 'Interface Templates')
+ self._topology.dump(self._model.artifact_templates, context, 'Artifact templates')
+ self._topology.dump(self._model.capability_templates, context, 'Capability templates')
+ self._topology.dump(self._model.requirement_templates, context, 'Requirement templates')
def coerce(self, **kwargs):
- self._coerce(self._template.properties,
- self._template.attributes,
- self._template.interface_templates,
- self._template.artifact_templates,
- self._template.capability_templates,
- self._template.requirement_templates,
+ self._coerce(self._model.properties,
+ self._model.attributes,
+ self._model.interface_templates,
+ self._model.artifact_templates,
+ self._model.capability_templates,
+ self._model.requirement_templates,
**kwargs)
def instantiate(self, instance_cls):
node = instance_cls(
- name=self._template._next_name,
- type=self._template.type,
- description=utils.deepcopy_with_locators(self._template.description),
- node_template=self._template
+ name=self._model._next_name,
+ type=self._model.type,
+ description=utils.deepcopy_with_locators(self._model.description),
+ node_template=self._model
)
- node.properties = self._topology.instantiate(self._template.properties)
- node.attributes = self._topology.instantiate(self._template.attributes)
- node.interfaces = self._topology.instantiate(self._template.interface_templates)
- node.artifacts = self._topology.instantiate(self._template.artifact_templates)
- node.capabilities = self._topology.instantiate(self._template.capability_templates)
+ node.properties = self._topology.instantiate(self._model.properties)
+ node.attributes = self._topology.instantiate(self._model.attributes)
+ node.interfaces = self._topology.instantiate(self._model.interface_templates)
+ node.artifacts = self._topology.instantiate(self._model.artifact_templates)
+ node.capabilities = self._topology.instantiate(self._model.capability_templates)
# Default attributes
if ('tosca_name' in node.attributes) \
and (node.attributes['tosca_name'].type_name == 'string'):
- node.attributes['tosca_name'].value = self._template.name
+ node.attributes['tosca_name'].value = self._model.name
if 'tosca_id' in node.attributes \
and (node.attributes['tosca_id'].type_name == 'string'):
node.attributes['tosca_id'].value = node.name
@@ -331,50 +389,50 @@ class NodeTemplate(common._TemplateHandler):
return node
def validate(self):
- self._validate(self._template.properties,
- self._template.attributes,
- self._template.interface_templates,
- self._template.artifact_templates,
- self._template.capability_templates,
- self._template.requirement_templates)
+ self._validate(self._model.properties,
+ self._model.attributes,
+ self._model.interface_templates,
+ self._model.artifact_templates,
+ self._model.capability_templates,
+ self._model.requirement_templates)
class PolicyTemplate(common._TemplateHandler):
def dump(self, context):
- context.write('Policy template: {0}'.format(context.style.node(self._template.name)))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write('Policy template: {0}'.format(context.style.node(self._model.name)))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- if self._template.node_templates:
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ if self._model.node_templates:
context.write('Target node templates: {0}'.format(', '.join(
- (str(context.style.node(v.name)) for v in self._template.node_templates))))
- if self._template.group_templates:
+ (str(context.style.node(v.name)) for v in self._model.node_templates))))
+ if self._model.group_templates:
context.write('Target group templates: {0}'.format(', '.join(
- (str(context.style.node(v.name)) for v in self._template.group_templates))))
+ (str(context.style.node(v.name)) for v in self._model.group_templates))))
def coerce(self, **kwargs):
- self._topology.coerce(self._template.properties, **kwargs)
+ self._topology.coerce(self._model.properties, **kwargs)
def instantiate(self, instance_cls):
policy = instance_cls(
- name=self._template.name,
- type=self._template.type,
- description=utils.deepcopy_with_locators(self._template.description),
- policy_template=self._template)
-
- policy.properties = self._topology.instantiate(self._template.properties)
- if self._template.node_templates:
- for node_template in self._template.node_templates:
+ name=self._model.name,
+ type=self._model.type,
+ description=utils.deepcopy_with_locators(self._model.description),
+ policy_template=self._model)
+
+ policy.properties = self._topology.instantiate(self._model.properties)
+ if self._model.node_templates:
+ for node_template in self._model.node_templates:
policy.nodes += node_template.nodes
- if self._template.group_templates:
- for group_template in self._template.group_templates:
+ if self._model.group_templates:
+ for group_template in self._model.group_templates:
policy.groups += group_template.groups
return policy
def validate(self):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
class SubstitutionTemplate(common._TemplateHandler):
@@ -382,18 +440,18 @@ class SubstitutionTemplate(common._TemplateHandler):
def dump(self, context):
context.write('Substitution template:')
with context.style.indent:
- context.write('Node type: {0}'.format(context.style.type(self._template.node_type.name)))
- self._topology.dump(self._template.mappings, context, 'Mappings')
+ context.write('Node type: {0}'.format(context.style.type(self._model.node_type.name)))
+ self._topology.dump(self._model.mappings, context, 'Mappings')
def coerce(self, **kwargs):
- self._topology.coerce(self._template.mappings, **kwargs)
+ self._topology.coerce(self._model.mappings, **kwargs)
def instantiate(self, instance_cls):
- return instance_cls(node_type=self._template.node_type,
- substitution_template=self._template)
+ return instance_cls(node_type=self._model.node_type,
+ substitution_template=self._model)
def validate(self):
- self._topology.validate(self._template.mappings)
+ self._topology.validate(self._model.mappings)
class SubstitutionTemplateMapping(common._TemplateHandler):
@@ -415,13 +473,13 @@ class SubstitutionTemplateMapping(common._TemplateHandler):
def instantiate(self, instance_cls):
substitution_mapping = instance_cls(
- name=self._template.name,
- requirement_template=self._template.requirement_template)
+ name=self._model.name,
+ requirement_template=self._model.requirement_template)
- if self._template.capability_template is not None:
- node_template = self._template.capability_template.node_template
+ if self._model.capability_template is not None:
+ node_template = self._model.capability_template.node_template
else:
- node_template = self._template.requirement_template.node_template
+ node_template = self._model.requirement_template.node_template
nodes = node_template.nodes
if len(nodes) == 0:
# TODO: manage the context report
@@ -434,10 +492,10 @@ class SubstitutionTemplateMapping(common._TemplateHandler):
# The TOSCA spec does not provide a way to choose the node,
# so we will just pick the first one
substitution_mapping.node = nodes[0]
- if self._template.capability_template:
+ if self._model.capability_template:
for a_capability in substitution_mapping.node.capabilities.itervalues():
if a_capability.capability_template.name == \
- self._template.capability_template.name:
+ self._model.capability_template.name:
substitution_mapping.capability = a_capability
return substitution_mapping
@@ -445,8 +503,8 @@ class SubstitutionTemplateMapping(common._TemplateHandler):
def validate(self):
# context = ConsumptionContext.get_thread_local()
if all([
- self._template.capability_template is None,
- self._template.requirement_template is None
+ self._model.capability_template is None,
+ self._model.requirement_template is None
]):
pass
# TODO: handle reporting
@@ -459,94 +517,94 @@ class SubstitutionTemplateMapping(common._TemplateHandler):
class RelationshipTemplate(common._TemplateHandler):
def dump(self, context):
- if self._template.type is not None:
- context.write('Relationship type: {0}'.format(context.style.type(self._template.type.name)))
+ if self._model.type is not None:
+ context.write('Relationship type: {0}'.format(context.style.type(self._model.type.name)))
else:
context.write('Relationship template: {0}'.format(
- context.style.node(self._template.name)))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.style.node(self._model.name)))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.interface_templates, context, 'Interface Templates')
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.interface_templates, context, 'Interface Templates')
def coerce(self, **kwargs):
- self._coerce(self._template.properties, self._template.interface_templates, **kwargs)
+ self._coerce(self._model.properties, self._model.interface_templates, **kwargs)
def instantiate(self, instance_cls):
relationship = instance_cls(
- name=self._template.name,
- type=self._template.type,
- relationship_template=self._template)
+ name=self._model.name,
+ type=self._model.type,
+ relationship_template=self._model)
- relationship.properties = self._topology.instantiate(self._template.properties)
- relationship.interfaces = self._topology.instantiate(self._template.interface_templates)
+ relationship.properties = self._topology.instantiate(self._model.properties)
+ relationship.interfaces = self._topology.instantiate(self._model.interface_templates)
return relationship
def validate(self):
# TODO: either type or name must be set
- self._validate(self._template.properties,
- self._template.interface_templates)
+ self._validate(self._model.properties,
+ self._model.interface_templates)
class OperationTemplate(common._TemplateHandler):
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- if self._template.implementation is not None:
+ if self._model.implementation is not None:
context.write('Implementation: {0}'.format(
- context.style.literal(self._template.implementation)))
- if self._template.dependencies:
+ context.style.literal(self._model.implementation)))
+ if self._model.dependencies:
context.write('Dependencies: {0}'.format(
- ', '.join((str(context.style.literal(v)) for v in self._template.dependencies))))
- self._topology.dump(self._template.inputs, context, 'Inputs')
- if self._template.executor is not None:
- context.write('Executor: {0}'.format(context.style.literal(self._template.executor)))
- if self._template.max_attempts is not None:
- context.write('Max attempts: {0}'.format(context.style.literal(self._template.max_attempts)))
- if self._template.retry_interval is not None:
+ ', '.join((str(context.style.literal(v)) for v in self._model.dependencies))))
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ if self._model.executor is not None:
+ context.write('Executor: {0}'.format(context.style.literal(self._model.executor)))
+ if self._model.max_attempts is not None:
+ context.write('Max attempts: {0}'.format(context.style.literal(self._model.max_attempts)))
+ if self._model.retry_interval is not None:
context.write('Retry interval: {0}'.format(
- context.style.literal(self._template.retry_interval)))
- if self._template.plugin_specification is not None:
+ context.style.literal(self._model.retry_interval)))
+ if self._model.plugin_specification is not None:
context.write('Plugin specification: {0}'.format(
- context.style.literal(self._template.plugin_specification.name)))
- self._topology.dump(self._template.configurations, context, 'Configuration')
- if self._template.function is not None:
- context.write('Function: {0}'.format(context.style.literal(self._template.function)))
+ context.style.literal(self._model.plugin_specification.name)))
+ self._topology.dump(self._model.configurations, context, 'Configuration')
+ if self._model.function is not None:
+ context.write('Function: {0}'.format(context.style.literal(self._model.function)))
def coerce(self, **kwargs):
- self._coerce(self._template.inputs,
- self._template.configurations,
+ self._coerce(self._model.inputs,
+ self._model.configurations,
**kwargs)
def instantiate(self, instance_cls):
operation = instance_cls(
- name=self._template.name,
- description=utils.deepcopy_with_locators(self._template.description),
- relationship_edge=self._template.relationship_edge,
- implementation=self._template.implementation,
- dependencies=self._template.dependencies,
- executor=self._template.executor,
- function=self._template.function,
- max_attempts=self._template.max_attempts,
- retry_interval=self._template.retry_interval,
- operation_template=self._template)
-
- if (self._template.plugin_specification is not None and
- self._template.plugin_specification.enabled):
- operation.plugin = self._template.plugin_specification.plugin
-
- operation.inputs = self._topology.instantiate(self._template.inputs)
- operation.configurations = self._topology.instantiate(self._template.configurations)
+ name=self._model.name,
+ description=utils.deepcopy_with_locators(self._model.description),
+ relationship_edge=self._model.relationship_edge,
+ implementation=self._model.implementation,
+ dependencies=self._model.dependencies,
+ executor=self._model.executor,
+ function=self._model.function,
+ max_attempts=self._model.max_attempts,
+ retry_interval=self._model.retry_interval,
+ operation_template=self._model)
+
+ if (self._model.plugin_specification is not None and
+ self._model.plugin_specification.enabled):
+ operation.plugin = self._model.plugin_specification.plugin
+
+ operation.inputs = self._topology.instantiate(self._model.inputs)
+ operation.configurations = self._topology.instantiate(self._model.configurations)
return operation
def validate(self):
- self._validate(self._template.inputs,
- self._template.configurations)
+ self._validate(self._model.inputs,
+ self._model.configurations)
class PluginSpecification(common._TemplateHandler):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/parser/consumption/modeling.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/modeling.py b/aria/parser/consumption/modeling.py
index 2d4f271..5774630 100644
--- a/aria/parser/consumption/modeling.py
+++ b/aria/parser/consumption/modeling.py
@@ -77,7 +77,7 @@ class ServiceTemplate(ConsumerChain):
raw = self.context.modeling.template_as_raw
self.context.write(json_dumps(raw, indent=indent))
else:
- self.context.modeling.template.dump()
+ self.handler.dump(self.context.modeling.template)
class Types(Consumer):
@@ -155,7 +155,7 @@ class SatisfyRequirements(Consumer):
"""
def consume(self):
- self.context.modeling.instance.satisfy_requirements()
+ self.handler.satisfy_requirements(self.context.modeling.instance)
class ValidateCapabilities(Consumer):
@@ -164,7 +164,7 @@ class ValidateCapabilities(Consumer):
"""
def consume(self):
- self.context.modeling.instance.validate_capabilities()
+ self.handler.validate_capabilities(self.context.modeling.instance)
class FindHosts(Consumer):
@@ -173,7 +173,7 @@ class FindHosts(Consumer):
"""
def consume(self):
- self.context.modeling.instance.find_hosts()
+ self.handler.find_hosts(self.context.modeling.instance)
class ConfigureOperations(Consumer):
@@ -182,7 +182,7 @@ class ConfigureOperations(Consumer):
"""
def consume(self):
- self.context.modeling.instance.configure_operations()
+ self.handler.configure_operations(self.context.modeling.instance)
class ServiceInstance(ConsumerChain):
[2/2] incubator-ariatosca git commit: removed all unnecessary method
from models into the topology package
Posted by mx...@apache.org.
removed all unnecessary method from models into the topology package
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/4ae0e5f9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/4ae0e5f9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/4ae0e5f9
Branch: refs/heads/ARIA-174-Refactor-instantiation-phase
Commit: 4ae0e5f99549655a074ef3a5653180339655a921
Parents: a964076
Author: max-orlov <ma...@gigaspaces.com>
Authored: Tue Jul 25 15:34:41 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Tue Jul 25 15:34:41 2017 +0300
----------------------------------------------------------------------
aria/modeling/service_instance.py | 247 +-------
aria/modeling/service_template.py | 135 +----
.../execution_plugin/instantiation.py | 3 -
aria/orchestrator/topology/__init__.py | 152 +++--
aria/orchestrator/topology/common.py | 7 +-
aria/orchestrator/topology/instance.py | 593 +++++++++++++------
aria/orchestrator/topology/template.py | 590 +++++++++---------
aria/parser/consumption/modeling.py | 10 +-
8 files changed, 866 insertions(+), 871 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 15cf8fd..8bd3b9e 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -32,16 +32,13 @@ from sqlalchemy.ext.orderinglist import ordering_list
from . import (
relationship,
- utils,
types as modeling_types
)
from .mixins import InstanceModelMixin
-from ..orchestrator import execution_plugin
-from ..parser import validation
+
from ..utils import (
collections,
formatting,
- console
)
@@ -231,50 +228,6 @@ class ServiceBase(InstanceModelMixin):
:type: :class:`~datetime.datetime`
""")
- def satisfy_requirements(self):
- satisfied = True
- for node in self.nodes.itervalues():
- if not node.satisfy_requirements():
- satisfied = False
- return satisfied
-
- def validate_capabilities(self):
- satisfied = True
- for node in self.nodes.itervalues():
- if not node.validate_capabilities():
- satisfied = False
- return satisfied
-
- def find_hosts(self):
- for node in self.nodes.itervalues():
- node.find_host()
-
- def configure_operations(self):
- for node in self.nodes.itervalues():
- node.configure_operations()
- for group in self.groups.itervalues():
- group.configure_operations()
- for operation in self.workflows.itervalues():
- operation.configure()
-
- def is_node_a_target(self, target_node):
- for node in self.nodes.itervalues():
- if self._is_node_a_target(node, target_node):
- return True
- return False
-
- def _is_node_a_target(self, source_node, target_node):
- if source_node.outbound_relationships:
- for relationship_model in source_node.outbound_relationships:
- if relationship_model.target_node.name == target_node.name:
- return True
- else:
- node = relationship_model.target_node
- if node is not None:
- if self._is_node_a_target(node, target_node):
- return True
- return False
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -288,33 +241,6 @@ class ServiceBase(InstanceModelMixin):
('outputs', formatting.as_raw_dict(self.outputs)),
('workflows', formatting.as_raw_list(self.workflows))))
- def dump_graph(self):
- for node in self.nodes.itervalues():
- if not self.is_node_a_target(node):
- self._dump_graph_node(node)
-
- def _dump_graph_node(self, node, capability=None):
- from ..parser.consumption import ConsumptionContext
-
- context = ConsumptionContext.get_thread_local()
- console.puts(context.style.node(node.name))
- if capability is not None:
- console.puts('{0} ({1})'.format(context.style.property(capability.name),
- context.style.type(capability.type.name)))
- if node.outbound_relationships:
- with context.style.indent:
- for relationship_model in node.outbound_relationships:
- relationship_name = context.style.property(relationship_model.name)
- if relationship_model.type is not None:
- console.puts('-> {0} ({1})'.format(relationship_name,
- context.style.type(
- relationship_model.type.name)))
- else:
- console.puts('-> {0}'.format(relationship_name))
- with console.indent(3):
- self._dump_graph_node(relationship_model.target_node,
- relationship_model.target_capability)
-
class NodeBase(InstanceModelMixin):
"""
@@ -578,123 +504,6 @@ class NodeBase(InstanceModelMixin):
return attribute.value if attribute else None
return None
- def satisfy_requirements(self):
- node_template = self.node_template
- satisfied = True
- for requirement_template in node_template.requirement_templates:
- # Find target template
- target_node_template, target_node_capability = \
- requirement_template.find_target(node_template)
- if target_node_template is not None:
- satisfied = self._satisfy_capability(target_node_capability,
- target_node_template,
- requirement_template)
- else:
- # TODO: fix
-
- # context = ConsumptionContext.get_thread_local()
- # context.validation.report('requirement "{0}" of node "{1}" has no target node '
- # 'template'.format(requirement_template.name, self.name),
- # level=validation.Issue.BETWEEN_INSTANCES)
- satisfied = False
- return satisfied
-
- def _satisfy_capability(self, target_node_capability, target_node_template,
- requirement_template):
- from . import models
- # TODO: fix reporting
- # context = ConsumptionContext.get_thread_local()
- # Find target nodes
- target_nodes = target_node_template.nodes
- if target_nodes:
- target_node = None
- target_capability = None
-
- if target_node_capability is not None:
- # Relate to the first target node that has capacity
- for node in target_nodes:
- a_target_capability = node.capabilities.get(target_node_capability.name)
- if a_target_capability.relate():
- target_node = node
- target_capability = a_target_capability
- break
- else:
- # Use first target node
- target_node = target_nodes[0]
-
- if target_node is not None:
- if requirement_template.relationship_template is not None:
- from aria.orchestrator import topology
- relationship_model = topology.handler.instantiate(
- requirement_template.relationship_template)
- else:
- relationship_model = models.Relationship()
- relationship_model.name = requirement_template.name
- relationship_model.requirement_template = requirement_template
- relationship_model.target_node = target_node
- relationship_model.target_capability = target_capability
- self.outbound_relationships.append(relationship_model)
- return True
- else:
- # context.validation.report('requirement "{0}" of node "{1}" targets node '
- # 'template "{2}" but its instantiated nodes do not '
- # 'have enough capacity'.format(
- # requirement_template.name,
- # self.name,
- # target_node_template.name),
- # level=validation.Issue.BETWEEN_INSTANCES)
- return False
- else:
- # context.validation.report('requirement "{0}" of node "{1}" targets node template '
- # '"{2}" but it has no instantiated nodes'.format(
- # requirement_template.name,
- # self.name,
- # target_node_template.name),
- # level=validation.Issue.BETWEEN_INSTANCES)
- return False
-
- def validate_capabilities(self):
- # TODO: fix
- # context = ConsumptionContext.get_thread_local()
- satisfied = False
- for capability in self.capabilities.itervalues():
- if not capability.has_enough_relationships:
- # context.validation.report('capability "{0}" of node "{1}" requires at least {2:d} '
- # 'relationships but has {3:d}'.format(
- # capability.name,
- # self.name,
- # capability.min_occurrences,
- # capability.occurrences),
- # level=validation.Issue.BETWEEN_INSTANCES)
- satisfied = False
- return satisfied
-
- def find_host(self):
- def _find_host(node):
- if node.type.role == 'host':
- return node
- for the_relationship in node.outbound_relationships:
- if (the_relationship.target_capability is not None) and \
- the_relationship.target_capability.type.role == 'host':
- host = _find_host(the_relationship.target_node)
- if host is not None:
- return host
- for the_relationship in node.inbound_relationships:
- if (the_relationship.target_capability is not None) and \
- the_relationship.target_capability.type.role == 'feature':
- host = _find_host(the_relationship.source_node)
- if host is not None:
- return host
- return None
-
- self.host = _find_host(self)
-
- def configure_operations(self):
- for interface in self.interfaces.itervalues():
- interface.configure_operations()
- for the_relationship in self.outbound_relationships:
- the_relationship.configure_operations()
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -812,10 +621,6 @@ class GroupBase(InstanceModelMixin):
:type: :obj:`basestring`
""")
- def configure_operations(self):
- for interface in self.interfaces.itervalues():
- interface.configure_operations()
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -1281,10 +1086,6 @@ class RelationshipBase(InstanceModelMixin):
:type: :obj:`int`
""")
- def configure_operations(self):
- for interface in self.interfaces.itervalues():
- interface.configure_operations()
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -1537,10 +1338,6 @@ class InterfaceBase(InstanceModelMixin):
:type: :obj:`basestring`
""")
- def configure_operations(self):
- for operation in self.operations.itervalues():
- operation.configure()
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -1725,47 +1522,6 @@ class OperationBase(InstanceModelMixin):
:type: :obj:`float`
""")
- def configure(self):
- from aria.orchestrator import topology
- if (self.implementation is None) and (self.function is None):
- return
-
- if (self.interface is not None) and (self.plugin is None) and (self.function is None):
- # ("interface" is None for workflow operations, which do not currently use "plugin")
- # The default (None) plugin is the execution plugin
- execution_plugin.instantiation.configure_operation(self)
- else:
- # In the future plugins may be able to add their own "configure_operation" hook that
- # can validate the configuration and otherwise create specially derived arguments. For
- # now, we just send all configuration parameters as arguments without validation.
- for key, conf in self.configurations.items():
- self.arguments[key] = topology.handler.instantiate(conf.as_argument())
-
- if self.interface is not None:
- # Send all interface inputs as extra arguments
- # ("interface" is None for workflow operations)
- # Note that they will override existing arguments of the same names
- for key, input in self.interface.inputs.items():
- self.arguments[key] = topology.handler.instantiate(input.as_argument())
-
- # Send all inputs as extra arguments
- # Note that they will override existing arguments of the same names
- for key, input in self.inputs.items():
- self.arguments[key] = topology.handler.instantiate(input.as_argument())
-
- # Check for reserved arguments
- from ..orchestrator.decorators import OPERATION_DECORATOR_RESERVED_ARGUMENTS
- used_reserved_names = \
- OPERATION_DECORATOR_RESERVED_ARGUMENTS.intersection(self.arguments.keys())
- # if used_reserved_names:
- # # context = ConsumptionContext.get_thread_local()
- # context.validation.report('using reserved arguments in operation "{0}": {1}'
- # .format(
- # self.name,
- # formatting.string_list_as_string(used_reserved_names)),
- # level=validation.Issue.EXTERNAL)
-
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -1776,7 +1532,6 @@ class OperationBase(InstanceModelMixin):
('inputs', formatting.as_raw_dict(self.inputs))))
-
class ArtifactBase(InstanceModelMixin):
"""
Typed file, either provided in a CSAR or downloaded from a repository.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 80a5dbb..f2e1e78 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -31,11 +31,10 @@ from sqlalchemy import (
)
from sqlalchemy.ext.declarative import declared_attr
-from ..utils import (collections, formatting, console)
+from ..utils import (collections, formatting)
from .mixins import TemplateModelMixin
from . import (
relationship,
- utils,
types as modeling_types
)
@@ -495,63 +494,6 @@ class NodeTemplateBase(TemplateModelMixin):
('capability_templates', formatting.as_raw_list(self.capability_templates)),
('requirement_templates', formatting.as_raw_list(self.requirement_templates))))
- @property
- def scaling(self):
- scaling = {}
-
- def extract_property(properties, name):
- if name in scaling:
- return
- prop = properties.get(name)
- if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
- scaling[name] = prop.value
-
- def extract_properties(properties):
- extract_property(properties, 'min_instances')
- extract_property(properties, 'max_instances')
- extract_property(properties, 'default_instances')
-
- def default_property(name, value):
- if name not in scaling:
- scaling[name] = value
-
- # From our scaling capabilities
- for capability_template in self.capability_templates.itervalues():
- if capability_template.type.role == 'scaling':
- extract_properties(capability_template.properties)
-
- # From service scaling policies
- for policy_template in self.service_template.policy_templates.itervalues():
- if policy_template.type.role == 'scaling':
- if policy_template.is_for_node_template(self.name):
- extract_properties(policy_template.properties)
-
- # Defaults
- default_property('min_instances', 0)
- default_property('max_instances', 1)
- default_property('default_instances', 1)
-
- # Validate
- # pylint: disable=too-many-boolean-expressions
- if ((scaling['min_instances'] < 0) or
- (scaling['max_instances'] < 0) or
- (scaling['default_instances'] < 0) or
- (scaling['max_instances'] < scaling['min_instances']) or
- (scaling['default_instances'] < scaling['min_instances']) or
- (scaling['default_instances'] > scaling['max_instances'])):
- pass
- # TODO: fix this
- # context = ConsumptionContext.get_thread_local()
- # context.validation.report('invalid scaling parameters for node template "{0}": '
- # 'min={1}, max={2}, default={3}'.format(
- # self.name,
- # scaling['min_instances'],
- # scaling['max_instances'],
- # scaling['default_instances']),
- # level=validation.Issue.BETWEEN_TYPES)
-
- return scaling
-
def is_target_node_template_valid(self, target_node_template):
"""
Checks if ``target_node_template`` matches all our ``target_node_template_constraints``.
@@ -1100,58 +1042,6 @@ class RequirementTemplateBase(TemplateModelMixin):
:type: [:class:`NodeTemplateConstraint`]
""")
- def find_target(self, source_node_template):
- # context = ConsumptionContext.get_thread_local()
-
- # We might already have a specific node template, so we'll just verify it
- if self.target_node_template is not None:
- if not source_node_template.is_target_node_template_valid(self.target_node_template):
- # TODO: fix
- pass
- # context.validation.report('requirement "{0}" of node template "{1}" is for node '
- # 'template "{2}" but it does not match constraints'.format(
- # self.name,
- # self.target_node_template.name,
- # source_node_template.name),
- # level=validation.Issue.BETWEEN_TYPES)
- if (self.target_capability_type is not None) \
- or (self.target_capability_name is not None):
- target_node_capability = self.find_target_capability(source_node_template,
- self.target_node_template)
- if target_node_capability is None:
- return None, None
- else:
- target_node_capability = None
-
- return self.target_node_template, target_node_capability
-
- # Find first node that matches the type
- elif self.target_node_type is not None:
- for target_node_template in \
- self.node_template.service_template.node_templates.itervalues():
- if self.target_node_type.get_descendant(target_node_template.type.name) is None:
- continue
-
- if not source_node_template.is_target_node_template_valid(target_node_template):
- continue
-
- target_node_capability = self.find_target_capability(source_node_template,
- target_node_template)
- if target_node_capability is None:
- continue
-
- return target_node_template, target_node_capability
-
- return None, None
-
- def find_target_capability(self, source_node_template, target_node_template):
- for capability_template in target_node_template.capability_templates.itervalues():
- if capability_template.satisfies_requirement(source_node_template,
- self,
- target_node_template):
- return capability_template
- return None
-
@property
def as_raw(self):
return collections.OrderedDict((
@@ -1349,29 +1239,6 @@ class CapabilityTemplateBase(TemplateModelMixin):
:type: :obj:`int`
""")
- def satisfies_requirement(self,
- source_node_template,
- requirement,
- target_node_template):
- # Do we match the required capability type?
- if requirement.target_capability_type and \
- requirement.target_capability_type.get_descendant(self.type.name) is None:
- return False
-
- # Are we in valid_source_node_types?
- if self.valid_source_node_types:
- for valid_source_node_type in self.valid_source_node_types:
- if valid_source_node_type.get_descendant(source_node_template.type.name) is None:
- return False
-
- # Apply requirement constraints
- if requirement.target_node_template_constraints:
- for node_template_constraint in requirement.target_node_template_constraints:
- if not node_template_constraint.matches(source_node_template, target_node_template):
- return False
-
- return True
-
@property
def as_raw(self):
return collections.OrderedDict((
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/orchestrator/execution_plugin/instantiation.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/instantiation.py b/aria/orchestrator/execution_plugin/instantiation.py
index 4390252..0e3a441 100644
--- a/aria/orchestrator/execution_plugin/instantiation.py
+++ b/aria/orchestrator/execution_plugin/instantiation.py
@@ -19,10 +19,7 @@ Instantiation of :class:`~aria.modeling.models.Operation` models.
# TODO: this module will eventually be moved to a new "aria.instantiation" package
-from ...utils.type import full_type_name
-from ...utils.formatting import safe_repr
from ...utils.collections import OrderedDict
-from ...parser import validation
from ...modeling.functions import Function
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/orchestrator/topology/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/__init__.py b/aria/orchestrator/topology/__init__.py
index aa9e306..9003c1e 100644
--- a/aria/orchestrator/topology/__init__.py
+++ b/aria/orchestrator/topology/__init__.py
@@ -83,63 +83,87 @@ class Handler(object):
if attribute_name.startswith('_'):
continue
attribute = getattr(module_, attribute_name)
- if isinstance(attribute, type) and issubclass(attribute, (common._TemplateHandler,
- common._InstanceHandler)):
+ if isinstance(attribute, type) and issubclass(attribute, common._Handler):
handlers[getattr(models, attribute_name)] = attribute
return handlers
- def instantiate(self, template, **kwargs):
+ def instantiate(self, model, **kwargs):
"""
all handlers used by instantiate should hold a tuple as value (handler, instnace_cls)
- :param template:
+ :param model:
:param kwargs:
:return:
"""
- if isinstance(template, dict):
+ if isinstance(model, dict):
return dict((name, self.instantiate(value, **kwargs))
- for name, value in template.iteritems())
- elif isinstance(template, list):
- return list(self.instantiate(value, **kwargs) for value in template)
- elif template is not None:
- handler = self._handlers.get(template.__class__)
- instance_cls = self._init_map.get(template.__class__)
- return handler(self, template).instantiate(instance_cls, **kwargs)
-
- def validate(self, template, **kwargs):
- if isinstance(template, dict):
- return self.validate(template.values())
- elif isinstance(template, list):
- return all(self.validate(value) for value in template)
- elif template is not None:
- handler = self._handlers.get(template.__class__)
- return handler(self, template).validate(**kwargs)
-
- def dump(self, template, context, **kwargs):
+ for name, value in model.iteritems())
+ elif isinstance(model, list):
+ return list(self.instantiate(value, **kwargs) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ instance_cls = self._init_map.get(model.__class__)
+ return handler(self, model).instantiate(instance_cls, **kwargs)
+
+ def validate(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.validate(model.values())
+ elif isinstance(model, list):
+ return all(self.validate(value) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ return handler(self, model).validate(**kwargs)
+
+ def dump(self, model, context, **kwargs):
if not isinstance(context, self.TopologyStylizer):
# Wrap the context to contain a stringIO object
context = self.TopologyStylizer(context)
- if isinstance(template, dict):
- return self.dump(template.values(), context, **kwargs)
- elif isinstance(template, list):
- context.write('%s:' % template)
+ if isinstance(model, dict):
+ return self.dump(model.values(), context, **kwargs)
+ elif isinstance(model, list):
+ context.write('%s:' % model)
with context.style.indent:
- for value in template:
+ for value in model:
self.dump(value, context, **kwargs)
- elif template is not None:
- handler = self._handlers.get(template.__class__)
- handler(self, template).dump(context, **kwargs)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ handler(self, model).dump(context, **kwargs)
return str(context)
- def coerce(self, template, **kwargs):
- if isinstance(template, dict):
- return self.validate(template.values())
- elif isinstance(template, list):
- return all(self.validate(value) for value in template)
- elif template is not None:
- handler = self._handlers.get(template.__class__)
- return handler(self, template).coerce(**kwargs)
+ def dump_graph(self, context, service, **kwargs):
+ context = self.TopologyStylizer(context)
+ for node in service.nodes.itervalues():
+ if not node.inbound_relationships:
+ self._dump_graph_node(context, node)
+
+ def _dump_graph_node(self, context, node, capability=None):
+ context.write(context.style.node(node.name))
+ if capability is not None:
+ context.write('{0} ({1})'.format(context.style.property(capability.name),
+ context.style.type(capability.type.name)))
+ if node.outbound_relationships:
+ with context.style.indent:
+ for relationship_model in node.outbound_relationships:
+ relationship_name = context.style.property(relationship_model.name)
+ if relationship_model.type is not None:
+ context.write('-> {0} ({1})'.format(
+ relationship_name, context.style.type(relationship_model.type.name)))
+ else:
+ context.write('-> {0}'.format(relationship_name))
+ # TODO: this needs to be fixed
+ # with console.indent(3):
+ # self._dump_graph_node(relationship_model.target_node,
+ # relationship_model.target_capability)
+
+ def coerce(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.validate(model.values())
+ elif isinstance(model, list):
+ return all(self.validate(value) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ return handler(self, model).coerce(**kwargs)
def dump_types(self, context, service_template):
self.dump(service_template.node_types, context)
@@ -150,5 +174,55 @@ class Handler(object):
self.dump(service_template.artifact_types, context)
self.dump(service_template.interface_types, context)
+ def satisfy_requirements(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.satisfy_requirements(model.values())
+ elif isinstance(model, list):
+ return all(self.satisfy_requirements(value) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ return handler(self, model).satisfy_requirements(**kwargs)
+
+ def validate_capabilities(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.validate_capabilities(model.values())
+ elif isinstance(model, list):
+ return all(self.validate_capabilities(value) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ return handler(self, model).validate_capabilities(**kwargs)
+
+ def _find_host(self, node):
+ if node.type.role == 'host':
+ return node
+
+ has_role = lambda rel, role: \
+ rel.target_capability is not None and rel.target_capability.type.role == role
+
+ for relationship in node.outbound_relationships:
+ if has_role(relationship, 'host'):
+ host = self._find_host(relationship.target_node)
+ if host is not None:
+ return host
+ for relationship in node.inbound_relationships:
+ if has_role(relationship, 'feature'):
+ host = self._find_host(relationship.source_node)
+ if host is not None:
+ return host
+ return None
+
+ def find_hosts(self, service):
+ for node in service.nodes.values():
+ service.host = self._find_host(node)
+
+ def configure_operations(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.configure_operations(model.values())
+ elif isinstance(model, list):
+ return all(self.configure_operations(value) for value in model)
+ elif model is not None:
+ handler = self._handlers.get(model.__class__)
+ return handler(self, model).configure_operations(**kwargs)
+
handler = Handler()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/orchestrator/topology/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/common.py b/aria/orchestrator/topology/common.py
index 9b00ce6..9437d56 100644
--- a/aria/orchestrator/topology/common.py
+++ b/aria/orchestrator/topology/common.py
@@ -17,7 +17,7 @@
class _Handler(object):
def __init__(self, topology, template):
self._topology = topology
- self._template = template
+ self._model = template
def _coerce(self, *templates, **kwargs):
for template in templates:
@@ -48,3 +48,8 @@ class _TemplateHandler(_Handler):
class _InstanceHandler(_Handler):
pass
+
+
+class _OperatorHolderHandler(_Handler):
+ def configure_operations(self):
+ raise NotImplementedError
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ae0e5f9/aria/orchestrator/topology/instance.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/instance.py b/aria/orchestrator/topology/instance.py
index cb3f747..3040b3b 100644
--- a/aria/orchestrator/topology/instance.py
+++ b/aria/orchestrator/topology/instance.py
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ... modeling import models
+from .. import execution_plugin
+from .. import decorators
from . import common
# TODO: this should this be here?
@@ -22,101 +25,109 @@ from aria.utils import formatting
class Artifact(common._InstanceHandler):
def coerce(self, **kwargs):
- self._topology.coerce(self._template.properties, **kwargs)
+ self._topology.coerce(self._model.properties, **kwargs)
def validate(self, **kwargs):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Artifact type: {0}'.format(context.style.type(self._template.type.name)))
+ context.write('Artifact type: {0}'.format(context.style.type(self._model.type.name)))
context.write('Source path: {0}'.format(
- context.style.literal(self._template.source_path)))
- if self._template.target_path is not None:
+ context.style.literal(self._model.source_path)))
+ if self._model.target_path is not None:
context.write('Target path: {0}'.format(
- context.style.literal(self._template.target_path)))
- if self._template.repository_url is not None:
+ context.style.literal(self._model.target_path)))
+ if self._model.repository_url is not None:
context.write('Repository URL: {0}'.format(
- context.style.literal(self._template.repository_url)))
- if self._template.repository_credential:
+ context.style.literal(self._model.repository_url)))
+ if self._model.repository_credential:
context.write('Repository credential: {0}'.format(
- context.style.literal(self._template.repository_credential)))
- self._topology.dump(self._template.properties, context, 'Properties')
+ context.style.literal(self._model.repository_credential)))
+ self._topology.dump(self._model.properties, context, 'Properties')
class Capability(common._InstanceHandler):
def coerce(self, **kwargs):
- self._topology.coerce(self._template.properties, **kwargs)
+ self._topology.coerce(self._model.properties, **kwargs)
def validate(self, **kwargs):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
def dump(self, context):
- context.write(context.style.node(self._template.name))
+ context.write(context.style.node(self._model.name))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
context.write('Occurrences: {0:d} ({1:d}{2})'.format(
- self._template.occurrences,
- self._template.min_occurrences or 0,
- ' to {0:d}'.format(self._template.max_occurrences)
- if self._template.max_occurrences is not None
+ self._model.occurrences,
+ self._model.min_occurrences or 0,
+ ' to {0:d}'.format(self._model.max_occurrences)
+ if self._model.max_occurrences is not None
else ' or more'))
- self._topology.dump(self._template.properties, context, 'Properties')
+ self._topology.dump(self._model.properties, context, 'Properties')
-class Group(common._InstanceHandler):
+class Group(common._OperatorHolderHandler):
+
def coerce(self, **kwargs):
- self._coerce(self._template.properties, self._template.interfaces, **kwargs)
+ self._coerce(self._model.properties, self._model.interfaces, **kwargs)
def validate(self, **kwargs):
- self._validate(self._template.properties,
- self._template.interfaces)
+ self._validate(self._model.properties,
+ self._model.interfaces)
def dump(self, context):
- context.write('Group: {0}'.format(context.style.node(self._template.name)))
+ context.write('Group: {0}'.format(context.style.node(self._model.name)))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.interfaces, context, 'Interfaces')
- if self._template.nodes:
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.interfaces, context, 'Interfaces')
+ if self._model.nodes:
context.write('Member nodes:')
with context.style.indent:
- for node in self._template.nodes:
+ for node in self._model.nodes:
context.write(context.style.node(node.name))
+ def configure_operations(self):
+ for interface in self._model.interfaces.values():
+ self._topology.configure_operations(interface)
+
-class Interface(common._InstanceHandler):
+class Interface(common._OperatorHolderHandler):
def coerce(self, **kwargs):
- self._coerce(self._template.inputs, self._template.operations, **kwargs)
+ self._coerce(self._model.inputs, self._model.operations, **kwargs)
def validate(self, **kwargs):
- self._validate(self._template.inputs,
- self._template.operations)
+ self._validate(self._model.inputs,
+ self._model.operations)
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- context.write('Interface type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.inputs, context, 'Inputs')
- self._topology.dump(self._template.operations, context, 'Operations')
+ context.write('Interface type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ self._topology.dump(self._model.operations, context, 'Operations')
+ def configure_operations(self):
+ for operation in self._model.operations.values():
+ self._topology.configure_operations(operation)
-class Node(common._InstanceHandler):
+
+class Node(common._OperatorHolderHandler):
def coerce(self, **kwargs):
- self._coerce(self._template.properties,
- self._template.attributes,
- self._template.interfaces,
- self._template.artifacts,
- self._template.capabilities,
- self._template.outbound_relationships,
+ self._coerce(self._model.properties,
+ self._model.attributes,
+ self._model.interfaces,
+ self._model.artifacts,
+ self._model.capabilities,
+ self._model.outbound_relationships,
**kwargs)
-
def validate(self, **kwargs):
# TODO: fix the context
# context = ConsumptionContext.get_thread_local()
@@ -129,180 +140,407 @@ class Node(common._InstanceHandler):
# len(self.name)),
# level=validation.Issue.BETWEEN_INSTANCES)
- self._validate(self._template.properties,
- self._template.attributes,
- self._template.interfaces,
- self._template.artifacts,
- self._template.capabilities,
- self._template.outbound_relationships)
+ self._validate(self._model.properties,
+ self._model.attributes,
+ self._model.interfaces,
+ self._model.artifacts,
+ self._model.capabilities,
+ self._model.outbound_relationships)
def dump(self, context):
- context.write('Node: {0}'.format(context.style.node(self._template.name)))
+ context.write('Node: {0}'.format(context.style.node(self._model.name)))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- context.write('Template: {0}'.format(context.style.node(self._template.node_template.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.attributes, context, 'Attributes')
- self._topology.dump(self._template.interfaces, context, 'Interfaces')
- self._topology.dump(self._template.artifacts, context, 'Artifacts')
- self._topology.dump(self._template.capabilities, context, 'Capabilities')
- self._topology.dump(self._template.outbound_relationships, context, 'Relationships')
-
-
-class Operation(common._InstanceHandler):
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ context.write('Template: {0}'.format(context.style.node(self._model.node_template.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.attributes, context, 'Attributes')
+ self._topology.dump(self._model.interfaces, context, 'Interfaces')
+ self._topology.dump(self._model.artifacts, context, 'Artifacts')
+ self._topology.dump(self._model.capabilities, context, 'Capabilities')
+ self._topology.dump(self._model.outbound_relationships, context, 'Relationships')
+
+ def configure_operations(self):
+ for interface in self._model.interfaces.values():
+ self._topology.configure_operations(interface)
+ for relationship in self._model.outbound_relationships:
+ self._topology.configure_operations(relationship)
+
+ def validate_capabilities(self):
+ # TODO: fix
+ # context = ConsumptionContext.get_thread_local()
+ satisfied = False
+ for capability in self._model.capabilities.itervalues():
+ if not capability.has_enough_relationships:
+ # context.validation.report('capability "{0}" of node "{1}" requires at least {2:d} '
+ # 'relationships but has {3:d}'.format(
+ # capability.name,
+ # self.name,
+ # capability.min_occurrences,
+ # capability.occurrences),
+ # level=validation.Issue.BETWEEN_INSTANCES)
+ satisfied = False
+ return satisfied
+
+ def satisfy_requirements(self):
+ satisfied = True
+ for requirement_template in self._model.node_template.requirement_templates:
+ # Find target template
+ target_node_template, target_node_capability = self._find_target(requirement_template)
+ if target_node_template is not None:
+ satisfied = self._satisfy_capability(
+ target_node_capability, target_node_template,
+ requirement_template)
+ else:
+ # TODO: fix
+
+ # context = ConsumptionContext.get_thread_local()
+ # context.validation.report('requirement "{0}" of node "{1}" has no target node '
+ # 'template'.format(requirement_template.name, self.name),
+ # level=validation.Issue.BETWEEN_INSTANCES)
+ satisfied = False
+ return satisfied
+
+ def _satisfy_capability(self, target_node_capability, target_node_template,
+ requirement_template):
+ # TODO: fix reporting
+ # context = ConsumptionContext.get_thread_local()
+ # Find target nodes
+ target_nodes = target_node_template.nodes
+ if target_nodes:
+ target_node = None
+ target_capability = None
+
+ if target_node_capability is not None:
+ # Relate to the first target node that has capacity
+ for node in target_nodes:
+ a_target_capability = node.capabilities.get(target_node_capability.name)
+ if a_target_capability.relate():
+ target_node = node
+ target_capability = a_target_capability
+ break
+ else:
+ # Use first target node
+ target_node = target_nodes[0]
+
+ if target_node is not None:
+ if requirement_template.relationship_template is not None:
+ from aria.orchestrator import topology
+ relationship_model = topology.handler.instantiate(
+ requirement_template.relationship_template)
+ else:
+ relationship_model = models.Relationship()
+ relationship_model.name = requirement_template.name
+ relationship_model.requirement_template = requirement_template
+ relationship_model.target_node = target_node
+ relationship_model.target_capability = target_capability
+ self._model.outbound_relationships.append(relationship_model)
+ return True
+ else:
+ # context.validation.report('requirement "{0}" of node "{1}" targets node '
+ # 'template "{2}" but its instantiated nodes do not '
+ # 'have enough capacity'.format(
+ # requirement_template.name,
+ # self.name,
+ # target_node_template.name),
+ # level=validation.Issue.BETWEEN_INSTANCES)
+ return False
+ else:
+ # context.validation.report('requirement "{0}" of node "{1}" targets node template '
+ # '"{2}" but it has no instantiated nodes'.format(
+ # requirement_template.name,
+ # self.name,
+ # target_node_template.name),
+ # level=validation.Issue.BETWEEN_INSTANCES)
+ return False
+
+ def _find_target(self, requirement_template):
+ # We might already have a specific node template, so we'll just verify it
+ if requirement_template.target_node_template is not None:
+ if not self._model.node_template.is_target_node_template_valid(requirement_template.target_node_template):
+ # TODO: fix
+ pass
+ # context.validation.report('requirement "{0}" of node template "{1}" is for node '
+ # 'template "{2}" but it does not match constraints'.format(
+ # self.name,
+ # self.target_node_template.name,
+ # source_node_template.name),
+ # level=validation.Issue.BETWEEN_TYPES)
+ if (requirement_template.target_capability_type is not None or
+ requirement_template.target_capability_name is not None):
+ target_node_capability = self._get_capability_from_requirement(requirement_template)
+ if target_node_capability is None:
+ return None, None
+ else:
+ target_node_capability = None
+
+ return self._model.node_template.target_node_template, target_node_capability
+
+ # Find first node that matches the type
+ elif requirement_template.target_node_type is not None:
+ for target_node_template in \
+ self._model.node_template.service_template.node_templates.itervalues():
+ if requirement_template.target_node_type.get_descendant(target_node_template.type.name) is None:
+ continue
+
+ if not self._model.node_template.is_target_node_template_valid(target_node_template):
+ continue
+
+ if requirement_template.target_node_template:
+ target_node_capability = self._get_capability_from_requirement(requirement_template)
+ if target_node_capability is None:
+ continue
+ else:
+ return target_node_template, target_node_capability
+
+ return None, None
+
+ def _get_capability_from_requirement(self, requirement_template):
+ for capability_template in requirement_template.target_node_template.capability_templates.values():
+ if self._satisfies_requirement(capability_template, requirement_template):
+ return capability_template
+ return None
+
+ def _satisfies_requirement(self, capability_template, requirement_template):
+ # Do we match the required capability type?
+ if (requirement_template.target_capability_type and
+ requirement_template.target_capability_type.get_descendant(
+ self._model.type.name) is None):
+ return False
+
+ # Are we in valid_source_node_types?
+ if capability_template.valid_source_node_types:
+ for valid_source_node_type in capability_template.valid_source_node_types:
+ if valid_source_node_type.get_descendant(
+ self._model.node_template.type.name) is None:
+ return False
+
+ # Apply requirement constraints
+ if requirement_template.target_node_template_constraints:
+ for node_template_constraint in requirement_template.target_node_template_constraints:
+ if not node_template_constraint.matches(
+ self._model.node_template, requirement_template.target_node_template):
+ return False
+
+ return True
+
+
+class Operation(common._OperatorHolderHandler):
def coerce(self, **kwargs):
- self._coerce(self._template.inputs,
- self._template.configurations,
- self._template.arguments,
+ self._coerce(self._model.inputs,
+ self._model.configurations,
+ self._model.arguments,
**kwargs)
def validate(self, **kwargs):
- self._validate(self._template.inputs,
- self._template.configurations,
- self._template.arguments)
+ self._validate(self._model.inputs,
+ self._model.configurations,
+ self._model.arguments)
def dump(self, context):
- context.write(context.style.node(self._template.name))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.write(context.style.node(self._model.name))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
with context.style.indent:
- if self._template.implementation is not None:
+ if self._model.implementation is not None:
context.write('Implementation: {0}'.format(
- context.style.literal(self._template.implementation)))
- if self._template.dependencies:
+ context.style.literal(self._model.implementation)))
+ if self._model.dependencies:
context.write(
'Dependencies: {0}'.format(
- ', '.join((str(context.style.literal(v)) for v in self._template.dependencies))))
- self._topology.dump(self._template.inputs, context, 'Inputs')
- if self._template.executor is not None:
- context.write('Executor: {0}'.format(context.style.literal(self._template.executor)))
- if self._template.max_attempts is not None:
- context.write('Max attempts: {0}'.format(context.style.literal(self._template.max_attempts)))
- if self._template.retry_interval is not None:
+ ', '.join((str(context.style.literal(v)) for v in self._model.dependencies))))
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ if self._model.executor is not None:
+ context.write('Executor: {0}'.format(context.style.literal(self._model.executor)))
+ if self._model.max_attempts is not None:
+ context.write('Max attempts: {0}'.format(context.style.literal(self._model.max_attempts)))
+ if self._model.retry_interval is not None:
context.write('Retry interval: {0}'.format(
- context.style.literal(self._template.retry_interval)))
- if self._template.plugin is not None:
+ context.style.literal(self._model.retry_interval)))
+ if self._model.plugin is not None:
context.write('Plugin: {0}'.format(
- context.style.literal(self._template.plugin.name)))
- self._topology.dump(self._template.configurations, context, 'Configuration')
- if self._template.function is not None:
- context.write('Function: {0}'.format(context.style.literal(self._template.function)))
- self._topology.dump(self._template.arguments, context, 'Arguments')
+ context.style.literal(self._model.plugin.name)))
+ self._topology.dump(self._model.configurations, context, 'Configuration')
+ if self._model.function is not None:
+ context.write('Function: {0}'.format(context.style.literal(self._model.function)))
+ self._topology.dump(self._model.arguments, context, 'Arguments')
+
+ def configure_operations(self):
+ if self._model.implementation is None and self._model.function is None:
+ return
+
+ if (self._model.interface is not None and
+ self._model.plugin is None and
+ self._model.function is None):
+ # ("interface" is None for workflow operations, which do not currently use "plugin")
+ # The default (None) plugin is the execution plugin
+ execution_plugin.instantiation.configure_operation(self._model)
+ else:
+ # In the future plugins may be able to add their own "configure_operation" hook that
+ # can validate the configuration and otherwise create specially derived arguments. For
+ # now, we just send all configuration parameters as arguments without validation.
+ for key, conf in self._model.configurations.items():
+ self._model.arguments[key] = self._topology.instantiate(conf.as_argument())
+
+ if self._model.interface is not None:
+ # Send all interface inputs as extra arguments
+ # ("interface" is None for workflow operations)
+ # Note that they will override existing arguments of the same names
+ for key, input in self._model.interface.inputs.items():
+ self._model.arguments[key] = self._topology.instantiate(input.as_argument())
+
+ # Send all inputs as extra arguments
+ # Note that they will override existing arguments of the same names
+ for key, input in self._model.inputs.items():
+ self._model.arguments[key] = self._topology.instantiate(input.as_argument())
+
+ # Check for reserved arguments
+ used_reserved_names = decorators.OPERATION_DECORATOR_RESERVED_ARGUMENTS.intersection(
+ self._model.arguments.keys())
+ # if used_reserved_names:
+ # # context = ConsumptionContext.get_thread_local()
+ # context.validation.report('using reserved arguments in operation "{0}": {1}'
+ # .format(
+ # self.name,
+ # formatting.string_list_as_string(used_reserved_names)),
+ # level=validation.Issue.EXTERNAL)
class Policy(common._InstanceHandler):
def coerce(self, **kwargs):
- self._topology.coerce(self._template.properties, **kwargs)
+ self._topology.coerce(self._model.properties, **kwargs)
def validate(self, **kwargs):
- self._topology.validate(self._template.properties)
+ self._topology.validate(self._model.properties)
def dump(self, context):
- context.write('Policy: {0}'.format(context.style.node(self._template.name)))
+ context.write('Policy: {0}'.format(context.style.node(self._model.name)))
with context.style.indent:
- context.write('Type: {0}'.format(context.style.type(self._template.type.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- if self._template.nodes:
+ context.write('Type: {0}'.format(context.style.type(self._model.type.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ if self._model.nodes:
context.write('Target nodes:')
with context.style.indent:
- for node in self._template.nodes:
+ for node in self._model.nodes:
context.write(context.style.node(node.name))
- if self._template.groups:
+ if self._model.groups:
context.write('Target groups:')
with context.style.indent:
- for group in self._template.groups:
+ for group in self._model.groups:
context.write(context.style.node(group.name))
-class Relationship(common._InstanceHandler):
+class Relationship(common._OperatorHolderHandler):
def coerce(self, **kwargs):
- self._coerce(self._template.properties,
- self._template.interfaces,
+ self._coerce(self._model.properties,
+ self._model.interfaces,
**kwargs)
def validate(self, **kwargs):
- self._validate(self._template.properties,
- self._template.interfaces)
+ self._validate(self._model.properties,
+ self._model.interfaces)
def dump(self, context):
- if self._template.name:
- context.write('{0} ->'.format(context.style.node(self._template.name)))
+ if self._model.name:
+ context.write('{0} ->'.format(context.style.node(self._model.name)))
else:
context.write('->')
with context.style.indent:
- context.write('Node: {0}'.format(context.style.node(self._template.target_node.name)))
- if self._template.target_capability:
+ context.write('Node: {0}'.format(context.style.node(self._model.target_node.name)))
+ if self._model.target_capability:
context.write('Capability: {0}'.format(context.style.node(
- self._template.target_capability.name)))
- if self._template.type is not None:
+ self._model.target_capability.name)))
+ if self._model.type is not None:
context.write('Relationship type: {0}'.format(
- context.style.type(self._template.type.name)))
- if (self._template.relationship_template is not None and
- self._template.relationship_template.name):
+ context.style.type(self._model.type.name)))
+ if (self._model.relationship_template is not None and
+ self._model.relationship_template.name):
context.write('Relationship template: {0}'.format(
- context.style.node(self._template.relationship_template.name)))
- self._topology.dump(self._template.properties, context, 'Properties')
- self._topology.dump(self._template.interfaces, context, 'Interfaces')
+ context.style.node(self._model.relationship_template.name)))
+ self._topology.dump(self._model.properties, context, 'Properties')
+ self._topology.dump(self._model.interfaces, context, 'Interfaces')
+
+ def configure_operations(self):
+ for interface in self._model.interfaces.values():
+ self._topology.configure_operations(interface)
-class Service(common._InstanceHandler):
+class Service(common._OperatorHolderHandler):
def coerce(self, **kwargs):
- self._coerce(self._template.meta_data,
- self._template.nodes,
- self._template.groups,
- self._template.policies,
- self._template.substitution,
- self._template.inputs,
- self._template.outputs,
- self._template.workflows,
+ self._coerce(self._model.meta_data,
+ self._model.nodes,
+ self._model.groups,
+ self._model.policies,
+ self._model.substitution,
+ self._model.inputs,
+ self._model.outputs,
+ self._model.workflows,
**kwargs)
def validate(self, **kwargs):
- self._validate(self._template.meta_data,
- self._template.nodes,
- self._template.groups,
- self._template.policies,
- self._template.substitution,
- self._template.inputs,
- self._template.outputs,
- self._template.workflows)
+ self._validate(self._model.meta_data,
+ self._model.nodes,
+ self._model.groups,
+ self._model.policies,
+ self._model.substitution,
+ self._model.inputs,
+ self._model.outputs,
+ self._model.workflows)
def dump(self, context):
- if self._template.description is not None:
- context.write(context.style.meta(self._template.description))
- self._topology.dump(self._template.meta_data, context, 'Metadata')
- for node in self._template.nodes.itervalues():
+ if self._model.description is not None:
+ context.write(context.style.meta(self._model.description))
+ self._topology.dump(self._model.meta_data, context, 'Metadata')
+ for node in self._model.nodes.itervalues():
node.dump()
- for group in self._template.groups.itervalues():
+ for group in self._model.groups.itervalues():
group.dump()
- for policy in self._template.policies.itervalues():
+ for policy in self._model.policies.itervalues():
policy.dump()
- if self._template.substitution is not None:
- self._template.substitution.dump()
- self._topology.dump(self._template.inputs, context, 'Inputs')
- self._topology.dump(self._template.outputs, context, 'Outputs')
- self._topology.dump(self._template.workflows, context, 'Workflows')
+ if self._model.substitution is not None:
+ self._model.substitution.dump()
+ self._topology.dump(self._model.inputs, context, 'Inputs')
+ self._topology.dump(self._model.outputs, context, 'Outputs')
+ self._topology.dump(self._model.workflows, context, 'Workflows')
+
+ def configure_operations(self):
+ for node in self._model.nodes.itervalues():
+ self._topology.configure_operations(node)
+ for group in self._model.groups.itervalues():
+ self._topology.configure_operations(group)
+ for operation in self._model.workflows.itervalues():
+ self._topology.configure_operations(operation)
+
+ def validate_capabilities(self):
+ satisfied = True
+ for node in self._model.nodes.values():
+ if not self._topology.validate_capabilities(node):
+ satisfied = False
+ return satisfied
+
+ def satisfy_requirements(self):
+ return all(self._topology.satisfy_requirements(node)
+ for node in self._model.nodes.values())
class Substitution(common._InstanceHandler):
def coerce(self, **kwargs):
- self._topology.coerce(self._template.mappings, **kwargs)
+ self._topology.coerce(self._model.mappings, **kwargs)
def validate(self, **kwargs):
- self._topology.validate(self._template.mappings)
+ self._topology.validate(self._model.mappings)
def dump(self, context):
context.write('Substitution:')
with context.style.indent:
- context.write('Node type: {0}'.format(context.style.type(self._template.node_type.name)))
- self._topology.dump(self._template.mappings, context, 'Mappings')
+ context.write('Node type: {0}'.format(context.style.type(self._model.node_type.name)))
+ self._topology.dump(self._model.mappings, context, 'Mappings')
class SubstitutionMapping(common._InstanceHandler):
def validate(self, **kwargs):
# context = ConsumptionContext.get_thread_local()
- if (self._template.capability is None) and (self._template.requirement_template is None):
+ if (self._model.capability is None) and (self._model.requirement_template is None):
pass
# TODO: handler reports
# context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
@@ -312,16 +550,17 @@ class SubstitutionMapping(common._InstanceHandler):
# level=validation.Issue.BETWEEN_TYPES)
def dump(self, context):
- if self._template.capability is not None:
+ if self._model.capability is not None:
context.write('{0} -> {1}.{2}'.format(
- context.style.node(self._template.name),
- context.style.node(self._template.capability.node.name),
- context.style.node(self._template.capability.name)))
+ context.style.node(self._model.name),
+ context.style.node(self._model.capability.node.name),
+ context.style.node(self._model.capability.name)))
else:
context.write('{0} -> {1}.{2}'.format(
- context.style.node(self._template.name),
- context.style.node(self._template.node.name),
- context.style.node(self._template.requirement_template.name)))
+ context.style.node(self._model.name),
+ context.style.node(self._model.node.name),
+ context.style.node(self._model.requirement_template.name)))
+
class Metadata(common._InstanceHandler):
@@ -334,7 +573,7 @@ class Metadata(common._InstanceHandler):
pass
def instantiate(self, instance_cls, **kwargs):
- return instance_cls(name=self._template.name, value=self._template.value)
+ return instance_cls(name=self._model.name, value=self._model.value)
def validate(self):
pass
@@ -343,24 +582,24 @@ class Metadata(common._InstanceHandler):
class _Parameter(common._InstanceHandler):
def dump(self, context):
- if self._template.type_name is not None:
+ if self._model.type_name is not None:
context.write('{0}: {1} ({2})'.format(
- context.style.property(self._template.name),
- context.style.literal(formatting.as_raw(self._template.value)),
- context.style.type(self._template.type_name)))
+ context.style.property(self._model.name),
+ context.style.literal(formatting.as_raw(self._model.value)),
+ context.style.type(self._model.type_name)))
else:
context.write('{0}: {1}'.format(
- context.style.property(self._template.name),
- context.style.literal(formatting.as_raw(self._template.value))))
- if self._template.description:
- context.write(context.style.meta(self._template.description))
+ context.style.property(self._model.name),
+ context.style.literal(formatting.as_raw(self._model.value))))
+ if self._model.description:
+ context.write(context.style.meta(self._model.description))
def instantiate(self, instance_cls, **kwargs):
return instance_cls(
- name=self._template.name, # pylint: disable=unexpected-keyword-arg
- type_name=self._template.type_name,
- _value=self._template._value,
- description=self._template.description
+ name=self._model.name, # pylint: disable=unexpected-keyword-arg
+ type_name=self._model.type_name,
+ _value=self._model._value,
+ description=self._model.description
)
def validate(self):
@@ -396,8 +635,8 @@ class Type(common._InstanceHandler):
pass
def dump(self, context):
- if self._template.name:
- context.write(context.style.type(self._template.name))
+ if self._model.name:
+ context.write(context.style.type(self._model.name))
with context.style.indent:
- for child in self._template.children:
+ for child in self._model.children:
self._topology.dump(context, child)