Example #1
0
    def test_error_value_as_data_value(self):
        ev = make_error_value_from_msgs(self.error_def, *self.multiple_messages)
        self.assertTrue(isinstance(ev, StructValue))
        self.assertEqual(self.error_name, ev.name)
        self.assertFalse(ev.get_field_names() is None)
        self.assertEqual(2, len(ev.get_field_names()))
        self.assertTrue('messages' in ev.get_field_names())

        msg_struct1 = StructValue('localizable_message')
        msg_struct1.set_field('id', StringValue(self.message1.id))
        msg_struct1.set_field('default_message',
                              StringValue(self.message1.def_msg))
        args_list = ListValue()
        args_list.add_all((StringValue(s) for s in self.message1.args))
        msg_struct1.set_field('args', args_list)
        msg_struct2 = StructValue('localizable_message')
        msg_struct2.set_field('id', StringValue(self.message2.id))
        msg_struct2.set_field('default_message',
                              StringValue(self.message2.def_msg))
        msg_struct2.set_field('args', ListValue())
        msg_struct3 = StructValue('localizable_message')
        msg_struct3.set_field('id', StringValue(self.message3.id))
        msg_struct3.set_field('default_message',
                              StringValue(self.message3.def_msg))
        msg_struct3.set_field('args', ListValue())
        messages = ListValue()
        messages.add_all([msg_struct1, msg_struct2, msg_struct3])
        expected_data_value = ev = make_error_value_from_msgs(self.error_def)
        expected_data_value.set_field('messages', messages)
        self.assertEqual(expected_data_value, ev)
Example #2
0
    def visit_map(self, type_info, json_value):
        """
        Deserialize a map value

        :type  type_info:
            :class:`com.vmware.vapi.metadata.metamodel_client.Type`
        :param type_info: Metamodel type information
        :type  json_value: :class:`object`
        :param json_value: Value to be visited
        :rtype: :class:`vmware.vapi.data.value.StructValue`
        :return: DataValue created using the input
        """
        if not isinstance(json_value, list):
            msg = 'Excepted list, but got %s' % type(json_value).__name__
            logger.error(msg)
            raise werkzeug.exceptions.BadRequest(msg)
        try:
            return ListValue([
                StructValue(name=MAP_ENTRY,
                            values={
                                'key':
                                self.visit(type_info.map_key_type,
                                           value['key']),
                                'value':
                                self.visit(type_info.map_value_type,
                                           value['value'])
                            }) for value in json_value
            ])
        except KeyError as e:
            msg = 'Invalid Map input, missing %s' % e
            logger.error(msg)
            raise werkzeug.exceptions.BadRequest(msg)
 def test_list(self):
     input_val = '["val1","val2"]'
     expected_val = ListValue(
         values=[StringValue('val1'),
                 StringValue('val2')])
     actual_val = DataValueConverter.convert_to_data_value(input_val)
     self.assertEqual(expected_val, actual_val)
