diff options
author | Steve Baker <sbaker@redhat.com> | 2020-07-29 16:03:25 +1200 |
---|---|---|
committer | Steve Baker <sbaker@redhat.com> | 2020-07-30 07:37:31 +1200 |
commit | 4fa65099de4e0f769cebb781bb3bacffee2066a2 (patch) | |
tree | aca08efb619cbf94771b42757d50cd6f9838b4f3 | |
parent | b6a25d467a18b271a51dc4e283693df82837e080 (diff) | |
download | ironic-4fa65099de4e0f769cebb781bb3bacffee2066a2.tar.gz |
Break out collection functions for json usage
With this change it will be possible for both type-based and
json-based result collections to use the same has_next/get_next
functions. Once the last type-based controller is converted the
Collection type can be deleted.
Change-Id: Ib1eb9a238a9ae9d42782880bd6cb6b2978d39463
Story: 1651346
Task: 10551
-rw-r--r-- | ironic/api/controllers/v1/collection.py | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/ironic/api/controllers/v1/collection.py b/ironic/api/controllers/v1/collection.py index 6e1b1faf3..c669b9309 100644 --- a/ironic/api/controllers/v1/collection.py +++ b/ironic/api/controllers/v1/collection.py @@ -19,6 +19,38 @@ from ironic.api.controllers import link from ironic.api import types as atypes +def has_next(collection, limit): + """Return whether collection has more items.""" + return len(collection) and len(collection) == limit + + +def get_next(collection, limit, url=None, key_field='uuid', **kwargs): + """Return a link to the next subset of the collection.""" + if not has_next(collection, limit): + return None + + fields = kwargs.pop('fields', None) + # NOTE(saga): If fields argument is present in kwargs and not None. It + # is a list so convert it into a comma seperated string. + if fields: + kwargs['fields'] = ','.join(fields) + q_args = ''.join(['%s=%s&' % (key, kwargs[key]) for key in kwargs]) + + last_item = collection[-1] + # handle items which are either objects or dicts + if hasattr(last_item, key_field): + marker = getattr(last_item, key_field) + else: + marker = last_item.get(key_field) + + next_args = '?%(args)slimit=%(limit)d&marker=%(marker)s' % { + 'args': q_args, 'limit': limit, + 'marker': marker} + + return link.make_link('next', api.request.public_url, + url, next_args)['href'] + + class Collection(base.Base): next = str @@ -34,23 +66,13 @@ class Collection(base.Base): def has_next(self, limit): """Return whether collection has more items.""" - return len(self.collection) and len(self.collection) == limit + return has_next(self.collection, limit) def get_next(self, limit, url=None, **kwargs): """Return a link to the next subset of the collection.""" - if not self.has_next(limit): - return atypes.Unset - resource_url = url or self._type - fields = kwargs.pop('fields', None) - # NOTE(saga): If fields argument is present in kwargs and not None. It - # is a list so convert it into a comma seperated string. - if fields: - kwargs['fields'] = ','.join(fields) - q_args = ''.join(['%s=%s&' % (key, kwargs[key]) for key in kwargs]) - next_args = '?%(args)slimit=%(limit)d&marker=%(marker)s' % { - 'args': q_args, 'limit': limit, - 'marker': getattr(self.collection[-1], self.get_key_field())} - - return link.make_link('next', api.request.public_url, - resource_url, next_args)['href'] + the_next = get_next(self.collection, limit, url=resource_url, + key_field=self.get_key_field(), **kwargs) + if the_next is None: + return atypes.Unset + return the_next |