From f4a684cdcb28228cee94aed43c9db4caee681460 Mon Sep 17 00:00:00 2001
From: Boden R <bodenvmw@gmail.com>
Date: Tue, 17 Jul 2018 12:06:37 -0600
Subject: [PATCH] use autonested_transaction from neutron-lib

A publically consumed db api is available in neutron-lib. This patch
consumes the autonested_transaction by removing it's def from neutron
and replacing all such usages to now use neutron-lib's version of
autonested_transaction.

NeutronLibImpact

Change-Id: I8d7cbb9b90151d252959e9fce8937f3e4e456811
---
 neutron/core_extensions/qos.py                  |  2 +-
 neutron/db/api.py                               | 12 ------------
 neutron/db/l3_db.py                             |  3 ++-
 neutron/objects/base.py                         |  5 +++--
 neutron/scheduler/l3_agent_scheduler.py         |  3 +--
 neutron/services/qos/qos_plugin.py              | 11 ++++++-----
 neutron/services/trunk/plugin.py                |  2 +-
 neutron/services/trunk/rpc/server.py            |  2 +-
 neutron/tests/unit/db/test_db_base_plugin_v2.py |  2 +-
 neutron/tests/unit/objects/test_base.py         |  5 +++--
 10 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/neutron/core_extensions/qos.py b/neutron/core_extensions/qos.py
index 72eecffd7d2..4eba04d961a 100644
--- a/neutron/core_extensions/qos.py
+++ b/neutron/core_extensions/qos.py
@@ -13,13 +13,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from neutron_lib.db import api as db_api
 from neutron_lib.plugins import constants as plugin_constants
 from neutron_lib.plugins import directory
 from neutron_lib.services.qos import constants as qos_consts
 
 from neutron.common import exceptions as n_exc
 from neutron.core_extensions import base
-from neutron.db import api as db_api
 from neutron.objects.qos import policy as policy_object
 
 
diff --git a/neutron/db/api.py b/neutron/db/api.py
index 9a9016d5ad3..08d6c6149eb 100644
--- a/neutron/db/api.py
+++ b/neutron/db/api.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import contextlib
 import copy
 import weakref
 
@@ -136,17 +135,6 @@ def _is_nested_instance(e, etypes):
     return False
 
 
-@contextlib.contextmanager
-def autonested_transaction(sess):
-    """This is a convenience method to not bother with 'nested' parameter."""
-    if sess.is_active:
-        session_context = sess.begin(nested=True)
-    else:
-        session_context = sess.begin(subtransactions=True)
-    with session_context as tx:
-        yield tx
-
-
 @event.listens_for(orm.session.Session, "after_flush")
 def add_to_rel_load_list(session, flush_context=None):
     # keep track of new items to load relationships on during commit
diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py
index 99b7abddaf3..193a64438a5 100644
--- a/neutron/db/l3_db.py
+++ b/neutron/db/l3_db.py
@@ -26,6 +26,7 @@ from neutron_lib.callbacks import registry
 from neutron_lib.callbacks import resources
 from neutron_lib import constants
 from neutron_lib import context as n_ctx
+from neutron_lib.db import api as lib_db_api
 from neutron_lib.db import utils as lib_db_utils
 from neutron_lib import exceptions as n_exc
 from neutron_lib.exceptions import l3 as l3_exc
@@ -716,7 +717,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
                 raise n_exc.BadRequest(resource='router', msg=msg)
 
     def _validate_router_port_info(self, context, router, port_id):
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # check again within transaction to mitigate race
             port = self._check_router_port(context, port_id, router.id)
 
diff --git a/neutron/objects/base.py b/neutron/objects/base.py
index cd39b11d0a7..0c5745ca79a 100644
--- a/neutron/objects/base.py
+++ b/neutron/objects/base.py
@@ -16,6 +16,7 @@ import copy
 import functools
 import itertools
 
+from neutron_lib.db import api as lib_db_api
 from neutron_lib import exceptions as n_exc
 from neutron_lib.objects import exceptions as o_exc
 from oslo_db import exception as obj_exc
