Change in vdsm[master]: add JsonPpcClientAPI class

shaohef at linux.vnet.ibm.com shaohef at linux.vnet.ibm.com
Thu Feb 7 13:51:58 UTC 2013


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 at 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 at linux.vnet.ibm.com>


More information about the vdsm-patches mailing list