blob: 5c3206b8a3392b84b21e24baadd58db5a3a41249 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
from aria.parser.modeling import (Type, RelationshipType, PolicyType, ServiceModel, NodeTemplate,
RequirementTemplate, RelationshipTemplate, CapabilityTemplate,
GroupTemplate, PolicyTemplate, SubstitutionTemplate,
MappingTemplate, InterfaceTemplate, OperationTemplate,
ArtifactTemplate, Metadata, Parameter)
from ..data_types import coerce_value
def create_service_model(context): # pylint: disable=too-many-locals,too-many-branches
model = ServiceModel()
model.description = context.presentation.get('service_template', 'description', 'value')
metadata = context.presentation.get('service_template', 'metadata')
if metadata is not None:
substitution_template = Metadata()
substitution_template.values['template_name'] = metadata.template_name
substitution_template.values['template_author'] = metadata.template_author
substitution_template.values['template_version'] = metadata.template_version
custom = metadata.custom
if custom:
for name, v in custom.iteritems():
substitution_template.values[name] = v
model.metadata = substitution_template
create_types(context,
context.modeling.node_types,
context.presentation.get('service_template', 'node_types'))
create_types(context,
context.modeling.group_types,
context.presentation.get('service_template', 'group_types'))
create_types(context,
context.modeling.capability_types,
context.presentation.get('service_template', 'capability_types'))
create_types(context,
context.modeling.relationship_types,
context.presentation.get('service_template', 'relationship_types'),
create_relationship_type)
create_types(context,
context.modeling.policy_types,
context.presentation.get('service_template', 'policy_types'),
create_policy_type)
create_types(context,
context.modeling.artifact_types,
context.presentation.get('service_template', 'artifact_types'))
create_types(context,
context.modeling.interface_types,
context.presentation.get('service_template', 'interface_types'))
topology_template = context.presentation.get('service_template', 'topology_template')
if topology_template is not None:
create_properties_from_values(model.inputs, topology_template._get_input_values(context))
create_properties_from_values(model.outputs, topology_template._get_output_values(context))
node_templates = context.presentation.get('service_template', 'topology_template',
'node_templates')
if node_templates:
for node_template_name, node_template in node_templates.iteritems():
model.node_templates[node_template_name] = create_node_template(context, node_template)
groups = context.presentation.get('service_template', 'topology_template', 'groups')
if groups:
for group_name, group in groups.iteritems():
model.group_templates[group_name] = create_group_template(context, group)
policies = context.presentation.get('service_template', 'topology_template', 'policies')
if policies:
for policy_name, policy in policies.iteritems():
model.policy_templates[policy_name] = create_policy_template(context, policy)
substitution_mappings = context.presentation.get('service_template', 'topology_template',
'substitution_mappings')
if substitution_mappings is not None:
substitution_template = SubstitutionTemplate(substitution_mappings.node_type)
capabilities = substitution_mappings.capabilities
if capabilities:
for mapped_capability_name, capability in capabilities.iteritems():
substitution_template.capability_templates[mapped_capability_name] = \
MappingTemplate(mapped_capability_name, capability.node_template,
capability.capability)
requirements = substitution_mappings.requirements
if requirements:
for mapped_requirement_name, requirement in requirements.iteritems():
substitution_template.requirement_templates[mapped_requirement_name] = \
MappingTemplate(mapped_requirement_name, requirement.node_template,
requirement.requirement)
model.substitution_template = substitution_template
return model
def create_node_template(context, node_template):
model = NodeTemplate(name=node_template._name, type_name=node_template.type)
if node_template.description:
model.description = node_template.description.value
create_properties_from_values(model.properties, node_template._get_property_values(context))
create_interface_templates(context, model.interface_templates,
node_template._get_interfaces(context))
artifacts = node_template._get_artifacts(context)
if artifacts:
for artifact_name, artifact in artifacts.iteritems():
model.artifact_templates[artifact_name] = create_artifact_template(context, artifact)
requirements = node_template._get_requirements(context)
if requirements:
for _, requirement in requirements:
model.requirement_templates.append(create_requirement_template(context, requirement))
capabilities = node_template._get_capabilities(context)
if capabilities:
for capability_name, capability in capabilities.iteritems():
model.capability_templates[capability_name] = create_capability_template(context,
capability)
create_node_filter_constraint_lambdas(context, node_template.node_filter,
model.target_node_template_constraints)
return model
def create_interface_template(context, interface):
the_type = interface._get_type(context)
model = InterfaceTemplate(name=interface._name, type_name=the_type._name)
if the_type.description:
model.description = the_type.description.value
inputs = interface.inputs
if inputs:
for input_name, the_input in inputs.iteritems():
model.inputs[input_name] = Parameter(the_input.value.type, the_input.value.value,
the_input.value.description)
operations = interface.operations
if operations:
for operation_name, operation in operations.iteritems():
model.operation_templates[operation_name] = create_operation_template(context,
operation)
return model if model.operation_templates else None
def create_operation_template(context, operation): # pylint: disable=unused-argument
model = OperationTemplate(name=operation._name)
if operation.description:
model.description = operation.description.value
implementation = operation.implementation
if implementation is not None:
model.implementation = implementation.primary
dependencies = implementation.dependencies
if dependencies is not None:
model.dependencies = dependencies
inputs = operation.inputs
if inputs:
for input_name, the_input in inputs.iteritems():
model.inputs[input_name] = Parameter(the_input.value.type, the_input.value.value,
the_input.value.description)
return model
def create_artifact_template(context, artifact):
model = ArtifactTemplate(name=artifact._name, type_name=artifact.type,
source_path=artifact.file)
if artifact.description:
model.description = artifact.description.value
model.target_path = artifact.deploy_path
repository = artifact._get_repository(context)
if repository is not None:
model.repository_url = repository.url
credential = repository._get_credential(context)
if credential:
for k, v in credential.iteritems():
model.repository_credential[k] = v
create_properties_from_values(model.properties, artifact._get_property_values(context))
return model
def create_requirement_template(context, requirement):
model = {'name': requirement._name}
node, node_variant = requirement._get_node(context)
if node is not None:
if node_variant == 'node_type':
model['target_node_type_name'] = node._name
else:
model['target_node_template_name'] = node._name
capability, capability_variant = requirement._get_capability(context)
if capability is not None:
if capability_variant == 'capability_type':
model['target_capability_type_name'] = capability._name
else:
model['target_capability_name'] = capability._name
model = RequirementTemplate(**model)
create_node_filter_constraint_lambdas(context, requirement.node_filter,
model.target_node_template_constraints)
relationship = requirement.relationship
if relationship is not None:
model.relationship_template = create_relationship_template(context, relationship)
return model
def create_relationship_type(context, relationship_type): # pylint: disable=unused-argument
return RelationshipType(relationship_type._name)
def create_policy_type(context, policy_type): # pylint: disable=unused-argument
return PolicyType(policy_type._name)
def create_relationship_template(context, relationship):
relationship_type, relationship_type_variant = relationship._get_type(context)
if relationship_type_variant == 'relationship_type':
model = RelationshipTemplate(type_name=relationship_type._name)
else:
relationship_template = relationship_type
relationship_type = relationship_template._get_type(context)
model = RelationshipTemplate(type_name=relationship_type._name,
template_name=relationship_template._name)
if relationship_template.description:
model.description = relationship_template.description.value
create_properties_from_assignments(model.properties, relationship.properties)
create_interface_templates(context, model.source_interface_templates, relationship.interfaces)
return model
def create_capability_template(context, capability):
capability_type = capability._get_type(context)
model = CapabilityTemplate(name=capability._name, type_name=capability_type._name)
capability_definition = capability._get_definition(context)
if capability_definition.description:
model.description = capability_definition.description.value
occurrences = capability_definition.occurrences
if occurrences is not None:
model.min_occurrences = occurrences.value[0]
if occurrences.value[1] != 'UNBOUNDED':
model.max_occurrences = occurrences.value[1]
valid_source_types = capability_definition.valid_source_types
if valid_source_types:
model.valid_source_node_type_names = valid_source_types
create_properties_from_assignments(model.properties, capability.properties)
return model
def create_group_template(context, group):
group_type = group._get_type(context)
model = GroupTemplate(name=group._name, type_name=group_type._name)
if group.description:
model.description = group.description.value
create_properties_from_values(model.properties, group._get_property_values(context))
create_interface_templates(context, model.interface_templates, group._get_interfaces(context))
members = group.members
if members:
for member in members:
model.member_node_template_names.append(member)
return model
def create_policy_template(context, policy):
policy_type = policy._get_type(context)
model = PolicyTemplate(name=policy._name, type_name=policy_type._name)
if policy.description:
model.description = policy.description.value
create_properties_from_values(model.properties, policy._get_property_values(context))
node_templates, groups = policy._get_targets(context)
for node_template in node_templates:
model.target_node_template_names.append(node_template._name)
for group in groups:
model.target_group_template_names.append(group._name)
return model
#
# Utils
#
def create_types(context, root, types, normalize=None):
if types is None:
return
def added_all():
for name in types:
if root.get_descendant(name) is None:
return False
return True
while not added_all():
for name, the_type in types.iteritems():
if root.get_descendant(name) is None:
parent_type = the_type._get_parent(context)
if normalize:
model = normalize(context, the_type)
else:
model = Type(the_type._name)
if the_type.description:
model.description = the_type.description.value
if parent_type is None:
root.children.append(model)
else:
container = root.get_descendant(parent_type._name)
if container is not None:
container.children.append(model)
def create_properties_from_values(properties, source_properties):
if source_properties:
for property_name, prop in source_properties.iteritems():
properties[property_name] = Parameter(prop.type, prop.value, prop.description)
def create_properties_from_assignments(properties, source_properties):
if source_properties:
for property_name, prop in source_properties.iteritems():
properties[property_name] = Parameter(prop.value.type, prop.value.value,
prop.value.description)
def create_interface_templates(context, interfaces, source_interfaces):
if source_interfaces:
for interface_name, interface in source_interfaces.iteritems():
interface = create_interface_template(context, interface)
if interface is not None:
interfaces[interface_name] = interface
def create_node_filter_constraint_lambdas(context, node_filter, node_type_constraints):
if node_filter is None:
return
properties = node_filter.properties
if properties is not None:
for property_name, constraint_clause in properties:
func = create_constraint_clause_lambda(context, node_filter, constraint_clause,
property_name, None)
if func is not None:
node_type_constraints.append(func)
capabilities = node_filter.capabilities
if capabilities is not None:
for capability_name, capability in capabilities:
properties = capability.properties
if properties is not None:
for property_name, constraint_clause in properties:
func = create_constraint_clause_lambda(context, node_filter, constraint_clause,
property_name, capability_name)
if func is not None:
node_type_constraints.append(func)
def create_constraint_clause_lambda(context, node_filter, constraint_clause, property_name, # pylint: disable=too-many-return-statements
capability_name):
constraint_key = constraint_clause._raw.keys()[0]
the_type = constraint_clause._get_type(context)
def coerce_constraint(constraint, container):
constraint = coerce_value(context, node_filter, the_type, None, None, constraint,
constraint_key) if the_type is not None else constraint
if hasattr(constraint, '_evaluate'):
constraint = constraint._evaluate(context, container)
return constraint
def get_value(node_type):
if capability_name is not None:
capability = node_type.capability_templates.get(capability_name)
prop = capability.properties.get(property_name) if capability is not None else None
return prop.value if prop is not None else None
value = node_type.properties.get(property_name)
return value.value if value is not None else None
if constraint_key == 'equal':
def equal(node_type, container):
constraint = coerce_constraint(constraint_clause.equal, container)
value = get_value(node_type)
return value == constraint
return equal
elif constraint_key == 'greater_than':
def greater_than(node_type, container):
constraint = coerce_constraint(constraint_clause.greater_than, container)
value = get_value(node_type)
return value > constraint
return greater_than
elif constraint_key == 'greater_or_equal':
def greater_or_equal(node_type, container):
constraint = coerce_constraint(constraint_clause.greater_or_equal, container)
value = get_value(node_type)
return value >= constraint
return greater_or_equal
elif constraint_key == 'less_than':
def less_than(node_type, container):
constraint = coerce_constraint(constraint_clause.less_than, container)
value = get_value(node_type)
return value < constraint
return less_than
elif constraint_key == 'less_or_equal':
def less_or_equal(node_type, container):
constraint = coerce_constraint(constraint_clause.less_or_equal, container)
value = get_value(node_type)
return value <= constraint
return less_or_equal
elif constraint_key == 'in_range':
def in_range(node_type, container):
lower, upper = constraint_clause.in_range
lower, upper = coerce_constraint(lower, container), coerce_constraint(upper, container)
value = get_value(node_type)
if value < lower:
return False
if (upper != 'UNBOUNDED') and (value > upper):
return False
return True
return in_range
elif constraint_key == 'valid_values':
def valid_values(node_type, container):
constraint = tuple(coerce_constraint(v, container)
for v in constraint_clause.valid_values)
value = get_value(node_type)
return value in constraint
return valid_values
elif constraint_key == 'length':
def length(node_type, container): # pylint: disable=unused-argument
constraint = constraint_clause.length
value = get_value(node_type)
return len(value) == constraint
return length
elif constraint_key == 'min_length':
def min_length(node_type, container): # pylint: disable=unused-argument
constraint = constraint_clause.min_length
value = get_value(node_type)
return len(value) >= constraint
return min_length
elif constraint_key == 'max_length':
def max_length(node_type, container): # pylint: disable=unused-argument
constraint = constraint_clause.max_length
value = get_value(node_type)
return len(value) >= constraint
return max_length
elif constraint_key == 'pattern':
def pattern(node_type, container): # pylint: disable=unused-argument
constraint = constraint_clause.pattern
# Note: the TOSCA 1.0 spec does not specify the regular expression grammar, so we will
# just use Python's
value = node_type.properties.get(property_name)
return re.match(constraint, str(value)) is not None
return pattern
return None