zoukankan      html  css  js  c++  java
  • nova-api中ExtensionManager的构造

    源码版本:H版

    nova/api/openstack/__init__.py

    APIRouter类:
    def __init__(self, ext_mgr=None, init_only=None):
        if ext_mgr is None:
            if self.ExtensionManager:
                ext_mgr = self.ExtensionManager()
            else:
                raise Exception(_("Must specify an ExtensionManager class"))
        ...

          其中的ExtensionManager由子类nova/api/openstack/compute/__init__.py中的APIRouter指定为nova/api/openstack/compute/extensions.py中的ExtensionManager类,下面看其构造函数:

    class ExtensionManager(base_extensions.ExtensionManager):
        def __init__(self):
            LOG.audit(_('Initializing extension manager.'))
            self.cls_list = CONF.osapi_compute_extension
            self.extensions = {}
            self.sorted_ext_list = []
            self._load_extensions()

         其中self.cls_list是扩展包的引导类列表,此处为[nova.api.openstack.compute.contrib.standard_extensions](注意只有一个元素)。接着看self._load_extensions()的内容,由于ExtensionManager的类继承关系,该函数为nova.api.openstack. extensions ExtensionManager的函数,内容如下:

    def _load_extensions(self):
        extensions = list(self.cls_list)
        for ext_factory in extensions:
            try:
                self.load_extension(ext_factory)
            except Exception as exc:
                LOG.warn(_('Failed to load extension %(ext_factory)s: '
                           '%(exc)s'),
                         {'ext_factory': ext_factory, 'exc': exc})

           其中self.load_extension函数内容如下:

    def load_extension(self, ext_factory):
        LOG.debug(_("Loading extension %s"), ext_factory)
        if isinstance(ext_factory, basestring):
            factory = importutils.import_class(ext_factory)
        else:
            factory = ext_factory
        LOG.debug(_("Calling extension factory %s"), ext_factory)
        factory(self)

          最终结果就是调用nova.api.openstack.compute.contrib.standard_extensions。接下来看standard_extensions函数,内容如下:

    def standard_extensions(ext_mgr):
        extensions.load_standard_extensions(ext_mgr, LOG, __path__, __package__)

         其中extensions为nova.api.openstack.extensions,看load_standard_extensions内容如下:

    def load_standard_extensions(ext_mgr, logger, path, package, ext_list=None):
        our_dir = path[0]
        for dirpath, dirnames, filenames in os.walk(our_dir):
            relpath = os.path.relpath(dirpath, our_dir)
            if relpath == '.':
                relpkg = ''
            else:
                relpkg = '.%s' % '.'.join(relpath.split(os.sep))
            for fname in filenames:
                root, ext = os.path.splitext(fname)
                if ext != '.py' or root == '__init__':
                    continue
                classname = "%s%s" % (root[0].upper(), root[1:])
                classpath = ("%s%s.%s.%s" %
                             (package, relpkg, root, classname))
                if ext_list is not None and classname not in ext_list:
                    logger.debug("Skipping extension: %s" % classpath)
                    continue
                try:
                    ext_mgr.load_extension(classpath)
                except Exception as exc:
                    logger.warn(_('Failed to load extension %(classpath)s: '
                                  '%(exc)s'),
                                {'classpath': classpath, 'exc': exc})
            ...

           实际上也就是调用之前ExtensionManager的 load_extension函数加载模块,并构造模块中与模块名对应的类,由于这些类都是nova.api.openstack.extensions.ExtensionDescriptor的子类,且看其__init__函数:

    def __init__(self, ext_mgr):
        ext_mgr.register(self)
        self.ext_mgr = ext_mgr

      可知构造这些扩展类会在ExtensionManager中进行注册,注册过程就是在ExtensionManag中将扩展类的实例存入ExtensionManager的extensions列表中,对应的key为扩展类的alias。

      综上所述,ExtensionManager的构造就是对其中的self.cls_list进行加载调用,self.cls_list包含扩展包的引导类或引导函数,此处为nova.api.openstack.compute.contrib.standard_extensions,该引导函数负责加载扩展包中模块,并构造相应的类实例,这些类实例在构造时会向ExtensionManager进行注册。

  • 相关阅读:
    [转]中英文混合字符截取方法样式表解决方法
    Asp.Net小技巧集合
    [分享]整理后的Discuz!NT 2.0项目源码
    [原创]Web2.0之Tag标签原理实现浅析
    [转]CSS完美兼容IE6/IE7/FF的通用hack方法
    [转]常用CSS缩写语法总结
    文本类文件编码转换器及DiscuzNTdotNet2.0 - -
    [驳]ASP伪静态页简单教程
    SELECT中很多程序都不用的NOLOCK“加锁选项”的功能说明
    iOS 微博 OAuth2.0 分享 文字 + 图片 微博的方法
  • 原文地址:https://www.cnblogs.com/littlebugfish/p/4049853.html
Copyright © 2011-2022 走看看