Expose trove conductor manager class as conf property
The current implementation of trove conductor hard-codes the conductor manager class name in the cmd entry point thus not allowing it to be set by consumers. This change exposes that classname on the conductor conf so that consumers could plug-in their own manager class. Additionally unit tests are provided to ensure a user defined and conductor manager can be used in addition to the default trove conductor manager. Change-Id: I6bf88dd9cf119f0eb6a197f4bda48c309511297e Implements: blueprint pluggable-conductor-manager
This commit is contained in:
@@ -32,3 +32,6 @@ rabbit_password=f7999d1955c5014aa32c
|
||||
#rabbit_notification_topic = ['notifications']
|
||||
|
||||
rpc_backend = trove.openstack.common.rpc.impl_kombu
|
||||
|
||||
# The manager class to use for conductor. (string value)
|
||||
conductor_manager = trove.conductor.manager.Manager
|
||||
|
||||
@@ -20,9 +20,9 @@ def main(conf):
|
||||
from trove.common.rpc import service as rpc_service
|
||||
from trove.openstack.common import service as openstack_service
|
||||
|
||||
manager = 'trove.conductor.manager.Manager'
|
||||
topic = conf.conductor_queue
|
||||
server = rpc_service.RpcService(manager=manager, topic=topic)
|
||||
server = rpc_service.RpcService(manager=conf.conductor_manager,
|
||||
topic=topic)
|
||||
launcher = openstack_service.launch(server,
|
||||
workers=conf.trove_conductor_workers)
|
||||
launcher.wait()
|
||||
|
||||
@@ -263,6 +263,8 @@ common_opts = [
|
||||
'max_header_line may need to be increased when using '
|
||||
'large tokens (typically those generated by the '
|
||||
'Keystone v3 API with big service catalogs).'),
|
||||
cfg.StrOpt('conductor_manager', default='trove.conductor.manager.Manager',
|
||||
help='Qualified class name to use for conductor manager.')
|
||||
]
|
||||
|
||||
# Datastore specific option groups
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright 2014 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class FakeConf(object):
|
||||
|
||||
def __init__(self, conf_dict):
|
||||
self._conf = conf_dict
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self._conf[name]
|
||||
@@ -0,0 +1,71 @@
|
||||
# Copyright 2014 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
import trove.common.cfg as cfg
|
||||
import trove.tests.fakes.conf as fake_conf
|
||||
|
||||
from trove.cmd import conductor as conductor_cmd
|
||||
from trove.cmd import common as common_cmd
|
||||
from trove.openstack.common import service as os_service
|
||||
|
||||
CONF = cfg.CONF
|
||||
TROVE_UT = 'trove.tests.unittests'
|
||||
|
||||
|
||||
def mocked_conf(manager):
|
||||
return fake_conf.FakeConf({
|
||||
'conductor_queue': 'conductor',
|
||||
'conductor_manager': manager,
|
||||
'trove_conductor_workers': 1,
|
||||
'host': 'mockhost',
|
||||
'report_interval': 1})
|
||||
|
||||
|
||||
class NoopManager(object):
|
||||
pass
|
||||
|
||||
|
||||
class ConductorConfTests(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(ConductorConfTests, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(ConductorConfTests, self).tearDown()
|
||||
|
||||
def _test_manager(self, conf, rt_mgr_name):
|
||||
def mock_launch(server, workers):
|
||||
qualified_mgr = "%s.%s" % (server.manager_impl.__module__,
|
||||
server.manager_impl.__class__.__name__)
|
||||
self.assertEqual(rt_mgr_name, qualified_mgr, "Invalid manager")
|
||||
return mock.MagicMock()
|
||||
|
||||
os_service.launch = mock_launch
|
||||
common_cmd.initialize = mock.MagicMock(return_value=conf)
|
||||
conductor_cmd.main()
|
||||
|
||||
def test_user_defined_manager(self):
|
||||
qualified_mgr = TROVE_UT + ".conductor.test_conf.NoopManager"
|
||||
self._test_manager(mocked_conf(qualified_mgr), qualified_mgr)
|
||||
|
||||
def test_default_manager(self):
|
||||
qualified_mgr = "trove.conductor.manager.Manager"
|
||||
self._test_manager(CONF, qualified_mgr)
|
||||
|
||||
def test_invalid_manager(self):
|
||||
self.assertRaises(ImportError, self._test_manager,
|
||||
mocked_conf('foo.bar.MissingMgr'),
|
||||
'foo.bar.MissingMgr')
|
||||
Reference in New Issue
Block a user