diff options
author | Boris Pavlovic <boris@pavlovic.me> | 2013-05-08 16:25:46 +0400 |
---|---|---|
committer | Boris Pavlovic <boris@pavlovic.me> | 2013-05-08 17:16:46 +0400 |
commit | ac9cc15164f0afcac4b3320bcd58d36c00f3232c (patch) | |
tree | 9d2ae38fc73fc2231270a601bc89ee18803b3708 | |
parent | 2e35d7177830e16abd3e919510437f48c6691d51 (diff) | |
download | nova-ac9cc15164f0afcac4b3320bcd58d36c00f3232c.tar.gz nova-ac9cc15164f0afcac4b3320bcd58d36c00f3232c.tar.xz nova-ac9cc15164f0afcac4b3320bcd58d36c00f3232c.zip |
Optimize db.instance_floating_address_get_all method
Optimize db.instance_floating_address_get_all
Was:
Get FixedIps with corresponding instance_uuid
For each FixedIp get associated FloatIp (N request)
Now:
Get only list of FixedIps ids
Get all corresponding FloatingIp with one query (select in)
Get only addresses from FloatingIps (because we are using only it)
Add temporary test for db.instance_floating_address_get_all to
ensure that it works as expected.
Change-Id: Id3c515de0ca35707bbfe46b991c2d7cf591e431b
-rw-r--r-- | nova/db/sqlalchemy/api.py | 21 | ||||
-rw-r--r-- | nova/network/api.py | 2 | ||||
-rw-r--r-- | nova/tests/test_db_api.py | 28 |
3 files changed, 44 insertions, 7 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d5f4c8e6f..bb5978f82 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1911,14 +1911,23 @@ def instance_get_floating_address(context, instance_id): @require_context def instance_floating_address_get_all(context, instance_uuid): - fixed_ips = fixed_ip_get_by_instance(context, instance_uuid) + if not uuidutils.is_uuid_like(instance_uuid): + raise exception.InvalidUUID(uuid=instance_uuid) + + fixed_ip_ids = model_query(context, models.FixedIp.id, + base_model=models.FixedIp).\ + filter_by(instance_uuid=instance_uuid).\ + all() + if not fixed_ip_ids: + raise exception.FixedIpNotFoundForInstance(instance_uuid=instance_uuid) - floating_ips = [] - for fixed_ip in fixed_ips: - _floating_ips = floating_ip_get_by_fixed_ip_id(context, fixed_ip['id']) - floating_ips += _floating_ips + fixed_ip_ids = [fixed_ip_id.id for fixed_ip_id in fixed_ip_ids] - return floating_ips + floating_ips = model_query(context, models.FloatingIp.address, + base_model=models.FloatingIp).\ + filter(models.FloatingIp.fixed_ip_id.in_(fixed_ip_ids)).\ + all() + return [floating_ip.address for floating_ip in floating_ips] @require_admin_context diff --git a/nova/network/api.py b/nova/network/api.py index b8baf9810..26ca7584a 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -486,7 +486,7 @@ class API(base.Base): def _get_floating_ip_addresses(self, context, instance): floating_ips = self.db.instance_floating_address_get_all(context, instance['uuid']) - return [floating_ip['address'] for floating_ip in floating_ips] + return floating_ips @wrap_check_policy def migrate_instance_start(self, context, instance, migration): diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py index cfed3ab3b..626cad630 100644 --- a/nova/tests/test_db_api.py +++ b/nova/tests/test_db_api.py @@ -1023,6 +1023,34 @@ class DbApiTestCase(DbTestCase): self.assertEqual(db.network_in_use_on_host(ctxt, 1, 'foo'), True) self.assertEqual(db.network_in_use_on_host(ctxt, 1, 'bar'), False) + def test_instance_floating_address_get_all(self): + ctxt = context.get_admin_context() + + instance1 = db.instance_create(ctxt, {'host': 'h1', 'hostname': 'n1'}) + instance2 = db.instance_create(ctxt, {'host': 'h2', 'hostname': 'n2'}) + + fixed_addresses = ['1.1.1.1', '1.1.1.2', '1.1.1.3'] + float_addresses = ['2.1.1.1', '2.1.1.2', '2.1.1.3'] + instance_uuids = [instance1['uuid'], instance1['uuid'], + instance2['uuid']] + + for fixed_addr, float_addr, instance_uuid in zip(fixed_addresses, + float_addresses, + instance_uuids): + db.fixed_ip_create(ctxt, {'address': fixed_addr, + 'instance_uuid': instance_uuid}) + fixed_id = db.fixed_ip_get_by_address(ctxt, fixed_addr)['id'] + db.floating_ip_create(ctxt, + {'address': float_addr, + 'fixed_ip_id': fixed_id}) + + real_float_addresses = \ + db.instance_floating_address_get_all(ctxt, instance_uuids[0]) + self.assertEqual(set(float_addresses[:2]), set(real_float_addresses)) + real_float_addresses = \ + db.instance_floating_address_get_all(ctxt, instance_uuids[2]) + self.assertEqual(set([float_addresses[2]]), set(real_float_addresses)) + def test_get_vol_mapping_non_admin(self): ref = db.ec2_volume_create(self.context, 'fake-uuid') ec2_id = db.get_ec2_volume_id_by_uuid(self.context, 'fake-uuid') |