From 6a961246fed279d56ae7099915aa2f4d7fd3c469 Mon Sep 17 00:00:00 2001 From: zhaohua Date: Mon, 17 Aug 2015 17:27:25 +0800 Subject: [PATCH] Change huawei driver send REST command serially - Add 'synchronization decorator' to the 'call' function of huawei driver. If the connection broke down, there will be only one re-login executed. - Change REST command timeout to 52s, change login timeout to 4s, to avoid long time waiting for failure. - Move the assemble of URL in the 'do_call' function. When re-login successed, the new connection will be used automatically. Change-Id: Ideb7e70d7f3d2f0fa3ec0b900c27bbd87bea6aef Closes-Bug: 1485441 --- manila/share/drivers/huawei/constants.py | 3 +- manila/share/drivers/huawei/v3/helper.py | 60 +++++++++------- .../share/drivers/huawei/test_huawei_nas.py | 71 ++++++++++--------- 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/manila/share/drivers/huawei/constants.py b/manila/share/drivers/huawei/constants.py index 3e72b272a5..de1da30394 100644 --- a/manila/share/drivers/huawei/constants.py +++ b/manila/share/drivers/huawei/constants.py @@ -20,7 +20,8 @@ DEFAULT_TIMEOUT = 60 MSG_SNAPSHOT_NOT_FOUND = 1073754118 IP_ALLOCATIONS = 0 -SOCKET_TIMEOUT = 720 +SOCKET_TIMEOUT = 52 +LOGIN_SOCKET_TIMEOUT = 4 ACCESS_NFS_RW = "1" ACCESS_NFS_RO = "0" diff --git a/manila/share/drivers/huawei/v3/helper.py b/manila/share/drivers/huawei/v3/helper.py index 15cbd27872..e1a2b04158 100644 --- a/manila/share/drivers/huawei/v3/helper.py +++ b/manila/share/drivers/huawei/v3/helper.py @@ -36,6 +36,9 @@ class RestHelper(object): def __init__(self, configuration): self.configuration = configuration + self.init_http_head() + + def init_http_head(self): self.cookie = http_cookiejar.CookieJar() self.url = None self.headers = { @@ -43,12 +46,15 @@ class RestHelper(object): "Content-Type": "application/json", } - def do_call(self, url, data=None, method=None): + def do_call(self, url, data=None, method=None, + calltimeout=constants.SOCKET_TIMEOUT): """Send requests to server. Send HTTPS call, get response in JSON. Convert response into Python Object and return it. """ + if self.url: + url = self.url + url if "xx/sessions" not in url: LOG.debug('Request URL: %(url)s\n' 'Call Method: %(method)s\n' @@ -64,7 +70,7 @@ class RestHelper(object): req = urlreq.Request(url, data, self.headers) if method: req.get_method = lambda: method - res_temp = urlreq.urlopen(req, timeout=constants.SOCKET_TIMEOUT) + res_temp = urlreq.urlopen(req, timeout=calltimeout) res = res_temp.read().decode("utf-8") LOG.debug('Response Data: %(res)s.', {'res': res}) @@ -96,7 +102,9 @@ class RestHelper(object): data = jsonutils.dumps({"username": login_info['UserName'], "password": login_info['UserPassword'], "scope": "0"}) - result = self.do_call(url, data) + self.init_http_head() + result = self.do_call(url, data, + calltimeout=constants.LOGIN_SOCKET_TIMEOUT) if((result['error']['code'] != 0) or ("data" not in result) @@ -119,6 +127,7 @@ class RestHelper(object): return deviceid + @utils.synchronized('huawei_manila', external=True) def call(self, url, data=None, method=None): """Send requests to server. @@ -140,13 +149,12 @@ class RestHelper(object): 'New URL: %(new_url)s\n', {'old_url': old_url, 'new_url': self.url}) - url = url.replace(old_url, self.url) result = self.do_call(url, data, method) return result def _create_filesystem(self, fs_param): """Create file system.""" - url = self.url + "/filesystem" + url = "/filesystem" data = jsonutils.dumps(fs_param) result = self.call(url, data) @@ -237,7 +245,7 @@ class RestHelper(object): reason=(_('Invalid NAS protocol supplied: %s.') % share_proto)) - url = self.url + "/" + share_url_type + url = "/" + share_url_type data = jsonutils.dumps(filepath) result = self.call(url, data, "POST") @@ -250,7 +258,7 @@ class RestHelper(object): def _delete_share_by_id(self, share_id, share_url_type): """Delete share by share id.""" - url = self.url + "/" + share_url_type + "/" + share_id + url = "/" + share_url_type + "/" + share_id result = self.call(url, None, "DELETE") self._assert_rest_result(result, 'Delete share error.') @@ -258,13 +266,13 @@ class RestHelper(object): def _delete_fs(self, fs_id): """Delete file system.""" # Get available file system - url = self.url + "/filesystem/" + fs_id + url = "/filesystem/" + fs_id result = self.call(url, None, "DELETE") self._assert_rest_result(result, 'Delete file system error.') def _get_cifs_service_status(self): - url = self.url + "/CIFSSERVICE" + url = "/CIFSSERVICE" result = self.call(url, None, "GET") msg = 'Get CIFS service status error.' @@ -274,7 +282,7 @@ class RestHelper(object): return result['data']['RUNNINGSTATUS'] def _get_nfs_service_status(self): - url = self.url + "/NFSSERVICE" + url = "/NFSSERVICE" result = self.call(url, None, "GET") msg = 'Get NFS service status error.' @@ -289,7 +297,7 @@ class RestHelper(object): return service def _start_nfs_service_status(self): - url = self.url + "/NFSSERVICE" + url = "/NFSSERVICE" nfsserviceinfo = { "NFSV4DOMAIN": "localdomain", "RUNNINGSTATUS": "2", @@ -304,7 +312,7 @@ class RestHelper(object): self._assert_rest_result(result, 'Start NFS service error.') def _start_cifs_service_status(self): - url = self.url + "/CIFSSERVICE" + url = "/CIFSSERVICE" cifsserviceinfo = { "ENABLENOTIFY": "true", "ENABLEOPLOCK": "true", @@ -341,7 +349,7 @@ class RestHelper(object): return poolinfo def _find_all_pool_info(self): - url = self.url + "/storagepool" + url = "/storagepool" result = self.call(url, None) msg = "Query resource pool error." @@ -366,14 +374,14 @@ class RestHelper(object): return root def _remove_access_from_share(self, access_id, access_type): - url = self.url + "/" + access_type + "/" + access_id + url = "/" + access_type + "/" + access_id result = self.call(url, None, "DELETE") self._assert_rest_result(result, 'delete access from share error!') def _get_access_from_count(self, share_id, share_client_type): url_subfix = ("/" + share_client_type + "/count?" + "filter=PARENTID::" + share_id) - url = self.url + url_subfix + url = url_subfix result = self.call(url, None, "GET") msg = "Get access count by share error!" @@ -404,7 +412,7 @@ class RestHelper(object): access_to, range_begin, share_client_type): range_end = range_begin + 100 - url = (self.url + "/" + share_client_type + "?filter=PARENTID::" + url = ("/" + share_client_type + "?filter=PARENTID::" + share_id + "&range=[" + six.text_type(range_begin) + "-" + six.text_type(range_end) + "]") result = self.call(url, None, "GET") @@ -418,7 +426,7 @@ class RestHelper(object): share_proto, access_level): """Allow access to the share.""" access_type = self._get_share_client_type(share_proto) - url = self.url + "/" + access_type + url = "/" + access_type access = {} if access_type == "NFS_SHARE_AUTH_CLIENT": @@ -461,7 +469,7 @@ class RestHelper(object): """Check the snapshot id exists.""" url_subfix = "/FSSNAPSHOT/" + snap_id - url = self.url + url_subfix + url = url_subfix result = self.call(url, None, "GET") if result['error']['code'] == constants.MSG_SNAPSHOT_NOT_FOUND: @@ -477,7 +485,7 @@ class RestHelper(object): def _delete_snapshot(self, snap_id): """Deletes snapshot.""" - url = self.url + "/FSSNAPSHOT/%s" % snap_id + url = "/FSSNAPSHOT/%s" % snap_id data = jsonutils.dumps({"TYPE": "48", "ID": snap_id}) result = self.call(url, data, "DELETE") self._assert_rest_result(result, 'Delete snapshot error.') @@ -492,7 +500,7 @@ class RestHelper(object): "DESCRIPTION": "", } - url = self.url + "/FSSNAPSHOT" + url = "/FSSNAPSHOT" data = jsonutils.dumps(filepath) result = self.call(url, data, "POST") @@ -522,7 +530,7 @@ class RestHelper(object): def _get_share_count(self, share_url_type): """Get share count.""" - url = self.url + "/" + share_url_type + "/count" + url = "/" + share_url_type + "/count" result = self.call(url, None, "GET") self._assert_rest_result(result, 'Get share count error!') @@ -532,7 +540,7 @@ class RestHelper(object): range_begin, share_url_type): """Get share by share name.""" range_end = range_begin + 100 - url = (self.url + "/" + share_url_type + "?range=[" + url = ("/" + share_url_type + "?range=[" + six.text_type(range_begin) + "-" + six.text_type(range_end) + "]") result = self.call(url, None, "GET") @@ -563,7 +571,7 @@ class RestHelper(object): return share_url_type def _get_fsid_by_name(self, share_name): - url = self.url + "/FILESYSTEM?range=[0-8191]" + url = "/FILESYSTEM?range=[0-8191]" result = self.call(url, None, "GET") self._assert_rest_result(result, 'Get filesystem by name error!') sharename = share_name.replace("-", "_") @@ -573,7 +581,7 @@ class RestHelper(object): return item['ID'] def _get_fs_info_by_id(self, fsid): - url = self.url + "/filesystem/%s" % fsid + url = "/filesystem/%s" % fsid result = self.call(url, None, "GET") msg = "Get filesystem info by id error!" @@ -639,7 +647,7 @@ class RestHelper(object): return snapshot_id def _change_share_size(self, fsid, new_size): - url = self.url + "/filesystem/%s" % fsid + url = "/filesystem/%s" % fsid capacityinfo = { "CAPACITY": new_size, @@ -653,7 +661,7 @@ class RestHelper(object): self._assert_data_in_result(result, msg) def _change_fs_name(self, fsid, name): - url = self.url + "/filesystem/%s" % fsid + url = "/filesystem/%s" % fsid fs_param = { "NAME": name.replace("-", "_"), } diff --git a/manila/tests/share/drivers/huawei/test_huawei_nas.py b/manila/tests/share/drivers/huawei/test_huawei_nas.py index 391f25da21..5a9cf7b222 100644 --- a/manila/tests/share/drivers/huawei/test_huawei_nas.py +++ b/manila/tests/share/drivers/huawei/test_huawei_nas.py @@ -164,7 +164,7 @@ class FakeHuaweiNasHelper(helper.RestHelper): def _change_file_mode(self, filepath): pass - def do_call(self, url, data=None, method=None): + def do_call(self, url, data=None, method=None, calltimeout=4): url = url.replace('http://100.115.10.69:8082/deviceManager/rest', '') url = url.replace('/210235G7J20000000000/', '') @@ -174,18 +174,23 @@ class FakeHuaweiNasHelper(helper.RestHelper): res_json = jsonutils.loads(data) return res_json elif self.test_multi_url_flag == 2: - if 'http://100.115.10.70:8082/deviceManager/rest' in url: - url = url.replace('http://100.115.10.70:8082/' - 'deviceManager/rest', '') - else: + if ('http://100.115.10.70:8082/deviceManager/rest/xx/' + 'sessions' == url): + self.url = url + data = data_session("/xx/sessions") + res_json = jsonutils.loads(data) + return res_json + elif (('/xx/sessions' == url) or (self.url is not None + and 'http://100.115.10.69:8082/deviceManager/rest' + in self.url)): data = '{"error":{"code":-403}}' res_json = jsonutils.loads(data) return res_json - if url == "/xx/sessions" or url == "sessions": + if url == "/xx/sessions" or url == "/sessions": data = data_session(url) - if url == "storagepool": + if url == "/storagepool": data = """{"error":{"code":0}, "data":[{"USERFREECAPACITY":"2097152", "ID":"1", @@ -194,11 +199,11 @@ class FakeHuaweiNasHelper(helper.RestHelper): "USAGETYPE":"2", "USERCONSUMEDCAPACITY":"2097152"}]}""" - if url == "filesystem": + if url == "/filesystem": data = """{"error":{"code":0},"data":{ "ID":"4"}}""" - if url == "NFSHARE" or url == "CIFSHARE": + if url == "/NFSHARE" or url == "/CIFSHARE": if self.create_share_flag: data = '{"error":{"code":31755596}}' elif self.create_share_data_flag: @@ -207,7 +212,7 @@ class FakeHuaweiNasHelper(helper.RestHelper): data = """{"error":{"code":0},"data":{ "ID":"10"}}""" - if url == "NFSHARE?range=[100-200]": + if url == "/NFSHARE?range=[100-200]": if self.share_exist: data = """{"error":{"code":0}, "data":[{"ID":"1", @@ -221,104 +226,104 @@ class FakeHuaweiNasHelper(helper.RestHelper): "NAME":"test", "SHAREPATH":"/share_fake_uuid_fail/"}]}""" - if url == "CIFSHARE?range=[100-200]": + if url == "/CIFSHARE?range=[100-200]": data = """{"error":{"code":0}, "data":[{"ID":"2", "FSID":"4", "NAME":"test", "SHAREPATH":"/share_fake_uuid/"}]}""" - if url == "NFSHARE?range=[0-100]": + if url == "/NFSHARE?range=[0-100]": data = """{"error":{"code":0}, "data":[{"ID":"1", "FSID":"4", "NAME":"test_fail", "SHAREPATH":"/share_fake_uuid_fail/"}]}""" - if url == "CIFSHARE?range=[0-100]": + if url == "/CIFSHARE?range=[0-100]": data = """{"error":{"code":0}, "data":[{"ID":"2", "FSID":"4", "NAME":"test_fail", "SHAREPATH":"/share_fake_uuid_fail/"}]}""" - if url == "NFSHARE/1" or url == "CIFSHARE/2": + if url == "/NFSHARE/1" or url == "/CIFSHARE/2": data = """{"error":{"code":0}}""" self.delete_flag = True - if url == "FSSNAPSHOT": + if url == "/FSSNAPSHOT": data = """{"error":{"code":0},"data":{ "ID":"3"}}""" self.create_snapflag = True - if url == "FSSNAPSHOT/4@share_snapshot_fake_snapshot_uuid": + if url == "/FSSNAPSHOT/4@share_snapshot_fake_snapshot_uuid": if self.snapshot_flag: data = """{"error":{"code":0},"data":{"ID":"3"}}""" else: data = '{"error":{"code":1073754118}}' self.delete_flag = True - if url == "FSSNAPSHOT/3": + if url == "/FSSNAPSHOT/3": data = """{"error":{"code":0}}""" self.delete_flag = True - if url == "NFS_SHARE_AUTH_CLIENT": + if url == "/NFS_SHARE_AUTH_CLIENT": data, self.allow_ro_flag, self.allow_rw_flag = \ allow_access('NFS', method, data) self.allow_flag = True - if url == "CIFS_SHARE_AUTH_CLIENT": + if url == "/CIFS_SHARE_AUTH_CLIENT": data, self.allow_ro_flag, self.allow_rw_flag = \ allow_access('CIFS', method, data) self.allow_flag = True - if url == "FSSNAPSHOT?TYPE=48&PARENTID=4"\ + if url == "/FSSNAPSHOT?TYPE=48&PARENTID=4"\ "&&sortby=TIMESTAMP,d&range=[0-2000]": data = """{"error":{"code":0}, "data":[{"ID":"3", "NAME":"share_snapshot_fake_snapshot_uuid"}]}""" self.delete_flag = True - if url == "NFS_SHARE_AUTH_CLIENT?"\ + if url == "/NFS_SHARE_AUTH_CLIENT?"\ "filter=PARENTID::1&range=[0-100]": data = """{"error":{"code":0}, "data":[{"ID":"0", "NAME":"100.112.0.1_fail"}]}""" - if url == "CIFS_SHARE_AUTH_CLIENT?"\ + if url == "/CIFS_SHARE_AUTH_CLIENT?"\ "filter=PARENTID::2&range=[0-100]": data = """{"error":{"code":0}, "data":[{"ID":"0", "NAME":"user_name_fail"}]}""" - if url == "NFS_SHARE_AUTH_CLIENT?"\ + if url == "/NFS_SHARE_AUTH_CLIENT?"\ "filter=PARENTID::1&range=[100-200]": data = """{"error":{"code":0}, "data":[{"ID":"5", "NAME":"100.112.0.1"}]}""" - if url == "CIFS_SHARE_AUTH_CLIENT?"\ + if url == "/CIFS_SHARE_AUTH_CLIENT?"\ "filter=PARENTID::2&range=[100-200]": data = """{"error":{"code":0}, "data":[{"ID":"6", "NAME":"user_name"}]}""" - if url == "NFS_SHARE_AUTH_CLIENT/5"\ - or url == "CIFS_SHARE_AUTH_CLIENT/6": + if url == "/NFS_SHARE_AUTH_CLIENT/5"\ + or url == "/CIFS_SHARE_AUTH_CLIENT/6": data = """{"error":{"code":0}}""" self.deny_flag = True - if url == "NFSHARE/count" or url == "CIFSHARE/count": + if url == "/NFSHARE/count" or url == "/CIFSHARE/count": data = """{"error":{"code":0},"data":{ "COUNT":"196"}}""" - if url == "NFS_SHARE_AUTH_CLIENT/count?filter=PARENTID::1"\ - or url == "CIFS_SHARE_AUTH_CLIENT/count?filter="\ + if url == "/NFS_SHARE_AUTH_CLIENT/count?filter=PARENTID::1"\ + or url == "/CIFS_SHARE_AUTH_CLIENT/count?filter="\ "PARENTID::2": data = """{"error":{"code":0},"data":{ "COUNT":"196"}}""" - if url == "CIFSSERVICE": + if url == "/CIFSSERVICE": if self.service_status_flag: data = """{"error":{"code":0},"data":{ "RUNNINGSTATUS":"2"}}""" @@ -326,7 +331,7 @@ class FakeHuaweiNasHelper(helper.RestHelper): data = """{"error":{"code":0},"data":{ "RUNNINGSTATUS":"1"}}""" - if url == "NFSSERVICE": + if url == "/NFSSERVICE": if self.service_nfs_status_flag: data = """{"error":{"code":0}, "data":{"RUNNINGSTATUS":"2", @@ -339,12 +344,12 @@ class FakeHuaweiNasHelper(helper.RestHelper): "SUPPORTV4":"true"}}""" self.setupserver_flag = True - if url == "FILESYSTEM?range=[0-8191]": + if url == "/FILESYSTEM?range=[0-8191]": data = """{"error":{"code":0}, "data":[{"ID":"4", "NAME":"share_fake_uuid"}]}""" - if url == "filesystem/4": + if url == "/filesystem/4": data, self.extend_share_flag, self.shrink_share_flag = ( filesystem(method, data, self.fs_status_flag)) self.delete_flag = True