Exemplo n.º 1
0
    def invoke(self, service_id, operation_id, input_value, ctx):
        """
        Invoke an API request

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        sec_ctx = ctx.security_context
        app_ctx = ctx.application_context
        authn_result = None

        request_scheme = sec_ctx.get(SCHEME_ID)
        if (self._authn_handlers and request_scheme
                and request_scheme != NO_AUTH):
            for handler in self._authn_handlers:
                # Call authenticate method and get the UserIdentity
                try:
                    authn_result = handler.authenticate(sec_ctx)
                except Exception as e:
                    logger.exception(
                        'Error in invoking authentication handler %s - %s',
                        handler, e)
                    error_value = make_error_value_from_msg_id(
                        self._internal_server_error_def,
                        'vapi.security.authentication.exception', str(e))
                    return MethodResult(error=error_value)

                # authn result false means authentication failed
                if authn_result is False:
                    error_value = make_error_value_from_msg_id(
                        self._unauthenticated_error_def,
                        'vapi.security.authentication.invalid')
                    return MethodResult(error=error_value)

                if authn_result is not None:
                    # Matching authN handler found
                    break

        if authn_result:
            # Add the authN identity to the security context to pass on to next
            # provider
            sec_ctx[AUTHN_IDENTITY] = authn_result
            ctx = ExecutionContext(app_ctx, sec_ctx)
        else:
            # No AuthN handler found pass an empty security context
            ctx = ExecutionContext(app_ctx, SecurityContext())

        return ApiProviderFilter.invoke(self, service_id, operation_id,
                                        input_value, ctx)
Exemplo n.º 2
0
 def invoke(self, ctx, method_id, input_value):
     name = method_id.get_name()
     if name == raise_python_exception:
         raise RuntimeError()
     elif name == return_invalid_output:
         return MethodResult(output=StructValue())
     elif name == mock_definition:
         return MethodResult(output=VoidValue())
     return MethodResult(error=not_found_error)
Exemplo n.º 3
0
    def test_method_result(self):
        # Method result
        error_value = self.get_error_value()
        method_result = MethodResult(error=error_value)
        self.assertEqual(self.to_vapi_method_result(self.to_json(method_result)).error, method_result.error)

        data_values = self.get_data_values()
        for data_value in data_values:
            method_result = MethodResult(output=data_value)
            self.assertEqual(self.to_vapi_method_result(self.to_json(method_result)).output, method_result.output)
Exemplo n.º 4
0
 def invoke(self, ctx, method_id, input_):
     name = method_id.get_name()
     self.counters[name] = self.counters.get(name, 0) + 1
     if name == veto_method_name:
         method_input = input_.get_field('operation_input')
         raise_error = method_input.get_field('raise')
         if raise_error.value:
             msg = Message('mockup.message.id', 'mockup error message')
             return MethodResult(
                 error=make_error_value_from_msgs(not_found_error_def, msg))
     return MethodResult(output=VoidValue())
Exemplo n.º 5
0
 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 invoke(self, service_id, operation_id, input_value, ctx):
     # Allowed service_id: 'svc'
     if service_id != 'svc':
         return MethodResult(error=error_values[2])
     # Allowed operation_ids: 'op1', 'op2'
     if operation_id == 'op1':
         return MethodResult(output=IntegerValue(10))
     elif operation_id == 'op2':
         if ctx.security_context:
             return MethodResult(output=IntegerValue(20))
         else:
             return MethodResult(error=error_values[3])
     else:
         return MethodResult(error=error_values[2])
Exemplo n.º 7
0
    def _invoke_int(self, service_id, operation_id, input_value, ctx):
        """
        Internal implementation of invoke method

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        # Check if the provider exists
        provider = self._service_id_map.get(service_id)
        if not provider:
            msg = message_factory.get_message(
                'vapi.method.input.invalid.interface', service_id)
            logger.error(msg)
            error_value = make_error_value_from_msgs(
                self._operation_not_found_def, msg)
            return MethodResult(error=error_value)

        # Continue the authentication chain only if the target service
        # is not in the local provider of this process. i.e. for only
        # remote calls
        if service_id not in self._local_service_ids:
            for processor in self._authn_chain_processors:
                ctx.security_context = processor.next_context(
                    ctx.security_context)

        # Actual method execution
        try:
            method_result = provider.invoke(service_id, operation_id,
                                            input_value, ctx)
            return method_result
        except Exception as e:
            stack_trace = traceback.format_exc()
            logger.error(
                'Service: %s, Operation: %s, input_value %s: exception: %s',
                service_id, operation_id, input_value, stack_trace)
            msg = message_factory.get_message('vapi.method.invoke.exception',
                                              str(e))
            error_value = make_error_value_from_msgs(
                self._internal_server_error_def, msg)
            method_result = MethodResult(error=error_value)
            return method_result
