From 963ece6feac200151b35df2efa0df4b1c75f1763 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Thu, 6 Jan 2011 13:18:17 -0500 Subject: Add factories into the wsgi classes. --- nova/wsgi.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/nova/wsgi.py b/nova/wsgi.py index b5d6b96c1..5ecc21eed 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -63,10 +63,20 @@ class Server(object): class Application(object): -# TODO(gundlach): I think we should toss this class, now that it has no -# purpose. """Base WSGI application wrapper. Subclasses need to implement __call__.""" + @classmethod + def factory(cls, global_config, **local_config): + """Used for paste app factories in paste.deploy config fles.""" + rv = cls() + for k,v in local_config.iteritems(): + if hasattr(rv, k): + setattr(rv, k, v) + else: + logging.debug(_("Unknown local config option %s for %s"), + k, cls) + return rv + def __call__(self, environ, start_response): r"""Subclasses will probably want to implement __call__ like this: @@ -111,6 +121,20 @@ class Middleware(Application): behavior. """ + @classmethod + def factory(cls, global_config, **local_config): + """Used for paste app factories in paste.deploy config fles.""" + def _factory(app): + rv = cls(app) + for k,v in local_config.iteritems(): + if hasattr(rv, k): + setattr(rv, k, v) + else: + logging.debug(_("Unknown local config option %s for %s"), + k, cls) + return rv + return _factory + def __init__(self, application): # pylint: disable-msg=W0231 self.application = application -- cgit From 4e034f3d69c6aba6920dd7dd38e07aeb495b45db Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Thu, 6 Jan 2011 13:57:48 -0500 Subject: Remove module-level factory methods in favor of having a factory class-method on wsgi components themselves. Local options from config are passed to the __init__ method of the component as kwargs. --- etc/nova-api.conf | 26 ++++++------ nova/api/ec2/__init__.py | 36 +---------------- nova/api/ec2/metadatarequesthandler.py | 7 +--- nova/api/openstack/__init__.py | 19 +++------ nova/api/openstack/auth.py | 6 --- nova/api/openstack/ratelimiting/__init__.py | 6 --- nova/wsgi.py | 62 ++++++++++++++++++++--------- 7 files changed, 66 insertions(+), 96 deletions(-) diff --git a/etc/nova-api.conf b/etc/nova-api.conf index 59b21f387..43597b96d 100644 --- a/etc/nova-api.conf +++ b/etc/nova-api.conf @@ -26,30 +26,30 @@ pipeline = authenticate cloudrequest authorizer ec2executor pipeline = authenticate adminrequest authorizer ec2executor [filter:ec2lockout] -paste.filter_factory = nova.api.ec2:lockout_factory +paste.filter_factory = nova.api.ec2:Lockout.factory [filter:authenticate] -paste.filter_factory = nova.api.ec2:authenticate_factory +paste.filter_factory = nova.api.ec2:Authenticate.factory [filter:cloudrequest] controller = nova.api.ec2.cloud.CloudController -paste.filter_factory = nova.api.ec2:requestify_factory +paste.filter_factory = nova.api.ec2:Requestify.factory [filter:adminrequest] controller = nova.api.ec2.admin.AdminController -paste.filter_factory = nova.api.ec2:requestify_factory +paste.filter_factory = nova.api.ec2:Requestify.factory [filter:authorizer] -paste.filter_factory = nova.api.ec2:authorizer_factory +paste.filter_factory = nova.api.ec2:Authorizer.factory [app:ec2executor] -paste.app_factory = nova.api.ec2:executor_factory +paste.app_factory = nova.api.ec2:Executor.factory [app:ec2versions] -paste.app_factory = nova.api.ec2:versions_factory +paste.app_factory = nova.api.ec2:Versions.factory [app:ec2metadata] -paste.app_factory = nova.api.ec2.metadatarequesthandler:metadata_factory +paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory ############# # Openstack # @@ -64,19 +64,19 @@ use = egg:Paste#urlmap pipeline = faultwrap auth ratelimit osapi [filter:faultwrap] -paste.filter_factory = nova.api.openstack:fault_wrapper_factory +paste.filter_factory = nova.api.openstack:FaultWrapper.factory [filter:auth] -paste.filter_factory = nova.api.openstack.auth:auth_factory +paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory [filter:ratelimit] -paste.filter_factory = nova.api.openstack.ratelimiting:ratelimit_factory +paste.filter_factory = nova.api.openstack.ratelimiting:RateLimitingMiddleware.factory [app:osapi] -paste.app_factory = nova.api.openstack:router_factory +paste.app_factory = nova.api.openstack:APIRouter.factory [pipeline:osversions] pipeline = faultwrap osversionapp [app:osversionapp] -paste.app_factory = nova.api.openstack:versions_factory +paste.app_factory = nova.api.openstack:Versions.factory diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index dfa919e07..0836c3411 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -146,9 +146,9 @@ class Authenticate(wsgi.Middleware): class Requestify(wsgi.Middleware): - def __init__(self, app, controller_name): + def __init__(self, app, controller): super(Requestify, self).__init__(app) - self.controller = utils.import_class(controller_name)() + self.controller = utils.import_class(controller)() @webob.dec.wsgify def __call__(self, req): @@ -306,35 +306,3 @@ class Versions(wsgi.Application): '2009-04-04', ] return ''.join('%s\n' % v for v in versions) - - -def authenticate_factory(global_args, **local_args): - def authenticator(app): - return Authenticate(app) - return authenticator - - -def authorizer_factory(global_args, **local_args): - def authorizer(app): - return Authorizer(app) - return authorizer - - -def executor_factory(global_args, **local_args): - return Executor() - - -def versions_factory(global_args, **local_args): - return Versions() - - -def requestify_factory(global_args, **local_args): - def requestifier(app): - return Requestify(app, local_args['controller']) - return requestifier - - -def lockout_factory(global_args, **local_args): - def locksmith(app): - return Lockout(app) - return locksmith diff --git a/nova/api/ec2/metadatarequesthandler.py b/nova/api/ec2/metadatarequesthandler.py index a57a6698a..9067568a4 100644 --- a/nova/api/ec2/metadatarequesthandler.py +++ b/nova/api/ec2/metadatarequesthandler.py @@ -24,13 +24,14 @@ import webob.dec import webob.exc from nova import flags +from nova import wsgi from nova.api.ec2 import cloud FLAGS = flags.FLAGS -class MetadataRequestHandler(object): +class MetadataRequestHandler(wsgi.Application): """Serve metadata from the EC2 API.""" def print_data(self, data): @@ -79,7 +80,3 @@ class MetadataRequestHandler(object): if data is None: raise webob.exc.HTTPNotFound() return self.print_data(data) - - -def metadata_factory(global_args, **local_args): - return MetadataRequestHandler() diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 21b9b1d7d..76e3aeed9 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -62,6 +62,11 @@ class APIRouter(wsgi.Router): and method. """ + @classmethod + def factory(cls, global_config, **local_config): + """Simple paste factory, :class:`nova.wsgi.Router` doesn't have one""" + return cls() + def __init__(self): mapper = routes.Mapper() @@ -105,17 +110,3 @@ class Versions(wsgi.Application): "application/xml": { "attributes": dict(version=["status", "id"])}} return wsgi.Serializer(req.environ, metadata).to_content_type(response) - - -def router_factory(global_cof, **local_conf): - return APIRouter() - - -def versions_factory(global_conf, **local_conf): - return Versions() - - -def fault_wrapper_factory(global_conf, **local_conf): - def fwrap(app): - return FaultWrapper(app) - return fwrap diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 00e817c8d..1dfdd5318 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -134,9 +134,3 @@ class AuthMiddleware(wsgi.Middleware): token = self.db.auth_create_token(ctxt, token_dict) return token, user return None, None - - -def auth_factory(global_conf, **local_conf): - def auth(app): - return AuthMiddleware(app) - return auth diff --git a/nova/api/openstack/ratelimiting/__init__.py b/nova/api/openstack/ratelimiting/__init__.py index 81b83142f..cbb4b897e 100644 --- a/nova/api/openstack/ratelimiting/__init__.py +++ b/nova/api/openstack/ratelimiting/__init__.py @@ -219,9 +219,3 @@ class WSGIAppProxy(object): # No delay return None return float(resp.getheader('X-Wait-Seconds')) - - -def ratelimit_factory(global_conf, **local_conf): - def rl(app): - return RateLimitingMiddleware(app) - return rl diff --git a/nova/wsgi.py b/nova/wsgi.py index 5ecc21eed..aa8f315d6 100644 --- a/nova/wsgi.py +++ b/nova/wsgi.py @@ -67,15 +67,28 @@ class Application(object): @classmethod def factory(cls, global_config, **local_config): - """Used for paste app factories in paste.deploy config fles.""" - rv = cls() - for k,v in local_config.iteritems(): - if hasattr(rv, k): - setattr(rv, k, v) - else: - logging.debug(_("Unknown local config option %s for %s"), - k, cls) - return rv + """Used for paste app factories in paste.deploy config fles. + + Any local configuration (that is, values under the [app:APPNAME] + section of the paste config) will be passed into the `__init__` method + as kwargs. + + A hypothetical configuration would look like: + + [app:wadl] + latest_version = 1.3 + paste.app_factory = nova.api.fancy_api:Wadl.factory + + which would result in a call to the `Wadl` class as + + import nova.api.fancy_api + fancy_api.Wadl(latest_version='1.3') + + You could of course re-implement the `factory` method in subclasses, + but using the kwarg passing it shouldn't be necessary. + + """ + return cls(**local_config) def __call__(self, environ, start_response): r"""Subclasses will probably want to implement __call__ like this: @@ -123,16 +136,29 @@ class Middleware(Application): @classmethod def factory(cls, global_config, **local_config): - """Used for paste app factories in paste.deploy config fles.""" + """Used for paste app factories in paste.deploy config fles. + + Any local configuration (that is, values under the [filter:APPNAME] + section of the paste config) will be passed into the `__init__` method + as kwargs. + + A hypothetical configuration would look like: + + [filter:analytics] + redis_host = 127.0.0.1 + paste.filter_factory = nova.api.analytics:Analytics.factory + + which would result in a call to the `Analytics` class as + + import nova.api.analytics + analytics.Analytics(app_from_paste, redis_host='127.0.0.1') + + You could of course re-implement the `factory` method in subclasses, + but using the kwarg passing it shouldn't be necessary. + + """ def _factory(app): - rv = cls(app) - for k,v in local_config.iteritems(): - if hasattr(rv, k): - setattr(rv, k, v) - else: - logging.debug(_("Unknown local config option %s for %s"), - k, cls) - return rv + return cls(app, **local_config) return _factory def __init__(self, application): # pylint: disable-msg=W0231 -- cgit