Exemple #1
0
 def test_to_xml_with_list(self):
     fixture = {"name": ["1", "2"]}
     expected = b'<name><member>1</member><member>2</member></name>'
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     actual_xml_tree = etree.XML(actual)
     actual_xml_dict = self._recursive_dict(actual_xml_tree)
     expected_xml_tree = etree.XML(expected)
     expected_xml_dict = self._recursive_dict(expected_xml_tree)
     self.assertEqual(expected_xml_dict, actual_xml_dict)
Exemple #2
0
 def test_to_xml_with_more_deep_format(self):
     # Note we expect tree traversal from one root key, which is compatible
     # with the AWS format responses we need to serialize
     fixture = {"aresponse":
                {"is_public": True, "name": [{"name1": "test"}]}}
     expected = ('<aresponse><is_public>True</is_public>'
                 '<name><member><name1>test</name1></member></name>'
                 '</aresponse>')
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
Exemple #3
0
 def test_default(self):
     fixture = {"key": "value"}
     response = webob.Response()
     serializers.XMLResponseSerializer().default(response, fixture)
     self.assertEqual(200, response.status_int)
     content_types = list(filter(lambda h: h[0] == 'Content-Type',
                                 response.headerlist))
     self.assertEqual(1, len(content_types))
     self.assertEqual('application/xml', response.content_type)
     self.assertEqual('<key>value</key>', response.body)
Exemple #4
0
    def __init__(self, detail=None):
        """Overload HTTPError constructor to create a default serialized body.

        This is required because not all error responses are processed
        by the wsgi controller (such as auth errors), which are further up the
        paste pipeline.  We serialize in XML by default (as AWS does).
        """
        webob.exc.HTTPError.__init__(self, detail=detail)
        serializer = serializers.XMLResponseSerializer()
        serializer.default(self, self.get_unserialized_body())
Exemple #5
0
 def __call__(self, req):
     if req.content_type == 'application/xml':
         serializer = serializers.XMLResponseSerializer()
     else:
         serializer = serializers.JSONResponseSerializer()
     resp = webob.Response(request=req)
     default_webob_exc = webob.exc.HTTPInternalServerError()
     resp.status_code = self.error.get('code', default_webob_exc.code)
     serializer.default(resp, self.error)
     return resp
Exemple #6
0
 def test_to_xml_with_json_only_keys(self):
     # Certain keys are excluded from serialization because CFN
     # format demands a json blob in the XML body
     fixture = {"aresponse":
                {"is_public": True,
                 "TemplateBody": {"name1": "test"},
                 "Metadata": {"name2": "test2"}}}
     expected = ('<aresponse><is_public>True</is_public>'
                 '<TemplateBody>{"name1": "test"}</TemplateBody>'
                 '<Metadata>{"name2": "test2"}</Metadata></aresponse>')
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
 def test_to_xml_with_json_only_keys(self):
     # Certain keys are excluded from serialization because CFN
     # format demands a json blob in the XML body
     fixture = collections.OrderedDict([
         ('aresponse', collections.OrderedDict([
             ('is_public', True),
             ('TemplateBody', {"name1": "test"}),
             ('Metadata', {"name2": "test2"}),
         ]))
     ])
     expected = ('<aresponse><is_public>True</is_public>'
                 '<TemplateBody>{"name1": "test"}</TemplateBody>'
                 '<Metadata>{"name2": "test2"}</Metadata></aresponse>')
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
 def test_to_xml_with_more_deep_format(self):
     # Note we expect tree traversal from one root key, which is compatible
     # with the AWS format responses we need to serialize
     fixture = collections.OrderedDict([
         ('aresponse', collections.OrderedDict([
             ('is_public', True),
             ('name', [collections.OrderedDict([
                 ('name1', 'test'),
             ])])
         ]))
     ])
     expected = ('<aresponse><is_public>True</is_public>'
                 '<name><member><name1>test</name1></member></name>'
                 '</aresponse>')
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
Exemple #9
0
 def test_to_xml_with_json_only_keys(self):
     # Certain keys are excluded from serialization because CFN
     # format demands a json blob in the XML body
     fixture = collections.OrderedDict([('aresponse',
                                         collections.OrderedDict([
                                             ('is_public', True),
                                             ('TemplateBody', {
                                                 "name1": "test"
                                             }),
                                             ('Metadata', {
                                                 "name2": "test2"
                                             }),
                                         ]))])
     expected = '<aresponse>' \
                '<is_public>True</is_public>' \
                '<TemplateBody>{"name1": "test"}</TemplateBody>' \
                '<Metadata>{"name2": "test2"}</Metadata>' \
                '</aresponse>'.encode('latin-1')
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     actual_xml_tree = etree.XML(actual)
     actual_xml_dict = self._recursive_dict(actual_xml_tree)
     expected_xml_tree = etree.XML(expected)
     expected_xml_dict = self._recursive_dict(expected_xml_tree)
     self.assertEqual(expected_xml_dict, actual_xml_dict)
