3.2 Calling Apirouter's __call__ function
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 to 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
When OSAPI_COMPUTE_APP_V2 receives an HTTP request, the NOVA.WSGI.ROUTER.__CALL__ function is called based on the inheritance of the class, as shown above. Look at the source code of Webob.dec.wsgify, and find that if the function returns the Wsgi app, it will also be called and return its processing results.
3.2.1 Self._router is a routes.middleware.RoutesMiddleware instance, so the routes.middleware.routesmiddleware.__call__ function is called, The function calls Routes.mapper.routematch to get parameters such as the controller mapped by the URL of the HTTP request, with {"Controller": Resource (Controller ()), "action": FuncName, "project_id": uuid, ...} Format is placed in match. and set the following Environ variable, convenient for subsequent calls to the Self._dispatch access.
environ[' Wsgiorg.routing_args ' = ((URL), match) environ[' routes.route '] = route environ[' routes.url '] = URL
Finally call Self._dispatch (). Self._dispatch the controller that corresponds to the URL by using the environ[' Wsgiorg.routing_args ' that was set earlier, and returns the controller.
3.2.2 the controller here is the controller set in Apirouter initialization, which is the resource instance initialized with the corresponding controller class. So then call the NOVA.API.OPENSTACK.WSGI.RESOURCE.__CALL__ function, which gets the match set above by environ[' Wsgiorg.routing_args '). The match has an action property that specifies the name of the controller member function to invoke, as well as other related invocation parameters. When we define a member function for a controller, we generally need to pass NOVA.API.OPENSTACK.WSGI. {serializers, deserializers} to specify the template that interprets the body content, either in XML or JSON format. The goal of NOVA.API.OPENSTACK.URLMAP.URLMAP definition is to Judge Content_Type. Resource then in the parsing body will refer to Content_Type, and then call the corresponding parser for body parsing (such as Xmldeserializer, Jsondeserializer), and then update the parsed parameters into Action_ args, using Action_args to invoke the Controller member function, which is the final HTTP request handler function. Finally, the execution result is serialized using the specified serializer and the result is returned.
3.2.3 Here is a special description of the handling of action requests other than common restful requests. In the case of the/servers/xxx/action request, the function that requested the call is actually contained in the body of the request. After parsing the Routes.middleware.RoutesMiddleware __call__ function, the resource that is being called is determined to be the resource built by the controller in which module, and the action parameter is "Action", the next step in resource's __call__ function will be action== "action" to start parsing body content, find the corresponding method in the controller. The controller fills in a dictionary of all of its action-type methods in the process of the build, and the key is given by the @wsgi.action (' xxx ') adornment function before each _action_xxx method, value for each The name of the _action_xxx method (which can be seen in the rule, in the body inside the request method name plus _aciton_ is the controller in the corresponding call method). The contents of this controller's dictionary are then registered to resource in the process of building the resource object using a controller. In this way, you simply give the key to the calling method in the body of the request, then you can find the method that the key maps, and finally call the Controller class in the resource __call__ function!
Reference Documentation:
Http://www.it165.net/pro/html/201407/17020.html
Nova-api Source Analysis (app call)