Add xml serialization for all /images/<id>/meta and /images/<id>/meta/<key> responses
This commit is contained in:
commit
ca9384eb55
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user