All controller actions receive a 'req' parameter containing the webob Request.

This commit is contained in:
Michael Gundlach
2010-08-16 13:22:41 -04:00
parent 5c4a806c85
commit f78a8936b1
5 changed files with 40 additions and 47 deletions

View File

@@ -36,16 +36,16 @@ import routes
from nova.endpoint import rackspace from nova.endpoint import rackspace
from nova.endpoint import aws from nova.endpoint import aws
class ApiVersionRouter(wsgi.Router): class APIVersionRouter(wsgi.Router):
"""Routes top-level requests to the appropriate API.""" """Routes top-level requests to the appropriate API."""
def __init__(self): def __init__(self):
mapper = routes.Mapper() mapper = routes.Mapper()
mapper.connect(None, "/v1.0/{path_info:.*}", controller="rs") rsapi = rackspace.API()
mapper.connect(None, "/ec2/{path_info:.*}", controller="ec2") mapper.connect(None, "/v1.0/{path_info:.*}", controller=rsapi)
targets = {"rs": rackspace.Api(), "ec2": aws.Api()} mapper.connect(None, "/ec2/{path_info:.*}", controller=aws.API())
super(ApiVersionRouter, self).__init__(mapper, targets) super(APIVersionRouter, self).__init__(mapper)

View File

@@ -10,11 +10,9 @@ class API(wsgi.Router):
def __init__(self): def __init__(self):
mapper = routes.Mapper() mapper = routes.Mapper()
mapper.connect(None, "{all:.*}", controller="dummy") mapper.connect(None, "{all:.*}", controller=self.dummy)
targets = {"dummy": self.dummy } super(API, self).__init__(mapper)
super(API, self).__init__(mapper, targets)
@webob.dec.wsgify @webob.dec.wsgify
def dummy(self, req): def dummy(self, req):

View File

@@ -75,16 +75,13 @@ class APIRouter(wsgi.Router):
def __init__(self): def __init__(self):
mapper = routes.Mapper() mapper = routes.Mapper()
mapper.resource("server", "servers") mapper.resource("server", "servers",
mapper.resource("image", "images") controller=controllers.ServersController())
mapper.resource("flavor", "flavors") mapper.resource("image", "images",
mapper.resource("sharedipgroup", "sharedipgroups") controller=controllers.ImagesController())
mapper.resource("flavor", "flavors",
controller=controllers.FlavorsController())
mapper.resource("sharedipgroup", "sharedipgroups",
controller=controllers.SharedIpGroupsController())
targets = { super(APIRouter, self).__init__(mapper)
'servers': controllers.ServersController(),
'images': controllers.ImagesController(),
'flavors': controllers.FlavorsController(),
'sharedipgroups': controllers.SharedIpGroupsController()
}
super(APIRouter, self).__init__(mapper, targets)

View File

@@ -5,7 +5,7 @@ from nova.endpoint.rackspace.controllers.base import BaseController
class ServersController(BaseController): class ServersController(BaseController):
entity_name = 'servers' entity_name = 'servers'
def index(cls): def index(self, **kwargs):
return [instance_details(inst) for inst in compute.InstanceDirectory().all] return [instance_details(inst) for inst in compute.InstanceDirectory().all]
def show(self, **kwargs): def show(self, **kwargs):

View File

@@ -140,34 +140,31 @@ class Router(object):
WSGI middleware that maps incoming requests to WSGI apps. WSGI middleware that maps incoming requests to WSGI apps.
""" """
def __init__(self, mapper, targets): def __init__(self, mapper):
""" """
Create a router for the given routes.Mapper. Create a router for the given routes.Mapper.
Each route in `mapper` must specify a 'controller' string, which is Each route in `mapper` must specify a 'controller', which is a
a key into the 'targets' dictionary whose value is a WSGI app to WSGI app to call. You'll probably want to specify an 'action' as
run. If routing to a wsgi.Controller, you'll want to specify well and have your controller be a wsgi.Controller, who will route
'action' as well so the controller knows what method to call on the request to the action method.
itself.
Examples: Examples:
mapper = routes.Mapper() mapper = routes.Mapper()
targets = { "servers": ServerController(), "blog": BlogWsgiApp() } sc = ServerController()
# Explicit mapping of one route to a controller+action # Explicit mapping of one route to a controller+action
mapper.connect(None, "/svrlist", controller="servers", action="list") mapper.connect(None, "/svrlist", controller=sc, action="list")
# Controller string is implicitly equal to 2nd param here, and # Actions are all implicitly defined
# actions are all implicitly defined mapper.resource("server", "servers", controller=sc)
mapper.resource("server", "servers")
# Pointing to an arbitrary WSGI app. You can specify the # Pointing to an arbitrary WSGI app. You can specify the
# {path_info:.*} parameter so the target app can be handed just that # {path_info:.*} parameter so the target app can be handed just that
# section of the URL. # section of the URL.
mapper.connect(None, "/v1.0/{path_info:.*}", controller="blog") mapper.connect(None, "/v1.0/{path_info:.*}", controller=BlogApp())
""" """
self.map = mapper self.map = mapper
self.targets = targets
self._router = routes.middleware.RoutesMiddleware(self._dispatch, self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map) self.map)
@@ -186,31 +183,32 @@ class Router(object):
and putting the information into req.environ. Either returns 404 and putting the information into req.environ. Either returns 404
or the routed WSGI app's response. or the routed WSGI app's response.
""" """
if req.environ['routes.route'] is None:
return webob.exc.HTTPNotFound()
match = req.environ['wsgiorg.routing_args'][1] match = req.environ['wsgiorg.routing_args'][1]
app_name = match['controller'] if not match:
return webob.exc.HTTPNotFound()
app = self.targets[app_name] app = match['controller']
return app return app
class Controller(object): class Controller(object):
""" """
WSGI app that reads routing information supplied by RoutesMiddleware WSGI app that reads routing information supplied by RoutesMiddleware
and calls the requested action method on itself. and calls the requested action method upon itself. All action methods
must, in addition to their normal parameters, accept a 'req' argument
which is the incoming webob.Request.
""" """
@webob.dec.wsgify @webob.dec.wsgify
def __call__(self, req): def __call__(self, req):
""" """
Call the method on self specified in req.environ by RoutesMiddleware. Call the method specified in req.environ by RoutesMiddleware.
""" """
routes_dict = req.environ['wsgiorg.routing_args'][1] arg_dict = req.environ['wsgiorg.routing_args'][1]
action = routes_dict['action'] action = arg_dict['action']
method = getattr(self, action) method = getattr(self, action)
del routes_dict['controller'] del arg_dict['controller']
del routes_dict['action'] del arg_dict['action']
return method(**routes_dict) arg_dict['req'] = req
return method(**arg_dict)
class Serializer(object): class Serializer(object):