ShaoHe Feng has uploaded a new change for review.
Change subject: add JsonPpcClientAPI class ......................................................................
add JsonPpcClientAPI class
This new class will parse the json schema and generate the json API dynamically
Change-Id: Iaa825e7fed1eb11a0b612c779b39220a69a1c875 Signed-off-by: ShaoHe Feng shaohef@linux.vnet.ibm.com --- M vdsm_api/jsonrpc/client.py 1 file changed, 60 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/46/11846/1
diff --git a/vdsm_api/jsonrpc/client.py b/vdsm_api/jsonrpc/client.py index 0975f64..3d4aec9 100644 --- a/vdsm_api/jsonrpc/client.py +++ b/vdsm_api/jsonrpc/client.py @@ -1,6 +1,11 @@ +import os +from vdsm import constants +import vdsmapi +from functools import partial import json import socket import logging +import random import uuid from jsonrpc import \ JsonRpcError, \ @@ -47,6 +52,61 @@ self._transport.close()
+class JsonPpcClientAPI(JsonRpcClient): + def __init__(self, reactorClient): + super(JsonPpcClientAPI, self).__init__(reactorClient) + self.commands = {} + schema = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json') + self._dynamicAttribute(schema) + + def callMethodWaper(self, method, *args, **kwargs): + + # get all original names of argument, described in vdsmapi-schema.json + allArgs = self.commands[method].get('data', {}).keys() + allArgs = [v.lstrip('*') for v in allArgs] + allArgs.extend(['reqId', 'timeout']) + + # validate the keytwork of arguments + invalidKey = [k for k in kwargs.iterkeys() if k not in allArgs] + if invalidKey: + raise ValueError("no %s argument for %s method" % (k, method)) + + args = list(args) + params = args[:] + # get 'reqId' and 'timeout' + agrsDict = kwargs.copy() + agrsDict.update(dict(zip(args, allArgs))) + reqId = agrsDict.pop('reqId', None) + timeout = agrsDict.pop('timeout', None) + # remove 'reqId' and 'timeout' + kwargs.pop('reqId', None) + kwargs.pop('timeout', None) + kparams = [{k: v} for k, v in kwargs.iteritems()] + params.append(kparams) + reqId = random.randint(0, 65535) if reqId is None else reqId + return self.callMethod(method, params, reqId=reqId, timeout=timeout) + + def _dynamicAttribute(self, schema): + dynamicAttr = {} + with open(schema) as f: + symbols = vdsmapi.parse_schema(f) + for s in symbols: + if 'command' in s: + className = s['command']['class'] + functionName = s['command']['name'] + if className not in dynamicAttr.keys(): + dynamicAttr[className] = [] + dynamicAttr[className].append(functionName) + self.commands[".".join((className, functionName))] = s + for key, funs in dynamicAttr.items(): + funDicts = {} + for fun in funs: + method = ".".join((key, fun)) + funDicts[fun] = partial(self.callMethodWaper, method) + cls = type(key, (object,), funDicts) + setattr(self, key, cls()) + + class TCPReactorClient(object): def __init__(self, address): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-- To view, visit http://gerrit.ovirt.org/11846 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange Gerrit-Change-Id: Iaa825e7fed1eb11a0b612c779b39220a69a1c875 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: ShaoHe Feng shaohef@linux.vnet.ibm.com