Github user mxmrlv commented on a diff in the pull request:

    https://github.com/apache/incubator-ariatosca/pull/189#discussion_r131132996
  
    --- Diff: aria/orchestrator/topology/instance_handler.py ---
    @@ -0,0 +1,644 @@
    +# 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.
    +
    +from ... parser.modeling import context
    +from ... modeling import models
    +from ... utils import formatting
    +from .. import execution_plugin
    +from .. import decorators
    +from . import common
    +
    +
    +class Artifact(common._InstanceHandlerMixin):
    +
    +    def coerce(self, **kwargs):
    +        self._topology.coerce(self._model.properties, **kwargs)
    +
    +    def validate(self, **kwargs):
    +        self._topology.validate(self._model.properties)
    +
    +    def dump(self, out_stream):
    +        with out_stream.indent():
    +            out_stream.write(out_stream.node(self._model.name))
    +            out_stream.write(out_stream.meta(self._model.description))
    +            with out_stream.indent():
    +                out_stream.write('Artifact type: 
{0}'.format(out_stream.type(
    +                    self._model.type.name)))
    +                out_stream.write('Source path: {0}'.format(
    +                    out_stream.literal(self._model.source_path)))
    +                if self._model.target_path is not None:
    +                    out_stream.write('Target path: {0}'.format(
    +                        out_stream.literal(self._model.target_path)))
    +                if self._model.repository_url is not None:
    +                    out_stream.write('Repository URL: {0}'.format(
    +                        out_stream.literal(self._model.repository_url)))
    +                if self._model.repository_credential:
    +                    out_stream.write('Repository credential: {0}'.format(
    +                        
out_stream.literal(self._model.repository_credential)))
    +                self._topology.dump(self._model.properties, out_stream, 
'Properties')
    +
    +
    +class Capability(common._InstanceHandlerMixin):
    +    def coerce(self, **kwargs):
    +        self._topology.coerce(self._model.properties, **kwargs)
    +
    +    def validate(self, **kwargs):
    +        self._topology.validate(self._model.properties)
    +
    +    def dump(self, out_stream):
    +        out_stream.write(out_stream.node(self._model.name))
    +        with out_stream.indent():
    +            out_stream.write('Type: 
{0}'.format(out_stream.type(self._model.type.name)))
    +            out_stream.write('Occurrences: {0:d} ({1:d}{2})'.format(
    +                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._model.properties, out_stream, 
'Properties')
    +
    +
    +class Group(common._OperatorHolderHandlerMixin):
    +
    +    def coerce(self, **kwargs):
    +        self._coerce(self._model.properties, self._model.interfaces, 
**kwargs)
    +
    +    def validate(self, **kwargs):
    +        self._validate(self._model.properties,
    +                       self._model.interfaces)
    +
    +    def dump(self, out_stream):
    +        out_stream.write('Group: 
{0}'.format(out_stream.node(self._model.name)))
    +        with out_stream.indent():
    +            out_stream.write('Type: 
{0}'.format(out_stream.type(self._model.type.name)))
    +            self._topology.dump(self._model.properties, out_stream, 
'Properties')
    +            self._topology.dump(self._model.interfaces, out_stream, 
'Interfaces')
    +            if self._model.nodes:
    +                out_stream.write('Member nodes:')
    +                with out_stream.indent():
    +                    for node in self._model.nodes:
    +                        out_stream.write(out_stream.node(node.name))
    +
    +    def configure_operations(self):
    +        for interface in self._model.interfaces.values():
    +            self._topology.configure_operations(interface)
    +
    +
    +class Interface(common._OperatorHolderHandlerMixin):
    +    def coerce(self, **kwargs):
    +        self._coerce(self._model.inputs, self._model.operations, **kwargs)
    +
    +    def validate(self, **kwargs):
    +        self._validate(self._model.inputs,
    +                       self._model.operations)
    +
    +    def dump(self, out_stream):
    +        out_stream.write(out_stream.node(self._model.name))
    +        if self._model.description:
    +            out_stream.write(out_stream.meta(self._model.description))
    +        with out_stream.indent():
    +            out_stream.write('Interface type: 
{0}'.format(out_stream.type(self._model.type.name)))
    +            self._topology.dump(self._model.inputs, out_stream, 'Inputs')
    +            self._topology.dump(self._model.operations, out_stream, 
'Operations')
    +
    +    def configure_operations(self):
    +        for operation in self._model.operations.values():
    +            self._topology.configure_operations(operation)
    +
    +
    +class Node(common._OperatorHolderHandlerMixin):
    +    def coerce(self, **kwargs):
    +        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):
    +        if len(self._model.name) > context.ID_MAX_LENGTH:
    +            self._topology.report(
    +                '"{0}" has an ID longer than the limit of {1:d} 
characters: {2:d}'.format(
    +                    self._model.name, context.ID_MAX_LENGTH, 
len(self._model.name)),
    +                level=self._topology.Issue.BETWEEN_INSTANCES)
    +
    +        self._validate(self._model.properties,
    +                       self._model.attributes,
    +                       self._model.interfaces,
    +                       self._model.artifacts,
    +                       self._model.capabilities,
    +                       self._model.outbound_relationships)
    +
    +    def dump(self, out_stream):
    +        out_stream.write('Node: 
{0}'.format(out_stream.node(self._model.name)))
    +        with out_stream.indent():
    +            out_stream.write('Type: 
{0}'.format(out_stream.type(self._model.type.name)))
    +            out_stream.write('Template: {0}'.format(
    +                out_stream.node(self._model.node_template.name)))
    +            self._topology.dump(self._model.properties, out_stream, 
'Properties')
    +            self._topology.dump(self._model.attributes, out_stream, 
'Attributes')
    +            self._topology.dump(self._model.interfaces, out_stream, 
'Interfaces')
    +            self._topology.dump(self._model.artifacts, out_stream, 
'Artifacts')
    +            self._topology.dump(self._model.capabilities, out_stream, 
'Capabilities')
    +            self._topology.dump(self._model.outbound_relationships, 
out_stream, '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):
    +        satisfied = False
    +        for capability in self._model.capabilities.itervalues():
    +            if not capability.has_enough_relationships:
    +                self._topology.report(
    +                    'capability "{0}" of node "{1}" requires at least 
{2:d} '
    +                    'relationships but has {3:d}'.format(capability.name,
    +                                                         self._model.name,
    +                                                         
capability.min_occurrences,
    +                                                         
capability.occurrences),
    +                    level=self._topology.Issue.BETWEEN_INSTANCES)
    +                satisfied = False
    +        return satisfied
    +
    +    def satisfy_requirements(self):
    +        satisfied = True
    +        for requirement_template in 
self._model.node_template.requirement_templates:
    +
    +            # Since we try and satisfy requirements, which are node 
template bound, and use that
    +            # information in the creation of the relationship, Some 
requirements may have been
    +            # satisfied by a previous run on that node template.
    +            # The entire mechanism of satisfying requirements needs to be 
refactored.
    +            if any(r.requirement_template == requirement_template
    +                   for r in self._model.outbound_relationships):
    +                return satisfied
    +
    +            # 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:
    +                self._topology.report('requirement "{0}" of node "{1}" has 
no target node template'.
    +                                      format(requirement_template.name, 
self._model.name),
    +                                      
level=self._topology.Issue.BETWEEN_INSTANCES)
    +                satisfied = False
    +        return satisfied
    +
    +    def _satisfy_capability(self, target_node_capability, 
target_node_template,
    +                            requirement_template):
    +        # 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:
    +                    relationship_model = self._topology.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:
    +                self._topology.report(
    +                    'requirement "{0}" of node "{1}" targets node '
    +                    'template "{2}" but its instantiated nodes do not '
    +                    'have enough capacity'.format(
    +                        requirement_template.name, self._model.name, 
target_node_template.name),
    +                    level=self._topology.Issue.BETWEEN_INSTANCES)
    +                return False
    +        else:
    +            self._topology.report(
    +                'requirement "{0}" of node "{1}" targets node template '
    +                '"{2}" but it has no instantiated nodes'.format(
    +                    requirement_template.name, self._model.name, 
target_node_template.name),
    +                level=self._topology.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):
    +                self._topology.report(
    +                    'requirement "{0}" of node template "{1}" is for node '
    +                    'template "{2}" but it does not match 
constraints'.format(
    +                        requirement_template.name,
    +                        requirement_template.target_node_template.name,
    +                        self._model.node_template.name),
    +                    level=self._topology.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(requirement_template)
    +                if target_node_capability is None:
    +                    return None, None
    +            else:
    +                target_node_capability = None
    +
    +            return requirement_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
    +
    +                target_node_capability = 
self._get_capability(requirement_template,
    +                                                              
target_node_template)
    +
    +                if target_node_capability is None:
    +                    continue
    +
    +                return target_node_template, target_node_capability
    +
    --- End diff --
    
    documented


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---

Reply via email to