Nova API
http://docs.openstack.org/developer/nova/devref/addmethod.openstackapi.html
https://www.ibm.com/developerworks/community/blogs/e93514d3-c4f0-4aa0-8844-497f370090f5/entry/openstack_nova_api?lang=en
nova.wsgi.Server
为每一个 Nova API worker 进程提供一个封装的 web server。它封装并管理一个 eventlet 优化过(greened) 的 WSGI server,它运行在一个自己管理的 green thread pool(这个线程池的大小可配)和一个给定的 socket (port、最大队列连接数可配)上。
详见前面的文章 了解 WSGIService nova-api 如何起来
nova.api.openstack.compute.APIRouter
用来允许将多个 WSGI applications 绑定到一个单独的 WSGI server 上,这也是为什么每个核心的 API 和插件(extension)资源都是一个个独立的 WSGI application。
它继承自 nova.api.openstack.APIRouter
,这个父类会在初始化的时候寻找 ExtensionManager、用 nova.api.openstack.__init__
里的 ProjectMapper 类
创建 mapper( mapper.resource(member_name, collection_name, ...)
它将用于把属于一个 collection 的请求都映射到一个 controller 上),
并依次 _setup_routes
、_setup_ext_routes
、_setup_extensions
,其中的 _setup_routes
这一关键方法必须由子类来实现,
这里定义了详细的基本 route 策略:mapper 中的每一个 route 必须指定一个 WSGI app 作为它的 controller。
最后,用它父类 base_wsgi.Router
(nova/wsgi.py
) 里的 __init__
方法,将刚刚生成的 mapper 传进去。
nova.wsgi.Router
是 nova.api.openstack.compute.APIRouter
的父类,在内部用 routes.middleware.RoutesMiddleware
来把那些进来的请求映射到那些 WSGI applications。
在 nova/api/openstack/wsgi.py
中还有很多 wsgi 通讯时的实现,比如:
- 对 Request 的简单封装,加入一些简单的 cache;
- 定义了一些解析、生成 body 的类:
TextDeserializer
;DictSerializer
; - 定义了一些添加 (De)serializer 的装饰器;
- 什么是一个 action 的装饰器 @action;
- 继承某个 action 的装饰器 @extends(xxx);ResponseObject。。。
Resource 类
它自己是一个 WSGI app,管理着 (de)serialization 和 controller 的分发。
读取由 RoutesMiddleware
提供的 routing 信息,根据它的 controller 调用请求的 action。
所有的 controller 的 action 方法都必须接受一个叫 ‘req’ 的参数,内容是进来的 wsgi.Request 请求。
如果这个操作是 PUT 或是 POST,那么 controller 的方法就必须接受一个 ‘body’ 参数(内容为请求的 body)。
这些方法最后要么报一个 webob.exc 异常,要么返回一个 dict,这个字典将被按照要求的 content type 序列化。请细看 _process_stack(xxx) 这个方法。
Controller 类
默认的 Controller 类。
(这里待完善)
调用过程
> /opt/stack/nova/nova/api/openstack/wsgi.py(890)__call__()
889 return self._process_stack(request, action, action_args,
--> 890 content_type, body, accept)
891
> /opt/stack/nova/nova/api/openstack/wsgi.py(942)_process_stack()
941 with ResourceExceptionHandler():
--> 942 action_result = self.dispatch(meth, request, action_args)
943 except Fault as ex:
> /opt/stack/nova/nova/api/openstack/wsgi.py(1022)dispatch()
1021
-> 1022 return method(req=request, **action_args)
1023
> /opt/stack/nova/nova/api/openstack/compute/servers.py(480)detail()
479 try:
--> 480 servers = self._get_servers(req, is_detail=True)
481 except exception.Invalid as err:
> /opt/stack/nova/nova/api/openstack/compute/servers.py(564)_get_servers()
563 self._add_instance_faults(context, instance_list)
--> 564 response = self._view_builder.detail(req, instance_list)
565 else:
> /opt/stack/nova/nova/api/openstack/compute/views/servers.py(135)detail()
134 """Detailed view of a list of instance."""
--> 135 return self._list_view(self.show, request, instances)
136
> /opt/stack/nova/nova/api/openstack/compute/views/servers.py(139)_list_view()
138 """Provide a view for a list of servers."""
--> 139 server_list = [func(request, server)["server"] for server in servers]
140 servers_links = self._get_collection_links(request,
> nova/api/openstack/compute/views/servers.py (90)show()
def show(self, request, instance):
...
comments powered by Disqus