@@ -525,14 +526,14 @@ class NeutronDbObject(NeutronObject):
         """Return read-write session activation decorator."""
         if cls.new_facade or cls._use_db_facade(context):
             return db_api.context_manager.writer.using(context)
-        return db_api.autonested_transaction(context.session)
+        return lib_db_api.autonested_transaction(context.session)
 
     @classmethod
     def db_context_reader(cls, context):
         """Return read-only session activation decorator."""
         if cls.new_facade or cls._use_db_facade(context):
             return db_api.context_manager.reader.using(context)
-        return db_api.autonested_transaction(context.session)
+        return lib_db_api.autonested_transaction(context.session)
 
     @classmethod
     def get_object(cls, context, **kwargs):
diff --git a/neutron/scheduler/l3_agent_scheduler.py b/neutron/scheduler/l3_agent_scheduler.py
index de499d79484..924a72ed9d5 100644
--- a/neutron/scheduler/l3_agent_scheduler.py
+++ b/neutron/scheduler/l3_agent_scheduler.py
@@ -30,7 +30,6 @@ import six
 
 from neutron.common import utils
 from neutron.conf.db import l3_hamode_db
-from neutron.db import api as db_api
 from neutron.db.models import l3agent as rb_model
 from neutron.objects import l3agent as rb_obj
 
@@ -287,7 +286,7 @@ class L3Scheduler(object):
             port_binding = utils.create_object_with_dependency(
                 creator, dep_getter, dep_creator,
                 dep_id_attr, dep_deleter)[0]
