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.
from webob import exc
from xml.dom import minidom
from nova import flags
from nova import image
@ -103,9 +104,55 @@ class Controller(object):
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():
serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V11),
'application/xml': ImageMetadataXMLSerializer(),
}
return wsgi.Resource(Controller(), serializers=serializers)

View File

@ -232,12 +232,14 @@ class XMLDictSerializer(DictSerializer):
doc = minidom.Document()
node = self._to_xml_node(doc, self.metadata, root_key, data[root_key])
xmlns = node.getAttribute('xmlns')
if not xmlns and self.xmlns:
node.setAttribute('xmlns', self.xmlns)
self._add_xmlns(node)
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):
"""Recursive method to convert data members to XML nodes."""
result = doc.createElement(nodename)

View File

@ -19,6 +19,7 @@ import json
import stubout
import unittest
import webob
import xml.dom.minidom as minidom
from nova import flags
@ -105,6 +106,30 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual(200, res.status_int)
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):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'
@ -113,6 +138,24 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual(200, res.status_int)
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):
req = webob.Request.blank('/v1.1/images/1/meta/key9')
req.environ['api.version'] = '1.1'
@ -135,6 +178,34 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual('value2', res_dict['metadata']['key2'])
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):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'
@ -146,6 +217,24 @@ class ImageMetaDataTest(unittest.TestCase):
res_dict = json.loads(res.body)
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):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'