You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by av...@apache.org on 2017/07/26 12:27:58 UTC

incubator-ariatosca git commit: ARIA-313 Fix handling the `required` field of inputs

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-313-fix-handling-the-required-field-of-inputs [created] fd380f448


ARIA-313 Fix handling the `required` field of inputs

I split the logic of merging provided and declared input values into
three steps:

1. Validate that no undeclared inputs were provided.
2. Validate that all required inputs were provided with a value.
3. The actual merging process, which includes type checking.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/fd380f44
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/fd380f44
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/fd380f44

Branch: refs/heads/ARIA-313-fix-handling-the-required-field-of-inputs
Commit: fd380f44888aa2b18209a831d0855547ba1634bb
Parents: c2b8e65
Author: Avia Efrat <av...@gigaspaces.com>
Authored: Wed Jul 26 15:11:21 2017 +0300
Committer: Avia Efrat <av...@gigaspaces.com>
Committed: Wed Jul 26 15:26:01 2017 +0300

----------------------------------------------------------------------
 aria/modeling/exceptions.py                     |   4 +-
 aria/modeling/service_common.py                 |  13 +++
 aria/modeling/service_instance.py               |   2 +-
 aria/modeling/service_template.py               |   5 +
 aria/modeling/utils.py                          |  83 +++++++--------
 aria/orchestrator/workflow_runner.py            |   4 +
 aria/orchestrator/workflows/api/task.py         |   5 +
 aria/parser/consumption/style.py                |   5 +
 aria/parser/presentation/presentation.py        |   5 +-
 .../webserver-dbms-2/webserver-dbms-2.yaml      |   2 +-
 .../simple_v1_0/modeling/__init__.py            | 101 ++++++++++---------
 .../simple_v1_0/modeling/data_types.py          |   5 +-
 .../simple_v1_0/modeling/interfaces.py          |   8 +-
 .../simple_v1_0/modeling/parameters.py          |   3 +-
 tests/orchestrator/test_workflow_runner.py      |   6 +-
 15 files changed, 147 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/modeling/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/modeling/exceptions.py b/aria/modeling/exceptions.py
index 573efaf..cddc049 100644
--- a/aria/modeling/exceptions.py
+++ b/aria/modeling/exceptions.py
@@ -45,7 +45,7 @@ class CannotEvaluateFunctionException(ModelingException):
     """
 
 
-class MissingRequiredParametersException(ParameterException):
+class MissingRequiredInputsException(ParameterException):
     """
     ARIA modeling exception: Required parameters have been omitted.
     """
@@ -57,7 +57,7 @@ class ParametersOfWrongTypeException(ParameterException):
     """
 
 
-class UndeclaredParametersException(ParameterException):
+class UndeclaredInputsException(ParameterException):
     """
     ARIA modeling exception: Undeclared parameters have been provided.
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index b533a88..3d7b4de 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -22,6 +22,7 @@ ARIA modeling service common module
 from sqlalchemy import (
     Column,
     Text,
+    Boolean
 )
 from sqlalchemy.ext.declarative import declared_attr
 
@@ -84,6 +85,18 @@ class InputBase(ParameterMixin):
 
     __tablename__ = 'input'
 
+    required = Column(Boolean, doc="""
+    Is the input mandatory.
+
+    :type: :obj:`bool`
+    """)
+
+    @classmethod
+    def wrap(cls, name, value, description=None, required=True):
+        input = super(InputBase, cls).wrap(name, value, description)
+        input.required = required
+        return input
+
     # region many_to_one relationships
 
     @declared_attr

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 889465c..ae6a0a0 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -1939,7 +1939,7 @@ class OperationBase(InstanceModelMixin):
     """)
 
     retry_interval = Column(Integer, doc="""
-    Interval between task retry attemps (in seconds).
+    Interval between task retry attempts (in seconds).
 
     :type: :obj:`float`
     """)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 22912e2..5819e11 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -343,6 +343,11 @@ class ServiceTemplateBase(TemplateModelMixin):
         context = ConsumptionContext.get_thread_local()
         context.modeling.instance = service
 
