Source code for vmware.vapi.protocol.client.msg.json_connector
"""
Json client handler
"""
__author__ = 'VMware, Inc.'
__copyright__ = 'Copyright 2012-2014 VMware, Inc. All rights reserved. -- VMware Confidential'
import itertools
import logging
import six
from vmware.vapi.core import ApiProvider
from vmware.vapi.protocol.client.msg.generic_connector import GenericConnector
from vmware.vapi.lib.constants import PROCESSORS
from vmware.vapi.lib.load import import_multiple_classes
from vmware.vapi.data.serializers.jsonrpc import (
JsonRpcDictToVapi,
vapi_jsonrpc_request_factory, deserialize_response,
vapi_jsonrpc_error_transport_error,
VAPI_INVOKE
)
logger = logging.getLogger(__name__)
[docs]class JsonClientProvider(ApiProvider):
""" Json rpc client provider """
def __init__(self, rpc_provider):
"""
Json rpc client provider init
:type rpc_provider: :class:`vmware.vapi.protocol.client.rpc.provider.RpcProvider`
:param rpc_provider: rpc provider object
"""
ApiProvider.__init__(self)
self.rpc_provider = rpc_provider
self.counter = itertools.count()
self.to_vapi = JsonRpcDictToVapi
# Load all the post processors
self.post_processors = import_multiple_classes(__name__,
PROCESSORS)
[docs] def invoke(self, service_id, operation_id, input_value, ctx):
"""
Invokes the specified method using the input value and the
the execution context provided
: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.DataValue`
:param input_value: method input parameters
:type ctx: :class:`vmware.vapi.core.ExecutionContext`
:param ctx: execution context object
:rtype: :class:`vmware.vapi.core.MethodResult`
:return: method result object
"""
params = {
'serviceId': service_id,
'operationId': operation_id,
'input': input_value,
'ctx': ctx,
}
response = self._do_request(VAPI_INVOKE, params)
result = self.to_vapi.method_result(response.result)
return result
#
## vapi methods end
def _do_request(self, method, params=None):
"""
Perform json rpc request
:type method: :class:`str`
:param method: json rpc method name
:type params: :class:`dict` or None
:param params: json rpc method params
:rtype: :class:`vmware.vapi.data.serializer.jsonrpc.JsonRpcResponse`
:return: json rpc response
"""
logger.debug('_do_request: request %s', method)
if not self.rpc_provider.connect():
logger.error('Connection refused')
raise vapi_jsonrpc_error_transport_error()
request_ctx = {'Content-Type': 'application/json'}
id_ = six.advance_iterator(self.counter) # atomic increment
id_ = str(id_) # TODO: Bypass java barf temporary
request = vapi_jsonrpc_request_factory(method=method,
params=params,
id=id_)
request_msg = request.serialize()
for processor in self.post_processors:
request_msg = processor.process(request_msg)
logger.debug('_do_request: request %s', request_msg)
# do_request returns response_ctx, response_msg
_, response_msg = self.rpc_provider.do_request(request_ctx, request_msg)
logger.debug('_do_request: response %s', response_msg)
response = deserialize_response(response_msg)
request.validate_response(response)
if response.error is not None:
logger.error('_do_request: method %s response with error %s',
method, response.error)
raise response.error # pylint: disable=E0702
return response
[docs]def get_protocol_connector(rpc_provider):
"""
Get protocol connector
:type rpc_provider: :class:`vmware.vapi.protocol.client.rpc.provider.RpcProvider`
:param rpc_provider: rpc provider object
:rtype: :class:`vmware.vapi.protocol.client.connector.Connector`
:return: json rpc connector object
"""
api_provider = JsonClientProvider(rpc_provider)
connector = GenericConnector(rpc_provider, api_provider)
return connector