模擬openstack中的WSGI,先看一下運行過程當中的調用順序:python
[root@jeguan-ctrl-01 WSGI]# python wsgi.py Router app_factory Router __init__ Router __call__ Router _dispatch Router match = {'action': u'getMessage', 'controller': <wsgi.Controller object at 0x17965d0>, 'user_id': u'123'} Controller __call__ Controller action = getMessage Controller params = {} Controller method = <bound method Controller.getMessage of <wsgi.Controller object at 0x17965d0>> Controller getMessage Controller result = {'Message': 'TestMessage'}
import logging import os import webob.dec import webob.exc from paste.deploy import loadapp from wsgiref.simple_server import make_server import routes.middleware # Environment variable used to pass the request context CONTEXT_ENV = 'openstack.context' # Environment variable used to pass the request params PARAMS_ENV = 'openstack.params' LOG = logging.getLogger(__name__) class Controller(object): @webob.dec.wsgify def __call__(self, req): print "Controller __call__" arg_dict = req.environ['wsgiorg.routing_args'][1] action = arg_dict.pop('action') print "Controller action = %s" % action del arg_dict['controller'] context = req.environ.get(CONTEXT_ENV, {}) context['query_string'] = dict(req.params.iteritems()) context['headers'] = dict(req.headers.iteritems()) context['path'] = req.environ['PATH_INFO'] params = req.environ.get(PARAMS_ENV, {}) print "Controller params = %s" % params for name in ['REMOTE_USER', 'AUTH_TYPE']: try: context[name] = req.environ[name] except KeyError: try: del context[name] except KeyError: pass params.update(arg_dict) # TODO(termie): do some basic normalization on methods method = getattr(self, action) print "Controller method = %s" % method result = method(context, **params) print "Controller result = %s" % result return webob.Response('OK') def getMessage(self,context, user_id): print "Controller getMessage" return {'Message': 'TestMessage'} pass class Router(object): def __init__(self): print "Router __init__" self._mapper = routes.Mapper() self._mapper.connect('/test/{user_id}', controller=Controller(), action='getMessage', conditions={'method': ['GET']}) self._router = routes.middleware.RoutesMiddleware(self._dispatch, self._mapper) @webob.dec.wsgify def __call__(self, req): print "Router __call__" return self._router @staticmethod @webob.dec.wsgify def _dispatch(req): print "Router _dispatch" match = req.environ['wsgiorg.routing_args'][1] print "Router match = %s" % match if not match: return webob.exc.HTTPNotFound() app = match['controller'] return app @classmethod def app_factory(cls, global_config, **local_config): print "Router app_factory" return cls() if __name__ == '__main__': """ Openstack WSGI interface: create a "Controller" and "Router" class with webob,pastedeploy,routes. Test case for Openstack WSGI. """ configfile='testpaste.ini' appname="main" wsgi_app = loadapp("config:%s" % os.path.abspath(configfile), appname)
[DEFAULT] name=guan [composite:main] use=egg:Paste#urlmap /=show [pipeline:show] pipeline = root [app:root] paste.app_factory = wsgi:Router.app_factory
從testpaste.init能夠看出,程序的入口處:web
wsgi:Router.app_factory