nova-api对web请求的路由过程的分析

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处!

此篇有些凌乱,主要是服务的启动及web请求的调用跨越了多个模块,仅作为个人学习笔记分享,有任何问题欢迎交流!

nova-api提供了WSGI服务,它对来自web的请求通过router方式转给各个service的具体方法,由这些service的具体方法完成服务的请求。

/usr/bin/nova-api
server = service.WSGIService(api)

/nova/service.py
self.loader = loader or wsgi.Loader()
self.app = self.loader.load_app(name) 

/nova/wsgi.py
class Loader(object):load_app
加载 nova.api.openstack.compute: APIRouter.factory

/nova/api/openstack/compute/__init__.py
class  APIRouter(nova.api.openstack.APIRouter)
ExtensionManager = extensions.ExtensionManager
def  _setup_routes(self, mapper, ext_mgr)
    self.resources['xxxxxx'] =  xxxxxxx.create_resource()

/nova/api/openstack/__init__.py
class APIRouter(base_wsgi.Router)
def factory
def __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.py
class 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__.py
class ProjectMapper(APIMapper):
      def resource
class APIMapper
      def routematch

分析 _setup_ext_routes
/nova/api/openstack/__init__.py
def _setup_ext_routes(self, mapper, ext_mgr)
    for resource in  ext_mgr.get_resources():
        
分析 ext_mgr.get_resources()
/nova/api/openstack/extensions.py
class ExtensionManager(object)
def get_resources(self):
    resources.append(ResourceExtension('extensions',  ExtensionsResource(self)))
    .....
    
分析 ExtensionsResource
/nova/api/openstack/extensions.py
class 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.py
class Resource( wsgi.Application)  


分析wsgi.Application
/nova/wsgi.py


分析extensions.ExtensionManager
/nova/api/openstack/compute/extensions.py
class 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.py
class 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.py
class 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.py
class ExtensionManager:
def plugin_extension_factory
    ext_mgr. load_extension(descriptor) 


分析load_extension
/nova/api/openstack/extensions.py
class ExtensionManager:
def load_extension(self, ext_factory)
    factory =  importutils.import_class(ext_factory)

分析_load_extensions
/nova/api/openstack/extensions.py
class 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"  别名,web请求实际使用的就是别名,通过别名进行实际的功能入口查找
    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

你可能感兴趣的:(openstack,nova源码分析)