Example #4
0
 def test_introspection_operation_get(self):
     ctx = ExecutionContext()
     input_val = StructValue(OPERATION_INPUT)
     input_val.set_field('service_id', StringValue('mockup_interface'))
     input_val.set_field('operation_id', StringValue('mock'))
     actual_output = self.local_provider.invoke(
         'com.vmware.vapi.std.introspection.operation', 'get', input_val,
         ctx)
     expected_output = StructValue(
         name='com.vmware.vapi.std.introspection.operation.info')
     input_def_value = StructValue(
         'com.vmware.vapi.std.introspection.operation.data_definition')
     input_def_value.set_field('fields',
                               OptionalValue(ListValue(values=[])))
     input_def_value.set_field('element_definition', OptionalValue())
     input_def_value.set_field('type', StringValue('STRUCTURE'))
     input_def_value.set_field('name',
                               OptionalValue(StringValue(OPERATION_INPUT)))
     expected_output.set_field('input_definition', input_def_value)
     output_def_value = StructValue(
         'com.vmware.vapi.std.introspection.operation.data_definition')
     output_def_value.set_field('fields', OptionalValue())
     output_def_value.set_field('element_definition', OptionalValue())
     output_def_value.set_field('type', StringValue('VOID'))
     output_def_value.set_field('name', OptionalValue())
     expected_output.set_field('output_definition', output_def_value)
     expected_output.set_field('error_definitions', error_values)
     self.assertEqual(actual_output.output, expected_output)
    def _convert_method_def_to_data_value(method_def):
        """
        Converts a :class:`vmware.vapi.core.MethodDefinition` object
        to :class:`vmware.vapi.data.value.DataValue` object

        :type  method_def: :class:`vmware.vapi.core.MethodDefinition`
        :param method_def: Method definition
        :rtype: :class:`vmware.vapi.data.value.DataValue`
        :return: Data value object representing method definition
        """
        output = StructValue(
            name='com.vmware.vapi.std.introspection.operation.info',
            values={
                'input_definition':
                convert_data_def_to_data_value(
                    method_def.get_input_definition()),
                'output_definition':
                convert_data_def_to_data_value(
                    method_def.get_output_definition()),
                'error_definitions':
                ListValue(values=[
                    convert_data_def_to_data_value(error_def)
                    for error_def in method_def.get_error_definitions()
                ])
            })
        return output
 def get_data_values(self):
     # Data values
     list_value = ListValue()
     list_value.add_all([IntegerValue(val) for val in range(1,15)])
     data_values = [
         VoidValue(),
         IntegerValue(3),
         DoubleValue(decimal.Decimal('7.2')),
         StringValue('blah'),
         SecretValue(),
         BooleanValue(True),
         BlobValue(b"a blob"),
         BlobValue(b"0\x82\x04\x00"),
         list_value,
         OptionalValue(),
         OptionalValue(IntegerValue(7)),
         StructValue('name'),
         self.get_struct_value(),
         self.get_error_value(),
     ]
     struct_value = StructValue('struct')
     for idx, data_val in enumerate(data_values):
         struct_value.set_field(str(idx), data_val)
     data_values.append(struct_value)
     return data_values
 def test_list_value(self):
     input_val = ListValue(
         values=[StringValue('val1'),
                 StringValue('val2')])
     actual_val = DataValueConverter.convert_to_json(input_val)
     expected_val = '["val1","val2"]'
     self.assertEqual(expected_val, actual_val)
     # Verify json is valid
     json.loads(actual_val)
    def create_task(self,
                    description,
                    service_id,
                    operation_id,
                    cancelable,
                    error_types,
                    id_=None):
        """
        Creates a task in task manager.

        :type  description: :class:`com.vmware.vapi.std.LocalizableMessage`
        :param description: Task description.
        :type  service_id: :class:`str`
        :param service_id: Service Id.
        :type  operation_id: :class:`str`
        :param operation_id: Operation Id.
        :type  cancelable: :class:`bool`
        :param cancelable: Is the task cancelable.
        :type  error_types: :class:`list` of
            :class:`vmware.vapi.bindings.type.ReferenceType`
        :param error_types: Error definitions describing the errors this
            operation can report
        :type  id_: :class:`str`
        :param id_: Base task id
        """
        task_info = StructValue()
        if description is not None:
            task_info.set_field(
                'description',
                TypeConverter.convert_to_vapi(
                    description, LocalizableMessage.get_binding_type()))
        else:
            desc_value = StructValue()
            desc_value.set_field('id', StringValue())
            desc_value.set_field('default_message', StringValue())
            desc_value.set_field('args', ListValue())
            task_info.set_field('description', desc_value)

        user = self._get_user_from_sec_ctx()
        if user is not None:
            task_info.set_field('user', StringValue(user))

        task_info.set_field('service', StringValue(service_id))
        task_info.set_field('operation', StringValue(operation_id))
        task_info.set_field('cancelable',
                            BooleanValue(True if cancelable else False))
        task_info.set_field('status', PENDING_STRING_VALUE)
        base_id = id_ if id_ is not None else str(uuid.uuid4())
        task_id = self._create_task_id(base_id, service_id)

        task_summary = TaskSummary(task_info, error_types)
        with self.lock:
            self.task_map.setdefault(task_id, task_summary)

        self._remove_expired_task()
        return task_id