+        utils.validate_no_undeclared_inputs(declared_inputs=self.inputs,
+                                            supplied_inputs=inputs)
+        utils.validate_required_inputs_are_supplied(declared_inputs=self.inputs,
+                                                    supplied_inputs=inputs)
+
         service.inputs = utils.merge_parameter_values(inputs, self.inputs, model_cls=models.Input)
         # TODO: now that we have inputs, we should scan properties and inputs and evaluate functions
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index e0fd11b..8e0b0d5 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -64,81 +64,84 @@ class NodeTemplateContainerHolder(object):
         return self.container.service_template
 
 
-def merge_parameter_values(parameter_values, declared_parameters, model_cls):
+def validate_no_undeclared_inputs(declared_inputs, supplied_inputs):
+
+    undeclared_inputs = [input for input in supplied_inputs if input not in declared_inputs]
+    if undeclared_inputs:
+        raise exceptions.UndeclaredInputsException(
+            'Undeclared inputs have been provided: {0}; Declared inputs: {1}'
+            .format(string_list_as_string(list(undeclared_inputs)),
+                    string_list_as_string(declared_inputs.keys())))
+
+
+def validate_required_inputs_are_supplied(declared_inputs, supplied_inputs):
+    required_inputs = [input for input in declared_inputs.values() if input.required]
+    missing_required_inputs = [input for input in required_inputs
+                               if input.name not in supplied_inputs and not input.value]
+    if missing_required_inputs:
+        raise exceptions.MissingRequiredInputsException(
+            'Required inputs {0} have not been provided values'
+            .format(string_list_as_string(missing_required_inputs)))
+
+
+def merge_parameter_values(provided_values, declared_parameters, model_cls):
     """
     Merges parameter values according to those declared by a type.
 
     Exceptions will be raised for validation errors.
 
-    :param parameter_values: provided parameter values or None
-    :type parameter_values: {:obj:`basestring`: object}
-    :param declared_parameters: declared parameters
+    :param provided_values: provided parameter values or None
+    :type provided_values: {:obj:`basestring`: object}
+    :param declared_parameters: declared code_parameters
     :type declared_parameters: {:obj:`basestring`: :class:`~aria.modeling.models.Parameter`}
-    :return: the merged parameters
+    :param model_cls: the model class that should be created from a provided value
+    :type model_cls: :class:`~aria.modeling.models.Input` or :class:`~aria.modeling.models.Argument`
+    :return: the merged code_parameters
     :rtype: {:obj:`basestring`: :class:`~aria.modeling.models.Parameter`}
-    :raises ~aria.modeling.exceptions.UndeclaredParametersException: if a key in
+    :raises ~aria.modeling.exceptions.UndeclaredInputsException: if a key in
      ``parameter_values`` does not exist in ``declared_parameters``
-    :raises ~aria.modeling.exceptions.MissingRequiredParametersException: if a key in
+    :raises ~aria.modeling.exceptions.MissingRequiredInputsException: if a key in
      ``declared_parameters`` does not exist in ``parameter_values`` and also has no default value
     :raises ~aria.modeling.exceptions.ParametersOfWrongTypeException: if a value in
       ``parameter_values`` does not match its type in ``declared_parameters``
     """
 
-    parameter_values = parameter_values or {}
-
-    undeclared_names = list(set(parameter_values.keys()).difference(declared_parameters.keys()))
-    if undeclared_names:
-        raise exceptions.UndeclaredParametersException(
-            'Undeclared parameters have been provided: {0}; Declared: {1}'
-            .format(string_list_as_string(undeclared_names),
-                    string_list_as_string(declared_parameters.keys())))
+    provided_values = provided_values or {}
+    provided_values_of_wrong_type = OrderedDict()
+    model_parameters = OrderedDict()
 
-    parameters = OrderedDict()
-
-    missing_names = []
-    wrong_type_values = OrderedDict()
     for declared_parameter_name, declared_parameter in declared_parameters.iteritems():
-        if declared_parameter_name in parameter_values:
-            # Value has been provided
-            value = parameter_values[declared_parameter_name]
+        if declared_parameter_name in provided_values:
+            # a value has been provided
+            value = provided_values[declared_parameter_name]
 
             # Validate type
             type_name = declared_parameter.type_name
             try:
                 validate_value_type(value, type_name)
             except ValueError:
