Change in vdsm[master]: api: Move DynamicBridge to vdsmapi schema processing
agl at us.ibm.com
agl at us.ibm.com
Fri Feb 15 19:15:45 UTC 2013
Adam Litke has uploaded a new change for review.
Change subject: api: Move DynamicBridge to vdsmapi schema processing
......................................................................
api: Move DynamicBridge to vdsmapi schema processing
Signed-off-by: Adam Litke <agl at us.ibm.com>
Change-Id: I0bbcc2475a40749c959eade157f6030b2c2f5e71
---
M tests/apiTests.py
M vdsm/clientIF.py
M vdsm_api/Bridge.py
M vdsm_api/jsonrpc/__init__.py
4 files changed, 29 insertions(+), 59 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/07/12107/1
diff --git a/tests/apiTests.py b/tests/apiTests.py
index 7ad8a1f..5275391 100644
--- a/tests/apiTests.py
+++ b/tests/apiTests.py
@@ -27,7 +27,6 @@
from contextlib import closing
from testrunner import VdsmTestCase as TestCaseBase
-from vdsm import constants
import BindingJsonRpc
import jsonrpc
import apiData
@@ -110,21 +109,6 @@
sys.modules['API'] = _newAPI
-def findSchema():
- """
- Find the API schema file whether we are running tests from the source dir
- or from the tests install location
- """
- scriptdir = os.path.dirname(__file__)
- localpath = os.path.join(scriptdir, '../vdsm_api/vdsmapi-schema.json')
- installedpath = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json')
- for f in localpath, installedpath:
- if os.access(f, os.R_OK):
- return f
- raise Exception("Unable to find schema in %s or %s",
- localpath, installedpath)
-
-
def setUpModule():
"""
Set up the environment for all tests:
@@ -140,12 +124,11 @@
handler.setLevel(logging.INFO)
log.addHandler(handler)
- schema = findSchema()
createFakeAPI()
# Bridge imports the API module so we must set up the fake API first
import Bridge
- bridge = Bridge.DynamicBridge(schema)
+ bridge = Bridge.DynamicBridge()
# Support parallel testing. Try hard to find an open port to use
port = getFreePort()
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index 841e962..ef9a19b 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -153,11 +153,10 @@
def _loadBindingJsonRpc(self):
from BindingJsonRpc import BindingJsonRpc
from Bridge import DynamicBridge
- schema = os.path.join(constants.P_VDSM, 'vdsmapi-schema.json')
ip = self._getServerIP(config.get('addresses', 'management_ip'))
port = config.getint('addresses', 'json_port')
conf = [('tcp', {"ip": ip, "port": port})]
- self.bindings['json'] = BindingJsonRpc(DynamicBridge(schema), conf)
+ self.bindings['json'] = BindingJsonRpc(DynamicBridge(), conf)
def _prepareBindings(self):
self.bindings = {}
diff --git a/vdsm_api/Bridge.py b/vdsm_api/Bridge.py
index 8fade0f..cc3f227 100644
--- a/vdsm_api/Bridge.py
+++ b/vdsm_api/Bridge.py
@@ -29,8 +29,8 @@
class DynamicBridge(object):
- def __init__(self, schema):
- self._parseSchema(schema)
+ def __init__(self):
+ self.api = vdsmapi.get_api()
def dispatch(self, name, argobj):
methodName = name.replace('.', '_')
@@ -60,30 +60,13 @@
except KeyError:
raise VdsmError(5, "Response is missing '%s' member" % member)
- def _parseSchema(self, schema):
- self.commands = {}
- self.classes = {}
- self.types = {}
- with open(schema) as f:
- symbols = vdsmapi.parse_schema(f)
- for s in symbols:
- if 'command' in s:
- key = "%s_%s" % (s['command']['class'],
- s['command']['name'])
- self.commands[key] = s
- elif 'class' in s:
- cls = s['class']
- self.classes[cls] = s
- elif 'type' in s:
- t = s['type']
- self.types[t] = s
-
def __getattr__(self, attr):
- if attr in self.commands:
+ try:
className, methodName = attr.split('_')
- return partial(self._dynamicMethod, className, methodName)
- else:
+ self.api['commands'][className][methodName]
+ except (KeyError, ValueError):
raise AttributeError("Attribute not found '%s'" % attr)
+ return partial(self._dynamicMethod, className, methodName)
def _convertClassName(self, name):
"""
@@ -97,7 +80,7 @@
except KeyError:
return name
- def _getMethodArgs(self, className, cmd, argObj):
+ def _getMethodArgs(self, className, methodName, argObj):
"""
An internal API call currently looks like:
@@ -109,10 +92,11 @@
them from here. For any given method, the method_args are obtained by
chopping off the ctor_args from the beginning of argObj.
"""
- className = self._convertClassName(className)
# Get the full argument list
- allArgs = self.commands[cmd].get('data', {}).keys()
+ sym = self.api['commands'][className][methodName]
+ allArgs = sym.get('data', {}).keys()
+ className = self._convertClassName(className)
# Get the list of ctor_args
ctorArgs = getattr(API, className).ctorArgs
@@ -149,7 +133,7 @@
symName = self._symNameFilter(symName)
try:
- symbol = self.types[symTypeName]
+ symbol = self.api['types'][symTypeName]
except KeyError:
return
@@ -167,16 +151,17 @@
if k in item:
self._typeFixup(k, v, item[k])
- def _fixupArgs(self, cmd, args):
- argInfo = zip(self.commands[cmd].get('data', {}).items(), args)
+ def _fixupArgs(self, className, methodName, args):
+ argDef = self.api['commands'][className][methodName].get('data', {})
+ argInfo = zip(argDef.items(), args)
for typeInfo, val in argInfo:
argName, argType = typeInfo
- if argType not in self.types:
+ if argType not in self.api['types']:
continue
self._typeFixup(argName, argType, val)
- def _fixupRet(self, cmd, result):
- retType = self.commands[cmd].get('returns', None)
+ def _fixupRet(self, className, methodName, result):
+ retType = self.api['commands'][className][methodName].get('returns')
if retType is not None:
self._typeFixup('return', retType, result)
return result
@@ -189,17 +174,19 @@
return kwargs
- def _getArgList(self, cmd):
- return self.commands[cmd].get('data', {}).keys()
+ def _getArgList(self, className, methodName):
+ sym = self.api['commands'][className][methodName]
+ return sym.get('data', {}).keys()
def _dynamicMethod(self, className, methodName, *args, **kwargs):
- cmd = '%s_%s' % (className, methodName)
- argobj = self._nameArgs(args, kwargs, self._getArgList(cmd))
+ argobj = self._nameArgs(args, kwargs,
+ self._getArgList(className, methodName))
api = self._getApiInstance(className, argobj)
- methodArgs = self._getMethodArgs(className, cmd, argobj)
- self._fixupArgs(cmd, methodArgs)
+ methodArgs = self._getMethodArgs(className, methodName, argobj)
+ self._fixupArgs(className, methodName, methodArgs)
# Call the override function (if given). Otherwise, just call directly
+ cmd = '%s_%s' % (className, methodName)
fn = command_info.get(cmd, {}).get('call')
if fn:
result = fn(api, argobj)
@@ -217,7 +204,7 @@
ret = retfield(result)
else:
ret = self._getResult(result, retfield)
- return self._fixupRet(cmd, ret)
+ return self._fixupRet(className, methodName, ret)
def Host_getStorageRepoStats_Ret(ret):
diff --git a/vdsm_api/jsonrpc/__init__.py b/vdsm_api/jsonrpc/__init__.py
index 49e8788..03cbf2e 100644
--- a/vdsm_api/jsonrpc/__init__.py
+++ b/vdsm_api/jsonrpc/__init__.py
@@ -226,6 +226,7 @@
except JsonRpcError as e:
ctx.sendReply(None, e)
except Exception as e:
+ self.log.error("Unexpected exception", exc_info=True)
ctx.sendReply(None, JsonRpcInternalError(str(e)))
else:
return ctx.sendReply(res, None)
--
To view, visit http://gerrit.ovirt.org/12107
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0bbcc2475a40749c959eade157f6030b2c2f5e71
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <agl at us.ibm.com>
More information about the vdsm-patches
mailing list