Exemplo n.º 8
0
 def test_string_value(self):
     input_status = 200
     input_response = '"vm-100"'
     expected_result = MethodResult(output=StringValue('vm-100'))
     actual_result = RestSerializer.deserialize_response(
         status=input_status,
         response_str=input_response,
         is_vapi_rest=False)
     self.assertEqual(expected_result.output, actual_result.output)
     self.assertEqual(expected_result.error, actual_result.error)
Exemplo n.º 9
0
 def test_successful_status_202(self):
     input_status = 202
     input_response = '{"value":"vm-100"}'
     expected_result = MethodResult(output=StringValue('vm-100'))
     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)
Exemplo n.º 10
0
 def test_void_value(self):
     input_status = 200
     input_response = ''
     expected_result = MethodResult(output=VoidValue())
     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)
Exemplo n.º 11
0
 def get_service_info(self, service_id):
     provider = self._get_provider(service_id)
     if provider:
         ctx = ExecutionContext()
         struct_value = StructValue(name=OPERATION_INPUT,
                                    values={'id': StringValue(service_id)})
         return provider.invoke(Introspection.SERVICE_SVC, 'get',
                                struct_value, ctx)
     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)
Exemplo n.º 12
0
 def test_invoke_long_running_sync(self):
     ctx = ExecutionContext()
     input_ = StructValue(method_name)
     input_.set_field('message', StringValue('hello'))
     input_.set_field('throw', BooleanValue(False))
     actual_method_result = self.provider.invoke(interface_name,
                                                 task_method_name,
                                                 input_,
                                                 ctx)
     expected_method_result = MethodResult(output=StringValue('hello'))
     self.assertEqual(actual_method_result.output,
                      expected_method_result.output)
     self.assertEqual(actual_method_result.error,
                      expected_method_result.error)
Exemplo n.º 13
0
 def test_struct_value(self):
     input_status = 200
     input_response = '{"id":"vm-100", "name":"Linux VM"}'
     expected_result = MethodResult(output=StructValue(
         values={
             'id': StringValue('vm-100'),
             'name': StringValue('Linux VM')
         }))
     actual_result = RestSerializer.deserialize_response(
         status=input_status,
         response_str=input_response,
         is_vapi_rest=False)
     self.assertEqual(expected_result.output, actual_result.output)
     self.assertEqual(expected_result.error, actual_result.error)
