Merge "Pecan: move fields and filters logic to hooks"

This commit is contained in:
Jenkins
2016-06-26 18:10:36 +00:00
committed by Gerrit Code Review
6 changed files with 72 additions and 17 deletions

View File

@@ -51,6 +51,7 @@ def setup_app(*args, **kwargs):
hooks.QuotaEnforcementHook(), # priority 130
hooks.NotifierHook(), # priority 135
hooks.PolicyHook(), # priority 140
hooks.QueryParametersHook(), # priority 145
]
app = pecan.make_app(

View File

@@ -17,7 +17,6 @@ import pecan
from pecan import request
from neutron._i18n import _LW
from neutron.api import api_common
from neutron import manager
from neutron.pecan_wsgi.controllers import utils
@@ -39,7 +38,7 @@ class ItemController(utils.NeutronPecanController):
def get(self, *args, **kwargs):
getter = getattr(self.plugin, 'get_%s' % self.resource)
neutron_context = request.context['neutron_context']
fields = self._build_field_list(kwargs.pop('fields', []))
fields = request.context['query_params'].get('fields')
return {self.resource: getter(neutron_context, self.item,
fields=fields)}
@@ -99,18 +98,9 @@ class CollectionsController(utils.NeutronPecanController):
return self.get(*args, **kwargs)
def get(self, *args, **kwargs):
# list request
fields = kwargs.pop('fields', [])
# if only one fields query parameter is passed, pecan will not put
# that parameter in a list, so we need to convert it into a list
fields = fields if isinstance(fields, list) else [fields]
fields = self._build_field_list(fields)
_listify = lambda x: x if isinstance(x, list) else [x]
filters = api_common.get_filters_from_dict(
{k: _listify(v) for k, v in kwargs.items()},
self.resource_info,
skips=['fields', 'sort_key', 'sort_dir',
'limit', 'marker', 'page_reverse'])
# NOTE(blogan): these are set in the FieldsAndFiltersHoook
fields = request.context['query_params'].get('fields')
filters = request.context['query_params'].get('filters')
lister = getattr(self.plugin, 'get_%s' % self.collection)
neutron_context = request.context['neutron_context']
return {self.collection: lister(neutron_context,

View File

@@ -102,7 +102,7 @@ class NeutronPecanController(object):
else:
self._mandatory_fields = set()
def _build_field_list(self, request_fields):
def build_field_list(self, request_fields):
if request_fields:
return set(request_fields) | self._mandatory_fields
return []

View File

@@ -18,6 +18,7 @@ from neutron.pecan_wsgi.hooks import context
from neutron.pecan_wsgi.hooks import notifier
from neutron.pecan_wsgi.hooks import ownership_validation
from neutron.pecan_wsgi.hooks import policy_enforcement
from neutron.pecan_wsgi.hooks import query_parameters
from neutron.pecan_wsgi.hooks import quota_enforcement
from neutron.pecan_wsgi.hooks import translation
@@ -29,3 +30,4 @@ OwnershipValidationHook = ownership_validation.OwnershipValidationHook
PolicyHook = policy_enforcement.PolicyHook
QuotaEnforcementHook = quota_enforcement.QuotaEnforcementHook
NotifierHook = notifier.NotifierHook
QueryParametersHook = query_parameters.QueryParametersHook

View File

@@ -0,0 +1,59 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from pecan import hooks
from neutron.api import api_common
from neutron import manager
def _listify(thing):
return thing if isinstance(thing, list) else [thing]
def _set_fields(state, controller):
params = state.request.params.mixed()
fields = params.get('fields', [])
# if only one fields query parameter is passed, pecan will not put
# that parameter in a list, so we need to convert it into a list
fields = _listify(fields)
combined_fields = controller.build_field_list(fields)
return combined_fields
def _set_filters(state, controller):
params = state.request.params.mixed()
filters = api_common.get_filters_from_dict(
{k: _listify(v) for k, v in params.items()},
controller.resource_info,
skips=['fields', 'sort_key', 'sort_dir',
'limit', 'marker', 'page_reverse'])
return filters
class QueryParametersHook(hooks.PecanHook):
priority = 145
def before(self, state):
state.request.context['query_params'] = {}
if state.request.method != 'GET':
return
collection = state.request.context.get('collection')
if not collection:
return
controller = manager.NeutronManager.get_controller_for_resource(
collection)
combined_fields = _set_fields(state, controller)
filters = _set_filters(state, controller)
query_params = {'fields': combined_fields, 'filters': filters}
state.request.context['query_params'] = query_params

View File

@@ -23,6 +23,7 @@ from neutron.api import extensions
from neutron import context
from neutron import manager
from neutron.pecan_wsgi.controllers import root as controllers
from neutron.pecan_wsgi.controllers import utils as controller_utils
from neutron.plugins.common import constants
from neutron import policy
from neutron.tests.common import helpers
@@ -34,7 +35,7 @@ _SERVICE_PLUGIN_COLLECTION = _SERVICE_PLUGIN_RESOURCE + 's'
_SERVICE_PLUGIN_INDEX_BODY = {_SERVICE_PLUGIN_COLLECTION: []}
class FakeServicePluginController(object):
class FakeServicePluginController(controller_utils.NeutronPecanController):
resource = _SERVICE_PLUGIN_RESOURCE
collection = _SERVICE_PLUGIN_COLLECTION
@@ -58,7 +59,9 @@ class TestRootController(test_functional.PecanFunctionalTest):
def setup_service_plugin(self):
manager.NeutronManager.set_controller_for_resource(
_SERVICE_PLUGIN_COLLECTION, FakeServicePluginController())
_SERVICE_PLUGIN_COLLECTION,
FakeServicePluginController(_SERVICE_PLUGIN_COLLECTION,
_SERVICE_PLUGIN_RESOURCE))
def _test_method_returns_code(self, method, code=200):
api_method = getattr(self.app, method)