From e1b3010dd91df2d8dda69d2322c98e1575fb3fd7 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 31 Jan 2012 14:02:30 -0800 Subject: Use single call in ExtendedStatus extension Fixes bug 917400 Change-Id: I8bc78f5e5f03c1ea30e7ff23236774af48a2c059 --- .../openstack/compute/contrib/extended_status.py | 36 ++++++++-------- .../compute/contrib/test_extendedstatus.py | 49 +++++++++++++++++----- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/nova/api/openstack/compute/contrib/extended_status.py b/nova/api/openstack/compute/contrib/extended_status.py index 4ab7ca756..d68dee4e2 100644 --- a/nova/api/openstack/compute/contrib/extended_status.py +++ b/nova/api/openstack/compute/contrib/extended_status.py @@ -35,16 +35,15 @@ class ExtendedStatusController(wsgi.Controller): super(ExtendedStatusController, self).__init__(*args, **kwargs) self.compute_api = compute.API() - def _get_and_extend_one(self, context, server_id, body): - try: - inst_ref = self.compute_api.routing_get(context, server_id) - except exception.NotFound: - LOG.warn("Instance %s not found" % server_id) - raise + def _get_instances(self, context, instance_uuids): + filters = {'uuid': instance_uuids} + instances = self.compute_api.get_all(context, filters) + return dict((instance['uuid'], instance) for instance in instances) + def _extend_server(self, server, instance): for state in ['task_state', 'vm_state', 'power_state']: key = "%s:%s" % (Extended_status.alias, state) - body[key] = inst_ref[state] + server[key] = instance[state] @wsgi.extends def show(self, req, resp_obj, id): @@ -54,11 +53,13 @@ class ExtendedStatusController(wsgi.Controller): resp_obj.attach(xml=ExtendedStatusTemplate()) try: - self._get_and_extend_one(context, id, resp_obj.obj['server']) + instance = self.compute_api.routing_get(context, id) except exception.NotFound: explanation = _("Server not found.") raise exc.HTTPNotFound(explanation=explanation) + self._extend_server(resp_obj.obj['server'], instance) + @wsgi.extends def detail(self, req, resp_obj): context = req.environ['nova.context'] @@ -66,18 +67,19 @@ class ExtendedStatusController(wsgi.Controller): # Attach our slave template to the response object resp_obj.attach(xml=ExtendedStatusesTemplate()) - for server in list(resp_obj.obj['servers']): + servers = list(resp_obj.obj['servers']) + instance_uuids = [server['id'] for server in servers] + instances = self._get_instances(context, instance_uuids) + + for server_object in servers: try: - self._get_and_extend_one(context, server['id'], server) - except exception.NotFound: - # NOTE(dtroyer): A NotFound exception at this point - # happens because a delete was in progress and the - # server that was present in the original call to - # compute.api.get_all() is no longer present. - # Delete it from the response and move on. - resp_obj.obj['servers'].remove(server) + instance_data = instances[server_object['id']] + except KeyError: + # Ignore missing instance data continue + self._extend_server(server_object, instance_data) + class Extended_status(extensions.ExtensionDescriptor): """Extended Status support""" diff --git a/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py b/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py index 738ab8290..2ac7d2f30 100644 --- a/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py +++ b/nova/tests/api/openstack/compute/contrib/test_extendedstatus.py @@ -28,23 +28,35 @@ FLAGS = flags.FLAGS FLAGS.verbose = True +UUID1 = '70f6db34-de8d-4fbd-aafb-4065bdfa6114' +UUID2 = '65ba6da7-3b9a-4b71-bc08-f81fbdb72d1a' +UUID3 = 'b55c356f-4c22-47ed-b622-cc6ba0f4b1ab' + + def fake_compute_get(*args, **kwargs): - return fakes.stub_instance(1, task_state="kayaking", - vm_state="slightly crunchy", - power_state="empowered") + return fakes.stub_instance(1, uuid=UUID3, task_state="kayaking", + vm_state="slightly crunchy", power_state="empowered") + + +def fake_compute_get_all(*args, **kwargs): + return [ + fakes.stub_instance(1, uuid=UUID1, task_state="task%s" % UUID1, + vm_state="vm%s" % UUID1, power_state="power%s" % UUID1), + fakes.stub_instance(2, uuid=UUID2, task_state="task%s" % UUID2, + vm_state="vm%s" % UUID2, power_state="power%s" % UUID2), + ] class ExtendedStatusTest(test.TestCase): def setUp(self): super(ExtendedStatusTest, self).setUp() - self.uuid = '70f6db34-de8d-4fbd-aafb-4065bdfa6114' - self.url = '/v2/fake/servers/%s' % self.uuid fakes.stub_out_nw_api(self.stubs) self.stubs.Set(compute.api.API, 'routing_get', fake_compute_get) + self.stubs.Set(compute.api.API, 'get_all', fake_compute_get_all) - def _make_request(self): - req = webob.Request.blank(self.url) + def _make_request(self, url): + req = webob.Request.blank(url) req.headers['Accept'] = 'application/json' res = req.get_response(fakes.wsgi_app()) return res @@ -54,8 +66,9 @@ class ExtendedStatusTest(test.TestCase): self.assertEqual(server.get('OS-EXT-STS:power_state'), power_state) self.assertEqual(server.get('OS-EXT-STS:task_state'), task_state) - def test_extended_status(self): - res = self._make_request() + def test_show(self): + url = '/v2/fake/servers/%s' % UUID3 + res = self._make_request(url) body = json.loads(res.body) self.assertEqual(res.status_int, 200) @@ -64,12 +77,26 @@ class ExtendedStatusTest(test.TestCase): power_state='empowered', task_state='kayaking') - def test_extended_status_no_instance_fails(self): + def test_detail(self): + url = '/v2/fake/servers/detail' + res = self._make_request(url) + body = json.loads(res.body) + + self.assertEqual(res.status_int, 200) + for server in body['servers']: + sid = server['id'] + self.assertServerStates(server, + vm_state='vm%s' % sid, + power_state='power%s' % sid, + task_state='task%s' % sid) + + def test_no_instance_passthrough_404(self): def fake_compute_get(*args, **kwargs): raise exception.InstanceNotFound() self.stubs.Set(compute.api.API, 'routing_get', fake_compute_get) - res = self._make_request() + url = '/v2/fake/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115' + res = self._make_request(url) self.assertEqual(res.status_int, 404) -- cgit