• Ceilometer RESTful框架


    ceilometer-api使用pecan和flask来构建restful api,这里简单介绍一下pecan和flask的使用。

    ceilomter-api服务启动流程

    /usr/bin/ceilometer-api

    ...
    from ceilometer.cli import api
    
    if __name__ == "__main__":
        sys.exit(api())
    ...

    /usr/lib/python2.6/site-packages/ceilometer/cli.py

    ...
    def api(): service.prepare_service() srv = app.build_server() srv.serve_forever()
    ...

    /usr/lib/python2.6/site-packages/ceilometer/api/app.py

    ...
    def build_server(): # Build the WSGI app root = VersionSelectorApplication() # Create the WSGI server and start it host, port = cfg.CONF.api.host, cfg.CONF.api.port server_cls = get_server_cls(host) srv = simple_server.make_server(host, port, root, server_cls)
    ...
    ...
    class VersionSelectorApplication(object): def __init__(self): pc = get_pecan_config() pc.app.debug = CONF.debug pc.app.enable_acl = (CONF.auth_strategy == 'keystone') if cfg.CONF.enable_v1_api: from ceilometer.api.v1 import app as v1app self.v1 = v1app.make_app(cfg.CONF, enable_acl=pc.app.enable_acl) else: def not_found(environ, start_response): start_response('404 Not Found', []) return [] self.v1 = not_found self.v2 = setup_app(pecan_config=pc) def __call__(self, environ, start_response): if environ['PATH_INFO'].startswith('/v1/'): return self.v1(environ, start_response) return self.v2(environ, start_response)
    ...

    如上图所示,ceilometer-api有两种版本即V1和V2,分别使用Flask和Pecan来构建RESTful api,其中V1在Havana已deprecated。

    Pecan 是轻量的web框架,主页http://pecan.readthedocs.org/ ,其中URL Mapping如下图:

    ceilometer使用pecan代码如下:

    /usr/lib/python2.6/site-packages/ceilometer/api/app.py

    ...
    def setup_app(pecan_config=None, extra_hooks=None): # FIXME: Replace DBHook with a hooks.TransactionHook app_hooks = [hooks.ConfigHook(), hooks.DBHook( storage.get_connection(cfg.CONF, 'metric'), storage.get_connection(cfg.CONF, 'event'), ), hooks.PipelineHook(), hooks.TranslationHook()] if extra_hooks: app_hooks.extend(extra_hooks) if not pecan_config: pecan_config = get_pecan_config() pecan.configuration.set_config(dict(pecan_config), overwrite=True) app = pecan.make_app( pecan_config.app.root, static_root=pecan_config.app.static_root, template_path=pecan_config.app.template_path, debug=CONF.debug, force_canonical=getattr(pecan_config.app, 'force_canonical', True), hooks=app_hooks, wrap_app=middleware.ParsableErrorMiddleware, guess_content_type_from_ext=False ) if getattr(pecan_config.app, 'enable_acl', True): return acl.install(app, cfg.CONF) return app
    ...

    ceilometer中pecan的配置 /usr/lib/python2.6/site-packages/ceilometer/api/config.py

    ...
    app = { 'root': 'ceilometer.api.controllers.root.RootController', 'modules': ['ceilometer.api'], 'static_root': '%(confdir)s/public', 'template_path': '%(confdir)s/ceilometer/api/templates', }
    ...

    RootController /usr/lib/python2.6/site-packages/ceilometer/api/controllers/root.py

    ...
    class RootController(object): v2 = v2.V2Controller() @pecan.expose(generic=True, template='index.html') def index(self): # FIXME: Return version information return dict()
    ...

    V2Controller包含多个Resource的Controller, /usr/lib/python2.6/site-packages/ceilometer/api/controllers/v2.py

    class V2Controller(object):
        """Version 2 API controller root."""
    
        resources = ResourcesController()
        meters = MetersController()
        samples = SamplesController()
        alarms = AlarmsController()
        event_types = EventTypesController()
        events = EventsController()
        status = StatusController()
        query = QueryController()
        capabilities = CapabilitiesController()

    下面以MetersController进行分析:/usr/lib/python2.6/site-packages/ceilometer/api/controllers/v2.py

    class MetersController(rest.RestController):
        """Works on meters."""
    
        @pecan.expose()
        def _lookup(self, meter_name, *remainder):
            return MeterController(meter_name), remainder
    
    #wsme_pecan是来自wsmeext.pecan @wsme_pecan.wsexpose([Meter], [Query]) def get_all(self, q=[]): """Return all known meters, based on the data recorded so far. :param q: Filter rules for the meters to be returned. """ #Timestamp field is not supported for Meter queries kwargs = _query_to_kwargs(q, pecan.request.metric_conn.get_meters, allow_timestamps=False) return [Meter.from_db_model(m) for m in pecan.request.metric_conn.get_meters(**kwargs)]

       这里用到了wsme和wsmeext.pecan。wsme即Web Services Made Easy,简化了REST Web服务的编写。可以运行在另一个框架的顶层,如(Cornice、Flask、Pecan)等,这里就是运行在了pecan之上来更加简单的构建restapi,用法:

    wsmeext.pecan.wsexpose(return_type, *arg_types, **options)
    

    Flask与Pecan类似,是基于Python的开源微RESTful框架,ceilometer使用Flask代码如下: /usr/lib/python2.6/site-packages/ceilometer/api/v1/app.py

    ...
    def make_app(conf, enable_acl=True, attach_storage=True, sources_file='sources.json'): app = flask.Flask('ceilometer.api') app.register_blueprint(v1_blueprint.blueprint, url_prefix='/v1') app.json_encoder = JSONEncoder try: with open(sources_file, "r") as f: sources = jsonutils.load(f) except IOError: sources = {} @app.before_request def attach_config(): flask.request.cfg = conf flask.request.sources = sources if attach_storage: @app.before_request def attach_storage(): flask.request.storage_conn = storage.get_connection(conf) # Install the middleware wrapper if enable_acl: app.wsgi_app = acl.install(app.wsgi_app, conf) return app
    ...
    app.register_blueprint 注册RESTful方法,如下图所示
    ...
    blueprint = flask.Blueprint('v1', __name__, template_folder='templates', static_folder='static') @blueprint.route('/meters') def list_meters_all(): """Return a list of meters. :param metadata.<key>: match on the metadata within the resource. (optional) """ rq = flask.request meters = rq.storage_conn.get_meters( project=acl.get_limited_to_project(rq.headers), metaquery=_get_metaquery(rq.args)) return flask.jsonify(meters=[m.as_dict() for m in meters])
    ...
  • 相关阅读:
    linux源码方式安装Apache
    linux的chmod,chown命令详解
    2011年10月18日
    mysql检查查询及索引效率方法(explain)
    php中英文字符串的研究
    2011年10月20日
    PHP JSON中文乱码解决方法大全
    解决PHP下载文件名中文乱码
    php字符串学习笔记
    CSU_BMW正式组队纪念赛出题+部分解题报告
  • 原文地址:https://www.cnblogs.com/gaozhengwei/p/7101372.html
Copyright © 2020-2023  润新知