Moving lp:~rackspace-titan/nova/extensions-xml-serialization to new branch based off of trunk. To remove dep on another branch.

This commit is contained in:
Naveed Massjouni
2011-07-21 15:08:46 -04:00
parent 74c399cb2e
commit af5c549d77
3 changed files with 152 additions and 8 deletions

View File

@@ -23,6 +23,7 @@ import sys
import routes
import webob.dec
import webob.exc
from xml.etree import ElementTree
from nova import exception
from nova import flags
@@ -194,7 +195,7 @@ class ExtensionsResource(wsgi.Resource):
def show(self, req, id):
# NOTE(dprince): the extensions alias is used as the 'id' for show
ext = self.extension_manager.extensions[id]
return self._translate(ext)
return dict(extension=self._translate(ext))
def delete(self, req, id):
raise faults.Fault(webob.exc.HTTPNotFound())
@@ -258,15 +259,18 @@ class ExtensionMiddleware(base_wsgi.Middleware):
mapper = routes.Mapper()
serializer = wsgi.ResponseSerializer(
{'application/xml': ExtensionsXMLSerializer()})
# extended resources
for resource in ext_mgr.get_resources():
LOG.debug(_('Extended resource: %s'),
resource.collection)
mapper.resource(resource.collection, resource.collection,
controller=wsgi.Resource(resource.controller),
collection=resource.collection_actions,
member=resource.member_actions,
parent_resource=resource.parent)
controller=wsgi.Resource(
resource.controller, serializer=serializer),
collection=resource.collection_actions,
member=resource.member_actions,
parent_resource=resource.parent)
# extended actions
action_resources = self._action_ext_resources(application, ext_mgr,
@@ -462,3 +466,32 @@ class ResourceExtension(object):
self.parent = parent
self.collection_actions = collection_actions
self.member_actions = member_actions
class ExtensionsXMLSerializer(wsgi.XMLDictSerializer):
def _add_extension_attributes(self, node, extension):
node.setAttribute('name', extension['name'])
node.setAttribute('namespace', extension['namespace'])
node.setAttribute('alias', extension['alias'])
node.setAttribute('updated', extension['updated'])
def show(self, ext_dict):
root = ElementTree.Element('extension');
extension = ext_dict['extension']
root.set('xmlns', wsgi.XMLNS_V11)
root.set('xmlns:atom', wsgi.XMLNS_ATOM)
root.set('name', extension['name'])
root.set('namespace', extension['namespace'])
root.set('alias', extension['alias'])
root.set('updated', extension['updated'])
desc = ElementTree.Element('description');
desc.text = extension['description']
root.append(desc)
for link in extension.get('links', []):
elem = ElementTree.Element('atom:link');
elem.set('rel', link['rel'])
elem.set('href', link['href'])
elem.set('type', link['type'])
root.append(elem)
return ElementTree.tostring(root)

View File

@@ -13,6 +13,7 @@ from nova import wsgi
XMLNS_V10 = 'http://docs.rackspacecloud.com/servers/api/v1.0'
XMLNS_V11 = 'http://docs.openstack.org/compute/api/v1.1'
XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
LOG = logging.getLogger('nova.api.openstack.wsgi')
@@ -352,6 +353,9 @@ class XMLDictSerializer(DictSerializer):
link_node = xml_doc.createElement('atom:link')
link_node.setAttribute('rel', link['rel'])
link_node.setAttribute('href', link['href'])
if link.get('type'):
link_node.setAttribute('type', link['type'])
link_nodes.append(link_node)
return link_nodes

View File

@@ -16,10 +16,11 @@
# under the License.
import json
import os.path
import stubout
import unittest
import webob
import os.path
from xml.etree import ElementTree
from nova import context
from nova import flags
@@ -80,20 +81,74 @@ class StubExtensionManager(object):
class ExtensionControllerTest(unittest.TestCase):
def test_index(self):
def setUp(self):
FLAGS.osapi_extensions_path = os.path.join(
os.path.dirname(__file__), "extensions")
def test_list_extensions_json(self):
app = openstack.APIRouterV11()
ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/extensions")
response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
def test_get_by_alias(self):
# Make sure we have all the extensions.
data = json.loads(response.body)
names = [x['name'] for x in data['extensions']]
names.sort()
self.assertEqual(names, ["FlavorExtraSpecs", "Floating_ips",
"Fox In Socks", "Hosts", "Multinic", "Volumes"])
# Make sure that at least Fox in Sox is correct.
(fox_ext,) = [
x for x in data['extensions'] if x['alias'] == 'FOXNSOX']
self.assertEqual(fox_ext, {
"namespace" : "http://www.fox.in.socks/api/ext/pie/v1.0",
"name" : "Fox In Socks",
"updated" : "2011-01-22T13:25:27-06:00",
"description" : "The Fox In Socks Extension",
"alias" : "FOXNSOX",
"links" : []
}
)
def test_get_extension_json(self):
app = openstack.APIRouterV11()
ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/extensions/FOXNSOX")
response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
data = json.loads(response.body)
self.assertEqual(data['extension'], {
"namespace" : "http://www.fox.in.socks/api/ext/pie/v1.0",
"name" : "Fox In Socks",
"updated" : "2011-01-22T13:25:27-06:00",
"description" : "The Fox In Socks Extension",
"alias" : "FOXNSOX",
"links" : []
}
)
def test_get_extension_xml(self):
app = openstack.APIRouterV11()
ext_midware = extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/extensions/FOXNSOX")
request.accept = "application/xml"
response = request.get_response(ext_midware)
self.assertEqual(200, response.status_int)
print response.body
elem = ElementTree.XML(response.body.replace(" ", ""))
self.assertEqual(elem.get('alias'), 'FOXNSOX')
self.assertEqual(elem.get('name'), 'Fox In Socks')
self.assertEqual(elem.get('namespace'),
'http://www.fox.in.socks/api/ext/pie/v1.0')
self.assertEqual(elem.get('updated'), '2011-01-22T13:25:27-06:00')
ns = "{http://docs.openstack.org/compute/api/v1.1}"
self.assertEqual(elem.findtext('{0}description'.format(ns)),
'The Fox In Socks Extension')
class ResourceExtensionTest(unittest.TestCase):
@@ -244,3 +299,55 @@ class RequestExtensionTest(unittest.TestCase):
response_data = json.loads(response.body)
self.assertEqual('newblue', response_data['flavor']['googoose'])
self.assertEqual("Pig Bands!", response_data['big_bands'])
class ExtensionsXMLSerializerTest(unittest.TestCase):
def test_serialize(self):
serializer = extensions.ExtensionsXMLSerializer()
data = {
'extension': {
'name': 'ext1',
"namespace" : "http://docs.rack.com/servers/api/ext/pie/v1.0",
"alias" : "RS-PIE",
"updated" : "2011-01-22T13:25:27-06:00",
"description" : "Adds the capability to share an image.",
"links" : [
{
"rel" : "describedby",
"type" : "application/pdf",
"href" : "http://docs.rack.com/servers/api/ext/cs.pdf"
},
{
"rel" : "describedby",
"type" : "application/vnd.sun.wadl+xml",
"href" : "http://docs.rack.com/servers/api/ext/cs.wadl"
}
]
},
}
ns = "{http://docs.openstack.org/compute/api/v1.1}"
atomns = "{http://www.w3.org/2005/Atom}"
elem = ElementTree.XML(serializer.serialize(data, 'show'))
self.assertEqual(elem.tag.split('extension')[0], ns)
self.assertEqual(elem.get('alias'), 'RS-PIE')
self.assertEqual(elem.get('name'), 'ext1')
self.assertEqual(elem.get('namespace'),
'http://docs.rack.com/servers/api/ext/pie/v1.0')
self.assertEqual(elem.get('updated'), '2011-01-22T13:25:27-06:00')
self.assertEqual(elem.findtext('{0}description'.format(ns)),
'Adds the capability to share an image.')
link_nodes = elem.findall('{0}link'.format(atomns))
self.assertEqual(len(link_nodes), 2)
link_nodes.sort(key=lambda x: x.get('type'))
self.assertEqual(link_nodes[0].get('type'), 'application/pdf')
self.assertEqual(link_nodes[0].get('rel'), 'describedby')
self.assertEqual(link_nodes[0].get('href'),
'http://docs.rack.com/servers/api/ext/cs.pdf')
self.assertEqual(link_nodes[1].get('type'),
'application/vnd.sun.wadl+xml')
self.assertEqual(link_nodes[1].get('rel'), 'describedby')
self.assertEqual(link_nodes[1].get('href'),
'http://docs.rack.com/servers/api/ext/cs.wadl')