VMAX driver - pagination on get vols from SG list.

No pagination for listing volumes from storage group,
if volumes exceed maxPageSize of 1000. Need to utilize
'to', 'from' and 'count' attributes of the rest call.

Change-Id: I8123ef3823345a4092c20e5de546edb234df742a
Closes-Bug: #1778954
This commit is contained in:
michael-mcaleer 2018-06-27 17:45:30 +01:00 committed by Helen Walsh
parent 40c563a841
commit 3536a82f1b
2 changed files with 82 additions and 57 deletions

View File

@ -3130,7 +3130,7 @@ class VMAXRestTest(test.TestCase):
VMAXCommonData.private_vol_rest_response_iterator_second['result'])
@mock.patch.object(
rest.VMAXRest, 'get_resource', return_value=
VMAXCommonData.private_vol_rest_response_iterator_first)
deepcopy(VMAXCommonData.private_vol_rest_response_iterator_first))
def test_get_private_volume_list_iterator(self, mock_get_resource,
mock_iterator):
array_id = self.data.array
@ -3161,9 +3161,11 @@ class VMAXRestTest(test.TestCase):
result_count = 1500
start_position = 1
end_position = 1000
max_page_size = 1000
actual_response = self.rest.get_iterator_page_list(
iterator_id, result_count, start_position, end_position)
iterator_id, result_count, start_position, end_position,
max_page_size)
self.assertEqual(expected_response, actual_response)
def test_set_rest_credentials(self):
@ -3181,6 +3183,16 @@ class VMAXRestTest(test.TestCase):
self.assertEqual('https://10.10.10.10:8443/univmax/restapi',
self.rest.base_uri)
@mock.patch.object(
rest.VMAXRest, 'get_iterator_page_list', return_value=
VMAXCommonData.private_vol_rest_response_iterator_second['result'])
def test_list_pagination(self, mock_iter):
result_list = self.rest.list_pagination(
deepcopy(self.data.private_vol_rest_response_iterator_first))
# reflects sample data, 1 from first iterator page and 1 from
# second iterator page
self.assertTrue(2 == len(result_list))
class VMAXProvisionTest(test.TestCase):
def setUp(self):

View File

@ -1012,8 +1012,8 @@ class VMAXRest(object):
device_ids = []
volumes = self.get_resource(
array, SLOPROVISIONING, 'volume', params=params)
volume_dict_list = self.list_pagination(volumes)
try:
volume_dict_list = volumes['resultList']['result']
for vol_dict in volume_dict_list:
device_id = vol_dict['volumeId']
device_ids.append(device_id)
@ -1028,64 +1028,11 @@ class VMAXRest(object):
:param params: filter parameters
:returns: list -- dicts with volume information
"""
volumes = []
volume_info = self.get_resource(
array, SLOPROVISIONING, 'volume', params=params,
private='/private')
try:
volumes = volume_info['resultList']['result']
iterator_id = volume_info['id']
volume_count = volume_info['count']
max_page_size = volume_info['maxPageSize']
start_position = volume_info['resultList']['from']
end_position = volume_info['resultList']['to']
except (KeyError, TypeError):
return volumes
if volume_count > max_page_size:
LOG.info("More entries exist in the result list, retrieving "
"remainder of results from iterator.")
start_position += 1000
end_position += 1000
iterator_response = self.get_iterator_page_list(
iterator_id, volume_count, start_position, end_position)
volumes += iterator_response
return volumes
def get_iterator_page_list(self, iterator_id, result_count, start_position,
end_position):
"""Iterate through response if more than one page available.
:param iterator_id: the iterator ID
:param result_count: the amount of results in the iterator
:param start_position: position to begin iterator from
:param end_position: position to stop iterator
:return: list -- merged results from multiple pages
"""
iterator_result = []
has_more_entries = True
while has_more_entries:
if start_position <= result_count <= end_position:
end_position = result_count
has_more_entries = False
params = {'to': start_position, 'from': end_position}
target_uri = ('/common/Iterator/%(iterator_id)s/page' % {
'iterator_id': iterator_id})
iterator_response = self._get_request(target_uri, 'iterator',
params)
try:
iterator_result += iterator_response['result']
start_position += 1000
end_position += 1000
except (KeyError, TypeError):
pass
return iterator_result
return self.list_pagination(volume_info)
def _modify_volume(self, array, device_id, payload):
"""Modify a volume (PUT operation).
@ -2416,3 +2363,69 @@ class VMAXRest(object):
'rdf_num': rdf_group_num})
self.delete_resource(
array, REPLICATION, 'storagegroup', resource_name=resource_name)
def list_pagination(self, list_info):
"""Process lists under or over the maxPageSize
:param list_info: the object list information
:return: the result list
"""
result_list = []
try:
result_list = list_info['resultList']['result']
iterator_id = list_info['id']
list_count = list_info['count']
max_page_size = list_info['maxPageSize']
start_position = list_info['resultList']['from']
end_position = list_info['resultList']['to']
except (KeyError, TypeError):
return result_list
if list_count > max_page_size:
LOG.info("More entries exist in the result list, retrieving "
"remainder of results from iterator.")
start_position = end_position + 1
if list_count < (end_position + max_page_size):
end_position = list_count
else:
end_position += max_page_size
iterator_response = self.get_iterator_page_list(
iterator_id, list_count, start_position, end_position,
max_page_size)
result_list += iterator_response
return result_list
def get_iterator_page_list(self, iterator_id, result_count, start_position,
end_position, max_page_size):
"""Iterate through response if more than one page available.
:param iterator_id: the iterator ID
:param result_count: the amount of results in the iterator
:param start_position: position to begin iterator from
:param end_position: position to stop iterator
:param max_page_size: the max page size
:return: list -- merged results from multiple pages
"""
iterator_result = []
has_more_entries = True
while has_more_entries:
if start_position <= result_count <= end_position:
end_position = result_count
has_more_entries = False
params = {'to': end_position, 'from': start_position}
target_uri = ('/common/Iterator/%(iterator_id)s/page' % {
'iterator_id': iterator_id})
iterator_response = self._get_request(target_uri, 'iterator',
params)
try:
iterator_result += iterator_response['result']
start_position += max_page_size
end_position += max_page_size
except (KeyError, TypeError):
pass
return iterator_result