Example #9
0
    def _visit_list(self, obj):
        """
        Visit python list object

        :type  obj: :class:`list`
        :param obj: Python list object
        :rtype: :class:`vmware.vapi.data.value.ListValue`
        :return: List value
        """
        list_val = [self._visit(o) for o in obj]
        return ListValue(list_val)
 def get_operations(self, service_id):
     service_info = self._service_data.get(service_id)
     if service_info:
         method_ids = service_info.get_definition().get_method_identifiers()
         return MethodResult(output=ListValue(values=[
             StringValue(method_id.get_name()) for method_id in method_ids
         ]))
     else:
         msg = message_factory.get_message(
             'vapi.introspection.operation.service.not_found', service_id)
         error_value = make_error_value_from_msgs(not_found_def, msg)
         return MethodResult(error=error_value)
    def create_task(self,
                    provider_id,
                    description,
                    service_id,
                    operation_id,
                    cancelable,
                    id_=None):
        """
        Creates a task in task manager.

        :type  provider_id: :class:`str`
        :param provider_id: Service UUID
        :type  description: :class:`com.vmware.vapi.std.LocalizableMessage`
        :param description: Task description.
        :type  service_id: :class:`str`
        :param service_id: Service Id.
        :type  operation_id: :class:`str`
        :param operation_id: Operation Id.
        :type  cancelable: :class:`bool`
        :param cancelable: Is the task cancelable.
        :type  id_: :class:`str`
        :param id_: Base task id
        """
        task_info = StructValue()
        if description is not None:
            task_info.set_field(
                'description',
                TypeConverter.convert_to_vapi(
                    description, LocalizableMessage.get_binding_type()))
        else:
            desc_value = StructValue()
            desc_value.set_field('id', StringValue())
            desc_value.set_field('default_message', StringValue())
            desc_value.set_field('args', ListValue())
            task_info.set_field('description', desc_value)

        task_info.set_field('service', StringValue(service_id))
        task_info.set_field('operation', StringValue(operation_id))
        task_info.set_field('cancelable',
                            BooleanValue(True if cancelable else False))
        task_info.set_field('status', StringValue('PENDING'))
        base_id = id_ if id_ is not None else str(uuid.uuid4())
        task_id = self._create_task_id(base_id, provider_id)

        with self.lock:
            self.task_map.setdefault(task_id, task_info)

        self._remove_expired_task()
        return task_id
Example #12
0
 def test_not_found_error_value(self):
     input_status = 404
     input_response = '{"type":"com.vmware.vapi.std.errors.not_found","value":{"messages":[{"args":["datacenter-21"],"default_message":"Datacenter with identifier \'datacenter-21\' does not exist.","id":"com.vmware.api.vcenter.datacenter.not_found"}]}}'
     msg_val = StructValue(
         values={
             'id':
             StringValue('com.vmware.api.vcenter.datacenter.not_found'),
             'default_message':
             StringValue(
                 'Datacenter with identifier \'datacenter-21\' does not exist.'
             ),
             'args':
             ListValue([StringValue('datacenter-21')])
         })
     error_val = ErrorValue('com.vmware.vapi.std.errors.not_found',
                            {'messages': ListValue([msg_val])})
     expected_result = MethodResult(error=error_val)
     logging.debug(expected_result)
     actual_result = RestSerializer.deserialize_response(
         status=input_status,
         response_str=input_response,
         is_vapi_rest=True)
     self.assertEqual(expected_result.output, actual_result.output)
     self.assertEqual(expected_result.error, actual_result.error)
 def test_error_to_value(self):
     struct_def = ErrorDefinition('mock', [('field1', StringDefinition())])
     actual_output = convert_data_def_to_data_value(struct_def)
     expected_output = StructValue(Introspection.DATA_DEFINITION)
     expected_output.set_field('type', StringValue('ERROR'))
     expected_output.set_field('name', OptionalValue(StringValue('mock')))
     expected_output.set_field('element_definition', OptionalValue())
     field_value = self.generate_primitive_value('STRING')
     field_entry = StructValue(MAP_ENTRY)
     field_entry.set_field('key', StringValue('field1'))
     field_entry.set_field('value', field_value)
     field_values = ListValue()
     field_values.add(field_entry)
     expected_output.set_field('fields', OptionalValue(field_values))
     self.assertEqual(actual_output, expected_output)
