nova-api源码分析(APP的调用)
调用APIRouter的 __call__函数
nova/wsgi.py
class Router(object):
def __init__(self, mapper):
self.map = mapper
self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map) @webob.dec.wsgify(RequestClass=Request)
def __call__(self, req):
return self._router @staticmethod
@webob.dec.wsgify(RequestClass=Request)
def _dispatch(req):
match = req.environ['wsgiorg.routing_args'][1]
if not match:
return webob.exc.HTTPNotFound()
app = match['controller']
return app
当osapi_compute_app_v2接收到HTTP请求时,根据类的继承关系, 将调用nova.wsgi.Router.__call__函数,如上所示。查看一下webob.dec.wsgify 的源码,发现如果函数返回的是wsgi app时,它还会被继续调用,并返回它的处理结果。
3.2.1 self._router 为routes.middleware.RoutesMiddleware实例,所以会调用routes.middleware.RoutesMiddleware.__call__函数,该函数调用routes.mapper.routematch来获取HTTP请求的URL所映射的controller等参数,以{"controller":Resource(Controller()), "action": funcname, "project_id": uuid, ...}的格式放在match中。并设置如下的environ变量,方便后面调用的self._dispatch访问。
environ['wsgiorg.routing_args'] = ((url), match)
environ['routes.route'] = route
environ['routes.url'] = url
最后调用self._dispatch()。 self._dispatch通过前面设置的environ['wsgiorg.routing_args']来找到url对应的controller,并返回该controller。
3.2.2 这里的controller就是在APIRouter初始化中设置的controller,也就是使用相应Controller类初始化的Resource实例。所以接着调用nova.api.openstack.wsgi.Resource.__call__函数,该函数通过environ['wsgiorg.routing_args']获取上面设置的match,该match有一个action属性,它指定了所要调用Controller成员函数的名字,以及其它相关的调用参数。在我们定义Controller的成员函数时,一般需要通过nova.api.openstack.wsgi.{serializers, deserializers}来指定解释body内容的模板,可以是xml或者json格式的。前面说过重定义nova.api.openstack.urlmap.URLMap的目的是为了判断content_type。Resource接着在解析body时会参考content_type,然后调用相应的解析器进行body解析(如XMLDeserializer、JSONDeserializer),接着将解析出的参数更新进action_args,使用action_args来调用Controller成员函数,即最终的http请求处理函数。最后将执行结果使用指定的序列化器序列化,并返回结果。
3.2.3 这里特别说明一下对常见RESTful请求之外的action请求的处理。以/servers/xxx/action请求为例,请求调用的函数实际包含在请求的body中。经过routes.middleware.RoutesMiddleware的__call__函数解析后,此时即将调用的Resource已经确定为哪个模块中的Controller所构建的Resource,而action参数为"action",接下来在Resource的__call__函数里面会因为action=="action"从而开始解析body的内容,找出Controller中所对应的方法。Controller在构建的过程中会由于MetaClass的影响将其所有action类型的方法填入一个字典中,key由每个_action_xxx方法前的@wsgi.action('xxx')装饰函数给出,value为每个_action_xxx方法的名字(从中可以看出规律,在body里面请求的方法名前加上_aciton_即为Controller中对应调用的方法)。之后在使用Controller构建Resource对象的过程中会向Resource注册该Controller的这个字典中的内容。这样,只需在请求的body中给出调用方法的key,然后就可以找到这个key所映射的方法,最后在Resource的__call__函数中会调用Controller类的这个函数!
参考文档:
http://www.it165.net/pro/html/201407/17020.html
nova-api源码分析(APP的调用)的更多相关文章
- Spring源码分析之`BeanFactoryPostProcessor`调用过程
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 本文内容: AbstractApplicationContext#refresh前部分的一点小内容 ...
- Openstack Nova 源码分析 — RPC 远程调用过程
目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacompute ...
- mybatis源码分析(方法调用过程)
十一月月底,宿舍楼失火啦,搞得20多天没有网,目测直到放假也不会来了... 正题 嗯~,其实阅读源码不是为了应付面试,更重要的让你知道,大师是怎样去写代码的,同样是用Java,为啥Clinton Be ...
- Mybatis源码分析之存储过程调用
这一篇博客我们学习一下Mybatis调用存储过程的使用和运行流程.首先我们先创建一个简单的存储过程 DELIMITER $ CREATE PROCEDURE mybatis.ges_user_coun ...
- requests库核心API源码分析
requests库是python爬虫使用频率最高的库,在网络请求中发挥着重要的作用,这边文章浅析requests的API源码. 该库文件结构如图: 提供的核心接口在__init__文件中,如下: fr ...
- jQuery1.11源码分析(8)-----jQuery调用Sizzle引擎的相关API
之所以把这部分放在这里,是因为这里用到了一些基本API,前一篇介绍过后才能使用. //jQuery通过find方法调用Sizzle引擎 //jQuery通过find方法调用Sizzle引擎 jQuer ...
- MapReduce新版客户端API源码分析
使用MapReduce新版客户端API提交MapReduce Job需要使用 org.apache.hadoop.mapreduce.Job 类.JavaDoc给出以下使用范例. // Create ...
- 3. 源码分析---SOFARPC客户端服务调用
我们首先看看BoltClientProxyInvoker的关系图 所以当我们用BoltClientProxyInvoker#invoke的时候实际上是调用了父类的invoke方法 ClientProx ...
- Spring源码分析之AOP从解析到调用
正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...
- 9.源码分析---SOFARPC是如何实现故障剔除的?
SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...
随机推荐
- ASP.NET Core采用Web Deploy方式发布到 Windows Server 2012 IIS上
小白一枚,租个服务器,发布下网站,满足下好奇心,讲的粗糙,请大家谅解哈~ 1.配置服务器环境.这部分网上教程比较多. (1)开启IIS,参考其他博客的,担心的话,将Web服务器(IIS)全选哈~ (2 ...
- Laya鼠标事件阅读
点击事件核心类:MouseManager和TouchManager. MouseManager负责收集相关事件,进行捕获阶段和目标阶段. TouchManger负责处理和分发事件,进行冒泡阶段. 捕获 ...
- App推荐 | Google Tasks
前不久,Google推出了一款移动任务管理应用Google Task,在使用2天后,写一下使用感受,并与Google同类产品Keep进行一个对比. 首先欣赏几张官方的App截图 然后来看一下官方的介绍 ...
- 用HackRF和Gqrx来听FM广播
本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...
- Docker swarm集群搭建教程
一.什么是Swarm Swarm这个项目名称特别贴切.在Wiki的解释中,Swarm behavior是指动物的群集行为.比如我们常见的蜂群,鱼群,秋天往南飞的雁群都可以称作Swarm behavio ...
- Python中的字典详解
https://www.cnblogs.com/yjd_hycf_space/p/6880026.html
- java第二次实验报告
课程:Java实验 班级:201352 姓名:池彬宁 学号:20135212 成绩: 指导教师:娄佳鹏 实验日期:15.05.05 实验密级: ...
- 《LINUX内核设计与实现》第三周读书笔记——第一二章
<Linux内核设计与实现>读书笔记--第一二章 20135301张忻 估算学习时间:共2小时 读书:1.5 代码:0 作业:0 博客:0.5 实际学习时间:共2.5小时 读书:2.0 代 ...
- Jquery封装ajax
Jquery封装ajax Load方法 <!-- 将jquery.js导入进来 --> <script type="text/javascript&qu ...
- android管理SD卡 mksdcard
在创建Android模拟器的时候,会创建一个虚拟的sd卡.我们还可以通过mksdcard命令创建sd卡,在运行模拟器的时候,可以选择具体的sd卡. 1.创建sd卡: mksdcard [-l labl ...