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:
Flavio Percoco 2014-08-05 13:44:30 +02:00 committed by Flavio Percoco
parent 83e57a6324
commit ab1d471d94
2 changed files with 48 additions and 7 deletions

View File

@ -17,6 +17,7 @@ import uuid
from oslo.config import cfg
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 sqlalchemy
from zaqar.queues.storage import utils
@ -40,16 +41,21 @@ class PoolCatalogTest(testing.TestBase):
control = utils.load_storage_driver(self.conf, cache,
control_mode=True)
self.catalogue_ctrl = control.catalogue_controller
self.pools_ctrl = control.pools_controller
self.flavors_ctrl = control.flavors_controller
self.catalogue_ctrl = control.catalogue_controller
# NOTE(cpp-cabrera): populate catalogue
self.pool = str(uuid.uuid1())
self.queue = str(uuid.uuid1())
self.flavor = str(uuid.uuid1())
self.project = str(uuid.uuid1())
self.pools_ctrl.create(self.pool, 100, 'sqlite://:memory:')
self.catalogue_ctrl.insert(self.project, self.queue, self.pool)
self.catalog = pooling.Catalog(self.conf, cache, control)
self.flavors_ctrl.create(self.flavor, self.pool,
project=self.project)
def tearDown(self):
self.catalogue_ctrl.drop_all()
@ -71,3 +77,16 @@ class PoolCatalogTest(testing.TestBase):
self.catalog.register('not_yet', 'mapped')
storage = self.catalog.lookup('not_yet', 'mapped')
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')

View File

@ -185,7 +185,8 @@ class QueueController(RoutingController):
return {}
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
# registered the project/queue. There is a race condition,
@ -380,6 +381,7 @@ class Catalog(object):
self._catalog_conf = self._conf[_CATALOG_GROUP]
self._pools_ctrl = control.pools_controller
self._flavor_ctrl = control.flavors_controller
self._catalogue_ctrl = control.catalogue_controller
# 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']
def register(self, queue, project=None):
def register(self, queue, project=None, flavor=None):
"""Register a new queue in the pool catalog.
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
None for the "global" or "generic" project.
:type project: six.text_type
:param flavor: Flavor for the queue (OPTIONAL)
:type flavor: six.text_type
:raises: NoPoolFound
"""
# NOTE(cpp-cabrera): only register a queue if the entry
# doesn't exist
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:
raise errors.NoPoolFound()
self._catalogue_ctrl.insert(project, queue, pool['name'])
self._catalogue_ctrl.insert(project, queue, pool)
@_pool_id.purges
def deregister(self, queue, project=None):