PowerMax Driver - REST Iterator Expiration Fix
This change addresses an issue whereby the Unisphere REST data iterator expires before all data can be read from it. Change-Id: Ifa953f72ca670843c25c5be04a004835c348476c Closes-Bug: #1894086
This commit is contained in:
parent
37749045c0
commit
13d5a757db
@ -1710,7 +1710,42 @@ class PowerMaxRestTest(test.TestCase):
|
||||
volume = self.rest.get_private_volume_list(array_id)
|
||||
self.assertEqual(response, volume)
|
||||
|
||||
def test_get_iterator_list(self):
|
||||
@mock.patch.object(rest.PowerMaxRest, 'get_resource')
|
||||
def test_get_private_volume_list_params_dict_input(self, mck_get):
|
||||
array_id = self.data.array
|
||||
input_param = {'unit-test': True}
|
||||
ref = {'unit-test': True,
|
||||
'expiration_time_mins': rest.ITERATOR_EXPIRATION}
|
||||
|
||||
self.rest.get_private_volume_list(array_id, input_param)
|
||||
mck_get.assert_called_once_with(
|
||||
self.data.array, rest.SLOPROVISIONING, 'volume', params=ref,
|
||||
private='/private')
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, 'get_resource')
|
||||
def test_get_private_volume_list_params_str_input(self, mck_get):
|
||||
array_id = self.data.array
|
||||
input_param = '&unit-test=True'
|
||||
ref = '&unit-test=True&expiration_time_mins=%(expire)s' % {
|
||||
'expire': rest.ITERATOR_EXPIRATION}
|
||||
|
||||
self.rest.get_private_volume_list(array_id, input_param)
|
||||
mck_get.assert_called_once_with(
|
||||
self.data.array, rest.SLOPROVISIONING, 'volume', params=ref,
|
||||
private='/private')
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, 'get_resource')
|
||||
def test_get_private_volume_list_params_no_input(self, mck_get):
|
||||
array_id = self.data.array
|
||||
ref = {'expiration_time_mins': rest.ITERATOR_EXPIRATION}
|
||||
|
||||
self.rest.get_private_volume_list(array_id)
|
||||
mck_get.assert_called_once_with(
|
||||
self.data.array, rest.SLOPROVISIONING, 'volume', params=ref,
|
||||
private='/private')
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, '_delete_iterator')
|
||||
def test_get_iterator_list(self, mck_del):
|
||||
with mock.patch.object(
|
||||
self.rest, 'get_request', side_effect=[
|
||||
self.data.rest_iterator_resonse_one,
|
||||
@ -1731,8 +1766,18 @@ class PowerMaxRestTest(test.TestCase):
|
||||
actual_response = self.rest.get_iterator_page_list(
|
||||
iterator_id, result_count, start_position, end_position,
|
||||
max_page_size)
|
||||
mck_del.assert_called_once_with(iterator_id)
|
||||
self.assertEqual(expected_response, actual_response)
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, 'request',
|
||||
return_value=(204, 'Deleted Iterator'))
|
||||
def test_delete_iterator(self, mck_del):
|
||||
iterator_id = 'test_iterator_id'
|
||||
self.rest._delete_iterator(iterator_id)
|
||||
mck_del.assert_called_once_with(
|
||||
'/common/Iterator/%(iter)s' % {'iter': iterator_id},
|
||||
rest.DELETE)
|
||||
|
||||
def test_set_rest_credentials(self):
|
||||
array_info = {
|
||||
'RestServerIp': '10.10.10.10',
|
||||
|
@ -51,6 +51,7 @@ STATUS_201 = 201
|
||||
STATUS_202 = 202
|
||||
STATUS_204 = 204
|
||||
SERVER_ERROR_STATUS_CODES = [408, 501, 502, 503, 504]
|
||||
ITERATOR_EXPIRATION = 180
|
||||
# Job constants
|
||||
INCOMPLETE_LIST = ['created', 'unscheduled', 'scheduled', 'running',
|
||||
'validating', 'validated']
|
||||
@ -1463,6 +1464,14 @@ class PowerMaxRest(object):
|
||||
:param params: filter parameters
|
||||
:returns: list -- dicts with volume information
|
||||
"""
|
||||
if isinstance(params, dict):
|
||||
params['expiration_time_mins'] = ITERATOR_EXPIRATION
|
||||
elif isinstance(params, str):
|
||||
params += '&expiration_time_mins=%(expire)s' % {
|
||||
'expire': ITERATOR_EXPIRATION}
|
||||
else:
|
||||
params = {'expiration_time_mins': ITERATOR_EXPIRATION}
|
||||
|
||||
return self.get_resource(
|
||||
array, SLOPROVISIONING, 'volume', params=params,
|
||||
private='/private')
|
||||
@ -3255,6 +3264,9 @@ class PowerMaxRest(object):
|
||||
:param max_page_size: the max page size
|
||||
:returns: list -- merged results from multiple pages
|
||||
"""
|
||||
LOG.debug('Iterator %(it)s contains %(cnt)s results.', {
|
||||
'it': iterator_id, 'cnt': result_count})
|
||||
|
||||
iterator_result = []
|
||||
has_more_entries = True
|
||||
|
||||
@ -3264,6 +3276,9 @@ class PowerMaxRest(object):
|
||||
has_more_entries = False
|
||||
|
||||
params = {'to': end_position, 'from': start_position}
|
||||
LOG.debug('Retrieving iterator %(it)s page %(st)s to %(fn)s', {
|
||||
'it': iterator_id, 'st': start_position, 'fn': end_position})
|
||||
|
||||
target_uri = ('/common/Iterator/%(iterator_id)s/page' % {
|
||||
'iterator_id': iterator_id})
|
||||
iterator_response = self.get_request(target_uri, 'iterator',
|
||||
@ -3275,8 +3290,28 @@ class PowerMaxRest(object):
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
|
||||
LOG.info('All results extracted, deleting iterator %(it)s', {
|
||||
'it': iterator_id})
|
||||
self._delete_iterator(iterator_id)
|
||||
|
||||
return iterator_result
|
||||
|
||||
def _delete_iterator(self, iterator_id):
|
||||
"""Delete an iterator containing full request result list.
|
||||
|
||||
Note: This should only be called once all required results have been
|
||||
extracted from the iterator.
|
||||
|
||||
:param iterator_id: the iterator ID -- str
|
||||
"""
|
||||
target_uri = self.build_uri(
|
||||
category='common', resource_level='Iterator',
|
||||
resource_level_id=iterator_id, no_version=True)
|
||||
status_code, message = self.request(target_uri, DELETE)
|
||||
operation = 'delete iterator'
|
||||
self.check_status_code_success(operation, status_code, message)
|
||||
LOG.info('Successfully deleted iterator %(it)s', {'it': iterator_id})
|
||||
|
||||
def validate_unisphere_version(self):
|
||||
"""Validate that the running Unisphere version meets min requirement
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
`Bug #1894086 <https://bugs.launchpad.net/cinder/+bug/1894086>`_:
|
||||
PowerMax Cinder driver addresses an issue whereby Unisphere REST iterators
|
||||
expire before all data can be read from them. The iterator expiration is now
|
||||
set to 180mins and deleted once all data has been read so no artifacts are
|
||||
left behind.
|
Loading…
Reference in New Issue
Block a user