1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2013 IBM Corp.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Utility methods for serializing responses."""
import datetime
from lxml import etree
from oslo_log import log as logging
from oslo_serialization import jsonutils
import six
LOG = logging.getLogger(__name__)
class JSONResponseSerializer(object):
def to_json(self, data):
def sanitizer(obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
return six.text_type(obj)
response = jsonutils.dumps(data, default=sanitizer)
# TODO(ricolin): Fix response through private credential information,
# before enable below debug message.
# LOG.debug("JSON response : %s" % response)
return response
def default(self, response, result):
response.content_type = 'application/json'
response.body = six.b(self.to_json(result))
# Escape XML serialization for these keys, as the AWS API defines them as
# JSON inside XML when the response format is XML.
JSON_ONLY_KEYS = ('TemplateBody', 'Metadata')
class XMLResponseSerializer(object):
def object_to_element(self, obj, element):
if isinstance(obj, list):
for item in obj:
subelement = etree.SubElement(element, "member")
self.object_to_element(item, subelement)
elif isinstance(obj, dict):
for key, value in obj.items():
subelement = etree.SubElement(element, key)
if key in JSON_ONLY_KEYS:
if value:
# Need to use json.dumps for the JSON inside XML
# otherwise quotes get mangled and json.loads breaks
try:
subelement.text = jsonutils.dumps(value)
except TypeError:
subelement.text = str(value)
else:
self.object_to_element(value, subelement)
else:
element.text = six.text_type(obj)
def to_xml(self, data):
# Assumption : root node is dict with single key
root = next(six.iterkeys(data))
eltree = etree.Element(root)
self.object_to_element(data.get(root), eltree)
response = etree.tostring(eltree)
return response
def default(self, response, result):
response.content_type = 'application/xml'
response.body = self.to_xml(result)
|