Pass the Idl directly to Connection
ovs.db.Idl does not actually create a connection on initialization. Instead, it makes the connection when run() is called. This means we don't have to wait until start() is called to create the Idl instance. In addition, adding the optional self.post_connect() call to start() will allow networking-ovn and others to more easily use the notification feature of the Idl. It is equivalent to the post_initalize function in networking_ovn's OvnIdl subclass, but as it is run after wait_for_change(), post_connect() is a more appropriate name. A from_server() classmethod which can be used to create an Idl instance by retrieving the schema from the server. Change-Id: I6638bc661ae5077192c06be33e77252b91653f4c
This commit is contained in:
parent
0e7ff45d95
commit
108d23177d
|
@ -16,6 +16,7 @@ import os
|
|||
import threading
|
||||
import traceback
|
||||
|
||||
from ovs.db import idl
|
||||
from ovs import poller
|
||||
import six
|
||||
from six.moves import queue as Queue
|
||||
|
@ -52,26 +53,30 @@ class TransactionQueue(Queue.Queue, object):
|
|||
|
||||
class Connection(object):
|
||||
|
||||
def __init__(self, idl_factory, timeout):
|
||||
def __init__(self, idl, timeout):
|
||||
"""Create a connection to an OVSDB server using the OVS IDL
|
||||
|
||||
:param timeout: The timeout value for OVSDB operations
|
||||
:param idl_factory: A factory function that produces an Idl instance
|
||||
:param idl: A newly created ovs.db.Idl instance (run never called)
|
||||
"""
|
||||
self.idl = None
|
||||
self.timeout = timeout
|
||||
self.txns = TransactionQueue(1)
|
||||
self.lock = threading.Lock()
|
||||
self.idl_factory = idl_factory
|
||||
self.idl = idl
|
||||
self.thread = None
|
||||
|
||||
def start(self):
|
||||
"""Start the connection."""
|
||||
with self.lock:
|
||||
if self.idl is not None:
|
||||
return
|
||||
|
||||
self.idl = self.idl_factory()
|
||||
idlutils.wait_for_change(self.idl, self.timeout)
|
||||
if self.thread is not None:
|
||||
return False
|
||||
if not self.idl.has_ever_connected():
|
||||
idlutils.wait_for_change(self.idl, self.timeout)
|
||||
try:
|
||||
self.idl.post_connect()
|
||||
except AttributeError:
|
||||
# An ovs.db.Idl class has no post_connect
|
||||
pass
|
||||
self.poller = poller.Poller()
|
||||
self.thread = threading.Thread(target=self.run)
|
||||
self.thread.setDaemon(True)
|
||||
|
@ -98,3 +103,19 @@ class Connection(object):
|
|||
|
||||
def queue_txn(self, txn):
|
||||
self.txns.put(txn)
|
||||
|
||||
|
||||
class OvsdbIdl(idl.Idl):
|
||||
@classmethod
|
||||
def from_server(cls, connection_string, schema_name):
|
||||
"""Create the Idl instance by pulling the schema from OVSDB server"""
|
||||
helper = idlutils.get_schema_helper(connection_string, schema_name)
|
||||
helper.register_all()
|
||||
return cls(connection_string, helper)
|
||||
|
||||
def post_connect(self):
|
||||
"""Operations to execute after the Idl has connected to the server
|
||||
|
||||
An example would be to set up Idl notification handling for watching
|
||||
and unwatching certain OVSDB change events
|
||||
"""
|
||||
|
|
|
@ -13,25 +13,16 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ovs.db import idl
|
||||
|
||||
from ovsdbapp.backend.ovs_idl import connection
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp import constants
|
||||
from ovsdbapp.schema.open_vswitch import impl_idl
|
||||
from ovsdbapp.tests import base
|
||||
from ovsdbapp.tests import utils
|
||||
|
||||
|
||||
def default_idl_factory():
|
||||
helper = idlutils.get_schema_helper(constants.DEFAULT_OVSDB_CONNECTION,
|
||||
'Open_vSwitch')
|
||||
helper.register_all()
|
||||
return idl.Idl(constants.DEFAULT_OVSDB_CONNECTION, helper)
|
||||
|
||||
|
||||
ovsdb_connection = connection.Connection(
|
||||
idl_factory=default_idl_factory, timeout=constants.DEFAULT_TIMEOUT)
|
||||
idl=connection.OvsdbIdl.from_server(
|
||||
constants.DEFAULT_OVSDB_CONNECTION, 'Open_vSwitch'),
|
||||
timeout=constants.DEFAULT_TIMEOUT)
|
||||
|
||||
|
||||
class TestOvsdbIdl(base.TestCase):
|
||||
|
|
|
@ -27,19 +27,18 @@ class TestOVSNativeConnection(base.TestCase):
|
|||
@mock.patch.object(connection, 'TransactionQueue')
|
||||
def setUp(self, mock_trans_queue):
|
||||
super(TestOVSNativeConnection, self).setUp()
|
||||
self.idl_factory = mock.Mock()
|
||||
self.idl = mock.Mock()
|
||||
self.mock_trans_queue = mock_trans_queue
|
||||
self.conn = connection.Connection(self.idl_factory,
|
||||
timeout=1)
|
||||
self.conn = connection.Connection(self.idl, timeout=1)
|
||||
self.mock_trans_queue.assert_called_once_with(1)
|
||||
|
||||
@mock.patch.object(threading, 'Thread')
|
||||
@mock.patch.object(poller, 'Poller')
|
||||
@mock.patch.object(idlutils, 'wait_for_change')
|
||||
def test_start(self, mock_wait_for_change, mock_poller, mock_thread):
|
||||
self.idl.has_ever_connected.return_value = False
|
||||
self.conn.start()
|
||||
|
||||
self.idl_factory.assert_called_once_with()
|
||||
self.idl.has_ever_connected.assert_called_once()
|
||||
mock_wait_for_change.assert_called_once_with(self.conn.idl,
|
||||
self.conn.timeout)
|
||||
mock_poller.assert_called_once_with()
|
||||
|
|
Loading…
Reference in New Issue