[ 
https://issues.apache.org/jira/browse/ARIA-105?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15932951#comment-15932951
 ] 

ASF GitHub Bot commented on ARIA-105:
-------------------------------------

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

    https://github.com/apache/incubator-ariatosca/pull/72#discussion_r106946082
  
    --- Diff: aria/modeling/orchestration.py ---
    @@ -0,0 +1,350 @@
    +# 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.
    +
    +"""
    +classes:
    +    * Execution - execution implementation model.
    +    * Plugin - plugin implementation model.
    +    * Task - a task
    +"""
    +
    +# pylint: disable=no-self-argument, no-member, abstract-method
    +
    +from datetime import datetime
    +
    +from sqlalchemy import (
    +    Column,
    +    Integer,
    +    Text,
    +    DateTime,
    +    Boolean,
    +    Enum,
    +    String,
    +    Float,
    +    orm,
    +)
    +from sqlalchemy.ext.associationproxy import association_proxy
    +from sqlalchemy.ext.declarative import declared_attr
    +
    +from ..orchestrator.exceptions import (TaskAbortException, 
TaskRetryException)
    +from .types import (List, Dict)
    +from .mixins import ModelMixin
    +from . import relationships
    +
    +
    +class ExecutionBase(ModelMixin):
    +    """
    +    Execution model representation.
    +    """
    +
    +    __tablename__ = 'execution'
    +
    +    TERMINATED = 'terminated'
    +    FAILED = 'failed'
    +    CANCELLED = 'cancelled'
    +    PENDING = 'pending'
    +    STARTED = 'started'
    +    CANCELLING = 'cancelling'
    +    FORCE_CANCELLING = 'force_cancelling'
    +
    +    STATES = [TERMINATED, FAILED, CANCELLED, PENDING, STARTED, CANCELLING, 
FORCE_CANCELLING]
    +    END_STATES = [TERMINATED, FAILED, CANCELLED]
    +    ACTIVE_STATES = [state for state in STATES if state not in END_STATES]
    +
    +    VALID_TRANSITIONS = {
    +        PENDING: [STARTED, CANCELLED],
    +        STARTED: END_STATES + [CANCELLING],
    +        CANCELLING: END_STATES + [FORCE_CANCELLING]
    +    }
    +
    +    @orm.validates('status')
    +    def validate_status(self, key, value):
    +        """Validation function that verifies execution status transitions 
are OK"""
    +        try:
    +            current_status = getattr(self, key)
    +        except AttributeError:
    +            return
    +        valid_transitions = self.VALID_TRANSITIONS.get(current_status, [])
    +        if all([current_status is not None,
    +                current_status != value,
    +                value not in valid_transitions]):
    +            raise ValueError('Cannot change execution status from 
{current} to {new}'.format(
    +                current=current_status,
    +                new=value))
    +        return value
    +
    +    created_at = Column(DateTime, index=True)
    +    started_at = Column(DateTime, nullable=True, index=True)
    +    ended_at = Column(DateTime, nullable=True, index=True)
    +    error = Column(Text, nullable=True)
    +    is_system_workflow = Column(Boolean, nullable=False, default=False)
    +    parameters = Column(Dict)
    +    status = Column(Enum(*STATES, name='execution_status'), 
default=PENDING)
    +    workflow_name = Column(Text)
    +
    +    @declared_attr
    +    def service(cls):
    +        return relationships.many_to_one(cls, 'service')
    +
    +    # region foreign keys
    +
    +    @declared_attr
    +    def service_fk(cls):
    +        return relationships.fk('service')
    +
    +    # endregion
    +
    +    # region association proxies
    +
    +    @declared_attr
    +    def service_name(cls):
    +        """Required for use by SQLAlchemy queries"""
    +        return association_proxy('service', cls.name_column_name())
    +
    +    @declared_attr
    +    def service_template(cls):
    +        """Required for use by SQLAlchemy queries"""
    +        return association_proxy('service', 'service_template')
    +
    +    @declared_attr
    +    def service_template_name(cls):
    +        """Required for use by SQLAlchemy queries"""
    +        return association_proxy('service', 'service_template_name')
    +
    +    # endregion
    +
    +    def __str__(self):
    +        return '<{0} id=`{1}` (status={2})>'.format(
    +            self.__class__.__name__,
    +            getattr(self, self.name_column_name()),
    +            self.status
    +        )
    +
    +    __private_fields__ = ['service_fk',
    +                          'service_name',
    +                          'service_template',
    +                          'service_template_name']
    +
    +
    +class PluginBase(ModelMixin):
    +    """
    +    Plugin model representation.
    +    """
    +
    +    __tablename__ = 'plugin'
    +
    +    archive_name = Column(Text, nullable=False, index=True)
    +    distribution = Column(Text)
    +    distribution_release = Column(Text)
    +    distribution_version = Column(Text)
    +    package_name = Column(Text, nullable=False, index=True)
    +    package_source = Column(Text)
    +    package_version = Column(Text)
    +    supported_platform = Column(Text)
    +    supported_py_versions = Column(List)
    +    uploaded_at = Column(DateTime, nullable=False, index=True)
    +    wheels = Column(List, nullable=False)
    +
    +
    +class TaskBase(ModelMixin):
    +    """
    +    A Model which represents an task
    +    """
    +
    +    __tablename__ = 'task'
    +
    +    PENDING = 'pending'
    +    RETRYING = 'retrying'
    +    SENT = 'sent'
    +    STARTED = 'started'
    +    SUCCESS = 'success'
    +    FAILED = 'failed'
    +    STATES = (
    +        PENDING,
    +        RETRYING,
    +        SENT,
    +        STARTED,
    +        SUCCESS,
    +        FAILED,
    +    )
    +
    +    WAIT_STATES = [PENDING, RETRYING]
    +    END_STATES = [SUCCESS, FAILED]
    +
    +    RUNS_ON_SOURCE = 'source'
    +    RUNS_ON_TARGET = 'target'
    +    RUNS_ON_NODE = 'node'
    +    RUNS_ON = (RUNS_ON_NODE, RUNS_ON_SOURCE, RUNS_ON_TARGET)
    +
    +    INFINITE_RETRIES = -1
    +
    +    @declared_attr
    +    def node(cls):
    +        return relationships.many_to_one(cls, 'node')
    +
    +    @declared_attr
    +    def relationship(cls):
    +        return relationships.many_to_one(cls, 'relationship')
    +
    +    @declared_attr
    +    def plugin(cls):
    +        return relationships.many_to_one(cls, 'plugin')
    +
    +    @declared_attr
    +    def execution(cls):
    +        return relationships.many_to_one(cls, 'execution')
    +
    +    @declared_attr
    +    def inputs(cls):
    +        return relationships.many_to_many(cls, 'parameter', 
prefix='inputs', dict_key='name')
    +
    +    status = Column(Enum(*STATES, name='status'), default=PENDING)
    +
    +    due_at = Column(DateTime, nullable=False, index=True, 
default=datetime.utcnow())
    +    started_at = Column(DateTime, default=None)
    +    ended_at = Column(DateTime, default=None)
    +    max_attempts = Column(Integer, default=1)
    +    retry_count = Column(Integer, default=0)
    +    retry_interval = Column(Float, default=0)
    +    ignore_failure = Column(Boolean, default=False)
    +
    +    # Operation specific fields
    +    implementation = Column(String)
    +    _runs_on = Column(Enum(*RUNS_ON, name='runs_on'), name='runs_on')
    +
    +    @property
    +    def runs_on(self):
    +        if self._runs_on == self.RUNS_ON_NODE:
    +            return self.node
    +        elif self._runs_on == self.RUNS_ON_SOURCE:
    +            return self.relationship.source_node  # pylint: 
disable=no-member
    +        elif self._runs_on == self.RUNS_ON_TARGET:
    +            return self.relationship.target_node  # pylint: 
disable=no-member
    +        return None
    +
    +    @property
    +    def actor(self):
    +        """
    +        Return the actor of the task
    +        :return:
    +        """
    +        return self.node or self.relationship
    +
    +    @orm.validates('max_attempts')
    +    def validate_max_attempts(self, _, value):                             
     # pylint: disable=no-self-use
    +        """Validates that max attempts is either -1 or a positive number"""
    +        if value < 1 and value != TaskBase.INFINITE_RETRIES:
    +            raise ValueError('Max attempts can be either -1 (infinite) or 
any positive number. '
    +                             'Got {value}'.format(value=value))
    +        return value
    +
    +    # region foreign keys
    +
    +    @declared_attr
    +    def node_fk(cls):
    +        return relationships.fk('node', nullable=True)
    --- End diff --
    
    Will change


> Integrate new models into parser
> --------------------------------
>
>                 Key: ARIA-105
>                 URL: https://issues.apache.org/jira/browse/ARIA-105
>             Project: AriaTosca
>          Issue Type: Task
>            Reporter: Ran Ziv
>            Assignee: Tal Liron
>




--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to