Make the catalog flavor-aware
This patch adds the knowledge of flavors to the catalog. When a new queue is registered, if a flavor is passed, it'll get the pool from the flavor record. If flavor is not passed, it'll preserve the previous behavior. Partially Implements blueprint: marconi-queue-flavors Change-Id: Idcf5a0215699269f29df793169ff21fc6435f3b2
This commit is contained in:
parent
83e57a6324
commit
ab1d471d94
@ -17,6 +17,7 @@ import uuid
|
|||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from zaqar.openstack.common.cache import cache as oslo_cache
|
from zaqar.openstack.common.cache import cache as oslo_cache
|
||||||
|
from zaqar.queues.storage import errors
|
||||||
from zaqar.queues.storage import pooling
|
from zaqar.queues.storage import pooling
|
||||||
from zaqar.queues.storage import sqlalchemy
|
from zaqar.queues.storage import sqlalchemy
|
||||||
from zaqar.queues.storage import utils
|
from zaqar.queues.storage import utils
|
||||||
@ -40,16 +41,21 @@ class PoolCatalogTest(testing.TestBase):
|
|||||||
control = utils.load_storage_driver(self.conf, cache,
|
control = utils.load_storage_driver(self.conf, cache,
|
||||||
control_mode=True)
|
control_mode=True)
|
||||||
|
|
||||||
self.catalogue_ctrl = control.catalogue_controller
|
|
||||||
self.pools_ctrl = control.pools_controller
|
self.pools_ctrl = control.pools_controller
|
||||||
|
self.flavors_ctrl = control.flavors_controller
|
||||||
|
self.catalogue_ctrl = control.catalogue_controller
|
||||||
|
|
||||||
# NOTE(cpp-cabrera): populate catalogue
|
# NOTE(cpp-cabrera): populate catalogue
|
||||||
self.pool = str(uuid.uuid1())
|
self.pool = str(uuid.uuid1())
|
||||||
self.queue = str(uuid.uuid1())
|
self.queue = str(uuid.uuid1())
|
||||||
|
self.flavor = str(uuid.uuid1())
|
||||||
self.project = str(uuid.uuid1())
|
self.project = str(uuid.uuid1())
|
||||||
|
|
||||||
self.pools_ctrl.create(self.pool, 100, 'sqlite://:memory:')
|
self.pools_ctrl.create(self.pool, 100, 'sqlite://:memory:')
|
||||||
self.catalogue_ctrl.insert(self.project, self.queue, self.pool)
|
self.catalogue_ctrl.insert(self.project, self.queue, self.pool)
|
||||||
self.catalog = pooling.Catalog(self.conf, cache, control)
|
self.catalog = pooling.Catalog(self.conf, cache, control)
|
||||||
|
self.flavors_ctrl.create(self.flavor, self.pool,
|
||||||
|
project=self.project)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.catalogue_ctrl.drop_all()
|
self.catalogue_ctrl.drop_all()
|
||||||
@ -71,3 +77,16 @@ class PoolCatalogTest(testing.TestBase):
|
|||||||
self.catalog.register('not_yet', 'mapped')
|
self.catalog.register('not_yet', 'mapped')
|
||||||
storage = self.catalog.lookup('not_yet', 'mapped')
|
storage = self.catalog.lookup('not_yet', 'mapped')
|
||||||
self.assertIsInstance(storage, sqlalchemy.DataDriver)
|
self.assertIsInstance(storage, sqlalchemy.DataDriver)
|
||||||
|
|
||||||
|
def test_register_with_flavor(self):
|
||||||
|
queue = 'test'
|
||||||
|
self.catalog.register(queue, project=self.project,
|
||||||
|
flavor=self.flavor)
|
||||||
|
storage = self.catalog.lookup(queue, self.project)
|
||||||
|
self.assertIsInstance(storage, sqlalchemy.DataDriver)
|
||||||
|
|
||||||
|
def test_register_with_fake_flavor(self):
|
||||||
|
self.assertRaises(errors.FlavorDoesNotExist,
|
||||||
|
self.catalog.register,
|
||||||
|
'test', project=self.project,
|
||||||
|
flavor='fake')
|
||||||
|
@ -185,7 +185,8 @@ class QueueController(RoutingController):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def create(self, name, metadata=None, project=None):
|
def create(self, name, metadata=None, project=None):
|
||||||
self._pool_catalog.register(name, project)
|
flavor = metadata and metadata.get('_flavor', None)
|
||||||
|
self._pool_catalog.register(name, project=project, flavor=flavor)
|
||||||
|
|
||||||
# NOTE(cpp-cabrera): This should always succeed since we just
|
# NOTE(cpp-cabrera): This should always succeed since we just
|
||||||
# registered the project/queue. There is a race condition,
|
# registered the project/queue. There is a race condition,
|
||||||
@ -380,6 +381,7 @@ class Catalog(object):
|
|||||||
self._catalog_conf = self._conf[_CATALOG_GROUP]
|
self._catalog_conf = self._conf[_CATALOG_GROUP]
|
||||||
|
|
||||||
self._pools_ctrl = control.pools_controller
|
self._pools_ctrl = control.pools_controller
|
||||||
|
self._flavor_ctrl = control.flavors_controller
|
||||||
self._catalogue_ctrl = control.catalogue_controller
|
self._catalogue_ctrl = control.catalogue_controller
|
||||||
|
|
||||||
# FIXME(cpp-cabrera): https://bugs.launchpad.net/zaqar/+bug/1252791
|
# FIXME(cpp-cabrera): https://bugs.launchpad.net/zaqar/+bug/1252791
|
||||||
@ -408,7 +410,7 @@ class Catalog(object):
|
|||||||
"""
|
"""
|
||||||
return self._catalogue_ctrl.get(project, queue)['pool']
|
return self._catalogue_ctrl.get(project, queue)['pool']
|
||||||
|
|
||||||
def register(self, queue, project=None):
|
def register(self, queue, project=None, flavor=None):
|
||||||
"""Register a new queue in the pool catalog.
|
"""Register a new queue in the pool catalog.
|
||||||
|
|
||||||
This method should be called whenever a new queue is being
|
This method should be called whenever a new queue is being
|
||||||
@ -425,19 +427,39 @@ class Catalog(object):
|
|||||||
:param project: Project to which the queue belongs, or
|
:param project: Project to which the queue belongs, or
|
||||||
None for the "global" or "generic" project.
|
None for the "global" or "generic" project.
|
||||||
:type project: six.text_type
|
:type project: six.text_type
|
||||||
|
:param flavor: Flavor for the queue (OPTIONAL)
|
||||||
|
:type flavor: six.text_type
|
||||||
|
|
||||||
:raises: NoPoolFound
|
:raises: NoPoolFound
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# NOTE(cpp-cabrera): only register a queue if the entry
|
# NOTE(cpp-cabrera): only register a queue if the entry
|
||||||
# doesn't exist
|
# doesn't exist
|
||||||
if not self._catalogue_ctrl.exists(project, queue):
|
if not self._catalogue_ctrl.exists(project, queue):
|
||||||
# NOTE(cpp-cabrera): limit=0 implies unlimited - select from
|
|
||||||
# all pools
|
|
||||||
pool = select.weighted(self._pools_ctrl.list(limit=0))
|
|
||||||
|
|
||||||
|
if flavor is not None:
|
||||||
|
# TODO(flaper87): If the flavor doesn't exist, this will
|
||||||
|
# raise a `FlavorDoesNotExist` making the transport to treat
|
||||||
|
# this failure as an internal error. However, this is actually
|
||||||
|
# an user error erro since a non valid flavor has been used.
|
||||||
|
# Make sure this error is caught in the queue creation endpoint
|
||||||
|
# and a proper message is logged.
|
||||||
|
flavor = self._flavor_ctrl.get(flavor, project=project)
|
||||||
|
pool = flavor['pool']
|
||||||
|
else:
|
||||||
|
# NOTE(cpp-cabrera): limit=0 implies unlimited - select from
|
||||||
|
# all pools
|
||||||
|
pool = select.weighted(self._pools_ctrl.list(limit=0))
|
||||||
|
pool = pool and pool['name'] or None
|
||||||
|
|
||||||
|
# TODO(flaper87): If the pool is being registered by a
|
||||||
|
# queue creation, we shouldn't raise `NotFound` but a 500
|
||||||
|
# and a proper error message should be logged.wq
|
||||||
if not pool:
|
if not pool:
|
||||||
raise errors.NoPoolFound()
|
raise errors.NoPoolFound()
|
||||||
|
|
||||||
self._catalogue_ctrl.insert(project, queue, pool['name'])
|
self._catalogue_ctrl.insert(project, queue, pool)
|
||||||
|
|
||||||
@_pool_id.purges
|
@_pool_id.purges
|
||||||
def deregister(self, queue, project=None):
|
def deregister(self, queue, project=None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user