Exemplo n.º 14
0
    def invoke(self, service_id, operation_id, input_value, ctx):
        """
        Invoke an API request

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        try:
            veto_error = self.execute(
                'veto', service_id, operation_id, ctx, input_value)
            if veto_error is not None:
                return MethodResult(error=veto_error)
            else:
                self.execute('pre', service_id, operation_id, ctx, input_value)
                method_result = ApiProviderFilter.invoke(
                    self, service_id, operation_id, input_value, ctx)
                self.execute('post', service_id, operation_id, ctx, input_value)
                return method_result
        except Exception as e:
            logger.exception('service: %s, operation: %s, input_value: %s',
                             service_id, operation_id, input_value)
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.invoke.exception',
                str(e))
            method_result = MethodResult(error=error_value)
            return method_result
Exemplo n.º 15
0
 def get_operation_info(self, service_id, operation_id):
     service_info = self._service_data.get(service_id)
     if service_info:
         method_ids = service_info.get_definition().get_method_identifiers()
         operation_names = [
             method_id.get_name() for method_id in method_ids
         ]
         if operation_id in operation_names:
             method_def = service_info.get_method_definition(
                 MethodIdentifier(InterfaceIdentifier(service_id),
                                  operation_id))
             output = self._convert_method_def_to_data_value(method_def)
             return MethodResult(output=output)
         else:
             msg = message_factory.get_message(
                 'vapi.introspection.operation.not_found', operation_id,
                 service_id)
             error_value = make_error_value_from_msgs(not_found_def, msg)
             return MethodResult(error=error_value)
     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)
Exemplo n.º 16
0
    def method_result(result):
        """
        get method result from jsonrpc dict

        :type  result: :class:`dict`
        :param result: json method result
        :rtype:  :class:`vmware.vapi.core.MethodResult`
        :return: method result
        """
        output = None
        if 'output' in result:
            output = JsonRpcDictToVapi.data_value(result['output'])
        error = None
        if 'error' in result:
            error = JsonRpcDictToVapi.error_value(result['error'])
        return MethodResult(output=output, error=error)
Exemplo n.º 17
0
    def _list(self, method_def, ctx, input_value):
        """
        Get the set of service identifiers

        :type  method_def: :class:`vmware.vapi.core.MethodDefinition`
        :param method_def: Method definition
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Struct value input
        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Set of service identifiers
        """
        output = method_def.get_output_definition().new_value()
        for service in self._adapter.get_services():
            output.add(StringValue(service))
        return MethodResult(output=output)
Exemplo n.º 18
0
    def _get(self, method_def, ctx, input_value):
        """
        Returns information about the vAPI provider

        :type  method_def: :class:`vmware.vapi.core.MethodDefinition`
        :param method_def: Method definition
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Struct value input
        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Information about the vAPI provider
        """
        output = method_def.get_output_definition().new_value()
        output.set_field('id', StringValue(self._name))
        output.set_field('checksum', StringValue(self._adapter.get_checksum()))
        return MethodResult(output=output)
Exemplo n.º 19
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
Exemplo n.º 20
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)
Exemplo n.º 21
0
 def test_invoke_long_running(self):
     ctx = ExecutionContext()
     input_ = StructValue(method_name)
     input_.set_field('message', StringValue('hello'))
     input_.set_field('throw', BooleanValue(False))
     actual_method_result = self.provider.invoke(interface_name,
                                                 '%s$task' % task_method_name,
                                                 input_,
                                                 ctx)
     expected_method_result = MethodResult(output=StringValue('hello'))
     try:
         id_split = actual_method_result.output.value.split(':')
         uuid.UUID(id_split[0], version=4)
         uuid.UUID(id_split[1], version=4)
     except ValueError:
         # There's no assertNotRaises so explicitly fail assert
         # in case a ValueError is thrown for invalid uuid.
         self.assertTrue(False)
     self.assertEqual(actual_method_result.error,
                      expected_method_result.error)
Exemplo n.º 22
0
 def invoke(self, service_id, operation_id, input_value, ctx):
     logger.debug(
         'Operation started: Service: %s, Operation: %s, Ctx: %s, Input: %s',
         service_id, operation_id, ctx, input_value)
     try:
         method_result = self._invoke_int(service_id, operation_id,
                                          input_value, ctx)
         if method_result.success():
             method_result = augment_method_result_with_errors(
                 service_id, operation_id, method_result,
                 self._error_values_to_augment)
     except Exception as e:
         logger.exception("Error in invoking %s in %s - %s", service_id,
                          operation_id, e)
         error_value = make_error_value_from_msg_id(
             self._internal_server_error_def,
             'vapi.method.invoke.exception', str(e))
         method_result = MethodResult(error=error_value)
     logger.debug(
         'Operation finished: Service: %s, Operation %s, Ctx: %s, '
         'Output: %s', service_id, operation_id, ctx, method_result)
     return method_result
Exemplo n.º 23
0
 def invoke(self, service_id, operation_id, input, ctx):
     if operation_id == report_vapi_error:
         error_value = make_error_value_from_msgs(not_found_def, self.msg)
         return MethodResult(error=error_value)
     elif operation_id == report_vapi_success:
         return MethodResult(output=BooleanValue(True))
     elif operation_id == 'echo':
         msg = input.get_field('message')
         return MethodResult(output=msg)
     elif operation_id == 'echo_long_running':
         msg = input.get_field('message')
         return MethodResult(output=msg)
     elif operation_id == 'echo_long_running$task':
         return MethodResult(output=StringValue(str(uuid.uuid4())))
     else:
         error_value = make_error_value_from_msgs(operation_not_found_def,
                                                  self.msg)
         return MethodResult(error=error_value)
Exemplo n.º 24
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)
Exemplo n.º 25
0
 def invoke(self, ctx, method_id, input_value):
     return MethodResult(output=input_value)
Exemplo n.º 26
0
    def invoke(self, service_id, operation_id, input_value, ctx):
        """
        Invoke an API request

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        sec_ctx = ctx.security_context
        authn_result = sec_ctx.get(AUTHN_IDENTITY)

        try:
            allowed_authn_schemes = self._allowed_schemes(
                service_id, operation_id)
        except Exception:
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.security.authentication.metadata.invalid', operation_id,
                service_id)
            return MethodResult(error=error_value)

        if allowed_authn_schemes is None or NO_AUTH in allowed_authn_schemes:
            is_no_auth_allowed = True
        else:
            is_no_auth_allowed = False

        # No valid AuthN info received from AuthN filter for an
        # operation which requires authentication
        if (authn_result is None and not is_no_auth_allowed):
            error_value = make_error_value_from_msg_id(
                self._unauthorized_error_def,
                'vapi.security.authorization.invalid')
            return MethodResult(error=error_value)

        if is_no_auth_allowed:
            return ApiProviderFilter.invoke(self, service_id, operation_id,
                                            input_value, ctx)
        else:
            result = None
            for handler in self._authz_handlers:
                # Call authorize method and validate authZ info
                try:
                    result = handler.authorize(service_id, operation_id,
                                               sec_ctx)
                except Exception as e:
                    logger.exception(
                        'Error in invoking authorization handler %s - %s',
                        handler, e)
                    error_value = make_error_value_from_msg_id(
                        self._internal_server_error_def,
                        'vapi.security.authorization.exception', str(e))
                    return MethodResult(error=error_value)

                if result:
                    return ApiProviderFilter.invoke(self, service_id,
                                                    operation_id, input_value,
                                                    ctx)

            error_value = make_error_value_from_msg_id(
                self._unauthorized_error_def,
                'vapi.security.authorization.invalid')
            return MethodResult(error=error_value)
