Skip to content

Commit

Permalink
Use single call in ExtendedStatus extension
Browse files Browse the repository at this point in the history
Fixes bug 917400

Change-Id: I8bc78f5e5f03c1ea30e7ff23236774af48a2c059
  • Loading branch information
bcwaldon committed Jan 31, 2012
1 parent 2757b81 commit e1b3010
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 28 deletions.
36 changes: 19 additions & 17 deletions nova/api/openstack/compute/contrib/extended_status.py
Expand Up @@ -35,16 +35,15 @@ def __init__(self, *args, **kwargs):
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):
Expand All @@ -54,30 +53,33 @@ def show(self, req, resp_obj, id):
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']
if authorize(context):
# 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"""
Expand Down
49 changes: 38 additions & 11 deletions nova/tests/api/openstack/compute/contrib/test_extendedstatus.py
Expand Up @@ -28,23 +28,35 @@
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
Expand All @@ -54,8 +66,9 @@ def assertServerStates(self, server, vm_state, power_state, task_state):
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)
Expand All @@ -64,12 +77,26 @@ def test_extended_status(self):
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)

0 comments on commit e1b3010

Please sign in to comment.