-            with db_api.autonested_transaction(context.session):
+            with lib_db_api.autonested_transaction(context.session):
                 port_binding.l3_agent_id = agent['id']
         except db_exc.DBDuplicateEntry:
             LOG.debug("Router %(router)s already scheduled for agent "
diff --git a/neutron/services/qos/qos_plugin.py b/neutron/services/qos/qos_plugin.py
index c870e5acfe9..59ddd601798 100644
--- a/neutron/services/qos/qos_plugin.py
+++ b/neutron/services/qos/qos_plugin.py
@@ -17,6 +17,7 @@ from neutron_lib.api.definitions import qos as qos_apidef
 from neutron_lib.callbacks import events as callbacks_events
 from neutron_lib.callbacks import registry as callbacks_registry
 from neutron_lib.callbacks import resources as callbacks_resources
+from neutron_lib.db import api as lib_db_api
 from neutron_lib import exceptions as lib_exc
 from neutron_lib.services.qos import constants as qos_consts
 
@@ -298,7 +299,7 @@ class QoSPlugin(qos.QoSPluginBase):
         rule_type = rule_cls.rule_type
         rule_data = rule_data[rule_type + '_rule']
 
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # Ensure that we have access to the policy.
             policy = policy_object.QosPolicy.get_policy_obj(context, policy_id)
             checker.check_bandwidth_rule_conflict(policy, rule_data)
@@ -335,7 +336,7 @@ class QoSPlugin(qos.QoSPluginBase):
         rule_type = rule_cls.rule_type
         rule_data = rule_data[rule_type + '_rule']
 
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # Ensure we have access to the policy.
             policy = policy_object.QosPolicy.get_policy_obj(context, policy_id)
             # Ensure the rule belongs to the policy.
@@ -368,7 +369,7 @@ class QoSPlugin(qos.QoSPluginBase):
 
         :returns: None
         """
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # Ensure we have access to the policy.
             policy = policy_object.QosPolicy.get_policy_obj(context, policy_id)
             rule = policy.get_rule_by_id(rule_id)
@@ -397,7 +398,7 @@ class QoSPlugin(qos.QoSPluginBase):
         :returns: a QoS policy rule object
         :raises: n_exc.QosRuleNotFound
         """
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # Ensure we have access to the policy.
             policy_object.QosPolicy.get_policy_obj(context, policy_id)
             rule = rule_cls.get_object(context, id=rule_id)
@@ -422,7 +423,7 @@ class QoSPlugin(qos.QoSPluginBase):
 
         :returns: QoS policy rule objects meeting the search criteria
         """
-        with db_api.autonested_transaction(context.session):
+        with lib_db_api.autonested_transaction(context.session):
             # Ensure we have access to the policy.
             policy_object.QosPolicy.get_policy_obj(context, policy_id)
             filters = filters or dict()
diff --git a/neutron/services/trunk/plugin.py b/neutron/services/trunk/plugin.py
index 6270ea0b1a3..88afb45d1f2 100644
--- a/neutron/services/trunk/plugin.py
+++ b/neutron/services/trunk/plugin.py
@@ -20,13 +20,13 @@ from neutron_lib.callbacks import events
 from neutron_lib.callbacks import registry
 from neutron_lib.callbacks import resources
 from neutron_lib import context
+from neutron_lib.db import api as db_api
 from neutron_lib.plugins import directory
 from neutron_lib.services import base as service_base
 from oslo_log import log as logging
 from oslo_utils import uuidutils
 
 from neutron.db import _resource_extend as resource_extend
-from neutron.db import api as db_api
 from neutron.db import common_db_mixin
 from neutron.db import db_base_plugin_common
 from neutron.objects import base as objects_base
diff --git a/neutron/services/trunk/rpc/server.py b/neutron/services/trunk/rpc/server.py
index 7004632257e..677d8b892cf 100644
--- a/neutron/services/trunk/rpc/server.py
+++ b/neutron/services/trunk/rpc/server.py
@@ -15,6 +15,7 @@
 import collections
 
 from neutron_lib.api.definitions import portbindings
+from neutron_lib.db import api as db_api
 from neutron_lib.plugins import directory
 from oslo_log import helpers as log_helpers
 from oslo_log import log as logging
@@ -25,7 +26,6 @@ from neutron.api.rpc.callbacks.producer import registry
 from neutron.api.rpc.callbacks import resources
 from neutron.api.rpc.handlers import resources_rpc
 from neutron.common import rpc as n_rpc
-from neutron.db import api as db_api
 from neutron.objects import trunk as trunk_objects
 from neutron.services.trunk import constants as trunk_consts
 from neutron.services.trunk import exceptions as trunk_exc
diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py
index ed9145d0e58..a1125e4ff08 100644
--- a/neutron/tests/unit/db/test_db_base_plugin_v2.py
+++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py
@@ -6274,7 +6274,7 @@ class DbModelMixin(object):
             network = models_v2.Network(name="net_net", status="OK",
                                         admin_state_up=True)
             ctx.session.add(network)
-            with db_api.autonested_transaction(ctx.session):
+            with lib_db_api.autonested_transaction(ctx.session):
                 sg = sg_models.SecurityGroup(name='sg', description='sg')
                 ctx.session.add(sg)
             # ensure db rels aren't loaded until commit for network object
diff --git a/neutron/tests/unit/objects/test_base.py b/neutron/tests/unit/objects/test_base.py
index a06551a1d0b..a5710e0c598 100644
--- a/neutron/tests/unit/objects/test_base.py
+++ b/neutron/tests/unit/objects/test_base.py
@@ -20,6 +20,7 @@ import mock
 import netaddr
 from neutron_lib import constants
 from neutron_lib import context
+from neutron_lib.db import api as lib_db_api
 from neutron_lib import exceptions as n_exc
 from neutron_lib.objects import exceptions as o_exc
 from neutron_lib.objects import utils as obj_utils
@@ -1706,7 +1707,7 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
 
     def test_get_objects_single_transaction(self):
         with mock.patch(self._get_ro_txn_exit_func_name()) as mock_exit:
-            with db_api.autonested_transaction(self.context.session):
+            with lib_db_api.autonested_transaction(self.context.session):
                 self._test_class.get_objects(self.context)
         self.assertEqual(1, mock_exit.call_count)
 
@@ -1721,7 +1722,7 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
         obj.create()
 
         with mock.patch(self._get_ro_txn_exit_func_name()) as mock_exit:
-            with db_api.autonested_transaction(self.context.session):
+            with lib_db_api.autonested_transaction(self.context.session):
                 obj = self._test_class.get_object(self.context,
                                                   **obj._get_composite_keys())
         self.assertEqual(1, mock_exit.call_count)