Exemplo n.º 27
0
    def invoke(self, ctx, method_id, input_value):
        """
        Invokes the specified method using the execution context and
        the input provided

        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        op_info = self._operations.get(method_id.get_name())

        # Set execution context
        set_context(ctx)

        try:
            # input validators
            validators = op_info['input_value_validator_list']
            input_type = op_info['input_type']
            for validator in validators:
                msg_list = validator.validate(input_value, input_type)
                if msg_list:
                    error_value = make_error_value_from_msgs(
                        self._invalid_argument_def, *msg_list)
                    return MethodResult(error=error_value)
            error_value = ApiInterfaceSkeleton.check_for_unknown_fields(
                input_type, input_value)
            if error_value:
                return MethodResult(error=error_value)

            try:
                meth_args = TypeConverter.convert_to_python(
                    input_value, binding_type=input_type,
                    resolver=self._resolver)
            except CoreException as e:
                error_value = make_error_value_from_msgs(
                    self._invalid_argument_def, *e.messages)
                return MethodResult(error=error_value)

            method_name = Converter.canonical_to_pep(
                            get_non_task_operation_name(method_id.get_name()))
            method = getattr(self._impl, method_name)

            # If it's a task method then create a new thread to run provider
            # impl and return task id or result depending upon type of
            # invocation.
            if op_info['task_type'] != TaskType.NONE:
                meth_output, task_accepted = self._invoke_task_operation(
                    ctx, method_id, method, meth_args)

                if isinstance(meth_output, VapiError):
                    raise meth_output  # pylint: disable=raising-bad-type

                # In case of provider not accepting task throw an error.
                if task_accepted is False:
                    msg_list = [message_factory.get_message(
                                'vapi.bindings.skeleton.task.invalidstate')]
                    error_value = make_error_value_from_msgs(
                        self._internal_server_error_def,
                        *msg_list)
                    return MethodResult(error=error_value)
            else:
                meth_output = method(**meth_args)

            output_type = op_info['output_type']
            # output validators
            validators = op_info['output_validator_list']

            output = TypeConverter.convert_to_vapi(meth_output,
                                                   output_type)

            for validator in validators:
                msg_list = validator.validate(output, output_type)
                if msg_list:
                    error_value = make_error_value_from_msgs(
                        self._internal_server_error_def, *msg_list)
                    return MethodResult(error=error_value)
            result = MethodResult(output=output)
        except CoreException as e:
            logger.exception("Error in invoking %s - %s",
                             str(method_id), e)
            error_value = make_error_value_from_msgs(
                self._internal_server_error_def,
                *e.messages)
            result = MethodResult(error=error_value)
        except VapiError as e:
            exc_info = sys.exc_info()
            error_type = e.__class__.get_binding_type()
            try:
                error = TypeConverter.convert_to_vapi(e, error_type)
            except CoreException as ce:
                logger.error('Failed to convert %s to error type %s because %s',
                             e, error_type.name,
                             ' because '.join((e.def_msg for e in ce.messages)),
                             exc_info=exc_info)
                raise
            result = MethodResult(error=error)
        finally:
            # Reset the execution context after the operation
            clear_context()

        return result
 def invoke(self, service_id, operation_id, input_value, ctx):
     return MethodResult(output=IntegerValue(10))
Exemplo n.º 29
0
    def _invoke_int(self, service_id, operation_id, input_value, ctx):  # pylint: disable=R0911
        """
        Internal implementation of InvokeMethod

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        # Step 0: Verify input types
        if (input_value and not (input_value.type == Type.STRUCTURE)):
            logger.error("Invalid inputs")
            error_value = make_error_value_from_msg_id(
                self._invalid_argument_def, 'vapi.method.input.invalid')
            return MethodResult(error=error_value)

        iface_id = InterfaceIdentifier(service_id)
        method_id = MethodIdentifier(iface_id, operation_id)

        # Step 1: Get method definition
        iface = self._service_map.get(service_id)
        if not iface:
            logger.error('Could not find service: %s', service_id)
            error_value = make_error_value_from_msg_id(
                self._operation_not_found_def,
                'vapi.method.input.invalid.interface', service_id)
            return MethodResult(error=error_value)

        method_def = iface.get_method_definition(method_id)
        if not method_def:
            logger.error("Could not find method %s", method_id.get_name())
            error_value = make_error_value_from_msg_id(
                self._operation_not_found_def,
                'vapi.method.input.invalid.method', method_id.get_name())
            return MethodResult(error=error_value)

        input_def = method_def.get_input_definition()
        if not isinstance(input_def, StructDefinition):
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.input.invalid.definition')
            return MethodResult(error=error_value)

        output_def = method_def.get_output_definition()
        if not isinstance(output_def, DataDefinition):
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.output.invalid.definition')
            return MethodResult(error=error_value)

        # Step 2: Validate input with input def
        input_def.complete_value(input_value)
        messages = input_def.validate(input_value)
        if messages:
            logger.error("Input validation failed for method %s",
                         method_id.get_name())
            error_value = make_error_value_from_msgs(
                self._invalid_argument_def, *messages)
            return MethodResult(error=error_value)

        # Step 3: Execute method
        method_result = iface.invoke(ctx, method_id, input_value)

        # Step 4: Validate output with output def or error against errors set
        if method_result.success():
            messages = output_def.validate(method_result.output)
            if messages:
                logger.error("Output validation failed for method %s",
                             method_id.get_name())
                error_value = make_error_value_from_msgs(
                    self._internal_server_error_def, *messages)
                return MethodResult(error=error_value)
        else:
            error_value = method_result.error
            messages = self._validate_error(error_value, method_def)
            if messages:
                new_error_value = make_error_value_from_error_value_and_msgs(
                    self._internal_server_error_def, error_value, *messages)
                return MethodResult(error=new_error_value)

        return method_result
 def invoke(self, ctx, method_id, input_value):
     return MethodResult(output=IntegerValue(10))