分享

仿Openstack的WSGI接口及RESTul服务实现(python)

pig2 发表于 2014-8-8 21:42:43 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 9977
问题导读:
1.Openstack的WSGI接口通过什么实现了Controller类,和Router类?
2.这里测试程序主要测试什么功能?
3.测试的目的是什么?






Openstack的WSGI接口通过webob,pastedeploy,routes实现了Controller类,和Router类,这里仿照Openstack的WSG接口实现简单的测试程序

首先是testroutes.py文件

  1. import logging
  2. import os
  3. import webob.dec  
  4. import webob.exc
  5. from paste.deploy import loadapp
  6. from wsgiref.simple_server import make_server  
  7. import routes.middleware  
  8. # Environment variable used to pass the request context
  9. CONTEXT_ENV = 'openstack.context'
  10. # Environment variable used to pass the request params
  11. PARAMS_ENV = 'openstack.params'
  12. LOG = logging.getLogger(__name__)
  13. class Controller(object):
  14.     @webob.dec.wsgify
  15.     def __call__(self, req):
  16.         arg_dict = req.environ['wsgiorg.routing_args'][1]
  17.         action = arg_dict.pop('action')
  18.         del arg_dict['controller']
  19.         context = req.environ.get(CONTEXT_ENV, {})
  20.         context['query_string'] = dict(req.params.iteritems())
  21.         context['headers'] = dict(req.headers.iteritems())
  22.         context['path'] = req.environ['PATH_INFO']
  23.         params = req.environ.get(PARAMS_ENV, {})
  24.         for name in ['REMOTE_USER', 'AUTH_TYPE']:
  25.             try:
  26.                 context[name] = req.environ[name]
  27.             except KeyError:
  28.                 try:
  29.                     del context[name]
  30.                 except KeyError:
  31.                     pass
  32.         params.update(arg_dict)
  33.         # TODO(termie): do some basic normalization on methods
  34.         method = getattr(self, action)
  35.         
  36.         result = method(context, **params)
  37.         
  38.         return webob.Response('OK')
  39.    
  40.     def getMessage(self,context, user_id):
  41.         return {'Message': 'TestMessage'}
  42.         pass
  43.         
  44. class Router(object):  
  45.     def __init__(self):  
  46.         self._mapper = routes.Mapper()  
  47.         self._mapper.connect('/test/{user_id}',
  48.                             controller=Controller(),
  49.                             action='getMessage',
  50.                             conditions={'method': ['GET']})
  51.         
  52.         self._router = routes.middleware.RoutesMiddleware(self._dispatch, self._mapper)
  53.      
  54.     @webob.dec.wsgify  
  55.     def __call__(self, req):
  56.         return self._router
  57.    
  58.     @staticmethod  
  59.     @webob.dec.wsgify  
  60.     def _dispatch(req):
  61.         match = req.environ['wsgiorg.routing_args'][1]  
  62.                      
  63.         if not match:  
  64.             return webob.exc.HTTPNotFound()  
  65.               
  66.         app = match['controller']
  67.         return app
  68.    
  69.     @classmethod
  70.     def app_factory(cls, global_config, **local_config):   
  71.         return cls()
  72.         
  73. if __name__ == '__main__':
  74.     configfile='testroutes.ini'
  75.     appname="main"
  76.     wsgi_app = loadapp("config:%s" % os.path.abspath(configfile), appname)  
  77.     httpd = make_server('localhost', 8282, wsgi_app)  
  78.     httpd.serve_forever()
复制代码
由此可见,ini文件按照pastedeploy的模式配置了根目录/,指向pipeline show,pipeline又指向app root。app下指向的是Router的app_factory函数,返回的是Router().根据调用过程,初始化__init__->__call__返回self._routers.根据__init__下写的映射规则,能识别类似/test/123这样的路径,其处理函数调用"Controller"的"action"函数,也就是getMessage。


测试运行,在浏览器下输入127.0.0,1:8282/test/123

返回OK,如
  1. return webob.Response('OK')  
复制代码

测试完毕。


bluefire1991

2013.11.2

19:59:12


没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条