nova-api源碼分析(APP的調用)

來源:互聯網
上載者:User

標籤:

3.2  調用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的調用)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.