def __init__(self, iface_name, config, operations, rest_metadata=None, is_vapi_rest=None): """ Initialize the ApiMethod skeleton object :type iface_name: :class:`str` :param iface_name: Interface name :type config: :class:`StubConfiguration` :param config: Configuration data for vAPI stubs :type operations: :class:`dict` :param operations: Dictionary of operation name to operation information :type rest_metadata: :class:`dict` of :class:`str` and :class::`vmware.vapi.lib.rest.OperationRestMetadata` :param rest_metadata: Dictionary of operation name to operation REST metadata :type is_vapi_rest: :class:`bool` :param is_vapi_rest: Json message format. True for Vapi Rest and False for Swagger Rest """ self._iface_id = InterfaceIdentifier(iface_name) self._config = config self._operations = operations self._api_provider = config.connector.get_api_provider() self._rest_metadata = rest_metadata or {} self._is_vapi_rest = is_vapi_rest if isinstance(self._api_provider, ApiProviderFilter): # Get the API Provider (last provider in the chain) last_api_provider = self._api_provider.get_api_provider() else: last_api_provider = self._api_provider self._response_extractor = None # Determine whether REST format needs to be used self._use_rest = True if isinstance( # pylint: disable=R1719 last_api_provider, RestClientProvider) else False if self._use_rest: # Add the service metadata to the REST provider last_api_provider.set_rest_format(self._is_vapi_rest) for method_name, operation_rest_metadata in six.viewitems( self._rest_metadata): last_api_provider.add_rest_metadata(self._iface_id.get_name(), method_name, operation_rest_metadata) # Set the REST converter mode if is_vapi_rest: self._rest_converter_mode = RestConverter.VAPI_REST else: self._rest_converter_mode = RestConverter.SWAGGER_REST self._response_extractor = self._config._response_extractor # pylint: disable=W0212 else: self._rest_converter_mode = None ApiInterface.__init__(self)
def __init__(self, name, introspection_adapter): """ Initialize ProviderApiInterface :type name: :class:`str` :param name: Name of the provider :type introspection_adapter: :class:`vmware.vapi.provider.introspection.ApiProviderIntrospector` :param introspection_adapter: Adapter for fetching introspection information """ self._name = name self._adapter = introspection_adapter iface_id = InterfaceIdentifier( 'com.vmware.vapi.std.introspection.provider') method_defs = {} # get method get_method_id = MethodIdentifier(iface_id, 'get') output_def = StructDefinition( 'com.vmware.vapi.std.introspection.provider.info', [('id', StringDefinition()), ('checksum', StringDefinition())]) method_defs[get_method_id] = MethodDefinition( get_method_id, StructDefinition(OPERATION_INPUT, []), output_def, []) methods = {} methods[get_method_id] = self._get IntrospectionBaseApiInterface.__init__(self, iface_id, method_defs, methods)
def __init__(self, iface_name, impl, operations, error_types): """ Initialize the ApiInterface skeleton class :type iface_name: :class:`str` :param iface_name: Interface name :type impl: :class:`VapiInterface` :param impl: Class that implements this interface :type operations: :class:`dict` :param operations: Description of the operations in this service :type error_types: :class:`list` of :class:`vmware.vapi.bindings.type.ErrorType` :param error_types: error types to be registered in this configuration """ self._operations = operations self._iface_id = InterfaceIdentifier(iface_name) operation_ids = [MethodIdentifier(self._iface_id, operation_name) for operation_name in six.iterkeys(self._operations)] self._iface_def = InterfaceDefinition(self._iface_id, operation_ids) self._impl = impl error_types = error_types or [] self._resolver = NameToTypeResolver( {e.definition.name: e for e in error_types}) ApiInterface.__init__(self)
def get_method(self, service_id, operation_id): """ Get method definition for the specified operation :type service_id: :class:`str` :param service_id: Service identifier :type operation_id: :class:`str` :param operation_id: Operation identifier :rtype: :class:`vmware.vapi.core.MethodDefinition` :return: Method definition of the specified operation """ info = self._operation.get(service_id=service_id, operation_id=operation_id) input_def = convert_data_value_to_data_def( info.input_definition.get_struct_value()) output_def = convert_data_value_to_data_def( info.output_definition.get_struct_value()) error_defs = [convert_data_value_to_data_def(error_def.get_struct_value()) for error_def in info.error_definitions] interface_id = InterfaceIdentifier(service_id) method_id = MethodIdentifier(interface_id, operation_id) method_definition = MethodDefinition(method_id, input_def, output_def, error_defs) return method_definition
def __init__(self): self.if_id = InterfaceIdentifier(fake_iface_id) self.operations = { null_method_id: null_method_def, echo_method_id: echo_method_def } self.if_def = InterfaceDefinition( self.if_id, [MethodIdentifier(self.if_id, null_method_id), MethodIdentifier(self.if_id, echo_method_id),] )
def __init__(self, name, introspection_adapter): """ Initialize OperationApiInterface :type name: :class:`str` :param name: Name of the provider :type introspection_adapter: :class:`vmware.vapi.provider.introspection.ApiProviderIntrospector` :param introspection_adapter: Adapter for fetching introspection information """ self._adapter = introspection_adapter iface_id = InterfaceIdentifier( 'com.vmware.vapi.std.introspection.operation') method_defs = {} methods = {} # list method list_method_id = MethodIdentifier(iface_id, 'list') output_def = ListDefinition(StringDefinition()) method_defs[list_method_id] = MethodDefinition( list_method_id, StructDefinition(OPERATION_INPUT, [('service_id', StringDefinition())]), output_def, [not_found_def]) methods[list_method_id] = self._list # get method get_method_id = MethodIdentifier(iface_id, 'get') data_ref_def = StructRefDefinition( 'com.vmware.vapi.std.introspection.operation.data_definition') field_def = StructDefinition(MAP_ENTRY, [('key', StringDefinition()), ('value', data_ref_def)]) data_def = StructDefinition( 'com.vmware.vapi.std.introspection.operation.data_definition', [('type', StringDefinition()), ('element_definition', OptionalDefinition(data_ref_def)), ('name', OptionalDefinition(StringDefinition())), ('fields', OptionalDefinition(ListDefinition(field_def)))]) data_ref_def.target = data_def output_def = StructDefinition( 'com.vmware.vapi.std.introspection.operation.info', [('input_definition', data_def), ('output_definition', data_def), ('error_definitions', ListDefinition(data_def))]) method_defs[get_method_id] = MethodDefinition( get_method_id, StructDefinition(OPERATION_INPUT, [('service_id', StringDefinition()), ('operation_id', StringDefinition())]), output_def, [not_found_def]) methods[get_method_id] = self._get IntrospectionBaseApiInterface.__init__(self, iface_id, method_defs, methods)
def test_get_error_definition(self): method_def = MethodDefinition( MethodIdentifier(InterfaceIdentifier('interface'), 'method1'), StructDefinition('method1_input', []), VoidDefinition(), [self.error_def1, self.error_def2, self.error_def3]) self.assertEquals(self.error_def1, method_def.get_error_definition(self.ERROR1_NAME)) self.assertEquals(self.error_def2, method_def.get_error_definition(self.ERROR2_NAME)) self.assertEquals(self.error_def3, method_def.get_error_definition(self.ERROR3_NAME)) self.assertEquals( None, method_def.get_error_definition(self.BOGUS_ERROR_NAME))
class _MockStub(ApiInterfaceStub): interface_id = InterfaceIdentifier('mockup_interface') def __init__(self, config): operations = { 'echo': { 'input_type': StructType('echoInput', {'message': StringType()}), 'output_type': StringType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, }, 'echo_long_running': { 'input_type': StructType('echoInput', {'message': StringType()}), 'output_type': StringType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.TASK, }, 'echo_long_running$task': { 'input_type': StructType('echoInput', {'message': StringType()}), 'output_type': IdType(resource_types='com.vmware.cis.TASK'), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.TASK, }, 'invalid': { 'input_type': StructType('invalidInput', {}), 'output_type': StringType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } ApiInterfaceStub.__init__(self, iface_name=self.interface_id, config=config, operations=operations)
def __init__(self, name, introspection_adapter): """ Initialize ServiceApiInterface :type name: :class:`str` :param name: Name of the provider :type introspection_adapter: :class:`vmware.vapi.provider.introspection.ApiProviderIntrospector` :param introspection_adapter: Adapter for fetching introspection information """ self._adapter = introspection_adapter iface_id = InterfaceIdentifier( 'com.vmware.vapi.std.introspection.service') method_defs = {} methods = {} # list method list_method_id = MethodIdentifier(iface_id, 'list') output_def = ListDefinition(StringDefinition()) method_defs[list_method_id] = MethodDefinition( list_method_id, StructDefinition(OPERATION_INPUT, []), output_def, []) methods[list_method_id] = self._list # get method get_method_id = MethodIdentifier(iface_id, 'get') output_def = StructDefinition( 'com.vmware.vapi.std.introspection.service.info', [('operations', ListDefinition(StringDefinition()))]) method_defs[get_method_id] = MethodDefinition( get_method_id, StructDefinition(OPERATION_INPUT, [('id', StringDefinition())]), output_def, [not_found_def]) methods[get_method_id] = self._get IntrospectionBaseApiInterface.__init__(self, iface_id, method_defs, methods)
class _MockRestStub(ApiInterfaceStub): interface_id = InterfaceIdentifier('mockup_interface') def __init__(self, config): operations = { 'echo': { 'input_type': StructType('echoInput', {'message': StringType()}), 'output_type': StringType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, }, 'invalid': { 'input_type': StructType('invalidInput', {}), 'output_type': StringType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } rest_metadata = { 'echo': OperationRestMetadata(http_method='POST', url_template='/test/echo?action=echo'), 'invalid': OperationRestMetadata(http_method='POST', url_template='/test/echo?action=invalid') } ApiInterfaceStub.__init__(self, iface_name=self.interface_id, config=config, operations=operations, rest_metadata=rest_metadata, is_vapi_rest=False)
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)
VoidValue) from vmware.vapi.lib.std import make_error_value_from_msgs, make_std_error_def from vmware.vapi.lib.constants import OPERATION_INPUT from vmware.vapi.message import Message from vmware.vapi.l10n.runtime import message_factory from vmware.vapi.provider.local import LocalProvider from vmware.vapi.stdlib.client.introspection import IntrospectableApiProvider from vmware.vapi.protocol.client.local_connector import LocalConnector from vmware.vapi.settings.config import ProviderConfig, Sections from vmware.vapi.data.serializers.introspection import convert_data_def_to_data_value logging.basicConfig(level=logging.DEBUG) ### Data used by the mockup classes and the test methods interface_id = InterfaceIdentifier('mockup_interface') # Method names missing_input_definition = 'missing_input_definition' invalid_input_definition = 'invalid_input_definition' missing_output_definition = 'missing_output_definition' invalid_output_definition = 'invalid_output_definition' mock_definition = 'mock' report_declared_error = 'report_declared_error' report_undeclared_error = 'report_undeclared_error' raise_python_exception = 'raise_python_exception' return_invalid_output = 'return_invalid_output' # Method identifiers missing_input_definition_id = MethodIdentifier(interface_id,
from vmware.vapi.security.authentication_handler import AuthenticationHandler from vmware.vapi.security.authentication_filter import AuthenticationFilter from vmware.vapi.data.serializers.introspection import convert_data_def_to_data_value from vmware.vapi.security.user_password import USER_PASSWORD_SCHEME_ID, USER_KEY, PASSWORD_KEY from vmware.vapi.security.oauth import OAUTH_SCHEME_ID, ACCESS_TOKEN from vmware.vapi.security.session import SESSION_SCHEME_ID, SESSION_ID from vmware.vapi.security.sso import SAML_SCHEME_ID, SAML_BEARER_SCHEME_ID, SAML_TOKEN, PRIVATE_KEY from vmware.vapi.security.user_identity import UserIdentity from vmware.vapi.lib.constants import SCHEME_ID from vmware.vapi.settings.config import ProviderConfig from vmware.vapi.provider.local import LocalProvider DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources') mock_interface_id = InterfaceIdentifier('mock') mock_method_id = MethodIdentifier(mock_interface_id, 'mock') mock_interface_def = InterfaceDefinition(mock_interface_id, [mock_method_id]) mock_method_def = MethodDefinition( mock_method_id, StructDefinition('input', [('input', VoidDefinition())]), IntegerDefinition(), []) errors = [ 'com.vmware.vapi.std.errors.internal_server_error', 'com.vmware.vapi.std.errors.invalid_argument', 'com.vmware.vapi.std.errors.operation_not_found', 'com.vmware.vapi.std.errors.unauthenticated', ] 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])
for field_name in data_def.get_field_names(): field_def = data_def.get_field(field_name) field_instance = build_adhoc_data_value(field_def) instance.set_field(field_name, field_instance) elif data_def.type == Type.LIST: # TODO: Randomize list len? instance.add_all([build_adhoc_data_value(data_def.element_type) for val in range(1,7)]) elif data_def.type == Type.OPTIONAL: # TODO: Randomize optional set or not set? instance = data_def.new_value(build_adhoc_data_value(data_def.element_type)) return instance fake_iface_id = 'vmware.test.fake.iface' null_method_id = 'Null' null_method_def = MethodDefinition(MethodIdentifier( InterfaceIdentifier(fake_iface_id), null_method_id), VoidDefinition(), VoidDefinition(), [make_std_error_def('error1'), make_std_error_def('error2')] ) echo_method_id = 'Echo' echo_method_def = MethodDefinition(MethodIdentifier( InterfaceIdentifier(fake_iface_id), echo_method_id), StructDefinition('struct', [('int', IntegerDefinition()), ('str', StringDefinition())] ), StructDefinition('struct', [('int', IntegerDefinition()), ('str', StringDefinition())]
from vmware.vapi.lib.constants import OPERATION_INPUT, TaskType from vmware.vapi.provider.local import LocalProvider from vmware.vapi.stdlib.provider.factories import MessageFactory, ErrorFactory from vmware.vapi.protocol.client.local_connector import LocalConnector from vmware.vapi.stdlib.client.factories import StubConfigurationFactory from vmware.vapi.stdlib.client.introspection import make_introspection_error_def from vmware.vapi.task.task_handle import get_task_handle from com.vmware.cis.task_provider import Info from com.vmware.vapi.std.introspection_client import Service, Operation from com.vmware.vapi.std_provider import LocalizableMessage interface_name = 'mock_interface' method_name = 'echo' task_method_name = 'echo_long_running' application_context_method_name = 'echo_application_context_values' interface_id = InterfaceIdentifier(interface_name) messages = { 'mock.not_found': 'not found', } message_factory = MessageFactory(messages) class MockImpl(VapiInterface): def __init__(self, error_types=None): VapiInterface.__init__(self, MockSkeleton, error_types=error_types) def echo(self, **kwargs): message = kwargs.get('message') throw = kwargs.get('throw') if throw: msg = message_factory.get_message('mock.not_found')
class ApiInterfaceStub(ApiInterface): # pylint: disable=W0223 """ Stub class for Api Interface """ def __init__(self, iface_name, config, operations, rest_metadata=None, is_vapi_rest=None): """ Initialize the ApiMethod skeleton object :type iface_name: :class:`str` :param iface_name: Interface name :type config: :class:`StubConfiguration` :param config: Configuration data for vAPI stubs :type operations: :class:`dict` :param operations: Dictionary of operation name to operation information :type rest_metadata: :class:`dict` of :class:`str` and :class::`vmware.vapi.lib.rest.OperationRestMetadata` :param rest_metadata: Dictionary of operation name to operation REST metadata :type is_vapi_rest: :class:`bool` :param is_vapi_rest: Json message format. True for Vapi Rest and False for Swagger Rest """ self._iface_id = InterfaceIdentifier(iface_name) self._config = config self._operations = operations self._api_provider = config.connector.get_api_provider() self._rest_metadata = rest_metadata or {} self._is_vapi_rest = is_vapi_rest if isinstance(self._api_provider, ApiProviderFilter): # Get the API Provider (last provider in the chain) last_api_provider = self._api_provider.get_api_provider() else: last_api_provider = self._api_provider # Determine whether REST format needs to be used self._use_rest = True if isinstance( last_api_provider, RestClientProvider) else False if self._use_rest: # Add the service metadata to the REST provider last_api_provider.set_rest_format(self._is_vapi_rest) for method_name, operation_rest_metadata in six.viewitems( self._rest_metadata): last_api_provider.add_rest_metadata( self._iface_id.get_name(), method_name, operation_rest_metadata) # Set the REST converter mode if is_vapi_rest: self._rest_converter_mode = RestConverter.VAPI_REST else: self._rest_converter_mode = RestConverter.SWAGGER_REST else: self._rest_converter_mode = None ApiInterface.__init__(self) def get_identifier(self): """ Returns interface identifier :rtype: :class:`InterfaceIdentifier` :return: Interface identifier """ return self._iface_id def get_definition(self): """ Returns interface definition :rtype: :class:`InterfaceDefinition` :return: Interface definition """ operations = [MethodIdentifier(self._iface_id, operation_name) for operation_name in six.iterkeys(self._operations)] return InterfaceDefinition(self._iface_id, operations) def get_method_definition(self, method_id): op_info = self._operations.get(method_id.get_name()) if op_info is None: return errors_defs = [ e.definition for e in six.itervalues(op_info.get('errors'))] return MethodDefinition(method_id, op_info.get('input_type').definition, op_info.get('output_type').definition, errors_defs) 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 method_id: :class:`vmware.vapi.core.MethodIdentifier` :param method_id: Method identifier :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 """ return self._api_provider.invoke(self._iface_id.get_name(), method_id.get_name(), input_value, ctx) def native_invoke(self, ctx, method_name, kwargs): """ Invokes the method corresponding to the given method name with the kwargs. In this method, python native values are converted to vAPI runtime values, operation is invoked and the result are converted back to python native values :type ctx: :class:`vmware.vapi.core.ExecutionContext` :param ctx: Execution context for this method :type method_name: :class:`str` :param method_name: Method name :type kwargs: :class:`dict` :param kwargs: arguments to be passed to the method :rtype: :class:`object` :return: Method result """ op_info = self._operations.get(method_name) if op_info is None: raise Exception('Could not find %s method in %s interface' % (method_name, str(self._iface_id))) # Convert input input_type = op_info['input_type'] data_val = TypeConverter.convert_to_vapi(kwargs, input_type, self._rest_converter_mode) # Validate input validators = op_info['input_value_validator_list'] for validator in validators: msg_list = validator.validate(data_val, input_type) raise_core_exception(msg_list) if OPID in ctx.application_context: logger.debug( 'opId: %s invoke: interface_id: %s, operation_name: %s', ctx.application_context[OPID], self._iface_id.get_name(), method_name) else: logger.debug('invoke: interface_id: %s, operation_name: %s', self._iface_id, method_name) # Invoke method_id = MethodIdentifier(self._iface_id, method_name) if self._use_rest: operation_rest_metadata = None if self._rest_metadata: operation_rest_metadata = self._rest_metadata.get(method_name) if operation_rest_metadata is None: msg = message_factory.get_message( 'vapi.bindings.stub.rest_metadata.unavailable') logger.debug(msg) raise CoreException(msg) else: if self._is_vapi_rest is not None and not self._is_vapi_rest: # If the rest format is not vapi, then the server # (OpenAPI based) will not be supporting json-rpc. msg = message_factory.get_message( 'vapi.bindings.stub.jsonrpc.unsupported') logger.debug(msg) raise CoreException(msg) method_result = self.invoke(ctx, method_id, data_val) # Validate output if method_result.success(): validators = op_info['output_validator_list'] output_type = op_info['output_type'] for validator in validators: msg_list = validator.validate(method_result.output, output_type) raise_core_exception(msg_list) # Convert output return TypeConverter.convert_to_python(method_result.output, output_type, self._config.resolver, self._rest_converter_mode) else: # Convert error errors = op_info['errors'] error_type = errors.get(method_result.error.name) if error_type is None: error_type = self._config.resolver.resolve( method_result.error.name) if error_type is None: logger.warning('Unable to convert unexpected vAPI error %s ' + 'to native Python exception', method_result.error.name) vapi_error = UnresolvedError(method_result.error) raise vapi_error raise TypeConverter.convert_to_python(method_result.error, # pylint: disable=E0702 error_type, self._config.resolver, self._rest_converter_mode)
def __init__(self): self.iface_id = InterfaceIdentifier('mock') self.method_id = MethodIdentifier(self.iface_id, 'mock')
ListValue) from vmware.vapi.message import Message from vmware.vapi.core import ExecutionContext from vmware.vapi.provider.local import LocalProvider from vmware.vapi.provider.interposer import InterposerProvider, NotFound, InvalidArgument from vmware.vapi.lib.constants import (MAP_ENTRY, OPERATION_INPUT) from vmware.vapi.lib.std import make_std_error_def, make_error_value_from_msgs from vmware.vapi.data.serializers.introspection import convert_data_def_to_data_value from vmware.vapi.bindings.error import VapiError import logging logging.basicConfig() ### Data used by the mockup classes and the test methods interface_name = 'com.vmware.pkg1.mockup_interface' interface_id = InterfaceIdentifier(interface_name) interface_name_2 = 'com.vmware.pkg2.mockup_interface' interface_id_2 = InterfaceIdentifier(interface_name_2) # Method names mock_method_name = 'mockup_method' pre_method_name = 'mockup_pre' post_method_name = 'mockup_post' veto_method_name = 'mockup_veto' # Method identifiers mock_method_id = MethodIdentifier(interface_id, mock_method_name) pre_method_id = MethodIdentifier(interface_id, pre_method_name) post_method_id = MethodIdentifier(interface_id, post_method_name) veto_method_id = MethodIdentifier(interface_id, veto_method_name)
class TestApiMethodStub(unittest.TestCase): interface_id = InterfaceIdentifier('mockup_interface') def test_report_success(self): config = StubConfiguration(get_local_connector(MockupApiProvider())) operations = { report_vapi_success: { 'input_type': StructType(report_vapi_success, {}), 'output_type': BooleanType(), 'errors': {}, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } stub = ApiInterfaceStub('mockup_interface', config=config, operations=operations) self.assertEqual( stub.native_invoke(ctx=config.connector.new_context(), method_name=report_vapi_success, kwargs={}), True) def test_report_vapi_error(self): config = StubConfiguration(get_local_connector(MockupApiProvider())) operations = { report_vapi_error: { 'input_type': StructType(report_vapi_error, {}), 'output_type': BooleanType(), 'errors': { not_found: not_found_error_type }, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } stub = ApiInterfaceStub('mockup_interface', config=config, operations=operations) self.assertRaises(MockupNotFound, stub.native_invoke, config.connector.new_context(), report_vapi_error, {}) def test_report_unexpected_error(self): config = StubConfiguration(get_local_connector(MockupApiProvider())) operations = { nonexistent_method: { 'input_type': StructType(nonexistent_method, {}), 'output_type': BooleanType(), 'errors': { not_found: not_found_error_type }, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } stub = ApiInterfaceStub('mockup_interface', config=config, operations=operations) self.assertRaises(VapiError, stub.native_invoke, config.connector.new_context(), nonexistent_method, {}) def test_catch_unexpected_error(self): config = StubConfiguration(get_local_connector(MockupApiProvider()), operation_not_found_error_type) operations = { nonexistent_method: { 'input_type': StructType(nonexistent_method, {}), 'output_type': VoidType(), 'errors': { not_found: not_found_error_type }, 'input_value_validator_list': [], 'output_validator_list': [], 'task_type': TaskType.NONE, } } stub = ApiInterfaceStub('mockup_interface', config=config, operations=operations) self.assertRaises(MockupServiceNotFound, stub.native_invoke, config.connector.new_context(), nonexistent_method, {})
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