From: Ihar Hrachyshka Date: Sun, 2 Aug 2015 21:44:53 +0000 (+0200) Subject: use single transaction to update qos policy associatation X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=651eeb6a5f40e58b7a6b3ccb59826bb6f08827c0;p=openstack-build%2Fneutron-build.git use single transaction to update qos policy associatation To make association changes atomic, use autonested transaction. Change-Id: I582ff43a0ce2f17e3f9fedf7cd32dfbac1ebae28 Partially-Implements: blueprint quantum-qos-api --- diff --git a/neutron/services/qos/qos_extension.py b/neutron/services/qos/qos_extension.py index fb1b09116..77ae4220e 100644 --- a/neutron/services/qos/qos_extension.py +++ b/neutron/services/qos/qos_extension.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron.db import api as db_api from neutron import manager from neutron.objects.qos import policy as policy_object from neutron.plugins.common import constants as plugin_constants @@ -39,11 +40,6 @@ class QosResourceExtensionHandler(object): old_policy = policy_object.QosPolicy.get_port_policy( context, port['id']) if old_policy: - #TODO(QoS): this means two transactions. One for detaching - # one for re-attaching, we may want to update - # within a single transaction instead, or put - # a whole transaction on top, or handle the switch - # at db api level automatically within transaction. old_policy.detach_port(port['id']) qos_policy_id = port_changes.get(qos_consts.QOS_POLICY_ID) @@ -71,7 +67,8 @@ class QosResourceExtensionHandler(object): network[qos_consts.QOS_POLICY_ID] = qos_policy_id def _exec(self, method_name, context, kwargs): - return getattr(self, method_name)(context=context, **kwargs) + with db_api.autonested_transaction(context.session): + return getattr(self, method_name)(context=context, **kwargs) def process_resource(self, context, resource_type, requested_resource, actual_resource): diff --git a/neutron/tests/unit/services/qos/test_qos_extension.py b/neutron/tests/unit/services/qos/test_qos_extension.py index bc1563b6f..4252167ea 100644 --- a/neutron/tests/unit/services/qos/test_qos_extension.py +++ b/neutron/tests/unit/services/qos/test_qos_extension.py @@ -15,6 +15,7 @@ import mock +from neutron import context from neutron.plugins.common import constants as plugin_constants from neutron.services.qos import qos_consts from neutron.services.qos import qos_extension @@ -33,9 +34,11 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): self.ext_handler = qos_extension.QosResourceExtensionHandler() policy_p = mock.patch('neutron.objects.qos.policy.QosPolicy') self.policy_m = policy_p.start() + self.context = context.get_admin_context() def test_process_resource_no_qos_policy_id(self): - self.ext_handler.process_resource(None, qos_extension.PORT, {}, None) + self.ext_handler.process_resource( + self.context, qos_extension.PORT, {}, None) self.assertFalse(self.policy_m.called) def _mock_plugin_loaded(self, plugin_loaded): @@ -48,7 +51,7 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): def test_process_resource_no_qos_plugin_loaded(self): with self._mock_plugin_loaded(False): self.ext_handler.process_resource( - None, qos_extension.PORT, + self.context, qos_extension.PORT, {qos_consts.QOS_POLICY_ID: None}, None) self.assertFalse(self.policy_m.called) @@ -60,7 +63,7 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): qos_policy = mock.MagicMock() self.policy_m.get_by_id = mock.Mock(return_value=qos_policy) self.ext_handler.process_resource( - None, qos_extension.PORT, + self.context, qos_extension.PORT, {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_port) @@ -78,7 +81,7 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): new_qos_policy = mock.MagicMock() self.policy_m.get_by_id = mock.Mock(return_value=new_qos_policy) self.ext_handler.process_resource( - None, qos_extension.PORT, + self.context, qos_extension.PORT, {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_port) @@ -93,7 +96,7 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): qos_policy = mock.MagicMock() self.policy_m.get_by_id = mock.Mock(return_value=qos_policy) self.ext_handler.process_resource( - None, qos_extension.NETWORK, + self.context, qos_extension.NETWORK, {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) qos_policy.attach_network.assert_called_once_with( @@ -111,7 +114,7 @@ class QosResourceExtensionHandlerTestCase(base.BaseTestCase): new_qos_policy = mock.MagicMock() self.policy_m.get_by_id = mock.Mock(return_value=new_qos_policy) self.ext_handler.process_resource( - None, qos_extension.NETWORK, + self.context, qos_extension.NETWORK, {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) old_qos_policy.detach_network.assert_called_once_with(network_id)