示例#1
0
 def test_empty_dic_xml(self):
     data = {}
     # Since it is an empty dict, we use quantum:type='dict' and
     # an empty XML element to represent it. In addition, we use an
     # virtual XML root _v_root to wrap the XML doc.
     # XML is:
     # <_v_root quantum:type="dict"
     #          xmlns="http://openstack.org/quantum/api/v2.0"
     #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
     #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
     serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
     result = serializer.serialize(data)
     deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     new_data = deserializer.deserialize(result)['body']
     self.assertEqual(data, new_data)
示例#2
0
    def test_non_root_one_item_dic_xml(self):
        data = {'test1': 1}
        # We have a key in this dict, and its value is an integer.
        # XML is:
        # <test1 quantum:type="int"
        #        xmlns="http://openstack.org/quantum/api/v2.0"
        #        xmlns:quantum="http://openstack.org/quantum/api/v2.0"
        #        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        # 1</test1>

        serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        result = serializer.serialize(data)
        deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        new_data = deserializer.deserialize(result)['body']
        self.assertEqual(data, new_data)
示例#3
0
 def test_None(self):
     data = None
     # Since it is None, we use xsi:nil='true'.
     # In addition, we use an
     # virtual XML root _v_root to wrap the XML doc.
     # XML is:
     # <_v_root xsi:nil="true"
     #          xmlns="http://openstack.org/quantum/api/v2.0"
     #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
     #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
     serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
     result = serializer.serialize(data)
     deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     new_data = deserializer.deserialize(result)['body']
     self.assertIsNone(new_data)
示例#4
0
    def test_non_root_two_items_dic_xml(self):
        data = {'test1': 1, 'test2': '2'}
        # We have no root element in this data, We will use a virtual
        # root element _v_root to wrap the doct.
        # The XML is:
        # <_v_root xmlns="http://openstack.org/quantum/api/v2.0"
        #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
        #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        #    <test1 quantum:type="int">1</test1><test2>2</test2>
        # </_v_root>

        serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        result = serializer.serialize(data)
        deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        new_data = deserializer.deserialize(result)['body']
        self.assertEqual(data, new_data)
示例#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
        #    <int quantum:type="float">5.0</int>  # Float text
        #    <dict quantum:type="dict" />     # Empty Dict
        #    <name>net1</name>
        #    <admin_state_up quantum:type="bool">True</admin_state_up> # Bool
        #    <test xsi:nil="true" />          # None
        #    <tenant_id>test-tenant</tenant_id>
        #    # We must have a namespace defined in root for prefix:external
        #    <prefix:external quantum:type="bool">True</prefix:external>
        #    <tests>                          # List
        #       <test><test1>value1</test1></test>
        #       <test><test3 quantum:type="int">3</test3>
        #             <test2 quantum:type="int">2</test2>
        #       </test></tests>
        # </network>

        metadata = attributes.get_attr_metadata()
        ns = {'prefix': 'http://xxxx.yy.com'}
        metadata[constants.EXT_NS] = ns
        metadata['plurals'] = {'tests': 'test'}
        serializer = wsgi.XMLDictSerializer(metadata)
        result = serializer.serialize(NETWORK)
        deserializer = wsgi.XMLDeserializer(metadata)
        new_net = deserializer.deserialize(result)['body']
        self.assertEqual(NETWORK, new_net)

    def test_None(self):
        data = None
        # Since it is None, we use xsi:nil='true'.
        # In addition, we use an
        # virtual XML root _v_root to wrap the XML doc.
        # XML is:
示例#7
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
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {'application/xml': xml_deserializer,
                             'application/json': wsgi.JSONDeserializer()}
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {'application/xml': xml_serializer,
                           'application/json': wsgi.JSONDictSerializer()}
    format_types = {'xml': 'application/xml',
                    '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
示例#8
0
 def serialize(self, data):
     ctype = 'application/%s' % self.fmt
     result = wsgi.Serializer(
         attributes.get_attr_metadata()).serialize(data, ctype)
     return result