Change in vdsm[master]: api: Organize schema symbols by type

agl at us.ibm.com agl at us.ibm.com
Fri Feb 15 19:15:44 UTC 2013


Adam Litke has uploaded a new change for review.

Change subject: api: Organize schema symbols by type
......................................................................

api: Organize schema symbols by type

Currently the vdsmapi module returns the parsed schema as a large list of
symbols.  Consumers of this list have all resorted to reorganizing the symbols
by type (commands, types, enums, maps, etc).  Rather than forcing each user to
rewrite this code, just do it correctly at the source.  This reduces code
duplication and makes at easier to add new symbol types (such as events and
errors).

Signed-off-by: Adam Litke <agl at us.ibm.com>
Change-Id: Ie20291689c402e3f49267181eeb96f2cedbe9690
---
M vdsm_api/vdsmapi.py
1 file changed, 122 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/06/12106/1

diff --git a/vdsm_api/vdsmapi.py b/vdsm_api/vdsmapi.py
index 889da71..f154e99 100644
--- a/vdsm_api/vdsmapi.py
+++ b/vdsm_api/vdsmapi.py
@@ -24,6 +24,9 @@
 # Refer to the README and COPYING files for full details of the license
 #
 
+import os
+from vdsm import constants
+
 try:
     from collections import OrderedDict
     OrderedDict  # make pyflakes happy
@@ -107,3 +110,122 @@
         exprs.append(expr_eval)
 
     return exprs
+
+
+def find_schema():
+    """
+    Find the API schema file whether we are running from within the source dir
+    or from an installed location
+    """
+    localpath = os.path.dirname(__file__)
+    installedpath = constants.P_VDSM
+    for directory in localpath, installedpath:
+        path = os.path.join(directory, 'vdsmapi-schema.json')
+        if os.access(path, os.R_OK):
+            return path
+    raise Exception("Unable to find API schema file in %s or %s",
+                    localpath, installedpath)
+
+
+_api_info = None
+
+
+def _load_api_info(schema):
+    """
+    Organize API information from the schema file into a useful structure:
+
+    types: A dictionary of type symbols indexed by type name
+    {
+     'type': <type name>
+     'data': <dict containing this type's attributes in name/type pairs>
+     'union': <an optional list of child types to which this type is castable>
+    }
+
+    enums: A dictionary of enum symbols indexed by enum name
+    {
+     'enum': <enum name>,
+     'data': <a list of valid values>
+    }
+
+    aliases: A dictionary of alias symbols indexed by alias name
+    {
+     'alias': <alias name>
+     'data': <aliased type>
+    }
+
+    maps: A dictionary of mapping types indexed by name
+    {
+     'map': <the name of the mapping type>
+     'key': <the type for this map's keys>
+     'value': <the type for this map's values>
+    }
+
+    commands: A dictionary of command namespaces indexed by namespace name that
+    contains dictionaries of command symbols indexed by command name
+    {
+     'command'
+     {
+      'class': <the namespace to which the command belongs>
+      'name': <the command name>
+     }
+     'data': <an optional ordered dictionary of parameters in name/type pairs>
+     'returns': <the type of the return value, if any>
+    }
+
+    unions: A dictionary that describes valid casts between related types.
+    Each key is a source type that is castable and the value is a list of types
+    to which the source type may be cast.
+    """
+    global _api_info
+
+    info_key = schema
+    if schema is None:
+        schema = find_schema()
+    with open(schema) as f:
+        symbols = parse_schema(f)
+
+    info = {'types': {}, 'enums': {}, 'aliases': {}, 'maps': {},
+            'commands': {}, 'unions': {}}
+
+    for s in symbols:
+        if 'alias' in s:
+            info['aliases'][s['alias']] = s
+        elif 'type' in s:
+            info['types'][s['type']] = s
+        elif 'enum' in s:
+            info['enums'][s['enum']] = s
+        elif 'map' in s:
+            info['maps'][s['map']] = s
+        elif 'command' in s:
+            ns = s['command']['class']
+            cmd = s['command']['name']
+            if ns not in info['commands']:
+                info['commands'][ns] = {cmd: s}
+            else:
+                info['commands'][ns][cmd] = s
+
+    # Determine the valid casts
+    def add_relation(mapping, typeA, typeB):
+        if typeA in mapping:
+            mapping[typeA].append(typeB)
+        else:
+            mapping[typeA] = [typeB, ]
+
+    for t in info['types'].values():
+        if 'union' not in t:
+            continue
+        for u in t['union']:
+            add_relation(info['unions'], u, t['type'])
+            add_relation(info['unions'], t['type'], u)
+
+    _api_info = {info_key: info}
+
+
+def get_api(schema=None):
+    """
+    Get organized information about the vdsm API.  If schema is specified,
+    read from a specific file.  Otherwise try to find the schema automatically.
+    """
+    if _api_info is None or schema not in _api_info:
+        _load_api_info(schema)
+    return _api_info[schema]


--
To view, visit http://gerrit.ovirt.org/12106
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie20291689c402e3f49267181eeb96f2cedbe9690
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