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. 源码分析- ...
随机推荐
- 使用 spring-boot-devtools 进行热部署
2019/3/5 更新: 发现热部署不生效,出现页面显示error的错误,然后在 application.properties 中注释了下面两行成功实现热部署(直接删掉也可以) #spring.dev ...
- SpringBoot整合Mybatis之进门篇
已经有好些日子没有总结了,不是变懒了,而是我一直在奋力学习springboot的路上,现在也算是完成了第一阶段的学习,今天给各位总结总结. 之前在网上找过不少关于springboot的教程,都是一些比 ...
- Mysql_临时表
CREATE TEMPORARY TABLE test_info ( test_name ) NOT NULL, test_totail ,) NOT NULL DEFAULT 0.00, test_ ...
- hdu 2036:改革春风吹满地(叉积求凸多边形面积)
改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- tomcat-内存溢出java.lang.OutOfMemoryErrory:PermGen space解决方法
如果是PermGen space方法区内存溢出,可尝试加大MaxPermSize,如果是heap space 堆内存移除,可尝试修改Xmx 正常解决方法: 在注释下的第一行添加: JAVA_OPTS= ...
- 如何使用URLOS进行docker应用开发
使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力.在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行的情况下,微服务+Docker的完 ...
- 微软职位内部推荐-Senior Software Engineer - Back End
微软近期Open的职位: SharePoint is a multi-billion dollar enterprise business that has grown from an on-prem ...
- 记初学net-SNMP
自从弄完那个jsp的网盘(其实还是个烂摊子),这几天一直在研究snmp. 有需求就激发动力,对,人都是被逼出来的.五一这几天,天天搁这坐着,毫无头绪. 下面切入正题. 要做一个监控园区网在线数的平台, ...
- 设置matplotlib画图支持中文显示
1.安装中文字体 git clone https://github.com/tracyone/program_font && cd program_font && ./ ...
- Leetcode题库——47.全排列II
@author: ZZQ @software: PyCharm @file: permuteUnique.py @time: 2018/11/16 13:34 要求:给定一个可包含重复数字的序列,返回 ...