Merge "Use exception_filter in RPC client"
This commit is contained in:
commit
48ef79c5f7
@ -112,12 +112,9 @@ class MultipartMime(software_config.SoftwareConfig):
|
||||
part = config
|
||||
|
||||
if uuidutils.is_uuid_like(config):
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
sc = self.rpc_client().show_software_config(
|
||||
self.context, config)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
else:
|
||||
part = sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||
|
||||
if part_type == self.MULTIPART:
|
||||
|
@ -130,14 +130,12 @@ class SoftwareComponent(sc.SoftwareConfig):
|
||||
an empty list is returned.
|
||||
"""
|
||||
if name == self.CONFIGS_ATTR and self.resource_id:
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
sc = self.rpc_client().show_software_config(
|
||||
self.context, self.resource_id)
|
||||
# configs list is stored in 'config' property of parent class
|
||||
# (see handle_create)
|
||||
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG].get(self.CONFIGS)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
def validate(self):
|
||||
"""Validate SoftwareComponent properties consistency."""
|
||||
|
@ -113,11 +113,9 @@ class SoftwareConfig(resource.Resource):
|
||||
if self.resource_id is None:
|
||||
return
|
||||
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
self.rpc_client().delete_software_config(
|
||||
self.context, self.resource_id)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
def _resolve_attribute(self, name):
|
||||
"""Retrieve attributes of the SoftwareConfig resource.
|
||||
@ -126,12 +124,10 @@ class SoftwareConfig(resource.Resource):
|
||||
software config does not exist, returns an empty string.
|
||||
"""
|
||||
if name == self.CONFIG_ATTR and self.resource_id:
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
sc = self.rpc_client().show_software_config(
|
||||
self.context, self.resource_id)
|
||||
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
|
@ -209,11 +209,9 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||
return props
|
||||
|
||||
def _delete_derived_config(self, derived_config_id):
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
self.rpc_client().delete_software_config(
|
||||
self.context, derived_config_id)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
def _create_derived_config(self, action, source_config):
|
||||
|
||||
@ -466,10 +464,8 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||
return self._check_complete()
|
||||
|
||||
def handle_delete(self):
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
return self._handle_action(self.DELETE)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
def check_delete_complete(self, sd=None):
|
||||
if not sd or not self._server_exists(sd) or self._check_complete():
|
||||
@ -479,12 +475,10 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||
def _delete_resource(self):
|
||||
derived_config_id = None
|
||||
if self.resource_id is not None:
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
derived_config_id = self._get_derived_config_id()
|
||||
self.rpc_client().delete_software_deployment(
|
||||
self.context, self.resource_id)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
|
||||
if derived_config_id:
|
||||
self._delete_derived_config(derived_config_id)
|
||||
|
@ -702,13 +702,11 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||
self.USER_DATA_FORMAT] == self.SOFTWARE_CONFIG
|
||||
|
||||
def get_software_config(self, ud_content):
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('NotFound'):
|
||||
sc = self.rpc_client().show_software_config(
|
||||
self.context, ud_content)
|
||||
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'NotFound')
|
||||
return ud_content
|
||||
return ud_content
|
||||
|
||||
def handle_create(self):
|
||||
security_groups = self.properties[self.SECURITY_GROUPS]
|
||||
|
@ -521,14 +521,12 @@ class StackResource(resource.Resource):
|
||||
if stack_identity is None:
|
||||
return
|
||||
|
||||
try:
|
||||
with self.rpc_client().ignore_error_by_name('EntityNotFound'):
|
||||
if self.abandon_in_progress:
|
||||
self.rpc_client().abandon_stack(self.context, stack_identity)
|
||||
else:
|
||||
self.rpc_client().delete_stack(self.context, stack_identity,
|
||||
cast=False)
|
||||
except Exception as ex:
|
||||
self.rpc_client().ignore_error_named(ex, 'EntityNotFound')
|
||||
|
||||
def handle_delete(self):
|
||||
return self.delete_nested()
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
"""Client side of the heat engine RPC API."""
|
||||
|
||||
import warnings
|
||||
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import reflection
|
||||
|
||||
from heat.common import messaging
|
||||
@ -100,14 +103,26 @@ class EngineClient(object):
|
||||
error_name = reflection.get_class_name(error, fully_qualified=False)
|
||||
return error_name.split('_Remote')[0]
|
||||
|
||||
def ignore_error_by_name(self, name):
|
||||
"""Returns a context manager that filters exceptions with a given name.
|
||||
|
||||
:param name: Name to compare the local exception name to.
|
||||
"""
|
||||
def error_name_matches(err):
|
||||
return self.local_error_name(err) == name
|
||||
|
||||
return excutils.exception_filter(error_name_matches)
|
||||
|
||||
def ignore_error_named(self, error, name):
|
||||
"""Raises the error unless its local name matches the supplied name.
|
||||
|
||||
:param error: Remote raised error to derive the local name from.
|
||||
:param name: Name to compare local name to.
|
||||
"""
|
||||
if self.local_error_name(error) != name:
|
||||
raise error
|
||||
warnings.warn("Use ignore_error_by_name() to get a context manager "
|
||||
"instead.",
|
||||
DeprecationWarning)
|
||||
return self.ignore_error_by_name(name)(error)
|
||||
|
||||
def identify_stack(self, ctxt, stack_name):
|
||||
"""Returns the full stack identifier for a single, live stack.
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import email
|
||||
import uuid
|
||||
|
||||
@ -99,7 +100,17 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||
'type': 'text'
|
||||
}]
|
||||
self.init_config(parts=parts)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter():
|
||||
try:
|
||||
yield
|
||||
except exc.NotFound:
|
||||
pass
|
||||
|
||||
self.rpc_client.ignore_error_by_name.return_value = exc_filter()
|
||||
self.rpc_client.show_software_config.side_effect = exc.NotFound()
|
||||
|
||||
result = self.config.get_message()
|
||||
|
||||
self.assertEqual(
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
import six
|
||||
|
||||
@ -59,6 +60,15 @@ class SoftwareComponentTest(common.HeatTestCase):
|
||||
self.rpc_client = mock.MagicMock()
|
||||
self.component._rpc_client = self.rpc_client
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exc.NotFound:
|
||||
pass
|
||||
|
||||
self.rpc_client.ignore_error_by_name.side_effect = exc_filter
|
||||
|
||||
def test_handle_create(self):
|
||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||
value = {'id': config_id}
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
|
||||
from heat.common import exception as exc
|
||||
@ -45,6 +46,15 @@ class SoftwareConfigTest(common.HeatTestCase):
|
||||
self.rpc_client = mock.MagicMock()
|
||||
self.config._rpc_client = self.rpc_client
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exc.NotFound:
|
||||
pass
|
||||
|
||||
self.rpc_client.ignore_error_by_name.side_effect = exc_filter
|
||||
|
||||
def test_handle_create(self):
|
||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||
value = {'id': config_id}
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import copy
|
||||
import re
|
||||
import uuid
|
||||
@ -204,6 +205,15 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||
self.rpc_client = mock.MagicMock()
|
||||
self.deployment._rpc_client = self.rpc_client
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exc.NotFound:
|
||||
pass
|
||||
|
||||
self.rpc_client.ignore_error_by_name.side_effect = exc_filter
|
||||
|
||||
def test_validate(self):
|
||||
template = dict(self.template_with_server)
|
||||
props = template['Resources']['server']['Properties']
|
||||
@ -1188,7 +1198,11 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||
}],
|
||||
'outputs': [],
|
||||
}
|
||||
self.rpc_client.show_software_config.return_value = config
|
||||
|
||||
def show_sw_config(*args):
|
||||
return config.copy()
|
||||
|
||||
self.rpc_client.show_software_config.side_effect = show_sw_config
|
||||
mock_sd = self.mock_deployment()
|
||||
|
||||
self.rpc_client.show_software_deployment.return_value = mock_sd
|
||||
|
@ -12,6 +12,7 @@
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import contextlib
|
||||
import copy
|
||||
import mock
|
||||
|
||||
@ -686,6 +687,14 @@ class ServersTest(common.HeatTestCase):
|
||||
self.rpc_client = mock.MagicMock()
|
||||
server._rpc_client = self.rpc_client
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
self.rpc_client.ignore_error_by_name.side_effect = exc_filter
|
||||
self.rpc_client.show_software_config.side_effect = exception.NotFound
|
||||
mock_create = self.patchobject(self.fc.servers, 'create',
|
||||
return_value=return_server)
|
||||
|
@ -56,6 +56,24 @@ class EngineRpcAPITestCase(common.HeatTestCase):
|
||||
reflection.get_class_name(exr, fully_qualified=False))
|
||||
self.assertEqual('NotFound', self.rpcapi.local_error_name(exr))
|
||||
|
||||
def test_ignore_error_by_name(self):
|
||||
ex = exception.NotFound()
|
||||
exr = self._to_remote_error(ex)
|
||||
|
||||
filter_exc = self.rpcapi.ignore_error_by_name('NotFound')
|
||||
|
||||
with filter_exc:
|
||||
raise ex
|
||||
with filter_exc:
|
||||
raise exr
|
||||
|
||||
def should_raise(exc):
|
||||
with self.rpcapi.ignore_error_by_name('NotSupported'):
|
||||
raise exc
|
||||
|
||||
self.assertRaises(exception.NotFound, should_raise, ex)
|
||||
self.assertRaises(exception.NotFound, should_raise, exr)
|
||||
|
||||
def test_ignore_error_named(self):
|
||||
ex = exception.NotFound()
|
||||
exr = self._to_remote_error(ex)
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import uuid
|
||||
|
||||
@ -204,7 +205,16 @@ class StackResourceTest(StackResourceBaseTest):
|
||||
self.assertEqual({}, ret)
|
||||
|
||||
def test_abandon_nested_sends_rpc_abandon(self):
|
||||
rpcc = mock.Mock()
|
||||
rpcc = mock.MagicMock()
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
rpcc.ignore_error_by_name.side_effect = exc_filter
|
||||
self.parent_resource.rpc_client = rpcc
|
||||
self.parent_resource.resource_id = 'fake_id'
|
||||
|
||||
@ -509,8 +519,17 @@ class StackResourceTest(StackResourceBaseTest):
|
||||
|
||||
def test_delete_nested_not_found_nested_stack(self):
|
||||
self.parent_resource.resource_id = 'fake_id'
|
||||
rpcc = mock.Mock()
|
||||
rpcc = mock.MagicMock()
|
||||
self.parent_resource.rpc_client = rpcc
|
||||
|
||||
@contextlib.contextmanager
|
||||
def exc_filter(*args):
|
||||
try:
|
||||
yield
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
rpcc.return_value.ignore_error_by_name.side_effect = exc_filter
|
||||
rpcc.return_value.delete_stack = mock.Mock(
|
||||
side_effect=exception.NotFound())
|
||||
self.assertIsNone(self.parent_resource.delete_nested())
|
||||
|
Loading…
Reference in New Issue
Block a user