zoukankan      html  css  js  c++  java
  • nova-api源码分析(APP中用到的开源库)

    源码版本:H版

    1、paste.deploy

    参考文章:

    http://pythonpaste.org/deploy/

    http://blog.csdn.net/xiangmin2587/article/details/8203503

    http://www.choudan.net/2013/07/28/OpenStack-paste-deploy%E4%BB%8B%E7%BB%8D.html

    用来解析/etc/nova/api-paste.ini文件,加载用于服务的wsgi app。它的功能有:

    1)api-paste.ini中配置多个wsgi app,deploy可根据传入的app name加载指定的wsgi app;

    deploy.loadapp("config:/etc/nova/api-paste.ini", name="osapi-compute")

    加载api-paste.ini中,名为osapi-compute的WSGI APP,并作为结果返回。

    2)通过写入api-paste.ini的配置,可方便地实现特定字符开始的url到特定wsgi app的映射。如:

    [composite:osapi_compute]                                                      
    use = call:nova.api.openstack.urlmap:urlmap_factory                            
    /: oscomputeversions                                                
    /v2: openstack_compute_api_v2

         通过该配置,以“/v2”开始的url将交给名为openstack_compute_api_v2的WSGI APP处理,其它以“/”开的url就交给oscomputerversions处理。其实这并非deploy的功能,而是上面配置的urlmap实现的。不过通过配置文件,再由deploy调用urlmap,使用就更简单了。

     3)middle ware的简单加载和去除。

    [composite:openstack_compute_api_v2]                                           
    use = call:nova.api.auth:pipeline_factory            
    keystone = faultwrap sizelimit authtoken keystonecontext ratelimit osapi_compute_app_v2

          上面的faultwrap sizelimit authtoken keystonecontext ratelimit都为middle ware(在nova代码中称为MiddleWare,deploy中称为filter),osapi_compute_app_v2才是wsgi app。请求先交给middle ware处理,再由middle ware决定要不要或者怎么交给wsgi app处理。这些middle ware是可以添加和去除的,如果不想对osapi_compute_app_v2进行限速,那么去掉ratelimit就可以了。其实这是pipeline_factory实现的功能,不过通过deploy来配置加载更方便。

          nova-api中提供了很多服务API:ec2(与EC2兼容的API),osapi_compute(openstack compute自己风格的API),osapi_volume(openstack volume服务API),metadata(metadata 服务API)等。通过配置文件api-paste.ini,可以方便管理这些API。

          deploy提供了server、filter、app的概念,其中filter(即middle ware)、app在nova-api被重度使用,的确太好用了。发布每个API时,它们有时需要一些相同的功能,如:keystone验证、限速、错误处理等功能。nova将这些功能实现为middle ware,如果需要,通过api-paste.ini配置,给它加上就可以。比如,我需要记录每个访问nova-api的ip,及它们的访问次数和访问的时间。那么我实现一个middle ware--nova.api.middleware:MonitorMiddleware来记录这些数据。通过下面的api-paste.ini配置,就可对nova-api的访问进行记录了。

    [composite:openstack_compute_api_v2]                                           
    use = call:nova.api.auth:pipeline_factory            
    keystone = faultwrap sizelimit authtoken keystonecontext ratelimit <strong>monitor</strong> osapi_compute_app_v2
     
    [filter:<strong>monitor</strong>]                                                                
    paste.filter_factory = nova.api.middleware:MonitorMiddleware.factory

    2、webob

    用于对wsgi app进行封装,简化wsgi app的定义与编写。webob主要提供三种功能。

    1)Request。该类用于对传给wsgi app的env参数进行封装,简化对HTTP请求参数的访问和设置。这种简化体现在(假设用env对Request实例化了一个对象req):

    1) 使用简洁明了的属性名对HTTP参数进行访问,req.method可获取HTTP请求方法(替代REQUEST_METHOD);req.scheme可获取HTTP请求协议http or https(替代wsgi.url_scheme);req.body获取请求body(替代wsgi.input)。

    2)大量使用property,省去繁琐细节,简化HTTP参数的访问和设置。req.body直接访问HTTP请求的body,而不用考虑body的长度和字符编码;req.POST以字典形式返回POST请求的参数;req.GET以字典形式返回GET请求的参数。

    nova.api.openstack.wsgi.Request继承该类,并加了一个缓存已访问db的记录的功能,和对content_type判断和检测的功能。

    2)Response。该类用于对HTTP的返回值进行封装。与Request对象类似,同样使用了property简化对http参数的访问和设置。支持wsgi app一次返回status和body,这样更直观。其实Response实例本身也是一个wsgi app。

    3)decorator--wsgify,装饰wsgi app,使其可以以如下方式定义:

    @webob.dec.wsgify                                    
    def wsgi_app(req):
      #do something with req
      return req.Response(...)

    其中参数req是一个Request(默认)或其子类(通过wsgify(RequestClass=XXX)指定)的实例,是用env初始化的。req.Response默认为webob.Response。以该种方式定义的wsgi app,其结果可以以三种形式返回:

    1)返回一个字符串。wsgify将其作为body,并加上一些默认的参数,如status=“200 OK", content_type, content_length等,构造成一个HTTP响应结果并返回;

    2)返回一个Response实例,直接返回该resp代表的HTTP请求结果;

    3)返回一个wsgi app,wsgify会继续调用该app,并返回app的响应结果。

    nova.wsgi.Router就是用第三种返回形式,两次返回wsgi app,最终将HTTP请求根据url映射到对应的controller处理。

    3、routes

    参考文章:

    http://routes.readthedocs.org/en/latest/

    用来给服务内部定义url到具体函数的映射。

      deploy也有url到服务映射功能,但这个映射层次偏高一点。根据上面配置,deploy将以“/v2”开始的url将交给名为openstack_compute_api_v2处理。但openstack_compute_api_v2怎么将/v2/project_id/servers/的GET请求交给nova.api.openstack.compute.servers.Controller.index()处理,并且将POST请求交给create()处理呢;怎么将/v2/project_id/servers/id的GET请求交给show()处理呢?这个就是routes.mappers所提供的功能,它根据path和请求方法,将请求映射到具体的函数上。如在nova中,添加/v2/project_id/servers/{list_vm_state, os_vmsum}两个GET请求来分别获取指定VM的状态和VM的总数。可在nova.api.openstack.compute.APIRouter中添加如下两行,将请求分别交给list_vm_state和os_vmsum两个函数处理并返回结果:

    self.resources['servers'] = servers.create_resource(ext_mgr)
    mapper.resource("server", "servers",
              controller=self.resources['servers'],
              <strong>collection={'list_vm_state': 'GET',
                      'os_vmsum': 'GET'}</strong>)

    这里利用了routes.mapper支持restful api的特性,仅用两条指令,就定义了十多个url到函数的映射。当然你可以如下方式添加接口,不过代码稍多,风格不那么统一:

    mapper.connect("server",
             "/{project_id}/servers/list_vm_state",
             controller=self.resources['servers'],
             action='list_vm_state',
             conditions={'list_vm_state': 'GET'})
    mapper.connect("server",
             "/{project_id}/servers/os_vmsum",
             controller=self.resources['servers'],
             action='os_vmsum',
             conditions={'os_vmsum': 'GET'})
  • 相关阅读:
    (五)Oracle学习笔记—— 视图
    (四)Oracle学习笔记—— 常见函数
    (三)Oracle学习笔记—— sql语句
    (二)Oracle学习笔记—— 序列
    mybatis部分版本异常invalid comparison: java.util.Date and java.lang.String
    spring 配置多数据源 (案例)
    spring 配置多数据源 (可行)
    使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法
    Java三大器之过滤器(Filter)的工作原理和代码演示
    Java三大器之监听器(Listener)的工作原理和代码演示
  • 原文地址:https://www.cnblogs.com/littlebugfish/p/4022900.html
Copyright © 2011-2022 走看看