Example #14
0
def augment_method_result_with_errors(service_id, operation_id, method_result,
                                      errors_to_augment):
    """
    Returns a new method result that is identical to `method_result` except that
    the `errors_definition` field in the `output` (which is of type
    Operation.Info from Introspection service) contains the errors from the Info
    structure in `method_result` plus the errors in `errors_to_augment`. This
    code will be executed only for "get" operation in vAPI Operation
    Introspection service.

    :type  service_id: :class:`str`
    :param service_id: Service identifier
    :type  operation_id: :class:`str`
    :param operation_id: Operation identifier
    :type  method_result: :class:`vmware.vapi.core.MethodResult`
    :param method_result: Operation result
    :type  errors_to_augment: :class:`list` of
        :class:`vmware.vapi.data.value.StructValue`
    :param errors_to_augment: Errors to augment. These are struct values of type
        com.vmware.vapi.std.introspection.Operation.DataDefinition whose `type`
        field has the value ERROR
        to the DataDefinition type in Introspection service IDL.
    :rtype: :class:`vmware.vapi.data.value.DataValue`
    :return: Output data value
    """
    if method_result.success():
        if (service_id == Introspection.OPERATION_SVC
                and operation_id == 'get'):
            output = method_result.output
            augmented_output = StructValue(
                'com.vmware.vapi.std.introspection.operation.info')
            augmented_output.set_field('input_definition',
                                       output.get_field('input_definition'))
            augmented_output.set_field('output_definition',
                                       output.get_field('output_definition'))
            errors = ListValue()
            error_names = []
            for error_def in output.get_field('error_definitions'):
                errors.add(error_def)
                error_names.append(error_def.get_field('name').value.value)
            for error_def in errors_to_augment:
                if error_def.get_field('name').value.value not in error_names:
                    errors.add(error_def)
            augmented_output.set_field('error_definitions', errors)
            return MethodResult(output=augmented_output)
    return method_result
Example #15
0
    def deserialize_response(status, response_str, is_vapi_rest):
        """
        Deserialize the REST response

        :type  status: :class:`int`
        :param status: HTTP response status code
        :type  response_str: :class:`str`
        :param response_str: HTTP response body
        :type  is_vapi_rest: :class:`bool`
        :param is_vapi_rest: Whether the Rest json message format is VAPI Rest
            or not
        :rtype   :class:`vmware.vapi.core.MethodResult`
        :return: VAPI MethodResult
        """
        output, error = None, None
        if response_str is not None and response_str != '':
            response_value = DataValueConverter.convert_to_data_value(
                response_str)
            if status in successful_status_codes:
                # Successful response, create output
                # Skyscraper uses 202 for returning tasks
                if is_vapi_rest:
                    # VAPI REST output has a value wrapper
                    output = response_value.get_field('value')
                else:
                    output = response_value
            else:
                # Create error
                if is_vapi_rest:
                    # VAPI REST error has specific format
                    name = response_value.get_field('type').value
                    values = dict(
                        response_value.get_field('value').get_fields())
                    error = ErrorValue(name=name, values=values)
                else:
                    # For other REST APIs create generic error for now
                    error = ErrorValue(name=http_to_vapi_error_map[status],
                                       values={
                                           'messages': ListValue(),
                                           'data': response_value,
                                       })
        else:
            # No response body
            if status == 200:
                output = VoidValue()
        return MethodResult(output=output, error=error)
Example #16
0
    def visit_list(self, type_info, json_value):
        """
        Deserialize a list value

        :type  type_info:
            :class:`com.vmware.vapi.metadata.metamodel_client.Type`
        :param type_info: Metamodel type information
        :type  json_value: :class:`object`
        :param json_value: Value to be visited
        :rtype: :class:`vmware.vapi.data.value.ListValue`
        :return: DataValue created using the input
        """
        if not isinstance(json_value, list):
            msg = 'Excepted list, but got %s' % type(json_value).__name__
            logger.error(msg)
            raise werkzeug.exceptions.BadRequest(msg)
        return ListValue([
            self.visit(type_info.element_type, value) for value in json_value
        ])
 def test_value_to_struct_ref_def(self):
     struct_value = StructValue(Introspection.DATA_DEFINITION)
     struct_value.set_field('type', StringValue('STRUCTURE'))
     struct_value.set_field('name', OptionalValue(StringValue('mock')))
     struct_value.set_field('element_definition', OptionalValue())
     field_value = self.generate_primitive_value('STRUCTURE_REF')
     field_value.set_field('name', OptionalValue(StringValue('mock')))
     field_entry = StructValue(MAP_ENTRY)
     field_entry.set_field('key', StringValue('field1'))
     field_entry.set_field('value', field_value)
     field_values = ListValue()
     field_values.add(field_entry)
     struct_value.set_field('fields', OptionalValue(field_values))
     actual_output = convert_data_value_to_data_def(struct_value)
     expected_output = StructDefinition(
         'mock', [('field1', StructRefDefinition('mock'))])
     self.assertEqual(actual_output, expected_output)
     # Check the circular reference as well
     self.assertEqual(
         actual_output.get_field('field1').target, expected_output)
