nova-api对web请求的路由过程的分析版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处!此
nova-api对web请求的路由过程的分析
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处!
此篇有些凌乱,主要是服务的启动及web请求的调用跨越了多个模块,仅作为个人学习笔记分享,有任何问题欢迎交流!
nova-api提供了RESTful服务,它对来自web的请求通过router方式转给各个service的具体方法,由这些service的具体方法完成服务的请求。
/usr/bin/nova-apiserver = service.WSGIService(api)
/nova/service.pyself.loader = loader or wsgi.Loader()self.app = self.loader.load_app(name)
/nova/wsgi.pyclass Loader(object):load_app加载 nova.api.openstack.compute:
APIRouter.factory
/nova/api/openstack/compute/__init__.pyclass
APIRouter(nova.api.openstack.APIRouter)
ExtensionManager = extensions.ExtensionManagerdef
_setup_routes(self, mapper, ext_mgr) self.resources['xxxxxx'] =
xxxxxxx.create_resource()
/nova/api/openstack/__init__.pyclass APIRouter(base_wsgi.Router)def factorydef __init__ ext_mgr = self.
ExtensionManager() mapper =
ProjectMapper() self.
_setup_routes(mapper, ext_mgr) self.
_setup_ext_routes(mapper, ext_mgr) self.
_setup_extensions(ext_mgr) super(APIRouter, self).__init__(mapper) 调用基类的初始化接口
/nova/wsgi.pyclass Router(object) 为基类 方法 __init__ self.map = mapper self._router = routes.middleware.RoutesMiddleware(self._dispatch, self.map) @webob.dec.wsgify(RequestClass=
Request) 方法 __call__ WSGI服务请求调用接口,通过装饰后实际上是将此处__call__方法的返回值作为参数传入到webob.dec.wsgify装饰类,并该类的同名方法__call__, __call__方法又根据web请求调用app既Resource的__call__来完成具体的功能,每当有nova-api相关请求时均会进入到Resource的__call__方法以便进行请求的dispatch,所以下面的ExtensionsResource就主要是将各个功能类进行manage操作,以便完成服务请求。此处需要注意的是设计模式-Decorator(装饰者模式)。
方法 def _dispatch(req): 转发web请求到具体的功能模块(extension加载的功能模块) match = req.environ['wsgiorg.routing_args'][1] retun app = match['controller']
分析ProjectMapper()/nova/api/openstack/__init__.pyclass ProjectMapper(APIMapper): def resourceclass APIMapper def routematch
分析
_setup_ext_routes/nova/api/openstack/__init__.pydef _setup_ext_routes(self, mapper, ext_mgr) for resource in
ext_mgr.get_resources(): 分析
ext_mgr.get_resources()/nova/api/openstack/extensions.pyclass ExtensionManager(object)def get_resources(self): resources.append(ResourceExtension('extensions',
ExtensionsResource(self))) ..... 分析
ExtensionsResource/nova/api/openstack/extensions.pyclass ExtensionsResource(
wsgi.Resource): __init__ ext_data = {} ext_data['name'] = ext.name ext_data['alias'] = ext.alias ext_data['description'] = ext.__doc__ ...... return ext_data通过该部分可以看出get_resources返回了extension加载的功能模块信息,以便在web请求路由时查找调用相应的功能方法
分析
wsgi.Resource/nova/api/openstack/wsgi.pyclass Resource(
wsgi.Application)
分析wsgi.Application/nova/wsgi.py
分析extensions.ExtensionManager/nova/api/openstack/compute/extensions.pyclass ExtensionManager(base_extensions.ExtensionManager) 基类base_extensions.ExtensionManager self.PluginManager = pluginmanager.PluginManager('nova','compute-extensions') self.PluginManager.
load_plugins() self.cls_list.append(self.PluginManager.
plugin_extension_factory) ...................... self.
_load_extensions()/nova/api/openstack/extensions.pyclass ExtensionManager(object)
self.cls_list = FLAGS.osapi_compute_extension既nova.api.openstack.compute.contrib.standard_extensions所指向的内容,形式如下: nova.api.openstack.volume.contrib.volume_actions.Volume_actions nova.api.openstack.volume.contrib.admin_actions.Admin_actions nova.api.openstack.volume.contrib.image_create.Image_create .........................
def _load_extensions(self) def get_resources(self)
分析load_plugins()/nova/openstack/common/plugin.pyclass PluginManager(object)def load_plugins(self): for entrypoint in pkg_resources.iter_entry_points('%s.plugin' %self._project_name) pluginclass = entrypoint.load() plugin = pluginclass(self._service_name) self.plugins.append(plugin)
分析plugin_extension_factory/nova/openstack/common/plugin/pluginmanager.pyclass ExtensionManager:def plugin_extension_factory ext_mgr.
load_extension(descriptor)
分析load_extension/nova/api/openstack/extensions.pyclass ExtensionManager:def load_extension(self, ext_factory) factory =
importutils.import_class(ext_factory)
分析_load_extensions/nova/api/openstack/extensions.pyclass ExtensionManager:def load_extension(self) extensions = list(
self.cls_list) for ext_factory in extensions: self.load_extension(ext_factory) 也是调用的load_extension
分析importutils.import_class/nova/openstack/common/importutils.py
加载的既nova/api/openstack/compute/contrib:standard_extensions所指定的功能类,就是nova/api/openstack/compute/contrib目录下的内容
def import_class(import_str):mod_str, _sep, class_str = import_str.rpartition('.') __import__(mod_str)getattr(sys.modules[mod_str], class_str)
以加载nova.api.openstack.volume.contrib.image_create.Floating_ips为例:class Floating_ips(extensions.ExtensionDescriptor):
"""Floating IPs support""" name = "FloatingIps"
alias = "os-floating-ips" 别名
namespace = "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"
updated = "2011-06-16T00:00:00+00:00"
def get_resources
FloatingIPController() def get_controller_extensions controller =
FloatingIPActionController() extension = extensions.ControllerExtension(self, 'servers', controller)
其中
FloatingIPController提供了show()、create()、delete()的方法以便对float IP进行操作
至此全部的extension功能模块都被加载完毕,再返回分析
create_resource nova.api.openstack.compute import flavors