Example #1
0
    def test_xml_root_key_is_list(self):
        input_dict = {'servers': ['test-pass']}
        serializer = wsgi.XMLDictSerializer(xmlns="fake")
        result = serializer.default(input_dict)
        result = result.replace('\n', '').replace(' ', '')
        expected = ('<?xmlversion=\'1.0\'encoding=\'UTF-8\'?>'
                    '<serversxmlns="fake"xmlns:quantum="fake"'
                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
                    '<server>test-pass</server></servers>')

        self.assertEqual(result, expected)
Example #2
0
 def test_xml_with_unicode(self):
     data = {'servers': u'\u7f51\u7edc'}
     serializer = wsgi.XMLDictSerializer()
     expected = ('<?xmlversion=\'1.0\'encoding=\'UTF-8\'?>'
                 '<serversxmlns="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">'
                 '\xe7\xbd\x91\xe7\xbb\x9c</servers>')
     result = serializer(data)
     result = result.replace('\n', '').replace(' ', '')
     self.assertEqual(expected, result)
Example #3
0
 def test_call(self):
     data = {'servers': {'a': {'2': '3'}}}
     serializer = wsgi.XMLDictSerializer()
     expected = ('<?xmlversion=\'1.0\'encoding=\'UTF-8\'?>'
                 '<serversxmlns="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">'
                 '<a><2>3</2></a></servers>')
     result = serializer(data)
     result = result.replace('\n', '').replace(' ', '')
     self.assertEqual(expected, result)
Example #4
0
    def test_xml_meta_contains_node_name_list(self):
        input_dict = {'servers': ['test-pass']}
        servers = {'nodename': 'test', 'item_name': 'test', 'item_key': 'test'}
        metadata = {'list_collections': {'servers': servers}}
        serializer = wsgi.XMLDictSerializer(xmlns="fake", metadata=metadata)
        result = serializer.default(input_dict)
        result = result.replace('\n', '').replace(' ', '')
        expected = ('<?xmlversion=\'1.0\'encoding=\'UTF-8\'?>'
                    '<serversxmlns="fake"xmlns:quantum="fake"'
                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
                    '<server>test-pass</server></servers>')

        self.assertEqual(result, expected)
Example #5
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)
Example #6
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)
Example #7
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)
Example #8
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)
Example #9
0
def create_resource(version, controller_dict):
    """
    Generic function for creating a wsgi resource
    The function takes as input:
     - desired version
     - controller and metadata dictionary
       e.g.: {'1.0': [ctrl_v10, meta_v10, xml_ns],
              '1.1': [ctrl_v11, meta_v11, xml_ns]}

    """
    # the first element of the iterable is expected to be the controller
    controller = controller_dict[version][0]
    # the second element should be the metadata
    metadata = controller_dict[version][1]
    # and the third element the xml namespace
    xmlns = controller_dict[version][2]
    # and also the function for building the fault body
    fault_body_function = faults.fault_body_function(version)

    headers_serializers = {
        '1.0': HeaderSerializer10(),
        '1.1': HeaderSerializer11()
    }
    xml_serializer = wsgi.XMLDictSerializer(metadata, xmlns)
    json_serializer = wsgi.JSONDictSerializer()
    xml_deserializer = wsgi.XMLDeserializer(metadata)
    json_deserializer = wsgi.JSONDeserializer()

    body_serializers = {
        'application/xml': xml_serializer,
        'application/json': json_serializer,
    }

    body_deserializers = {
        'application/xml': xml_deserializer,
        'application/json': json_deserializer,
    }

    serializer = wsgi.ResponseSerializer(body_serializers,
                                         headers_serializers[version])
    deserializer = wsgi.RequestDeserializer(body_deserializers)

    return wsgi.Resource(controller,
                         fault_body_function,
                         deserializer,
                         serializer)
Example #10
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """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())
        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.QuantumException,
                netaddr.AddrFormatError) as e:
            LOG.exception(_('%s failed'), action)
            body = serializer.serialize({'QuantumError': e})
            kwargs = {'body': body, 'content_type': content_type}
            for fault in faults:
                if isinstance(e, fault):
                    raise faults[fault](**kwargs)
            raise webob.exc.HTTPInternalServerError(**kwargs)
        except webob.exc.HTTPException as e:
            LOG.exception(_('%s failed'), action)
            e.body = serializer.serialize({'QuantumError': e})
            e.content_type = content_type
            raise
        except Exception as e:
            # NOTE(jkoelker) Everyting 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.')
            body = serializer.serialize({'QuantumError': 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
Example #11
0
        #    <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:
        # <_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" />
Example #12
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    default_deserializers = {
        'application/xml': wsgi.XMLDeserializer(),
        'application/json': lambda x: json.loads(x)
    }
    default_serializers = {
        'application/xml': wsgi.XMLDictSerializer(),
        'application/json': lambda x: json.dumps(x)
    }
    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())
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

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

            method = getattr(controller, action)

            result = method(request=request, **args)
        except exceptions.QuantumException as e:
            LOG.exception('%s failed' % action)
            body = serializer({'QuantumError': str(e)})
            kwargs = {'body': body, 'content_type': content_type}
            for fault in faults:
                if isinstance(e, fault):
                    raise faults[fault](**kwargs)
            raise webob.exc.HTTPInternalServerError(**kwargs)
        except webob.exc.HTTPException as e:
            LOG.exception('%s failed' % action)
            e.body = serializer({'QuantumError': str(e)})
            e.content_type = content_type
            raise
        except Exception as e:
            # NOTE(jkoelker) Everyting else is 500
            LOG.exception('%s failed' % action)
            body = serializer({'QuantumError': str(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer(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