Filter cgsnapshots data on the DB side
It filters cgsnapshots data on the DB side to improve performance. Change-Id: I399ddec9d21345bf0496a293059963363c7c8cbe Partial-Implements: blueprint data-filtering-on-the-db-side
This commit is contained in:
parent
a5c988f93e
commit
169482c887
|
@ -686,21 +686,9 @@ class API(base.Base):
|
||||||
if (context.is_admin and 'all_tenants' in search_opts):
|
if (context.is_admin and 'all_tenants' in search_opts):
|
||||||
# Need to remove all_tenants to pass the filtering below.
|
# Need to remove all_tenants to pass the filtering below.
|
||||||
del search_opts['all_tenants']
|
del search_opts['all_tenants']
|
||||||
cgsnapshots = self.db.cgsnapshot_get_all(context)
|
cgsnapshots = self.db.cgsnapshot_get_all(context, search_opts)
|
||||||
else:
|
else:
|
||||||
cgsnapshots = self.db.cgsnapshot_get_all_by_project(
|
cgsnapshots = self.db.cgsnapshot_get_all_by_project(
|
||||||
context.elevated(), context.project_id)
|
context.elevated(), context.project_id, search_opts)
|
||||||
|
|
||||||
if search_opts:
|
|
||||||
LOG.debug("Searching by: %s", search_opts)
|
|
||||||
|
|
||||||
results = []
|
|
||||||
not_found = object()
|
|
||||||
for cgsnapshot in cgsnapshots:
|
|
||||||
for opt, value in search_opts.items():
|
|
||||||
if cgsnapshot.get(opt, not_found) != value:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
results.append(cgsnapshot)
|
|
||||||
cgsnapshots = results
|
|
||||||
return cgsnapshots
|
return cgsnapshots
|
||||||
|
|
|
@ -936,9 +936,9 @@ def cgsnapshot_get(context, cgsnapshot_id):
|
||||||
return IMPL.cgsnapshot_get(context, cgsnapshot_id)
|
return IMPL.cgsnapshot_get(context, cgsnapshot_id)
|
||||||
|
|
||||||
|
|
||||||
def cgsnapshot_get_all(context):
|
def cgsnapshot_get_all(context, filters=None):
|
||||||
"""Get all cgsnapshots."""
|
"""Get all cgsnapshots."""
|
||||||
return IMPL.cgsnapshot_get_all(context)
|
return IMPL.cgsnapshot_get_all(context, filters)
|
||||||
|
|
||||||
|
|
||||||
def cgsnapshot_create(context, values):
|
def cgsnapshot_create(context, values):
|
||||||
|
@ -946,14 +946,14 @@ def cgsnapshot_create(context, values):
|
||||||
return IMPL.cgsnapshot_create(context, values)
|
return IMPL.cgsnapshot_create(context, values)
|
||||||
|
|
||||||
|
|
||||||
def cgsnapshot_get_all_by_group(context, group_id):
|
def cgsnapshot_get_all_by_group(context, group_id, filters=None):
|
||||||
"""Get all cgsnapshots belonging to a consistency group."""
|
"""Get all cgsnapshots belonging to a consistency group."""
|
||||||
return IMPL.cgsnapshot_get_all_by_group(context, group_id)
|
return IMPL.cgsnapshot_get_all_by_group(context, group_id, filters)
|
||||||
|
|
||||||
|
|
||||||
def cgsnapshot_get_all_by_project(context, project_id):
|
def cgsnapshot_get_all_by_project(context, project_id, filters=None):
|
||||||
"""Get all cgsnapshots belonging to a project."""
|
"""Get all cgsnapshots belonging to a project."""
|
||||||
return IMPL.cgsnapshot_get_all_by_project(context, project_id)
|
return IMPL.cgsnapshot_get_all_by_project(context, project_id, filters)
|
||||||
|
|
||||||
|
|
||||||
def cgsnapshot_update(context, cgsnapshot_id, values):
|
def cgsnapshot_update(context, cgsnapshot_id, values):
|
||||||
|
|
|
@ -3601,23 +3601,52 @@ def cgsnapshot_get(context, cgsnapshot_id):
|
||||||
return _cgsnapshot_get(context, cgsnapshot_id)
|
return _cgsnapshot_get(context, cgsnapshot_id)
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
def is_valid_model_filters(model, filters):
|
||||||
def cgsnapshot_get_all(context):
|
"""Return True if filter values exist on the model
|
||||||
return model_query(context, models.Cgsnapshot).all()
|
|
||||||
|
:param model: a Cinder model
|
||||||
|
:param filters: dictionary of filters
|
||||||
|
"""
|
||||||
|
for key in filters.keys():
|
||||||
|
try:
|
||||||
|
getattr(model, key)
|
||||||
|
except AttributeError:
|
||||||
|
LOG.debug("'%s' filter key is not valid.", key)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _cgsnapshot_get_all(context, project_id=None, group_id=None, filters=None):
|
||||||
|
query = model_query(context, models.Cgsnapshot)
|
||||||
|
|
||||||
|
if filters:
|
||||||
|
if not is_valid_model_filters(models.Cgsnapshot, filters):
|
||||||
|
return []
|
||||||
|
query = query.filter_by(**filters)
|
||||||
|
|
||||||
|
if project_id:
|
||||||
|
query.filter_by(project_id=project_id)
|
||||||
|
|
||||||
|
if group_id:
|
||||||
|
query.filter_by(consistencygroup_id=group_id)
|
||||||
|
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def cgsnapshot_get_all_by_group(context, group_id):
|
def cgsnapshot_get_all(context, filters=None):
|
||||||
return model_query(context, models.Cgsnapshot).\
|
return _cgsnapshot_get_all(context, filters=filters)
|
||||||
filter_by(consistencygroup_id=group_id).all()
|
|
||||||
|
|
||||||
|
@require_admin_context
|
||||||
|
def cgsnapshot_get_all_by_group(context, group_id, filters=None):
|
||||||
|
return _cgsnapshot_get_all(context, group_id=group_id, filters=filters)
|
||||||
|
|
||||||
|
|
||||||
@require_context
|
@require_context
|
||||||
def cgsnapshot_get_all_by_project(context, project_id):
|
def cgsnapshot_get_all_by_project(context, project_id, filters=None):
|
||||||
authorize_project_context(context, project_id)
|
authorize_project_context(context, project_id)
|
||||||
|
return _cgsnapshot_get_all(context, project_id=project_id, filters=filters)
|
||||||
return model_query(context, models.Cgsnapshot).\
|
|
||||||
filter_by(project_id=project_id).all()
|
|
||||||
|
|
||||||
|
|
||||||
@require_context
|
@require_context
|
||||||
|
|
|
@ -28,7 +28,6 @@ from cinder import exception
|
||||||
from cinder import quota
|
from cinder import quota
|
||||||
from cinder import test
|
from cinder import test
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
THREE = 3
|
THREE = 3
|
||||||
|
@ -1187,6 +1186,57 @@ class DBAPISnapshotTestCase(BaseTest):
|
||||||
self.assertEqual(should_be, db.snapshot_metadata_get(self.ctxt, 1))
|
self.assertEqual(should_be, db.snapshot_metadata_get(self.ctxt, 1))
|
||||||
|
|
||||||
|
|
||||||
|
class DBAPICgsnapshotTestCase(BaseTest):
|
||||||
|
"""Tests for cinder.db.api.cgsnapshot_*."""
|
||||||
|
|
||||||
|
def test_cgsnapshot_get_all_by_filter(self):
|
||||||
|
cgsnapshot1 = db.cgsnapshot_create(self.ctxt, {'id': 1,
|
||||||
|
'consistencygroup_id': 'g1'})
|
||||||
|
cgsnapshot2 = db.cgsnapshot_create(self.ctxt, {'id': 2,
|
||||||
|
'consistencygroup_id': 'g1'})
|
||||||
|
cgsnapshot3 = db.cgsnapshot_create(self.ctxt, {'id': 3,
|
||||||
|
'consistencygroup_id': 'g2'})
|
||||||
|
tests = [
|
||||||
|
({'consistencygroup_id': 'g1'}, [cgsnapshot1, cgsnapshot2]),
|
||||||
|
({'id': 3}, [cgsnapshot3]),
|
||||||
|
({'fake_key': 'fake'}, [])
|
||||||
|
]
|
||||||
|
|
||||||
|
# no filter
|
||||||
|
filters = None
|
||||||
|
cgsnapshots = db.cgsnapshot_get_all(self.ctxt, filters=filters)
|
||||||
|
self.assertEqual(3, len(cgsnapshots))
|
||||||
|
|
||||||
|
for filters, expected in tests:
|
||||||
|
self._assertEqualListsOfObjects(expected,
|
||||||
|
db.cgsnapshot_get_all(
|
||||||
|
self.ctxt,
|
||||||
|
filters))
|
||||||
|
|
||||||
|
def test_cgsnapshot_get_all_by_project(self):
|
||||||
|
cgsnapshot1 = db.cgsnapshot_create(self.ctxt,
|
||||||
|
{'id': 1,
|
||||||
|
'consistencygroup_id': 'g1',
|
||||||
|
'project_id': 1})
|
||||||
|
cgsnapshot2 = db.cgsnapshot_create(self.ctxt,
|
||||||
|
{'id': 2,
|
||||||
|
'consistencygroup_id': 'g1',
|
||||||
|
'project_id': 1})
|
||||||
|
project_id = 1
|
||||||
|
tests = [
|
||||||
|
({'id': 1}, [cgsnapshot1]),
|
||||||
|
({'consistencygroup_id': 'g1'}, [cgsnapshot1, cgsnapshot2]),
|
||||||
|
({'fake_key': 'fake'}, [])
|
||||||
|
]
|
||||||
|
|
||||||
|
for filters, expected in tests:
|
||||||
|
self._assertEqualListsOfObjects(expected,
|
||||||
|
db.cgsnapshot_get_all_by_project(
|
||||||
|
self.ctxt,
|
||||||
|
project_id,
|
||||||
|
filters))
|
||||||
|
|
||||||
|
|
||||||
class DBAPIVolumeTypeTestCase(BaseTest):
|
class DBAPIVolumeTypeTestCase(BaseTest):
|
||||||
|
|
||||||
"""Tests for the db.api.volume_type_* methods."""
|
"""Tests for the db.api.volume_type_* methods."""
|
||||||
|
|
Loading…
Reference in New Issue