-                wrong_type_values[declared_parameter_name] = type_name
+                provided_values_of_wrong_type[declared_parameter_name] = type_name
             except RuntimeError:
-                # TODO: This error shouldn't be raised (or caught), but right now we lack support
+                # TODO This error shouldn't be raised (or caught), but right now we lack support
                 # for custom data_types, which will raise this error. Skipping their validation.
                 pass
-
-            # Wrap in Parameter model
-            parameters[declared_parameter_name] = model_cls( # pylint: disable=unexpected-keyword-arg
+            model_parameters[declared_parameter_name] = model_cls( # pylint: disable=unexpected-keyword-arg
                 name=declared_parameter_name,
                 type_name=type_name,
                 description=declared_parameter.description,
                 value=value)
-        elif declared_parameter.value is not None:
-            # Copy default value from declaration
-            parameters[declared_parameter_name] = declared_parameter.instantiate(None)
         else:
-            # Required value has not been provided
-            missing_names.append(declared_parameter_name)
-
-    if missing_names:
-        raise exceptions.MissingRequiredParametersException(
-            'Declared parameters {0} have not been provided values'
-            .format(string_list_as_string(missing_names)))
+            # Copy default value from declaration
+            model_parameters[declared_parameter_name] = declared_parameter.instantiate(None)
 
-    if wrong_type_values:
+    if provided_values_of_wrong_type:
         error_message = StringIO()
-        for param_name, param_type in wrong_type_values.iteritems():
+        for param_name, param_type in provided_values_of_wrong_type.iteritems():
             error_message.write('Parameter "{0}" is not of declared type "{1}"{2}'
                                 .format(param_name, param_type, os.linesep))
         raise exceptions.ParametersOfWrongTypeException(error_message.getvalue())
 
-    return parameters
+    return model_parameters
 
 
 def coerce_dict_values(the_dict, report_issues=False):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/orchestrator/workflow_runner.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflow_runner.py b/aria/orchestrator/workflow_runner.py
index a85e7d3..d88e7bc 100644
--- a/aria/orchestrator/workflow_runner.py
+++ b/aria/orchestrator/workflow_runner.py
@@ -137,6 +137,10 @@ class WorkflowRunner(object):
         else:
             workflow_inputs = self.service.workflows[self._workflow_name].inputs
 
+        modeling_utils.validate_no_undeclared_inputs(declared_inputs=workflow_inputs,
+                                                     supplied_inputs=inputs)
+        modeling_utils.validate_required_inputs_are_supplied(declared_inputs=workflow_inputs,
+                                                             supplied_inputs=inputs)
         execution.inputs = modeling_utils.merge_parameter_values(inputs,
                                                                  workflow_inputs,
                                                                  model_cls=models.Input)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/orchestrator/workflows/api/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/api/task.py b/aria/orchestrator/workflows/api/task.py
index 4c518fc..9ea5485 100644
--- a/aria/orchestrator/workflows/api/task.py
+++ b/aria/orchestrator/workflows/api/task.py
@@ -137,6 +137,11 @@ class OperationTask(BaseTask):
         operation = self.actor.interfaces[self.interface_name].operations[self.operation_name]
         self.plugin = operation.plugin
         self.function = operation.function
+
+        modeling_utils.validate_required_inputs_are_supplied(
+            declared_inputs=operation.inputs,
+            supplied_inputs=operation.arguments)
+
         self.arguments = modeling_utils.merge_parameter_values(arguments,
                                                                operation.arguments,
                                                                model_cls=models.Argument)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/parser/consumption/style.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/style.py b/aria/parser/consumption/style.py
index 72892b9..0cd6a2d 100644
--- a/aria/parser/consumption/style.py
+++ b/aria/parser/consumption/style.py
@@ -48,3 +48,8 @@ class Style(object):
     @staticmethod
     def meta(value):
         return Colored.green(value)
+
+    @staticmethod
+    def required(value):
+        return Colored.white(value)
+

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/aria/parser/presentation/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index fe55b05..fb71a1e 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -29,10 +29,11 @@ class Value(object):
     Encapsulates a typed value assignment.
     """
 
-    def __init__(self, type_name, value, description):
+    def __init__(self, type_name, value, description, required):
         self.type = deepcopy_with_locators(type_name)
         self.value = deepcopy_with_locators(value)
         self.description = deepcopy_with_locators(description)
+        self.required = deepcopy_with_locators(required)
 
     def _dump(self, context):
         if self.type is not None:
@@ -41,6 +42,8 @@ class Value(object):
             puts(context.style.literal(self.value))
         if self.description is not None:
             puts(context.style.meta(self.description))
+        if self.required is not None:
+            puts(context.style.required(self.required))
 
 
 class PresentationBase(HasCachedMethods):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/examples/tosca-simple-1.0/use-cases/webserver-dbms-2/webserver-dbms-2.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/webserver-dbms-2/webserver-dbms-2.yaml b/examples/tosca-simple-1.0/use-cases/webserver-dbms-2/webserver-dbms-2.yaml
index 91f0b35..469c907 100644
--- a/examples/tosca-simple-1.0/use-cases/webserver-dbms-2/webserver-dbms-2.yaml
+++ b/examples/tosca-simple-1.0/use-cases/webserver-dbms-2/webserver-dbms-2.yaml
@@ -50,7 +50,7 @@ topology_template:
       interfaces:
         Standard:
            configure:
-             implementation: scripts/nodejs/configure.sh
+             implementation: scripts/nodejs/c\onfigure.sh
              inputs:
                github_url: { get_property: [ SELF, github_url ] }
                mongodb_ip: { get_attribute: [ mongo_server, private_address ] }

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 4d8e1db..441e4ca 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -94,12 +94,10 @@ def create_service_template_model(context): # pylint: disable=too-many-locals,to
     # Topology template
     topology_template = context.presentation.get('service_template', 'topology_template')
     if topology_template is not None:
-        create_parameter_models_from_values(model.inputs,
-                                            topology_template._get_input_values(context),
-                                            model_cls=Input)
-        create_parameter_models_from_values(model.outputs,
-                                            topology_template._get_output_values(context),
-                                            model_cls=Output)
+        create_input_models_from_values(model.inputs,
+                                        topology_template._get_input_values(context))
+        create_output_models_from_values(model.outputs,
+                                         topology_template._get_output_values(context))
 
     # Plugin specifications
     policies = context.presentation.get('service_template', 'topology_template', 'policies')
@@ -171,12 +169,10 @@ def create_node_template_model(context, service_template, node_template):
     if node_template.description:
         model.description = node_template.description.value
 
-    create_parameter_models_from_values(model.properties,
-                                        node_template._get_property_values(context),
-                                        model_cls=Property)
-    create_parameter_models_from_values(model.attributes,
-                                        node_template._get_attribute_default_values(context),
-                                        model_cls=Attribute)
+    create_property_models_from_values(model.properties,
+                                        node_template._get_property_values(context))
+    create_attribute_models_from_values(model.attributes,
+                                        node_template._get_attribute_default_values(context))
     create_interface_template_models(context, service_template, model.interface_templates,
                                      node_template._get_interfaces(context))
 
@@ -221,8 +217,7 @@ def create_group_template_model(context, service_template, group):
     if group.description:
         model.description = group.description.value
 
-    create_parameter_models_from_values(model.properties, group._get_property_values(context),
-                                        model_cls=Property)
+    create_property_models_from_values(model.properties, group._get_property_values(context))
     create_interface_template_models(context, service_template, model.interface_templates,
                                      group._get_interfaces(context))
 
@@ -245,8 +240,7 @@ def create_policy_template_model(context, service_template, policy):
     if policy.description:
         model.description = policy.description.value
 
-    create_parameter_models_from_values(model.properties, policy._get_property_values(context),
-                                        model_cls=Property)
+    create_property_models_from_values(model.properties, policy._get_property_values(context))
 
     node_templates, groups = policy._get_targets(context)
     if node_templates:
@@ -356,19 +350,12 @@ def create_capability_template_model(context, service_template, capability):
 def create_interface_template_model(context, service_template, interface):
     interface_type = interface._get_type(context)
     interface_type = service_template.interface_types.get_descendant(interface_type._name)
-    model = InterfaceTemplate(name=interface._name,
-                              type=interface_type)
+    model = InterfaceTemplate(name=interface._name, type=interface_type)
 
     if interface_type.description:
         model.description = interface_type.description
 
-    inputs = interface.inputs
-    if inputs:
-        for input_name, the_input in inputs.iteritems():
-            model.inputs[input_name] = Input(name=input_name, # pylint: disable=unexpected-keyword-arg
-                                             type_name=the_input.value.type,
-                                             value=the_input.value.value,
-                                             description=the_input.value.description)
+    create_parameter_models_from_assignments(model.inputs, interface.inputs, model_cls=Input)
 
     operations = interface.operations
     if operations:
@@ -430,14 +417,7 @@ def create_operation_template_model(context, service_template, operation):
             model.configurations[key] = Configuration.wrap(key, value,
                                                            description='Operation configuration.')
 
-    inputs = operation.inputs
-    if inputs:
-        for input_name, the_input in inputs.iteritems():
-            model.inputs[input_name] = Input(name=input_name, # pylint: disable=unexpected-keyword-arg
-                                             type_name=the_input.value.type,
-                                             value=the_input.value.value,
-                                             description=the_input.value.description)
-
+    create_parameter_models_from_assignments(model.inputs, operation.inputs, model_cls=Input)
     return model
 
 
@@ -462,8 +442,7 @@ def create_artifact_template_model(context, service_template, artifact):
             for k, v in credential.iteritems():
                 model.repository_credential[k] = v
 
-    create_parameter_models_from_values(model.properties, artifact._get_property_values(context),
-                                        model_cls=Property)
+    create_property_models_from_values(model.properties, artifact._get_property_values(context))
 
     return model
 
@@ -526,10 +505,9 @@ def create_workflow_operation_template_model(context, service_template, policy):
         if prop_name == 'implementation':
             model.function = prop.value
         else:
-            model.inputs[prop_name] = Input(name=prop_name, # pylint: disable=unexpected-keyword-arg
-                                            type_name=prop.type,
-                                            value=prop.value,
-                                            description=prop.description)
+            input_model = create_parameter_model_from_value(prop, prop_name, model_cls=Input)
+            input_model.required = prop.required
+            model.inputs[prop_name] = input_model
 
     used_reserved_names = WORKFLOW_DECORATOR_RESERVED_ARGUMENTS.intersection(model.inputs.keys())
     if used_reserved_names:
@@ -539,7 +517,6 @@ def create_workflow_operation_template_model(context, service_template, policy):
                                       string_list_as_string(used_reserved_names)),
                                   locator=policy._locator,
                                   level=Issue.EXTERNAL)
-
     return model
 
 
@@ -577,14 +554,44 @@ def create_types(context, root, types):
                         container.children.append(model)
 
 
-def create_parameter_models_from_values(properties, source_properties, model_cls):
+def create_input_models_from_values(inputs_field, template_inputs):
+    if template_inputs:
+        for template_input_name, template_input in template_inputs.iteritems():
+            model_input = create_parameter_model_from_value(template_input, template_input_name,
+                                                            model_cls=Input)
+            model_input.required = template_input.required
+            inputs_field[model_input.name] = model_input
 
-    if source_properties:
-        for property_name, prop in source_properties.iteritems():
-            properties[property_name] = model_cls(name=property_name,  # pylint: disable=unexpected-keyword-arg
-                                                  type_name=prop.type,
-                                                  value=prop.value,
-                                                  description=prop.description)
+
+def create_output_models_from_values(outputs_field, template_outputs):
+    for template_output_name, template_output in template_outputs.iteritems():
+        outputs_field[template_output_name] = \
+            create_parameter_model_from_value(template_output,
+                                              template_output_name,
+                                              model_cls=Output)
+
+
+def create_property_models_from_values(properties_field, template_properties):
+    for template_property_name, template_property in template_properties.iteritems():
+        properties_field[template_property_name] = \
+            create_parameter_model_from_value(template_property,
+                                              template_property_name,
+                                              model_cls=Property)
+
+
+def create_attribute_models_from_values(attributes_field, template_attributes):
+    for template_attribute_name, template_attribute in template_attributes.iteritems():
+        attributes_field[template_attribute_name] = \
+            create_parameter_model_from_value(template_attribute,
+                                              template_attribute_name,
+                                              model_cls=Attribute)
+
+
+def create_parameter_model_from_value(template_parameter, template_parameter_name, model_cls):
+    return model_cls(name=template_parameter_name,
+                     type_name=template_parameter.type,
+                     value=template_parameter.value,
+                     description=template_parameter.description)
 
 
 def create_parameter_models_from_assignments(properties, source_properties, model_cls):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
index fbb8280..9dee0f2 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -438,10 +438,7 @@ def coerce_to_primitive(context, presentation, primitive_type, constraints, valu
 
         # Check constraints
         apply_constraints_to_value(context, presentation, constraints, value)
-    except ValueError as e:
-        report_issue_for_bad_format(context, presentation, primitive_type, value, aspect, e)
-        value = None
-    except TypeError as e:
+    except (ValueError, TypeError) as e:
         report_issue_for_bad_format(context, presentation, primitive_type, value, aspect, e)
         value = None
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
index d5f447c..a25c7f8 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -61,7 +61,7 @@ def get_and_override_input_definitions_from_type(context, presentation):
     inputs = OrderedDict()
 
     # Get inputs from type
-    the_type = presentation._get_type(context) # IntefaceType
+    the_type = presentation._get_type(context) # InterfaceType
     type_inputs = the_type._get_inputs(context) if the_type is not None else None
     if type_inputs:
         for input_name, type_input in type_inputs.iteritems():
@@ -213,9 +213,9 @@ def convert_interface_definition_from_type_to_raw_template(context, presentation
     raw = OrderedDict()
 
     # Copy default values for inputs
-    inputs = presentation._get_inputs(context)
-    if inputs is not None:
-        raw['inputs'] = convert_parameter_definitions_to_values(context, inputs)
+    interface_inputs = presentation._get_inputs(context)
+    if interface_inputs is not None:
+        raw['inputs'] = convert_parameter_definitions_to_values(context, interface_inputs)
 
     # Copy operations
     operations = presentation._get_operations(context)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
index 87c1a3b..f271b4d 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
@@ -203,7 +203,8 @@ def coerce_parameter_value(context, presentation, definition, value, aspect=None
         type_name = getattr(definition, 'type', None)
     description = getattr(definition, 'description', None)
     description = description.value if description is not None else None
-    return Value(type_name, value, description)
+    required = getattr(definition, 'required', None)
+    return Value(type_name, value, description, required)
 
 
 def convert_parameter_definitions_to_values(context, definitions):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fd380f44/tests/orchestrator/test_workflow_runner.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/test_workflow_runner.py b/tests/orchestrator/test_workflow_runner.py
index 30176ae..bf6a7b9 100644
--- a/tests/orchestrator/test_workflow_runner.py
+++ b/tests/orchestrator/test_workflow_runner.py
@@ -216,7 +216,7 @@ def test_execution_inputs_override_workflow_inputs(request):
 def test_execution_inputs_undeclared_inputs(request):
     mock_workflow = _setup_mock_workflow_in_service(request)
 
-    with pytest.raises(modeling_exceptions.UndeclaredParametersException):
+    with pytest.raises(modeling_exceptions.UndeclaredInputsException):
         _create_workflow_runner(request, mock_workflow, inputs={'undeclared_input': 'value'})
 
 
@@ -224,7 +224,7 @@ def test_execution_inputs_missing_required_inputs(request):
     mock_workflow = _setup_mock_workflow_in_service(
         request, inputs={'required_input': models.Input.wrap('required_input', value=None)})
 
-    with pytest.raises(modeling_exceptions.MissingRequiredParametersException):
+    with pytest.raises(modeling_exceptions.MissingRequiredInputsException):
         _create_workflow_runner(request, mock_workflow, inputs={})
 
 
@@ -238,7 +238,7 @@ def test_execution_inputs_wrong_type_inputs(request):
 
 def test_execution_inputs_builtin_workflow_with_inputs(request):
     # built-in workflows don't have inputs
-    with pytest.raises(modeling_exceptions.UndeclaredParametersException):
+    with pytest.raises(modeling_exceptions.UndeclaredInputsException):
         _create_workflow_runner(request, 'install', inputs={'undeclared_input': 'value'})