def convert_data_def_to_data_value(data_def):
    """
    Convert :class:`vmware.vapi.data.definition.DataDefinition` object to
    :class:`vmware.vapi.data.value.DataValue` object. The type of the object
    returned is a struct value that corresponds to DataDefinition VMODL2 type
    present in introspection service.

    :type  data_def: :class:`vmware.vapi.data.definition.DataDefinition`
    :param data_def: Data definition
    :rtype: :class:`vmware.vapi.data.value.DataValue`
    :return: Data value representing the data definition object
    """
    result = StructValue(Introspection.DATA_DEFINITION)
    result.set_field('type', StringValue(data_type_map.get(data_def.type)))

    if (data_def.type == Type.STRUCTURE or data_def.type == Type.STRUCTURE_REF
            or data_def.type == Type.ERROR):
        result.set_field('name', OptionalValue(StringValue(data_def.name)))
    else:
        result.set_field('name', OptionalValue())

    if (data_def.type == Type.OPTIONAL or data_def.type == Type.LIST):
        element_definition = data_def.element_type
        element_value = convert_data_def_to_data_value(element_definition)
        result.set_field('element_definition', OptionalValue(element_value))
    else:
        result.set_field('element_definition', OptionalValue())

    if (data_def.type == Type.STRUCTURE or data_def.type == Type.ERROR):
        fields = ListValue()
        for field_name in data_def.get_field_names():
            element_definition = data_def.get_field(field_name)
            field_pair = StructValue(MAP_ENTRY)
            field_pair.set_field('key', StringValue(field_name))
            field_pair.set_field(
                'value', convert_data_def_to_data_value(element_definition))
            fields.add(field_pair)
        result.set_field('fields', OptionalValue(fields))
    else:
        result.set_field('fields', OptionalValue())
    return result
Example #19
0
 def test_invalid_query_params(self):
     input_val = StructValue(name='operation-input',
                             values={
                                 'string_val':
                                 StringValue('string1'),
                                 'action1_val':
                                 OptionalValue(value=StringValue('start')),
                                 'action2_val':
                                 ListValue([])
                             })
     rest_metadata = OperationRestMetadata(http_method='POST',
                                           url_template='/foo/bar',
                                           query_parameters={
                                               'action1_val': 'action1',
                                               'action2_val': 'action2'
                                           })
     self.assertRaises(CoreException,
                       RestSerializer.serialize_request,
                       input_value=input_val,
                       ctx=None,
                       rest_metadata=rest_metadata,
                       is_vapi_rest=True)
input_def = StructDefinition('input', [
    ('service_name', StringDefinition()),
    ('operation_name', StringDefinition()),
    ('operation_input', OpaqueDefinition()),
])
mock_input_def = StructDefinition('input', [('raise', BooleanDefinition())])
not_found_error_def = make_std_error_def(
    'com.vmware.vapi.std.errors.not_found')
errors = [
    'com.vmware.vapi.std.errors.not_found',
    'com.vmware.vapi.std.errors.internal_server_error',
    'com.vmware.vapi.std.errors.invalid_argument',
    'com.vmware.vapi.std.errors.operation_not_found',
]
error_defs = [make_std_error_def(error) for error in errors]
error_values = ListValue(
    [convert_data_def_to_data_value(error_def) for error_def in error_defs])


class MockupApiInterface(ApiInterface):
    def __init__(self, interface_id):
        self._interface_id = interface_id
        self.counters = {}
        for name in [
                mock_method_name, pre_method_name, post_method_name,
                veto_method_name
        ]:
            self.counters[name] = 0

    def get_identifier(self):
        return self._interface_id
Example #21
0
    raise_python_exception: raise_python_exception_id,
    return_invalid_output: return_invalid_output_id,
}

internal_server_error_def = make_std_error_def(
    'com.vmware.vapi.std.errors.internal_server_error')
invalid_argument_def = make_std_error_def(
    'com.vmware.vapi.std.errors.invalid_argument')
not_found_error_def = make_std_error_def(
    'com.vmware.vapi.std.errors.not_found')
operation_not_found_def = make_std_error_def(
    'com.vmware.vapi.std.errors.operation_not_found')

error_values = ListValue([
    convert_data_def_to_data_value(internal_server_error_def),
    convert_data_def_to_data_value(invalid_argument_def),
    convert_data_def_to_data_value(operation_not_found_def)
])

_msg = Message('mockup.message.id', 'mockup error message')
not_found_error = make_error_value_from_msgs(not_found_error_def, _msg)

param_name = 'param'


class MockupApiInterface(ApiInterface):
    def __init__(self):
        pass

    def get_identifier(self):
        return interface_id
 def test_empty_list(self):
     input_val = '[]'
     expected_val = ListValue()
     actual_val = DataValueConverter.convert_to_data_value(input_val)
     self.assertEqual(expected_val, actual_val)