diff --git a/cinder/tests/test_vmware_api.py b/cinder/tests/test_vmware_api.py index 09aa5361570..ccea4ae71ce 100644 --- a/cinder/tests/test_vmware_api.py +++ b/cinder/tests/test_vmware_api.py @@ -165,7 +165,7 @@ class VMwareAPISessionTest(test.TestCase): def test_invoke_api_with_expected_exception(self): api_session = self._create_api_session(True) ret = mock.Mock() - responses = [error_util.VimException(None), ret] + responses = [error_util.VimConnectionException(None), ret] def api(*args, **kwargs): response = responses.pop(0) @@ -231,3 +231,29 @@ class VMwareAPISessionTest(test.TestCase): sessionID=api_session._session_id, userName=api_session._session_username) api_session.create_session.assert_called_once_with() + + def test_invoke_api_with_session_is_active_error(self): + api_session = self._create_api_session(True) + api_session.create_session = mock.Mock() + vim_obj = api_session.vim + vim_obj.SessionIsActive.side_effect = error_util.VimFaultException( + None, None) + result = mock.Mock() + responses = [error_util.VimFaultException( + [error_util.NOT_AUTHENTICATED], "error"), result] + + def api(*args, **kwargs): + response = responses.pop(0) + if isinstance(response, Exception): + raise response + return response + + module = mock.Mock() + module.api = api + ret = api_session.invoke_api(module, 'api') + self.assertEqual(result, ret) + vim_obj.SessionIsActive.assert_called_once_with( + vim_obj.service_content.sessionManager, + sessionID=api_session._session_id, + userName=api_session._session_username) + api_session.create_session.assert_called_once_with() diff --git a/cinder/volume/drivers/vmware/api.py b/cinder/volume/drivers/vmware/api.py index 68e6844fc97..df3348db44a 100644 --- a/cinder/volume/drivers/vmware/api.py +++ b/cinder/volume/drivers/vmware/api.py @@ -94,7 +94,6 @@ class Retry(object): class VMwareAPISession(object): """Sets up a session with the server and handles all calls made to it.""" - @Retry(exceptions=(Exception)) def __init__(self, server_ip, server_username, server_password, api_retry_count, task_poll_interval, scheme='https', create_session=True, wsdl_loc=None, pbm_wsdl=None): @@ -145,6 +144,7 @@ class VMwareAPISession(object): host=self._server_ip) return self._pbm + @Retry(exceptions=(error_util.VimConnectionException,)) def create_session(self): """Establish session with the server.""" # Login and setup the session with the server for making @@ -213,7 +213,8 @@ class VMwareAPISession(object): """ @Retry(max_retry_count=self._api_retry_count, - exceptions=(error_util.VimException)) + exceptions=(error_util.SessionOverLoadException, + error_util.VimConnectionException)) def _invoke_api(module, method, *args, **kwargs): while True: try: diff --git a/cinder/volume/drivers/vmware/error_util.py b/cinder/volume/drivers/vmware/error_util.py index fdfc36210d3..fc69d432668 100644 --- a/cinder/volume/drivers/vmware/error_util.py +++ b/cinder/volume/drivers/vmware/error_util.py @@ -39,11 +39,16 @@ class VimAttributeException(VimException): pass -class VimFaultException(exception.VolumeBackendAPIException): - """The VIM Fault exception class.""" +class VimConnectionException(VimException): + """Thrown when there is a connection problem.""" + pass + + +class VimFaultException(VimException): + """Exception thrown when there are faults during VIM API calls.""" def __init__(self, fault_list, msg): - exception.VolumeBackendAPIException.__init__(self, msg) + super(VimFaultException, self).__init__(msg) self.fault_list = fault_list diff --git a/cinder/volume/drivers/vmware/vim.py b/cinder/volume/drivers/vmware/vim.py index d7f85ada81d..2135a567255 100644 --- a/cinder/volume/drivers/vmware/vim.py +++ b/cinder/volume/drivers/vmware/vim.py @@ -18,6 +18,7 @@ Classes for making VMware VI SOAP calls. """ import httplib +import urllib2 import suds @@ -193,6 +194,12 @@ class Vim(object): {'attr': attr_name, 'excep': excep}) + except (urllib2.URLError, urllib2.HTTPError) as excep: + raise error_util.VimConnectionException( + _("urllib2 error in %(attr)s: %(excep)s.") % + {'attr': attr_name, + 'excep': excep}) + except Exception as excep: # Socket errors which need special handling for they # might be caused by server API call overload