Don't reset endpoint_url in ResourceHandle but Client

1. What is the problem
In resource_handle.NeutronResourceHandle, after connection-fail
exception is caught, endpoint_url attribute is set to None and waits
for client.Client to update the endpoint.

However, local plugin directly uses resource_handle to talk to central
Neutron, so the endpoint_url attribute will not be updated after it's
set to None. Actually, for local plugin, endpoint_url should be read
from the configuration file and doesn't require updating, so it's not
necessary to set it to None.

2. What is the solution for the problem
Reset endpoint_url in Client instead of ResourceHandle

3. What features need to be implemented to the Tricircle to
realize the solution
N/A

Change-Id: If306031605f30adf933464b955386162c7f83c06
Closes-Bug: #1691306
This commit is contained in:
zhiyuan_cai 2017-05-17 17:04:18 +08:00
parent 50067c3b4b
commit 4a66a4d85c
3 changed files with 18 additions and 10 deletions

View File

@ -97,6 +97,7 @@ def _safe_operation(operation_name):
instance._ensure_token_for_admin(context)
return func(*args, **kwargs)
except exceptions.EndpointNotAvailable as e:
instance._unset_endpoint(service)
if i == retries:
raise
if cfg.CONF.client.auto_refresh_endpoint:
@ -263,6 +264,10 @@ class Client(object):
filters, pod, service, False)
return conf_list
def _unset_endpoint(self, service):
handle = self.service_handle_map[service]
handle.clear_endpoint_url()
def _ensure_endpoint_set(self, cxt, service):
handle = self.service_handle_map[service]
if not handle.is_endpoint_url_set():

View File

@ -58,6 +58,9 @@ class ResourceHandle(object):
def is_endpoint_url_set(self):
return self.endpoint_url is not None
def clear_endpoint_url(self):
self.endpoint_url = None
def update_endpoint_url(self, url):
self.endpoint_url = url
@ -111,7 +114,6 @@ class NeutronResourceHandle(ResourceHandle):
return [res for res in getattr(
client, 'list_%s' % collection)(**search_opts)[collection]]
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)
@ -125,7 +127,6 @@ class NeutronResourceHandle(ResourceHandle):
else:
return ret['%ss' % resource]
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)
@ -135,7 +136,6 @@ class NeutronResourceHandle(ResourceHandle):
return getattr(client, 'update_%s' % resource)(
*args, **kwargs)[resource]
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)
@ -144,7 +144,6 @@ class NeutronResourceHandle(ResourceHandle):
client = self._get_client(cxt)
return getattr(client, 'show_%s' % resource)(resource_id)[resource]
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)
except q_exceptions.NotFound:
@ -156,7 +155,6 @@ class NeutronResourceHandle(ResourceHandle):
client = self._get_client(cxt)
return getattr(client, 'delete_%s' % resource)(resource_id)
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)
except q_exceptions.NotFound:
@ -171,7 +169,6 @@ class NeutronResourceHandle(ResourceHandle):
func_name = '%s_%s' % (resource, action)
return getattr(client, func_name)(*args, **kwargs)
except q_exceptions.ConnectionFailed:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(
'neutron', client.httpclient.endpoint_url)

View File

@ -118,7 +118,6 @@ class FakeResHandle(resource_handle.ResourceHandle):
return cli.list_fake_res(
resource_handle._transform_filters(filters))
except FakeException:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(FAKE_TYPE, cli.endpoint)
def handle_create(self, cxt, resource, name):
@ -126,7 +125,6 @@ class FakeResHandle(resource_handle.ResourceHandle):
cli = self._get_client(cxt)
return cli.create_fake_res(name)
except FakeException:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(FAKE_TYPE, cli.endpoint)
def handle_delete(self, cxt, resource, name):
@ -134,7 +132,6 @@ class FakeResHandle(resource_handle.ResourceHandle):
cli = self._get_client(cxt)
cli.delete_fake_res(name)
except FakeException:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(FAKE_TYPE, cli.endpoint)
def handle_action(self, cxt, resource, action, name, rename):
@ -142,7 +139,6 @@ class FakeResHandle(resource_handle.ResourceHandle):
cli = self._get_client(cxt)
cli.action_fake_res(name, rename)
except FakeException:
self.endpoint_url = None
raise exceptions.EndpointNotAvailable(FAKE_TYPE, cli.endpoint)
@ -362,5 +358,15 @@ class ClientTest(unittest.TestCase):
url = self.client.get_endpoint(self.context, FAKE_SITE_ID, FAKE_TYPE)
self.assertEqual(url, FAKE_URL)
@patch.object(FakeClient, 'list_fake_res')
def test_resource_handle_endpoint_unavailable(self, mock_list):
handle = FakeResHandle(None)
handle.endpoint_url = FAKE_URL
mock_list.side_effect = FakeException
self.assertRaises(exceptions.EndpointNotAvailable,
handle.handle_list, self.context, FAKE_RESOURCE, [])
# endpont_url will not be set to None
self.assertIsNotNone(handle.endpoint_url)
def tearDown(self):
core.ModelBase.metadata.drop_all(core.get_engine())