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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user