Ocata Neutron代码分析(六)——APIRouter的初始化(1)加载core plugin和service plugin...
在分析api-paste.ini时,曾分析到wsgi app neutronapiapp_v2_0是直接调用/neutron/api/v2/router.py中APIRouter的factory方法:
class APIRouter(base_wsgi.Router):@classmethoddef factory(cls, global_config, **local_config):return cls(**local_config)
APIRouter的factory方法是一个classmethod,直接调用APIRouter的构造函数,对APIRouter进行初始化。下面重点分析一下APIRouter类的构造函数:
class APIRouter(base_wsgi.Router):def __init__(self, **local_config):mapper = routes_mapper.Mapper() # 获取routes.Mapper的实例。manager.init() # 初始化NeutronManager来读取配置文件和加载plugin,该部分最关键的步骤。plugin = directory.get_plugin() # 从_PLUGIN_DIRECTORY._plugin中获取core plugin。ext_mgr = extensions.PluginAwareExtensionManager.get_instance() # 根据所有的plugins获取相应path并加载extensions。ext_mgr.extend_resources("2.0", attributes.RESOURCE_ATTRIBUTE_MAP)col_kwargs = dict(collection_actions=COLLECTION_ACTIONS,member_actions=MEMBER_ACTIONS)def _map_resource(collection, resource, params, parent=None):......mapper.connect('index', '/', controller=Index(RESOURCES)) # http://controller:9696/v2.0/for resource in RESOURCES:_map_resource(RESOURCES[resource], resource,attributes.RESOURCE_ATTRIBUTE_MAP.get(RESOURCES[resource], dict()))resource_registry.register_resource_by_name(resource)for resource in SUB_RESOURCES:_map_resource(SUB_RESOURCES[resource]['collection_name'], resource,attributes.RESOURCE_ATTRIBUTE_MAP.get(SUB_RESOURCES[resource]['collection_name'],dict()),SUB_RESOURCES[resource]['parent'])# Certain policy checks require that the extensions are loaded# and the RESOURCE_ATTRIBUTE_MAP populated before they can be# properly initialized. This can only be claimed with certainty# once this point in the code has been reached. In the event# that the policies have been initialized before this point,# calling reset will cause the next policy check to# re-initialize with all of the required data in place. policy.reset()super(APIRouter, self).__init__(mapper)
- 初始化NeutronManager来加载core plugin和service plugin;
- 初始化PluginAwareExtensionManager;
- 调用_map_resource方法为四个顶级resource进行map。
manager.init()
调用/neutron/manager.py中的init方法:
def init():"""Call to load the plugins (core+services) machinery."""# TODO(armax): use is_loaded() when availableif not directory.get_plugins():NeutronManager.get_instance()
首先,调用了neutron_lib库中的plugins.directory.py中的get_plugins方法。这里把相关的方法都贴出来,一起分析。
_PLUGIN_DIRECTORY = None@_synchronized("plugin-directory") def _create_plugin_directory():global _PLUGIN_DIRECTORYif _PLUGIN_DIRECTORY is None:_PLUGIN_DIRECTORY = _PluginDirectory()return _PLUGIN_DIRECTORYdef _get_plugin_directory():if _PLUGIN_DIRECTORY is None:return _create_plugin_directory()return _PLUGIN_DIRECTORYdef add_plugin(alias, plugin):_get_plugin_directory().add_plugin(alias, plugin)def get_plugin(alias=constants.CORE):return _get_plugin_directory().get_plugin(alias)def get_plugins():return _get_plugin_directory().pluginsdef get_unique_plugins():return _get_plugin_directory().unique_pluginsdef is_loaded():return _get_plugin_directory().is_loaded
class _PluginDirectory(object):"""A directory of activated plugins in a Neutron Deployment.The directory is bootstrapped by a Neutron Manager running inthe context of a Neutron Server process."""def __init__(self):self._plugins = {} # 构造函数只是对_plugins属性进行了初始化。def add_plugin(self, alias, plugin):"""Add a plugin of type 'alias'."""self._plugins[alias] = plugindef get_plugin(self, alias):"""Get a plugin for a given alias or None if not present."""p = self._plugins.get(alias)return weakref.proxy(p) if p else None # 如果没有名为alias的plugin,返回None。否则返回对应plugin的弱引用。 @propertydef plugins(self): # _PluginDirectory的plugins属性是一个函数,返回各个plugin的弱引用。"""The mapping alias -> weak reference to the plugin."""return dict((x, weakref.proxy(y))for x, y in self._plugins.items())@propertydef unique_plugins(self):"""A sequence of the unique plugins activated in the environments."""return tuple(weakref.proxy(x) for x in set(self._plugins.values()))@propertydef is_loaded(self):"""True if the directory is non empty."""return len(self._plugins) > 0
回到/neutron/manager.py中的init方法:
def init():"""Call to load the plugins (core+services) machinery."""# TODO(armax): use is_loaded() when availableif not directory.get_plugins():NeutronManager.get_instance()
@six.add_metaclass(profiler.TracedMeta) class NeutronManager(object):"""Neutron's Manager class.Neutron's Manager class is responsible for parsing a config file andinstantiating the correct plugin that concretely implementsneutron_plugin_base class."""@classmethod@utils.synchronized("manager")def _create_instance(cls):if not cls.has_instance():cls._instance = cls()@classmethoddef has_instance(cls):return cls._instance is not None@classmethoddef get_instance(cls):# double checked lockingif not cls.has_instance():cls._create_instance()return cls._instance
通过对NeutronManager的has_instance的两次判断,确定NeutronManager没有被实例化,这时调用其构造函数:
@six.add_metaclass(profiler.TracedMeta) class NeutronManager(object):_instance = Nonedef __init__(self, options=None, config_file=None):# If no options have been provided, create an empty dictif not options:options = {}""" 检查配置文件中是否配置了core_plugin,否则抛出异常 """msg = validate_pre_plugin_load()if msg:LOG.critical(msg)raise Exception(msg)# NOTE(jkoelker) Testing for the subclass with the __subclasshook__# breaks tach monitoring. It has been removed# intentionally to allow v2 plugins to be monitored# for performance metrics.plugin_provider = cfg.CONF.core_plugin # 从配置文件中获取core_plugin,一般为ml2LOG.info(_LI("Loading core plugin: %s"), plugin_provider) # server.log中打印 INFO neutron.manager [-] Loading core plugin: ml2# NOTE(armax): keep hold of the actual plugin objectplugin = self._get_plugin_instance(CORE_PLUGINS_NAMESPACE, # 通过namespace和plugin_provider获取plugin。 plugin_provider)directory.add_plugin(lib_const.CORE, plugin) # 添加core_plugin(Ml2Plugin的实例)到_PLUGIN_DIRECTORY._plugins中。""" 检查配置文件中的dhcp_agents_per_network,否则抛出异常 """msg = validate_post_plugin_load()if msg:LOG.critical(msg)raise Exception(msg)# load services from the core plugin first self._load_services_from_core_plugin(plugin)self._load_service_plugins() # 加载service_plugins,包括配置文件中指定的和默认的。# Used by pecan WSGIself.resource_plugin_mappings = {}self.resource_controller_mappings = {}self.path_prefix_resource_mappings = defaultdict(list)
在构造函数中,分别对core plugin和service plugin进行了初始化,并调用directory.add_plugin将各个plugin的实例添加到_PLUGIN_DIRECTORY变量中,供之后调用。其中,core plugin是直接调用_get_plugin_instance方法来获取相应的plugin类(一般为Ml2Plugin)并初始化:
class NeutronManager(object):def _get_plugin_instance(self, namespace, plugin_provider): # 通过不同的namespace中的plugin_provider获取相应的plugin。plugin_class = self.load_class_for_provider(namespace, plugin_provider) # 调用load_class_for_provider函数来返回Plugin类。return plugin_class() # 实例化Plugin类,在此处完成各个plugin的__init__方法的调用。
转载于:https://www.cnblogs.com/Luka-Modric/p/8250426.html
Ocata Neutron代码分析(六)——APIRouter的初始化(1)加载core plugin和service plugin...相关推荐
- Ocata Neutron代码分析(六)——APIRouter的初始化(2)PluginAwareExtensionManager的初始化...
上篇分析了core plugin和service plugin的加载过程.APIRouter的构造函数下一步将进行PluginAwareExtensionManager的初始化: ext_mgr = ...
- Ocata Neutron代码分析(六)——APIRouter的初始化(3)顶级resource的map过程
在完成了plugins和extensions的加载后,进行四个顶级resource(分别是network.subnet.subnetpool和port)的map过程.map过程指的是,将各个resou ...
- Ocata Neutron代码分析(一)——Neutron API启动过程分析
首先,Neutron Server作为一种服务(neutron-server.service),可以到Neutron项目目录中的setup.cfg配置文件中找到对应的代码入口. [entry_poin ...
- DSS 代码分析【启动、初始化流程】
DSS加载module及和module交互的流程,如下: (1).DSS在fork子进程后调用StartServer启动服务 调用OS.OSThread.Socket.SocketUtils.QTSS ...
- GMap.NET入门详细教程【2】-------- 初始化并加载一张地图
GMap.NET入门 下载 GMap.NET,并在VS中添加GMap.NET控件 初始化并加载一张地图 添加标记点.线.多边形 为控件添加事件,在鼠标单击时打点 初始化 双击地图控件,编辑cs代码中的 ...
- java 初始化的加载顺序问题
总结一下java里面关于初始化的加载顺序问题: 考虑有一个基类和一个子类的情况 那么,当实例化一个子类的对象或者访问子类的静态域或静态方法时,会进行类的加载. 1)完成基类的static域和stati ...
- SpringMVC--Ajax异步加载数据$(function (){ 逻辑代码}) 的意思是让dom结构加载完毕后再去执行逻辑代码
1. SpringMVC–Ajax异步加载数据 1.1 实体类user User.java package com.tian.pojo;import lombok.AllArgsConstructor ...
- inputstream 初始化_MyBatis初始化之加载初始化
在MyBatis初始化过程中,大致会有以下几个步骤: 1. 创建Configuration全局配置对象,会往TypeAliasRegistry别名注册中心添加Mybatis需要用到的相关类,并设置默认 ...
- Spring Ioc 源码分析(一)--Spring Ioc容器的加载
1.目标:熟练使用spring,并分析其源码,了解其中的思想.这篇主要介绍spring ioc 容器的加载 2.前提条件:会使用debug 3.源码分析方法:Intellj idea debug 模式 ...
最新文章
- 浅说国际根域名服务器与中国电信的镜像服务器
- sina stock历史数据
- 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )
- npp夜光数据介绍 viirs_惊艳!珞珈一号卫星“眼中”的夜光衡水
- 学习区块链,绕不过去的“拜占庭将军问题”!!这里正好有通俗易懂的解释
- python itchat 的使用
- DDG全家桶之3022
- C++(STL):35---multimap容器
- html + css实现油画商场页面
- Bailian2899 Bailian3242 矩阵交换行【矩阵】
- 开启NTP时钟服务器,让电脑变成网络时间服务器
- C++开发坦克大战--补充(加入传送门)--附完整代码
- gps数据处理 java_GPS数据读取与处理
- EasyRecovery15绿色版免安装数据恢复软件
- 如何选择好的健身房管理系统而且还不收费
- 百度地图API仿链家地图找房 聚合开发 js实现
- Vue 组件封装之 Result 结果页
- scala中sorted,sortby,sortwith的用法(转)
- VGA、DVI、HDMI、DP 接口介绍及优劣
- Feature Selection详解(附带Relief、Relief-F、LVM详解)(一)
热门文章
- 安卓开发中的一些经验总结
- B450M MORTAR AMD R5 3600 组装机
- 前后端交互之——AJAX提交
- 外贸公司用邮件开发客户需要注意些什么?
- Errors while compiling. Reload prevented.
- “No JSON object could be decoded“问题定位
- codeforces 赛后总结
- 分享5款堪称神器的免费软件,建议先收藏再下载
- Flink OLAP 助力 ByteHTAP 亮相数据库顶会 VLDB
- 如何搭建一个属于自己的博客网站?(小白教程)