def test_mapped_tacker_error_with_json(self):
        msg = u'\u7f51\u7edc'

        class TestException(n_exc.TackerException):
            message = msg

        expected_res = {
            'body': {
                'TackerError': {
                    'type': 'TestException',
                    'message': msg,
                    'detail': ''
                }
            }
        }
        controller = mock.MagicMock()
        controller.test.side_effect = TestException()

        faults = {TestException: exc.HTTPGatewayTimeout}
        resource = webtest.TestApp(
            wsgi_resource.Resource(controller, faults=faults))

        environ = {
            'wsgiorg.routing_args': (None, {
                'action': 'test',
                'format': 'json'
            })
        }
        res = resource.get('', extra_environ=environ, expect_errors=True)
        self.assertEqual(res.status_int, exc.HTTPGatewayTimeout.code)
        self.assertEqual(wsgi.JSONDeserializer().deserialize(res.body),
                         expected_res)
    def test_mapped_tacker_error_localized(self, mock_translation):
        gettextutils.install('blaa', lazy=True)
        msg_translation = 'Translated error'
        mock_translation.return_value = msg_translation
        msg = _('Unmapped error')

        class TestException(n_exc.TackerException):
            message = msg

        controller = mock.MagicMock()
        controller.test.side_effect = TestException()
        faults = {TestException: exc.HTTPGatewayTimeout}
        resource = webtest.TestApp(
            wsgi_resource.Resource(controller, faults=faults))

        environ = {
            'wsgiorg.routing_args': (None, {
                'action': 'test',
                'format': 'json'
            })
        }

        res = resource.get('', extra_environ=environ, expect_errors=True)
        self.assertEqual(res.status_int, exc.HTTPGatewayTimeout.code)
        self.assertIn(msg_translation,
                      str(wsgi.JSONDeserializer().deserialize(res.body)))
示例#3
0
 def test_json(self):
     data = """{"a": {
             "a1": "1",
             "a2": "2",
             "bs": ["1", "2", "3", {"c": {"c1": "1"}}],
             "d": {"e": "1"},
             "f": "1"}}"""
     as_dict = {
         'body': {
             'a': {
                 'a1': '1',
                 'a2': '2',
                 'bs': ['1', '2', '3', {
                     'c': {
                         'c1': '1'
                     }
                 }],
                 'd': {
                     'e': '1'
                 },
                 'f': '1'
             }
         }
     }
     deserializer = wsgi.JSONDeserializer()
     self.assertEqual(deserializer.deserialize(data), as_dict)
示例#4
0
    def test_unhandled_error_with_json(self):
        expected_res = {
            'body': {
                'TackerError': {
                    'detail':
                    '',
                    'message':
                    _('Request Failed: internal server error'
                      ' while processing your request.'),
                    'type':
                    'HTTPInternalServerError'
                }
            }
        }
        controller = mock.MagicMock()
        controller.test.side_effect = Exception()

        resource = webtest.TestApp(wsgi_resource.Resource(controller))

        environ = {
            'wsgiorg.routing_args': (None, {
                'action': 'test',
                'format': 'json'
            })
        }
        res = resource.get('', extra_environ=environ, expect_errors=True)
        self.assertEqual(exc.HTTPInternalServerError.code, res.status_int)
        self.assertEqual(expected_res,
                         wsgi.JSONDeserializer().deserialize(res.body))
示例#5
0
 def setUp(self):
     super(WebTestCase, self).setUp()
     json_deserializer = wsgi.JSONDeserializer()
     xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     self._deserializers = {
         'application/json': json_deserializer,
         'application/xml': xml_deserializer,
     }
