/services?name=<name> API fails when using list_limit
When using list_limit configuration option in Default section of keystone.conf, the /services?name=<service_name> API fails to find the service if list_limit value is smaller than the total number of services and the searched service is not among the first 'list_limit' services. The API should first filter by name and only afterwards truncate the result list. Also, this patch fixes setting the 'truncated' attribute of the driver's hint.limit object when truncating the list outside of driver_hints.truncated decorator, problem exposed by fixing the problem described in the first paragraph. Closes-Bug: #1594482 Change-Id: I832f542c3cb0faf94a1e5bce5a894f7f4d26a8de
This commit is contained in:
parent
78161c8481
commit
6a9a9f002f
@ -38,7 +38,7 @@ def truncated(f):
|
|||||||
_('Cannot truncate a driver call without hints list as '
|
_('Cannot truncate a driver call without hints list as '
|
||||||
'first parameter after self '))
|
'first parameter after self '))
|
||||||
|
|
||||||
if hints.limit is None:
|
if hints.limit is None or hints.filters:
|
||||||
return f(self, hints, *args, **kwargs)
|
return f(self, hints, *args, **kwargs)
|
||||||
|
|
||||||
# A limit is set, so ask for one more entry than we need
|
# A limit is set, so ask for one more entry than we need
|
||||||
|
@ -371,7 +371,11 @@ def _limit(query, hints):
|
|||||||
|
|
||||||
# If we satisfied all the filters, set an upper limit if supplied
|
# If we satisfied all the filters, set an upper limit if supplied
|
||||||
if hints.limit:
|
if hints.limit:
|
||||||
query = query.limit(hints.limit['limit'])
|
original_len = query.count()
|
||||||
|
limit_query = query.limit(hints.limit['limit'])
|
||||||
|
if limit_query.count() < original_len:
|
||||||
|
hints.limit['truncated'] = True
|
||||||
|
query = limit_query
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
|
@ -345,12 +345,13 @@ class CatalogTestCase(test_v3.RestfulTestCase):
|
|||||||
|
|
||||||
def test_filter_list_services_by_name(self):
|
def test_filter_list_services_by_name(self):
|
||||||
"""Call ``GET /services?name=<some name>``."""
|
"""Call ``GET /services?name=<some name>``."""
|
||||||
target_ref = self._create_random_service()
|
|
||||||
|
|
||||||
# create unrelated services
|
# create unrelated services
|
||||||
self._create_random_service()
|
self._create_random_service()
|
||||||
self._create_random_service()
|
self._create_random_service()
|
||||||
|
|
||||||
|
# create the desired service
|
||||||
|
target_ref = self._create_random_service()
|
||||||
|
|
||||||
response = self.get('/services?name=' + target_ref['name'])
|
response = self.get('/services?name=' + target_ref['name'])
|
||||||
self.assertValidServiceListResponse(response, ref=target_ref)
|
self.assertValidServiceListResponse(response, ref=target_ref)
|
||||||
|
|
||||||
@ -360,6 +361,12 @@ class CatalogTestCase(test_v3.RestfulTestCase):
|
|||||||
filtered_service = filtered_service_list[0]
|
filtered_service = filtered_service_list[0]
|
||||||
self.assertEqual(target_ref['name'], filtered_service['name'])
|
self.assertEqual(target_ref['name'], filtered_service['name'])
|
||||||
|
|
||||||
|
def test_filter_list_services_by_name_with_list_limit(self):
|
||||||
|
"""Call ``GET /services?name=<some name>``."""
|
||||||
|
self.config_fixture.config(list_limit=1)
|
||||||
|
|
||||||
|
self.test_filter_list_services_by_name()
|
||||||
|
|
||||||
def test_get_head_service(self):
|
def test_get_head_service(self):
|
||||||
"""Call ``GET & HEAD /services/{service_id}``."""
|
"""Call ``GET & HEAD /services/{service_id}``."""
|
||||||
resource_url = '/services/%(service_id)s' % {
|
resource_url = '/services/%(service_id)s' % {
|
||||||
|
8
releasenotes/notes/bug-1594482-52a5dd1d8477b694.yaml
Normal file
8
releasenotes/notes/bug-1594482-52a5dd1d8477b694.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- >
|
||||||
|
[`bug 1594482 <https://bugs.launchpad.net/keystone/+bug/1594482>`_]
|
||||||
|
When using list_limit config option, the GET /services?name={service_name}
|
||||||
|
API was first truncating the list and afterwards filtering by name.
|
||||||
|
The API was fixed to first filter by name and only afterwards truncate the
|
||||||
|
result list to the desired limit.
|
Loading…
Reference in New Issue
Block a user