DB API: Pass columns_to_join to instance_get_active_by_window_joined
This makes the instance_get_active_by_window_joined database API configurable for which columns should be joined from other tables, similar to instance_get_all. This lays the groundwork for the Instance object to pass expected_attrs to the DB API for filtering which columns to load. Partial-Bug: #1383469 Change-Id: I7089d732cbd06a854d47b7b9e4faf21b9ef498f1
This commit is contained in:
parent
9736fc659c
commit
152767927c
|
@ -664,7 +664,8 @@ def instance_get_all_by_filters(context, filters, sort_key='created_at',
|
|||
|
||||
def instance_get_active_by_window_joined(context, begin, end=None,
|
||||
project_id=None, host=None,
|
||||
use_slave=False):
|
||||
use_slave=False,
|
||||
columns_to_join=None):
|
||||
"""Get instances and joins active during a certain time window.
|
||||
|
||||
Specifying a project_id will filter for a certain project.
|
||||
|
@ -672,7 +673,8 @@ def instance_get_active_by_window_joined(context, begin, end=None,
|
|||
"""
|
||||
return IMPL.instance_get_active_by_window_joined(context, begin, end,
|
||||
project_id, host,
|
||||
use_slave=use_slave)
|
||||
use_slave=use_slave,
|
||||
columns_to_join=columns_to_join)
|
||||
|
||||
|
||||
def instance_get_all_by_host(context, host,
|
||||
|
|
|
@ -2145,14 +2145,22 @@ def process_sort_params(sort_keys, sort_dirs,
|
|||
@require_context
|
||||
def instance_get_active_by_window_joined(context, begin, end=None,
|
||||
project_id=None, host=None,
|
||||
use_slave=False):
|
||||
use_slave=False,
|
||||
columns_to_join=None):
|
||||
"""Return instances and joins that were active during window."""
|
||||
session = get_session(use_slave=use_slave)
|
||||
query = session.query(models.Instance)
|
||||
|
||||
query = query.options(joinedload('info_cache')).\
|
||||
options(joinedload('security_groups')).\
|
||||
filter(or_(models.Instance.terminated_at == null(),
|
||||
if columns_to_join is None:
|
||||
columns_to_join = ['info_cache', 'security_groups']
|
||||
manual_joins = ['metadata', 'system_metadata']
|
||||
else:
|
||||
manual_joins, columns_to_join = _manual_join_columns(columns_to_join)
|
||||
|
||||
for column in columns_to_join:
|
||||
query = query.options(joinedload(column))
|
||||
|
||||
query = query.filter(or_(models.Instance.terminated_at == null(),
|
||||
models.Instance.terminated_at > begin))
|
||||
if end:
|
||||
query = query.filter(models.Instance.launched_at < end)
|
||||
|
@ -2161,7 +2169,7 @@ def instance_get_active_by_window_joined(context, begin, end=None,
|
|||
if host:
|
||||
query = query.filter_by(host=host)
|
||||
|
||||
return _instances_fill_metadata(context, query.all())
|
||||
return _instances_fill_metadata(context, query.all(), manual_joins)
|
||||
|
||||
|
||||
def _instance_get_all_query(context, project_only=False,
|
||||
|
|
|
@ -727,25 +727,65 @@ class SqlAlchemyDbApiTestCase(DbTestCase):
|
|||
now2 = now + datetime.timedelta(minutes=2)
|
||||
now3 = now + datetime.timedelta(minutes=3)
|
||||
ctxt = context.get_admin_context()
|
||||
self.create_instance_with_args(launched_at=now)
|
||||
self.create_instance_with_args(launched_at=now1, terminated_at=now2)
|
||||
self.create_instance_with_args(launched_at=now2, terminated_at=now3)
|
||||
self.create_instance_with_args(launched_at=now3, terminated_at=None)
|
||||
# used for testing columns_to_join
|
||||
network_info = jsonutils.dumps({'ckey': 'cvalue'})
|
||||
sample_data = {
|
||||
'metadata': {'mkey1': 'mval1', 'mkey2': 'mval2'},
|
||||
'system_metadata': {'smkey1': 'smval1', 'smkey2': 'smval2'},
|
||||
'info_cache': {'network_info': network_info},
|
||||
}
|
||||
self.create_instance_with_args(launched_at=now, **sample_data)
|
||||
self.create_instance_with_args(launched_at=now1, terminated_at=now2,
|
||||
**sample_data)
|
||||
self.create_instance_with_args(launched_at=now2, terminated_at=now3,
|
||||
**sample_data)
|
||||
self.create_instance_with_args(launched_at=now3, terminated_at=None,
|
||||
**sample_data)
|
||||
|
||||
result = sqlalchemy_api.instance_get_active_by_window_joined(
|
||||
ctxt, begin=now)
|
||||
self.assertEqual(4, len(result))
|
||||
# verify that all default columns are joined
|
||||
meta = utils.metadata_to_dict(result[0]['metadata'])
|
||||
self.assertEqual(sample_data['metadata'], meta)
|
||||
sys_meta = utils.metadata_to_dict(result[0]['system_metadata'])
|
||||
self.assertEqual(sample_data['system_metadata'], sys_meta)
|
||||
self.assertIn('info_cache', result[0])
|
||||
|
||||
result = sqlalchemy_api.instance_get_active_by_window_joined(
|
||||
ctxt, begin=now3)
|
||||
ctxt, begin=now3, columns_to_join=['info_cache'])
|
||||
self.assertEqual(2, len(result))
|
||||
# verify that only info_cache is loaded
|
||||
meta = utils.metadata_to_dict(result[0]['metadata'])
|
||||
self.assertEqual({}, meta)
|
||||
self.assertIn('info_cache', result[0])
|
||||
|
||||
result = sqlalchemy_api.instance_get_active_by_window_joined(
|
||||
ctxt, begin=start_time, end=now)
|
||||
self.assertEqual(0, len(result))
|
||||
|
||||
result = sqlalchemy_api.instance_get_active_by_window_joined(
|
||||
ctxt, begin=start_time, end=now2)
|
||||
ctxt, begin=start_time, end=now2,
|
||||
columns_to_join=['system_metadata'])
|
||||
self.assertEqual(2, len(result))
|
||||
# verify that only system_metadata is loaded
|
||||
meta = utils.metadata_to_dict(result[0]['metadata'])
|
||||
self.assertEqual({}, meta)
|
||||
sys_meta = utils.metadata_to_dict(result[0]['system_metadata'])
|
||||
self.assertEqual(sample_data['system_metadata'], sys_meta)
|
||||
self.assertNotIn('info_cache', result[0])
|
||||
|
||||
result = sqlalchemy_api.instance_get_active_by_window_joined(
|
||||
ctxt, begin=now2, end=now3)
|
||||
ctxt, begin=now2, end=now3,
|
||||
columns_to_join=['metadata', 'info_cache'])
|
||||
self.assertEqual(2, len(result))
|
||||
# verify that only metadata and info_cache are loaded
|
||||
meta = utils.metadata_to_dict(result[0]['metadata'])
|
||||
self.assertEqual(sample_data['metadata'], meta)
|
||||
sys_meta = utils.metadata_to_dict(result[0]['system_metadata'])
|
||||
self.assertEqual({}, sys_meta)
|
||||
self.assertIn('info_cache', result[0])
|
||||
self.assertEqual(network_info, result[0]['info_cache']['network_info'])
|
||||
|
||||
|
||||
class ProcessSortParamTestCase(test.TestCase):
|
||||
|
|
Loading…
Reference in New Issue