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 aws
class ApiVersionRouter(wsgi.Router):
class APIVersionRouter(wsgi.Router):
"""Routes top-level requests to the appropriate API."""
def __init__(self):
mapper = routes.Mapper()
mapper.connect(None, "/v1.0/{path_info:.*}", controller="rs")
mapper.connect(None, "/ec2/{path_info:.*}", controller="ec2")
rsapi = rackspace.API()
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):
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, targets)
super(API, self).__init__(mapper)
@webob.dec.wsgify
def dummy(self, req):

View File

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

View File

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

View File

@@ -140,34 +140,31 @@ class Router(object):
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.
Each route in `mapper` must specify a 'controller' string, which is
a key into the 'targets' dictionary whose value is a WSGI app to
run. If routing to a wsgi.Controller, you'll want to specify
'action' as well so the controller knows what method to call on
itself.
Each route in `mapper` must specify a 'controller', which is a
WSGI app to call. You'll probably want to specify an 'action' as
well and have your controller be a wsgi.Controller, who will route
the request to the action method.
Examples:
mapper = routes.Mapper()
targets = { "servers": ServerController(), "blog": BlogWsgiApp() }
sc = ServerController()
# 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
mapper.resource("server", "servers")
# Actions are all implicitly defined
mapper.resource("server", "servers", controller=sc)
# Pointing to an arbitrary WSGI app. You can specify the
# {path_info:.*} parameter so the target app can be handed just that
# 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.targets = targets
self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map)
@@ -186,31 +183,32 @@ class Router(object):
and putting the information into req.environ. Either returns 404
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]
app_name = match['controller']
app = self.targets[app_name]
if not match:
return webob.exc.HTTPNotFound()
app = match['controller']
return app
class Controller(object):
"""
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
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]
action = routes_dict['action']
arg_dict = req.environ['wsgiorg.routing_args'][1]
action = arg_dict['action']
method = getattr(self, action)
del routes_dict['controller']
del routes_dict['action']
return method(**routes_dict)
del arg_dict['controller']
del arg_dict['action']
arg_dict['req'] = req
return method(**arg_dict)
class Serializer(object):