Exemple #1
0
def instantiate_spec(spec_cls, data):
    """Instantiates specification accounting for specification hierarchies.

    :param spec_cls: Specification concrete or base class. In case if base
        class or the hierarchy is provided this method relies on attributes
        _polymorphic_key and _polymorphic_value in order to find a concrete
        class that needs to be instantiated.
    :param data: Raw specification data as a dictionary.
    """

    if issubclass(spec_cls, BaseSpecList):
        # Ignore polymorphic search for specification lists because
        # it doesn't make sense for them.
        return spec_cls(data)

    if not hasattr(spec_cls, '_polymorphic_key'):
        spec = spec_cls(data)

        spec.validate_semantics()

        return spec

    # In order to do polymorphic search we need to make sure that
    # a spec is backed by a dictionary. Otherwise we can't extract
    # a polymorphic key.
    if not isinstance(data, dict):
        raise exc.InvalidModelException(
            "A specification with polymorphic key must be backed by"
            " a dictionary [spec_cls=%s, data=%s]" % (spec_cls, data))

    key = spec_cls._polymorphic_key

    if not isinstance(key, tuple):
        key_name = key
        key_default = None
    else:
        key_name = key[0]
        key_default = key[1]

    for cls in utils.iter_subclasses(spec_cls):
        if not hasattr(cls, '_polymorphic_value'):
            raise exc.DSLParsingException(
                "Class '%s' is expected to have attribute '_polymorphic_value'"
                " because it's a part of specification hierarchy inherited "
                "from class '%s'." % (cls, spec_cls))

        if cls._polymorphic_value == data.get(key_name, key_default):
            spec = cls(data)

            spec.validate_semantics()

            return spec

    raise exc.DSLParsingException(
        'Failed to find a specification class to instantiate '
        '[spec_cls=%s, data=%s]' % (spec_cls, data))
Exemple #2
0
def _get_spec_version(spec_dict):
    # If version is not specified it will '2.0' by default.
    ver = V2_0

    if 'version' in spec_dict:
        ver = spec_dict['version']

    if not ver or str(float(ver)) not in ALL_VERSIONS:
        raise exc.DSLParsingException('Unsupported DSL version: %s' % ver)

    return ver
Exemple #3
0
def parse_yaml(text):
    """Loads a text in YAML format as dictionary object.

    :param text: YAML text.
    :return: Parsed YAML document as dictionary.
    """

    try:
        return yaml.safe_load(text) or {}
    except error.YAMLError as e:
        raise exc.DSLParsingException("Definition could not be parsed: %s\n" %
                                      e)
Exemple #4
0
    def validate_semantics(self):
        super(DirectWorkflowSpec, self).validate_semantics()

        # Check if there are start tasks.
        if not self.find_start_tasks():
            raise exc.DSLParsingException(
                'Failed to find start tasks in direct workflow. '
                'There must be at least one task without inbound transition.'
                '[workflow_name=%s]' % self._name)

        self._check_workflow_integrity()
        self._check_join_tasks()
Exemple #5
0
 def _raise(ver):
     raise exc.DSLParsingException('Unsupported DSL version: %s' % ver)