Source code for vmware.vapi.protocol.server.msg.json_handler

"""
Json rpc server side handler
"""

__author__ = 'VMware, Inc.'
__copyright__ = 'Copyright 2012-2013 VMware, Inc.  All rights reserved. -- VMware Confidential'


import logging
import traceback

from vmware.vapi.protocol.server.api_handler import ApiHandler
from vmware.vapi.lib.constants import PROCESSORS
from vmware.vapi.lib.load import import_multiple_classes
from vmware.vapi.data.serializers.jsonrpc import (
   JsonRpcDictToVapi,
   JsonRpcError,
   vapi_jsonrpc_response_factory, vapi_jsonrpc_error_invalid_request,
   vapi_jsonrpc_error_parse_error, vapi_jsonrpc_error_internal_error,
   vapi_jsonrpc_error_method_not_found, vapi_jsonrpc_error_invalid_params,
   deserialize_request, VAPI_INVOKE)
from vmware.vapi.lib.profiler import profile

logger = logging.getLogger(__name__)


[docs]class JsonApiHandler(ApiHandler): """ Json rpc api handler """ def __init__(self, provider): """ Json rpc api handler init :type provider: :class:`vmware.vapi.core.ApiProvider` :param provider: api provider object """ ApiHandler.__init__(self) self.ops = { VAPI_INVOKE: self.invoke, } self.provider = provider self.to_vapi = JsonRpcDictToVapi # Load all the pre processors self.pre_processors = import_multiple_classes(__name__, PROCESSORS) @profile
[docs] def handle_request(self, request_str): """ Handle a vapi request :type request_str: :class:`str` :param request_str: json rpc request string :rtype: :class:`str` :return: response string """ request = None request_method = None response_str = None # NYI: Need to sanitize password / escape the user str # Bug No: 1050609 logger.debug('request_str: "%s"', request_str) try: # Execute all the pre processors try: for processor in self.pre_processors: request_str = processor.process(request_str) except Exception as err: logger.debug('Encountered error during preprocessing' 'of JSON request %s', repr(request_str)) raise vapi_jsonrpc_error_invalid_request(err) try: request = deserialize_request(request_str) except JsonRpcError as err: raise except Exception as err: logger.debug('Deserialize error %s', repr(request_str)) raise vapi_jsonrpc_error_parse_error(err) try: request_method = request.method handler = self.ops[request_method] except KeyError as err: # No such method logger.error('No such method: %s', request_method) # raise vapi_jsonrpc_error_method_not_found() raise vapi_jsonrpc_error_method_not_found() # Invoke method result = handler(request) # Serialize response response = vapi_jsonrpc_response_factory(request, result=result) response_str = response.serialize() except JsonRpcError as err: logger.debug('JsonRpcError callstack: %s: %s', request_method, traceback.format_exc()) response = vapi_jsonrpc_response_factory(request, error=err) response_str = response.serialize() #except CoreException, err: # # NYI: We should *NEVER* see the core exception. Just in case, we # # should do the right thing # # For now, treated as normal Exception # logger.debug('Core exception callstack: %s: %s', # request_method, traceback.format_exc()) except Exception as err: # All other errors => internal server error logger.debug('Exception callstack: %s: %s', request_method, traceback.format_exc()) error = vapi_jsonrpc_error_internal_error(str(err)) response = vapi_jsonrpc_response_factory(request, error=error) response_str = response.serialize() # NYI: Need to sanitize password # Bug No: 1050609 logger.debug('response_str: "%s"', response_str) return response_str
@staticmethod def _verify_no_input_params(request): """ Verify no input params is given :type request: :class:`vmware.vapi.data.serializer.jsonrpc.JsonRpcRequest` :param request: json rpc request """ if request.params: logger.error('Unexpected input params %s', request.method) raise vapi_jsonrpc_error_invalid_params()
[docs] def invoke(self, request): """ Invokes a specified method given an execution context, a method identifier and method input parameter(s) :type request: :class:`vmware.vapi.data.serializer.jsonrpc.JsonRpcRequest` :param request: json rpc request object :rtype: :class:`dict` :return: Result of the method invocation """ try: params = request.params service_id = str(params.get('serviceId', '')) operation_id = str(params.get('operationId', '')) input_value = self.to_vapi.data_value(params.get('input')) ctx = self.to_vapi.execution_context(params.get('ctx')) except Exception: raise vapi_jsonrpc_error_invalid_params() # Invoke method invoke_result = self.provider.invoke( service_id, operation_id, input_value, ctx) # Build result return invoke_result
[docs]def get_protocol_handler(provider): """ Get protocol handler :type provider: :class:`vmware.vapi.core.ApiProvider` :param provider: api provider object :rtype :class:`vmware.vapi.protocol.server.api_handler.ApiHandler` :return: json rpc api handler object """ api_handler = JsonApiHandler(provider) return api_handler