Exemple #10
0
 def test_to_xml_with_list(self):
     fixture = {"name": ["1", "2"]}
     expected = '<name><member>1</member><member>2</member></name>'
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
Exemple #11
0
 def test_to_xml_with_date_format_value(self):
     fixture = {"date": datetime.datetime(1, 3, 8, 2)}
     expected = '<date>0001-03-08 02:00:00</date>'
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
Exemple #12
0
 def test_to_xml(self):
     fixture = {"key": "value"}
     expected = '<key>value</key>'
     actual = serializers.XMLResponseSerializer().to_xml(fixture)
     self.assertEqual(expected, actual)
Exemple #13
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""
        action_args = self.get_action_args(request.environ)
        action = action_args.pop('action', None)

        # From reading the boto code, and observation of real AWS api responses
        # it seems that the AWS api ignores the content-type in the html header
        # Instead it looks at a "ContentType" GET query parameter
        # This doesn't seem to be documented in the AWS cfn API spec, but it
        # would appear that the default response serialization is XML, as
        # described in the API docs, but passing a query parameter of
        # ContentType=JSON results in a JSON serialized response...
        content_type = request.params.get("ContentType")

        LOG.info("Processing request: %(method)s %(path)s",
                 {'method': request.method, 'path': request.path})

        try:
            deserialized_request = self.dispatch(self.deserializer,
                                                 action, request)
            action_args.update(deserialized_request)

            LOG.debug(('Calling %(controller)s.%(action)s'),
                      {'controller': type(self.controller).__name__,
                       'action': action})

            action_result = self.dispatch(self.controller, action,
                                          request, **action_args)
        except TypeError as err:
            LOG.error('Exception handling resource: %s', err)
            msg = _('The server could not comply with the request since '
                    'it is either malformed or otherwise incorrect.')
            err = webob.exc.HTTPBadRequest(msg)
            http_exc = translate_exception(err, request.best_match_language())
            # NOTE(luisg): We disguise HTTP exceptions, otherwise they will be
            # treated by wsgi as responses ready to be sent back and they
            # won't make it into the pipeline app that serializes errors
            raise exception.HTTPExceptionDisguise(http_exc)
        except webob.exc.HTTPException as err:
            if isinstance(err, aws_exception.HeatAPIException):
                # The AWS compatible API's don't use faultwrap, so
                # we want to detect the HeatAPIException subclasses
                # and raise rather than wrapping in HTTPExceptionDisguise
                raise
            if not isinstance(err, webob.exc.HTTPError):
                # Some HTTPException are actually not errors, they are
                # responses ready to be sent back to the users, so we don't
                # error log, disguise or translate those
                raise
            if isinstance(err, webob.exc.HTTPServerError):
                LOG.error(
                    "Returning %(code)s to user: %(explanation)s",
                    {'code': err.code, 'explanation': err.explanation})
            http_exc = translate_exception(err, request.best_match_language())
            raise exception.HTTPExceptionDisguise(http_exc)
        except exception.HeatException as err:
            raise translate_exception(err, request.best_match_language())
        except Exception as err:
            log_exception(err, sys.exc_info())
            raise translate_exception(err, request.best_match_language())
        # Here we support either passing in a serializer or detecting it
        # based on the content type.
        try:
            serializer = self.serializer
            if serializer is None:
                if content_type == "JSON":
                    serializer = serializers.JSONResponseSerializer()
                else:
                    serializer = serializers.XMLResponseSerializer()

            response = webob.Response(request=request)
            self.dispatch(serializer, action, response, action_result)
            return response

        # return unserializable result (typically an exception)
        except Exception:
            # Here we should get API exceptions derived from HeatAPIException
            # these implement get_unserialized_body(), which allow us to get
            # a dict containing the unserialized error response.
            # We only need to serialize for JSON content_type, as the
            # exception body is pre-serialized to the default XML in the
            # HeatAPIException constructor
            # If we get something else here (e.g a webob.exc exception),
            # this will fail, and we just return it without serializing,
            # which will not conform to the expected AWS error response format
            if content_type == "JSON":
                try:
                    err_body = action_result.get_unserialized_body()
                    serializer.default(action_result, err_body)
                except Exception:
                    LOG.warning("Unable to serialize exception response")

            return action_result