示例#6
0
    def test_default_raise_Malformed_Exception(self):
        """Test JsonDeserializer.default.

        Test verifies JsonDeserializer.default raises exception
        MalformedRequestBody correctly.
        """
        data_string = ""
        deserializer = wsgi.JSONDeserializer()

        self.assertRaises(exception.MalformedRequestBody, deserializer.default,
                          data_string)
    def test_unmapped_tacker_error_localized(self, mock_translation):
        oslo_i18n.install('blaa')
        msg_translation = 'Translated error'
        mock_translation.return_value = msg_translation
        msg = _('Unmapped error')

        class TestException(n_exc.TackerException):
            message = msg

        controller = mock.MagicMock()
        controller.test.side_effect = TestException()
        resource = webtest.TestApp(wsgi_resource.Resource(controller))

        environ = {'wsgiorg.routing_args': (None, {'action': 'test',
                                                   'format': 'json'})}

        res = resource.get('', extra_environ=environ, expect_errors=True)
        self.assertEqual(exc.HTTPInternalServerError.code, res.status_int)
        self.assertIn(msg_translation,
                      str(wsgi.JSONDeserializer().deserialize(res.body)))
示例#8
0
 def setUp(self):
     super(WebTestCase, self).setUp()
     json_deserializer = wsgi.JSONDeserializer()
     self._deserializers = {
         'application/json': json_deserializer,
     }
示例#9
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """API entity resource.

    Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    default_deserializers = {'application/json': wsgi.JSONDeserializer()}
    default_serializers = {'application/json': wsgi.JSONDictSerializer()}
    format_types = {'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt,
                                        request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']

            method = getattr(controller, action)

            result = method(request=request, **args)
        except (exceptions.TackerException,
                netaddr.AddrFormatError) as e:
            for fault in faults:
                if isinstance(e, fault):
                    mapped_exc = faults[fault]
                    break
            else:
                mapped_exc = webob.exc.HTTPInternalServerError
            if 400 <= mapped_exc.code < 500:
                LOG.info(_('%(action)s failed (client error): %(exc)s'),
                         {'action': action, 'exc': e})
            else:
                LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            # following structure is expected by python-tackerclient
            err_data = {'type': e.__class__.__name__,
                        'message': e, 'detail': ''}
            body = serializer.serialize({'TackerError': err_data})
            kwargs = {'body': body, 'content_type': content_type}
            raise mapped_exc(**kwargs)
        except webob.exc.HTTPException as e:
            type_, value, tb = sys.exc_info()
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            value.body = serializer.serialize({'TackerError': e})
            value.content_type = content_type
            six.reraise(type_, value, tb)
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize(
                {'NotImplementedError': e.message})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize({'TackerError': msg})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request, status=status,
                              content_type=content_type,
                              body=body)
    return resource
示例#10
0
 def test_json_with_unicode(self):
     data = '{"a": "\u7f51\u7edc"}'
     as_dict = {'body': {'a': u'\u7f51\u7edc'}}
     deserializer = wsgi.JSONDeserializer()
     self.assertEqual(deserializer.deserialize(data), as_dict)
示例#11
0
 def test_json_with_utf8(self):
     data = '{"a": "\xe7\xbd\x91\xe7\xbb\x9c"}'
     as_dict = {'body': {'a': u'\u7f51\u7edc'}}
     deserializer = wsgi.JSONDeserializer()
     self.assertEqual(deserializer.deserialize(data), as_dict)
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """API entity resource.

    Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    default_deserializers = {'application/json': wsgi.JSONDeserializer()}
    default_serializers = {'application/json': wsgi.JSONDictSerializer()}
    format_types = {'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt, request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']

            method = getattr(controller, action)

            result = method(request=request, **args)
        except Exception as e:
            mapped_exc = api_common.convert_exception_to_http_exc(
                e, faults, language)
            if hasattr(mapped_exc, 'code') and 400 <= mapped_exc.code < 500:
                LOG.info('%(action)s failed (client error): %(exc)s', {
                    'action': action,
                    'exc': mapped_exc
                })
            else:
                LOG.exception('%(action)s failed: %(details)s', {
                    'action': action,
                    'details': extract_exc_details(e)
                })
            raise mapped_exc

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request,
                              status=status,
                              content_type=content_type,
                              body=body)

    return resource