From 1b3d8c76e5b05d4790c0ab3c8bd5a7cca5bec81e Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 8 Aug 2011 00:31:31 +0100 Subject: [PATCH] Adding support for expressing format through Content-Type header Adding action detail for port resource (Member & Collection) --- quantum/api/__init__.py | 2 ++ quantum/api/ports.py | 49 +++++++++++++++++++++++++++----------- quantum/api/views/ports.py | 20 +++++----------- quantum/common/wsgi.py | 11 +++++++-- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/quantum/api/__init__.py b/quantum/api/__init__.py index 6abb6bed7..bee703a4c 100644 --- a/quantum/api/__init__.py +++ b/quantum/api/__init__.py @@ -58,6 +58,8 @@ class APIRouterV01(wsgi.Router): path_prefix=uri_prefix) mapper.resource('port', 'ports', controller=ports.Controller(plugin), + collection={'detail': 'GET'}, + member={'detail': 'GET'}, parent_resource=dict(member_name='network', collection_name=uri_prefix +\ 'networks')) diff --git a/quantum/api/ports.py b/quantum/api/ports.py index 9255a26e3..3b95e2d93 100644 --- a/quantum/api/ports.py +++ b/quantum/api/ports.py @@ -36,7 +36,9 @@ class Controller(common.QuantumController): _serialization_metadata = { "application/xml": { "attributes": { - "port": ["id", "state"], }, + "port": ["id", "state"], + "attachment": ["id"] + }, "plurals": {"ports": "port"} }, } @@ -45,35 +47,54 @@ class Controller(common.QuantumController): self._resource_name = 'port' super(Controller, self).__init__(plugin) - def index(self, request, tenant_id, network_id): - """ Returns a list of port ids for a given network """ - return self._items(request, tenant_id, network_id, is_detail=False) - - def _items(self, request, tenant_id, network_id, is_detail): - """ Returns a list of networks. """ + def _items(self, request, tenant_id, network_id, + port_details=False): + """ Returns a list of ports. """ try: ports = self._plugin.get_all_ports(tenant_id, network_id) builder = ports_view.get_view_builder(request) - result = [builder.build(port, is_detail)['port'] + result = [builder.build(port, port_details)['port'] for port in ports] return dict(ports=result) except exception.NetworkNotFound as e: return faults.Fault(faults.NetworkNotFound(e)) + + def _item(self, request, tenant_id, network_id, port_id, + att_details=False): + """ Returns a specific port. """ + port = self._plugin.get_port_details( + tenant_id, network_id, port_id) + builder = ports_view.get_view_builder(request) + result = builder.build(port, port_details=True, + att_details=att_details)['port'] + return dict(port=result) + + def index(self, request, tenant_id, network_id): + """ Returns a list of port ids for a given network """ + return self._items(request, tenant_id, network_id, port_details=False) def show(self, request, tenant_id, network_id, id): """ Returns port details for given port and network """ try: - port = self._plugin.get_port_details( - tenant_id, network_id, id) - builder = ports_view.get_view_builder(request) - #build response with details - result = builder.build(port, True)['port'] - return dict(port=result) + return self._item(request, tenant_id, network_id, id) except exception.NetworkNotFound as e: return faults.Fault(faults.NetworkNotFound(e)) except exception.PortNotFound as e: return faults.Fault(faults.PortNotFound(e)) + def detail(self, request, **kwargs): + tenant_id = kwargs.get('tenant_id') + network_id = kwargs.get('network_id') + port_id = kwargs.get('id') + if port_id: + # show details for a given network + return self._item(request, tenant_id, + network_id, port_id, att_details=True) + else: + # show details for all port + return self._items(request, tenant_id, + network_id, port_details=True) + def create(self, request, tenant_id, network_id): """ Creates a new port for a given network """ #look for port state in request diff --git a/quantum/api/views/ports.py b/quantum/api/views/ports.py index b743888ce..747ce1442 100644 --- a/quantum/api/views/ports.py +++ b/quantum/api/views/ports.py @@ -29,19 +29,11 @@ class ViewBuilder(object): """ self.base_url = base_url - def build(self, port_data, is_detail=False): + def build(self, port_data, port_details=False, att_details=False): """Generic method used to generate a port entity.""" - if is_detail: - port = self._build_detail(port_data) - else: - port = self._build_simple(port_data) + port = dict(port=dict(id=port_data['port-id'])) + if port_details: + port['port']['state'] = port_data['port-state'] + if att_details and port_data['attachment-id']: + port['attachment'] = dict(id=port_data['attachment-id']) return port - - def _build_simple(self, port_data): - """Return a simple model of a port.""" - return dict(port=dict(id=port_data['port-id'])) - - def _build_detail(self, port_data): - """Return a simple model of a port (with its state).""" - return dict(port=dict(id=port_data['port-id'], - state=port_data['port-state'])) diff --git a/quantum/common/wsgi.py b/quantum/common/wsgi.py index ca9734e87..c6d66fa71 100644 --- a/quantum/common/wsgi.py +++ b/quantum/common/wsgi.py @@ -122,14 +122,21 @@ class Request(webob.Request): Based on the query extension then the Accept header. """ + # First lookup http request parts = self.path.rsplit('.', 1) LOG.debug("Request parts:%s", parts) if len(parts) > 1: format = parts[1] if format in ['json', 'xml']: return 'application/{0}'.format(parts[1]) - + + #Then look up content header + type_from_header = self.get_content_type() + if type_from_header: + return type_from_header ctypes = ['application/json', 'application/xml'] + + #Finally search in Accept-* headers bm = self.accept.best_match(ctypes) return bm or 'application/json' @@ -143,7 +150,7 @@ class Request(webob.Request): if type in allowed_types: return type LOG.debug(_("Wrong Content-Type: %s") % type) - raise webob.exc.HTTPBadRequest("Invalid content type") + return None class Application(object): -- 2.45.2