Add xml serialization for all /images/<id>/meta and /images/<id>/meta/<key> responses

This commit is contained in:
Brian Waldon 2011-06-23 14:47:51 +00:00 committed by Tarmac
commit ca9384eb55
3 changed files with 142 additions and 4 deletions

View File

@ -16,6 +16,7 @@
# under the License. # under the License.
from webob import exc from webob import exc
from xml.dom import minidom
from nova import flags from nova import flags
from nova import image from nova import image
@ -103,9 +104,55 @@ class Controller(object):
self.image_service.update(context, image_id, img, None) self.image_service.update(context, image_id, img, None)
class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
def __init__(self):
xmlns = wsgi.XMLNS_V11
super(ImageMetadataXMLSerializer, self).__init__(xmlns=xmlns)
def _meta_item_to_xml(self, doc, key, value):
node = doc.createElement('meta')
node.setAttribute('key', key)
text = doc.createTextNode(value)
node.appendChild(text)
return node
def _meta_list_to_xml(self, xml_doc, meta_items):
container_node = xml_doc.createElement('metadata')
for (key, value) in meta_items:
item_node = self._meta_item_to_xml(xml_doc, key, value)
container_node.appendChild(item_node)
return container_node
def _meta_list_to_xml_string(self, metadata_dict):
xml_doc = minidom.Document()
items = metadata_dict['metadata'].items()
container_node = self._meta_list_to_xml(xml_doc, items)
self._add_xmlns(container_node)
return container_node.toprettyxml(indent=' ')
def index(self, metadata_dict):
return self._meta_list_to_xml_string(metadata_dict)
def create(self, metadata_dict):
return self._meta_list_to_xml_string(metadata_dict)
def _meta_item_to_xml_string(self, meta_item_dict):
xml_doc = minidom.Document()
item_key, item_value = meta_item_dict.items()[0]
item_node = self._meta_item_to_xml(xml_doc, item_key, item_value)
self._add_xmlns(item_node)
return item_node.toprettyxml(indent=' ')
def show(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
def update(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
def create_resource(): def create_resource():
serializers = { serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V11), 'application/xml': ImageMetadataXMLSerializer(),
} }
return wsgi.Resource(Controller(), serializers=serializers) return wsgi.Resource(Controller(), serializers=serializers)

View File

@ -232,12 +232,14 @@ class XMLDictSerializer(DictSerializer):
doc = minidom.Document() doc = minidom.Document()
node = self._to_xml_node(doc, self.metadata, root_key, data[root_key]) node = self._to_xml_node(doc, self.metadata, root_key, data[root_key])
xmlns = node.getAttribute('xmlns') self._add_xmlns(node)
if not xmlns and self.xmlns:
node.setAttribute('xmlns', self.xmlns)
return node.toprettyxml(indent=' ', encoding='utf-8') return node.toprettyxml(indent=' ', encoding='utf-8')
def _add_xmlns(self, node):
if self.xmlns is not None:
node.setAttribute('xmlns', self.xmlns)
def _to_xml_node(self, doc, metadata, nodename, data): def _to_xml_node(self, doc, metadata, nodename, data):
"""Recursive method to convert data members to XML nodes.""" """Recursive method to convert data members to XML nodes."""
result = doc.createElement(nodename) result = doc.createElement(nodename)

View File

@ -19,6 +19,7 @@ import json
import stubout import stubout
import unittest import unittest
import webob import webob
import xml.dom.minidom as minidom
from nova import flags from nova import flags
@ -105,6 +106,30 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual(200, res.status_int) self.assertEqual(200, res.status_int)
self.assertEqual('value1', res_dict['metadata']['key1']) self.assertEqual('value1', res_dict['metadata']['key1'])
def test_index_xml(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
'one': 'two',
'three': 'four',
},
}
output = serializer.index(fixture)
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="three">
four
</meta>
<meta key="one">
two
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_show(self): def test_show(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1') req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1' req.environ['api.version'] = '1.1'
@ -113,6 +138,24 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual(200, res.status_int) self.assertEqual(200, res.status_int)
self.assertEqual('value1', res_dict['key1']) self.assertEqual('value1', res_dict['key1'])
def test_show_xml(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'meta': {
'one': 'two',
},
}
output = serializer.show(fixture)
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_show_not_found(self): def test_show_not_found(self):
req = webob.Request.blank('/v1.1/images/1/meta/key9') req = webob.Request.blank('/v1.1/images/1/meta/key9')
req.environ['api.version'] = '1.1' req.environ['api.version'] = '1.1'
@ -135,6 +178,34 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual('value2', res_dict['metadata']['key2']) self.assertEqual('value2', res_dict['metadata']['key2'])
self.assertEqual(1, len(res_dict)) self.assertEqual(1, len(res_dict))
def test_create_xml(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
'key9': 'value9',
'key2': 'value2',
'key1': 'value1',
},
}
output = serializer.create(fixture)
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="key2">
value2
</meta>
<meta key="key9">
value9
</meta>
<meta key="key1">
value1
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_update_item(self): def test_update_item(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1') req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1' req.environ['api.version'] = '1.1'
@ -146,6 +217,24 @@ class ImageMetaDataTest(unittest.TestCase):
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
self.assertEqual('zz', res_dict['key1']) self.assertEqual('zz', res_dict['key1'])
def test_update_item_xml(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'meta': {
'one': 'two',
},
}
output = serializer.update(fixture)
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_update_item_too_many_keys(self): def test_update_item_too_many_keys(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1') req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1' req.environ['api.version'] = '1.1'