From 80bd1de65a3b8e7502ece9cedca3c027d176de39 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 7 Feb 2013 14:46:08 -0800 Subject: [PATCH] Simplify and optimize az server output extension. Displaying two different az results to users is confusing, so just return the az that the instance is actually in. Also, cache the result from looking up the az by host for an hour to avoid making lots of expensive db requests. DocImpact Change-Id: Ib39bf94c608874695aab00e61035e64f9594a985 --- .../OS-EXT-AZ/server-get-resp.json | 5 ++-- doc/api_samples/OS-EXT-AZ/server-get-resp.xml | 4 +-- .../OS-EXT-AZ/servers-detail-resp.json | 5 ++-- .../OS-EXT-AZ/servers-detail-resp.xml | 4 +-- .../all_extensions/server-get-resp.json | 5 ++-- .../all_extensions/server-get-resp.xml | 4 +-- .../all_extensions/servers-details-resp.json | 5 ++-- .../all_extensions/servers-details-resp.xml | 4 +-- .../contrib/extended_availability_zone.py | 27 ++++++++++------- .../test_extended_availability_zone.py | 30 +++++++++---------- .../OS-EXT-AZ/server-get-resp.json.tpl | 3 +- .../OS-EXT-AZ/server-get-resp.xml.tpl | 2 +- .../OS-EXT-AZ/servers-detail-resp.json.tpl | 3 +- .../OS-EXT-AZ/servers-detail-resp.xml.tpl | 2 +- .../all_extensions/server-get-resp.json.tpl | 3 +- .../all_extensions/server-get-resp.xml.tpl | 2 +- .../servers-details-resp.json.tpl | 3 +- .../servers-details-resp.xml.tpl | 2 +- 18 files changed, 54 insertions(+), 59 deletions(-) diff --git a/doc/api_samples/OS-EXT-AZ/server-get-resp.json b/doc/api_samples/OS-EXT-AZ/server-get-resp.json index a7cf031efd..c2f0fb2ba7 100644 --- a/doc/api_samples/OS-EXT-AZ/server-get-resp.json +++ b/doc/api_samples/OS-EXT-AZ/server-get-resp.json @@ -1,7 +1,6 @@ { "server": { - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "accessIPv4": "", "accessIPv6": "", "addresses": { @@ -53,4 +52,4 @@ "updated": "2013-01-30T13:38:49Z", "user_id": "fake" } -} \ No newline at end of file +} diff --git a/doc/api_samples/OS-EXT-AZ/server-get-resp.xml b/doc/api_samples/OS-EXT-AZ/server-get-resp.xml index 7a6edf0571..5025af4e81 100644 --- a/doc/api_samples/OS-EXT-AZ/server-get-resp.xml +++ b/doc/api_samples/OS-EXT-AZ/server-get-resp.xml @@ -1,5 +1,5 @@ - + @@ -16,4 +16,4 @@ - \ No newline at end of file + diff --git a/doc/api_samples/OS-EXT-AZ/servers-detail-resp.json b/doc/api_samples/OS-EXT-AZ/servers-detail-resp.json index 5fab02ac0c..2ecea959a1 100644 --- a/doc/api_samples/OS-EXT-AZ/servers-detail-resp.json +++ b/doc/api_samples/OS-EXT-AZ/servers-detail-resp.json @@ -1,8 +1,7 @@ { "servers": [ { - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "accessIPv4": "", "accessIPv6": "", "addresses": { @@ -55,4 +54,4 @@ "user_id": "fake" } ] -} \ No newline at end of file +} diff --git a/doc/api_samples/OS-EXT-AZ/servers-detail-resp.xml b/doc/api_samples/OS-EXT-AZ/servers-detail-resp.xml index 4f1f311a81..4cdf793346 100644 --- a/doc/api_samples/OS-EXT-AZ/servers-detail-resp.xml +++ b/doc/api_samples/OS-EXT-AZ/servers-detail-resp.xml @@ -1,6 +1,6 @@ - + @@ -18,4 +18,4 @@ - \ No newline at end of file + diff --git a/doc/api_samples/all_extensions/server-get-resp.json b/doc/api_samples/all_extensions/server-get-resp.json index f3dedd7d08..63f955ed60 100644 --- a/doc/api_samples/all_extensions/server-get-resp.json +++ b/doc/api_samples/all_extensions/server-get-resp.json @@ -1,8 +1,7 @@ { "server": { "OS-DCF:diskConfig": "AUTO", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "OS-EXT-SRV-ATTR:host": "b00875071c774b5487d217b82f03dfa2", "OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", @@ -68,4 +67,4 @@ "updated": "2013-02-07T18:58:57Z", "user_id": "fake" } -} \ No newline at end of file +} diff --git a/doc/api_samples/all_extensions/server-get-resp.xml b/doc/api_samples/all_extensions/server-get-resp.xml index 8a2ddf4e37..e2ded16e58 100644 --- a/doc/api_samples/all_extensions/server-get-resp.xml +++ b/doc/api_samples/all_extensions/server-get-resp.xml @@ -1,5 +1,5 @@ - + @@ -19,4 +19,4 @@ - \ No newline at end of file + diff --git a/doc/api_samples/all_extensions/servers-details-resp.json b/doc/api_samples/all_extensions/servers-details-resp.json index 475bce39bd..cc945edb54 100644 --- a/doc/api_samples/all_extensions/servers-details-resp.json +++ b/doc/api_samples/all_extensions/servers-details-resp.json @@ -2,8 +2,7 @@ "servers": [ { "OS-DCF:diskConfig": "AUTO", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "OS-EXT-SRV-ATTR:host": "33924d68ef4e4214bb9bc200178d23b8", "OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", @@ -70,4 +69,4 @@ "user_id": "fake" } ] -} \ No newline at end of file +} diff --git a/doc/api_samples/all_extensions/servers-details-resp.xml b/doc/api_samples/all_extensions/servers-details-resp.xml index 541f7aa5b2..44b3b09c56 100644 --- a/doc/api_samples/all_extensions/servers-details-resp.xml +++ b/doc/api_samples/all_extensions/servers-details-resp.xml @@ -1,6 +1,6 @@ - + @@ -21,4 +21,4 @@ - \ No newline at end of file + diff --git a/nova/api/openstack/compute/contrib/extended_availability_zone.py b/nova/api/openstack/compute/contrib/extended_availability_zone.py index b7451cb6a5..734ddf7c8f 100644 --- a/nova/api/openstack/compute/contrib/extended_availability_zone.py +++ b/nova/api/openstack/compute/contrib/extended_availability_zone.py @@ -21,26 +21,35 @@ from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil from nova import availability_zones +from nova.common import memorycache from nova.openstack.common import log as logging LOG = logging.getLogger(__name__) +# NOTE(vish): azs don't change that often, so cache them for an hour to +# avoid hitting the db multiple times on every request. +AZ_CACHE_SECONDS = 60 * 60 authorize = extensions.soft_extension_authorizer('compute', 'extended_availability_zone') class ExtendedAZController(wsgi.Controller): + def __init__(self): + self.mc = memorycache.get_client() def _get_host_az(self, context, instance): - admin_context = context.elevated() - if instance['host']: - return availability_zones.get_host_availability_zone( - admin_context, instance['host']) + host = instance.get('host') + if not host: + return None + cache_key = "azcache-%s" % host + az = self.mc.get(cache_key) + if not az: + elevated = context.elevated() + az = availability_zones.get_host_availability_zone(elevated, host) + self.mc.set(cache_key, az, AZ_CACHE_SECONDS) + return az def _extend_server(self, context, server, instance): key = "%s:availability_zone" % Extended_availability_zone.alias - server[key] = instance.get('availability_zone', None) - - key = "%s:host_availability_zone" % Extended_availability_zone.alias server[key] = self._get_host_az(context, instance) @wsgi.extends @@ -81,10 +90,6 @@ class Extended_availability_zone(extensions.ExtensionDescriptor): def make_server(elem): elem.set('{%s}availability_zone' % Extended_availability_zone.namespace, '%s:availability_zone' % Extended_availability_zone.alias) - elem.set('{%s}host_availability_zone' % - Extended_availability_zone.namespace, - '%s:host_availability_zone' % - Extended_availability_zone.alias) class ExtendedAZTemplate(xmlutil.TemplateBuilder): diff --git a/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py b/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py index 8ebd810aca..d847e54f9a 100644 --- a/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py +++ b/nova/tests/api/openstack/compute/contrib/test_extended_availability_zone.py @@ -17,6 +17,7 @@ from lxml import etree import webob from nova.api.openstack.compute.contrib import extended_availability_zone +from nova import availability_zones from nova import compute from nova import exception from nova.openstack.common import jsonutils @@ -29,19 +30,20 @@ UUID3 = '00000000-0000-0000-0000-000000000003' def fake_compute_get(*args, **kwargs): - inst = fakes.stub_instance(1, uuid=UUID3, host="host-fake") - inst['availability_zone'] = 'az-i' + inst = fakes.stub_instance(1, uuid=UUID3, host="get-host") return inst def fake_compute_get_all(*args, **kwargs): - inst1 = fakes.stub_instance(1, uuid=UUID1, host="host-1") - inst2 = fakes.stub_instance(2, uuid=UUID2, host="host-2") - inst1['availability_zone'] = 'az-i' - inst2['availability_zone'] = 'az-i' + inst1 = fakes.stub_instance(1, uuid=UUID1, host="all-host") + inst2 = fakes.stub_instance(2, uuid=UUID2, host="all-host") return [inst1, inst2] +def fake_get_host_availability_zone(context, host): + return host + + class ExtendedServerAttributesTest(test.TestCase): content_type = 'application/json' prefix = 'OS-EXT-AZ:' @@ -51,6 +53,8 @@ class ExtendedServerAttributesTest(test.TestCase): fakes.stub_out_nw_api(self.stubs) self.stubs.Set(compute.api.API, 'get', fake_compute_get) self.stubs.Set(compute.api.API, 'get_all', fake_compute_get_all) + self.stubs.Set(availability_zones, 'get_host_availability_zone', + fake_get_host_availability_zone) self.flags( osapi_compute_extension=[ @@ -69,20 +73,16 @@ class ExtendedServerAttributesTest(test.TestCase): def _get_servers(self, body): return jsonutils.loads(body).get('servers') - def assertServerAttributes(self, server, az_instance, az_host): + def assertServerAttributes(self, server, az): self.assertEqual(server.get('%savailability_zone' % self.prefix), - az_instance) - self.assertEqual(server.get('%shost_availability_zone' % self.prefix), - az_host) + az) def test_show(self): url = '/v2/fake/servers/%s' % UUID3 res = self._make_request(url) self.assertEqual(res.status_int, 200) - self.assertServerAttributes(self._get_server(res.body), - az_instance='az-i', - az_host='nova') + self.assertServerAttributes(self._get_server(res.body), 'get-host') def test_detail(self): url = '/v2/fake/servers/detail' @@ -90,9 +90,7 @@ class ExtendedServerAttributesTest(test.TestCase): self.assertEqual(res.status_int, 200) for i, server in enumerate(self._get_servers(res.body)): - self.assertServerAttributes(server, - az_instance='az-i', - az_host='nova') + self.assertServerAttributes(server, 'all-host') def test_no_instance_passthrough_404(self): diff --git a/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.json.tpl b/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.json.tpl index 25915610dc..413f3ce958 100644 --- a/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.json.tpl +++ b/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.json.tpl @@ -2,8 +2,7 @@ "server": { "updated": "%(timestamp)s", "created": "%(timestamp)s", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "accessIPv4": "", "accessIPv6": "", "addresses": { diff --git a/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.xml.tpl b/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.xml.tpl index 1cdbd2012e..849b9b750f 100644 --- a/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/OS-EXT-AZ/server-get-resp.xml.tpl @@ -1,5 +1,5 @@ - + diff --git a/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.json.tpl b/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.json.tpl index 895f0a514f..362c850851 100644 --- a/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.json.tpl +++ b/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.json.tpl @@ -3,8 +3,7 @@ { "updated": "%(timestamp)s", "created": "%(timestamp)s", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "accessIPv4": "", "accessIPv6": "", "addresses": { diff --git a/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.xml.tpl b/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.xml.tpl index 15cd9b1e17..9cd820cd02 100644 --- a/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/OS-EXT-AZ/servers-detail-resp.xml.tpl @@ -1,5 +1,5 @@ - + diff --git a/nova/tests/integrated/api_samples/all_extensions/server-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/server-get-resp.json.tpl index fefa37b4da..ccefc2dc75 100644 --- a/nova/tests/integrated/api_samples/all_extensions/server-get-resp.json.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/server-get-resp.json.tpl @@ -1,8 +1,7 @@ { "server": { "OS-DCF:diskConfig": "AUTO", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "OS-EXT-SRV-ATTR:host": "%(compute_host)s", "OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", diff --git a/nova/tests/integrated/api_samples/all_extensions/server-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/server-get-resp.xml.tpl index 4ba06b42e9..9733058544 100644 --- a/nova/tests/integrated/api_samples/all_extensions/server-get-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/server-get-resp.xml.tpl @@ -1,5 +1,5 @@ - + diff --git a/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.json.tpl index 667ef64712..d50088837b 100644 --- a/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.json.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.json.tpl @@ -2,8 +2,7 @@ "servers": [ { "OS-DCF:diskConfig": "AUTO", - "OS-EXT-AZ:availability_zone": null, - "OS-EXT-AZ:host_availability_zone": "nova", + "OS-EXT-AZ:availability_zone": "nova", "OS-EXT-SRV-ATTR:host": "%(compute_host)s", "OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", diff --git a/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.xml.tpl index 104c82bc5f..e2166c2ff9 100644 --- a/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/servers-details-resp.xml.tpl @@ -1,6 +1,6 @@ - +