In the Neutron API startup process analysis, it was analyzed that the load Wsgi app was first instantiated by Load_paste_app function Loader class in oslo_service.wsgi.py, returning a loader object. The Load_app function of the loader object is then called to implement.
def Load_paste_app (app_name): """ Builds and returns a WSGI app from a paste config file. :p Aram App_name:name of the application to load """ = Wsgi. Loader (CFG. CONF) = Loader.load_app (app_name) return app
classLoader (object):defLoad_app (self, name):"""Return The Paste UrlMap wrapped WSGI application. :p Aram Name:name of the application to load. : Returns:paste UrlMap Object wrapping the requested application. : Raises:pasteappnotfound""" Try: Log.debug ("Loading app% (name) s from% (path) s", {'name': Name,'Path': Self.config_path}) returnDeploy.loadapp ("config:%s"% Self.config_path, name=name)#Call the Loadapp function of the third-party library Paste.deploy to load the Wsgi_app and return exceptLookupError:LOG.exception ("couldn ' t lookup app:%s", name)RaisePasteappnotfound (Name=name, Path=self.config_path)
The following analysis of the Paste.deploy configuration file (that is, Self.config_path), the profile defaults to Api-paste.ini.
[Composite:neutron]use= Egg:paste#UrlMap/: Neutronversions_composite/v2.0:neutronapi_v2_0[composite:neutronapi_v2_0]use = Call:neutron.auth:pipeline_factorynoauth = cors http_proxy_to_wsgi request_id catch_errors Extensions Neutronapiapp_v2_0keystone = cors http_proxy_to_wsgi request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0[ Composite:neutronversions_composite]use=Call:neutron.auth:pipeline_factorynoauth=cors Http_proxy_to_wsgi Neutronversionskeystone=cors Http_proxy_to_wsgi neutronversions[filter:request_id]paste.filter_factory=oslo_middleware:requestid.factory[filter:catch_errors]paste.filter_factory=oslo_middleware:catcherrors.factory[filter:cors]paste.filter_factory=Oslo_middleware.cors:filter_factoryoslo_config_project=neutron[filter:http_proxy_to_wsgi]paste.filter_factory=oslo_middleware.http_proxy_to_wsgi:httpproxytowsgi.factory[filter:keystonecontext]paste.filter_factory =neutron.auth:neutronkeystonecontext.factory[filter:authtoken]paste.filter_factory=keystonemiddleware.auth_token:filter_factory[filter:extensions]paste.filter_factory=neutron.api.extensions:plugin_aware_extension_middleware_factory[app:neutronversions]paste.app_factory =neutron.api.versions:versions.factory[app:neutronapiapp_v2_0]paste.app_factory=neutron.api.v2.router:apirouter.factory[filter:osprofiler]paste.filter_factory= Osprofiler.web:WsgiMiddleware.factory
This only analyzes the processing flow of the Api-paste.ini, please refer to the other documentation for the syntax of the paste configuration file. App_name is the entry for the configuration file, and the app_name is passed to neutron in the Neutronapiservice.create function. Here neutron composite uses PASTE.URLMAP to construct the Wsgi app:
- URL is '/': handled by Neutronversions_composite;
- The URL is '/v2.0 ': Handled by NEUTRONAPI_V2_0.
Neutronversions_composite's handling is simple and returns information about the neutron API version in the response body. The following focuses on the analysis of Neutronapi_v2_0.
== = cors Http_proxy_to_wsgi request_id catch_errors authtoken keystonecontext Extensions Neutronapiapp_v2_0
Use specifies that the function to be called is/neutron/auth.py pipeline_factory. Noauth and Keystone Pass in the function as a parameter local_conf (dict).
defPipeline_factory (loader, global_conf, * *local_conf):"""Create A paste pipeline based on the ' auth_strategy ' config option."""Pipeline= Local_conf[cfg. Conf.auth_strategy]#whether the Auth_strategy setting in the configuration file requires authentication token (password)Pipeline = Pipeline.split ()#List Pipeline:strfilters = [Loader.get_filter (n) forNinchPIPELINE[:-1]]#Get all the filters (exclude the last neutronapiapp_v2_0 as it is the app), form listApp = Loader.get_app (Pipeline[-1])#The class called in Neutronapiapp_v2_0 (Apirouter) is initialized in this step, and the next section analyzesFilters.reverse ()#Reverse Filters list, the filter closest to Apirouter is executed first, that is, the first one that executes the extensions filter forFilterinchFilters:app= Filter (APP)#Pass the app as a parameter to each filter in turn returnApp
The auth_strategy in the configuration file defaults to Keystone, which means that tokens must be validated by default. The following focuses on the analysis of App:neutronapiapp_v2_0 and Filter:extensions.
1.neutronapiapp_v2_0
= Neutron.api.v2.router:APIRouter.factory
Call the factory method of Apirouter in/neutron/api/v2/router.py directly:
class Apirouter (Base_wsgi. Router): @classmethod def Factory (CLS, Global_config, * *local_config) : return CLS (* *local_config )def__init__(self, * *local_config): ......
The factory method of Apirouter is a classmethod that calls the constructor of Apirouter directly, initializes the Apirouter, which is analyzed in the next section.
2.extensions
= Neutron.api.extensions:plugin_aware_extension_middleware_factory
Extensions filter directly calls the Plugin_aware_extension_middleware_factory method in/neutron/api/extensions.py:
def plugin_aware_extension_middleware_factory (global_config, * *local_config) :"" " Paste Factory. """ def _factory (APP): = pluginawareextensionmanager.get_instance () return extensionmiddleware (app, ext_mgr= ext_mgr) return _factory
The function contains only one _factory function, which first obtains an instance of Pluginawareextensionmanager, which is an implementation of a singleton pattern, initialized at Apirouter initialization, and analyzed in the next section. Next, the constructor that initializes the extensionmiddleware,extensionmiddleware with Ext_mgr as a parameter is primarily to map resource in extensions, The top resource (network, subnet, and port) will map in the Apirouter constructor and will be analyzed in the next section.
Ocata Neutron Code Analysis (iv)--api-paste.ini analysis