def test_xml_empty(self): xml = '<a></a>' as_dict = {'body': {'a': ''}} deserializer = wsgi.XMLDeserializer() self.assertEqual( deserializer.deserialize(xml), as_dict)
def test_xml_with_utf8(self): xml = '<a>\xe7\xbd\x91\xe7\xbb\x9c</a>' as_dict = {'body': {'a': u'\u7f51\u7edc'}} deserializer = wsgi.XMLDeserializer() self.assertEqual( deserializer.deserialize(xml), as_dict)
def test_mapped_neutron_error_with_xml(self): msg = u'\u7f51\u7edc' class TestException(n_exc.NeutronException): message = msg expected_res = { 'body': { 'NeutronError': { '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': 'xml' }) } res = resource.get('', extra_environ=environ, expect_errors=True) self.assertEqual(res.status_int, exc.HTTPGatewayTimeout.code) self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body), expected_res)
def test_default_raise_Malformed_Exception(self): """Verify that exception MalformedRequestBody is raised.""" data_string = "" deserializer = wsgi.XMLDeserializer() self.assertRaises( exception.MalformedRequestBody, deserializer.default, data_string)
def handle(self, request, response): xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata()) deserializers = { 'application/xml': xml_deserializer, 'application/json': wsgi.JSONDeserializer() } xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata()) serializers = { 'application/xml': xml_serializer, 'application/json': wsgi.JSONDictSerializer() } format_types = {'xml': 'application/xml', 'json': 'application/json'} path = [part for part in request.path_url.split("/") if part] id = path[-1].split('.')[0] content_type = format_types.get(None, request.best_match_content_type()) deserializer = deserializers.get(content_type) serializer = serializers.get(content_type) body = None if request.body: body = deserializer.deserialize(request.body)['body'] api_response = self._plugin.post_update_port(request.context, id, body) return serializer.serialize({"port": api_response})
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, }
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)
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)
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)
def test_unhandled_error_with_xml(self): expected_res = {'body': {'NeutronError': _('Request Failed: internal server error ' 'while processing your request.')}} controller = mock.MagicMock() controller.test.side_effect = Exception() resource = webtest.TestApp(wsgi_resource.Resource(controller)) environ = {'wsgiorg.routing_args': (None, {'action': 'test', 'format': 'xml'})} res = resource.get('', extra_environ=environ, expect_errors=True) self.assertEqual(res.status_int, exc.HTTPInternalServerError.code) self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body), expected_res)
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)
def test_unmapped_neutron_error_with_xml(self): msg = u'\u7f51\u7edc' class TestException(q_exc.NeutronException): message = msg expected_res = {'body': {'NeutronError': msg}} controller = mock.MagicMock() controller.test.side_effect = TestException() resource = webtest.TestApp(wsgi_resource.Resource(controller)) environ = { 'wsgiorg.routing_args': (None, { 'action': 'test', 'format': 'xml' }) } res = resource.get('', extra_environ=environ, expect_errors=True) self.assertEqual(res.status_int, exc.HTTPInternalServerError.code) self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body), expected_res)
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): if request.path in ['/v2.0/floatingips','/v2.0/tenants'] and 'uos_staff' in request.context.roles: uos_utils.uos_staff_act_as_admin(request) if request.path in ['/v2.0/uos_resources.json'] and \ 'routers' in request.params.getall('uos_resources') and \ len(request.params.getall('uos_resources')) == 1 and \ 'uos_staff' in request.context.roles: uos_utils.uos_staff_act_as_admin(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.NeutronException, 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) body = serializer.serialize( {'NeutronError': get_exception_data(e)}) 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( {'NeutronError': get_exception_data(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': get_exception_data(e)}) 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( {'NeutronError': get_exception_data( webob.exc.HTTPInternalServerError(msg))}) kwargs = {'body': body, 'content_type': content_type} raise webob.exc.HTTPInternalServerError(**kwargs) status = action_status.get(action, 200) if type(result) == dict and 'file' in result.keys(): content_disposition = "attachment; filename=%s" % result['name'] content_type = "application/binary; charset=UTF-8" contents = result['contents'].decode('base64') return file_response(request,status,content_type, content_disposition, contents) 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
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()) 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.NeutronException, netaddr.AddrFormatError) as e: LOG.exception(_('%s failed'), action) e = translate(e, language) # following structure is expected by python-neutronclient err_data = { 'type': e.__class__.__name__, 'message': e, 'detail': '' } body = serializer.serialize({'NeutronError': err_data}) 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) translate(e, language) e.body = serializer.serialize({'NeutronError': e}) e.content_type = content_type raise 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 as e: # 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({'NeutronError': 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
def _get_deserializer(req_format): if req_format == 'json': return wsgi.JSONDeserializer() else: return wsgi.XMLDeserializer()
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 {} #neutron/api/v2/base.py 789 wsgi_resource.Resource(controller, FAULT_MAP) #FAULT_MAP :neutron/api/v2/base.py 38 @webob.dec.wsgify(RequestClass=Request) def resource(request): # #brk(host="10.10.12.21", port=49175) # #add by xm-2015.7.8:G-cloud7.0区域权限控制, # #根据api请求中是否附件resource_type及是否resource_type=0/1来区分用户角色 # #resource_type = request.params.get('resource_type', None) # resource_type = request.environ.get('HTTP_G_AUTH_RESOURCETYPE', None) # #resource_type = request.headers.environ.get('HTTP_G_AUTH_RESOURCETYPE', None) # LOG.debug(_('resource_type_xm: %(resource_type)s'), {'resource_type': resource_type}) # if resource_type == '0': # request.context.roles = list(set(request.context.roles) - set(['admin'])) # request.context.is_admin = False # elif resource_type == '1': # request.context.roles = list(set(request.context.roles) | set(['admin'])) # request.context.is_admin = True # #end-2015.7.8 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'] #首先进入/usr/lib/python2.7/site-packages/webob/request.py(671)_body__get() 然后return 到/usr/lib/python2.7/site-packages/neutron/wsgi.py(599)deserialize() method = getattr(controller, action) #pdb.set_trace() result = method(request=request, **args) except (exceptions.NeutronException, netaddr.AddrFormatError) as e: #faults = {<class 'neutron.common.exceptions.NotAuthorized'>: <class 'webob.exc.HTTPForbidden'>, # <class 'neutron.common.exceptions.Conflict'>: <class 'webob.exc.HTTPConflict'>, # <class 'neutron.common.exceptions.NotFound'>: <class 'webob.exc.HTTPNotFound'>, # <class 'neutron.common.exceptions.ServiceUnavailable'>: <class 'webob.exc.HTTPServiceUnavailable'>, # <class 'netaddr.core.AddrFormatError'>: <class 'webob.exc.HTTPBadRequest'>, # <class 'neutron.common.exceptions.BadRequest'>: <class 'webob.exc.HTTPBadRequest'>, # <class 'neutron.common.exceptions.InUse'>: <class 'webob.exc.HTTPConflict'>} for fault in faults: if isinstance(e, fault): mapped_exc = faults[fault] break else: if e.code and e.code != 500: mapped_exc = webob.exc.HTTPClientError 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) body = serializer.serialize( {'NeutronError': get_exception_data(e)}) 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( {'NeutronError': get_exception_data(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': get_exception_data(e)}) 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({ 'NeutronError': get_exception_data(webob.exc.HTTPInternalServerError(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
# # 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" /> serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata()) result = serializer.serialize(data)
def test_initialization(self): xml = '<a><b>test</b></a>' deserializer = wsgi.XMLDeserializer() self.assertEqual( {'body': {u'a': {u'b': u'test'}}}, deserializer(xml))