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(a)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(a)linux.vnet.ibm.com>