diff --git a/openstack-common.conf b/openstack-common.conf index 31b82b840..d451e1ef9 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -1,7 +1,7 @@ [DEFAULT] # The list of modules to copy from openstack-common -modules=cfg,importutils,iniparser,setup +modules=cfg,importutils,iniparser,jsonutils,setup # The base module to hold the copy of openstack.common base=quantum diff --git a/quantum/common/utils.py b/quantum/common/utils.py index bc88afa73..3d09ca6da 100644 --- a/quantum/common/utils.py +++ b/quantum/common/utils.py @@ -24,7 +24,6 @@ import ConfigParser import datetime import inspect -import json import logging import os import random @@ -36,14 +35,6 @@ from quantum.common.exceptions import ProcessExecutionError from quantum.common import flags -def dumps(value): - return json.dumps(value) - - -def loads(value): - return json.loads(value) - - TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" FLAGS = flags.FLAGS diff --git a/quantum/openstack/common/jsonutils.py b/quantum/openstack/common/jsonutils.py new file mode 100644 index 000000000..fa8b8f9d1 --- /dev/null +++ b/quantum/openstack/common/jsonutils.py @@ -0,0 +1,133 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +''' +JSON related utilities. + +This module provides a few things: + + 1) A handy function for getting an object down to something that can be + JSON serialized. See to_primitive(). + + 2) Wrappers around loads() and dumps(). The dumps() wrapper will + automatically use to_primitive() for you if needed. + + 3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson + is available. +''' + + +import datetime +import inspect +import itertools +import json + + +def to_primitive(value, convert_instances=False, level=0): + """Convert a complex object into primitives. + + Handy for JSON serialization. We can optionally handle instances, + but since this is a recursive function, we could have cyclical + data structures. + + To handle cyclical data structures we could track the actual objects + visited in a set, but not all objects are hashable. Instead we just + track the depth of the object inspections and don't go too deep. + + Therefore, convert_instances=True is lossy ... be aware. + + """ + nasty = [inspect.ismodule, inspect.isclass, inspect.ismethod, + inspect.isfunction, inspect.isgeneratorfunction, + inspect.isgenerator, inspect.istraceback, inspect.isframe, + inspect.iscode, inspect.isbuiltin, inspect.isroutine, + inspect.isabstract] + for test in nasty: + if test(value): + return unicode(value) + + # value of itertools.count doesn't get caught by inspects + # above and results in infinite loop when list(value) is called. + if type(value) == itertools.count: + return unicode(value) + + # FIXME(vish): Workaround for LP bug 852095. Without this workaround, + # tests that raise an exception in a mocked method that + # has a @wrap_exception with a notifier will fail. If + # we up the dependency to 0.5.4 (when it is released) we + # can remove this workaround. + if getattr(value, '__module__', None) == 'mox': + return 'mock' + + if level > 3: + return '?' + + # The try block may not be necessary after the class check above, + # but just in case ... + try: + if isinstance(value, (list, tuple)): + o = [] + for v in value: + o.append(to_primitive(v, convert_instances=convert_instances, + level=level)) + return o + elif isinstance(value, dict): + o = {} + for k, v in value.iteritems(): + o[k] = to_primitive(v, convert_instances=convert_instances, + level=level) + return o + elif isinstance(value, datetime.datetime): + return str(value) + elif hasattr(value, 'iteritems'): + return to_primitive(dict(value.iteritems()), + convert_instances=convert_instances, + level=level) + elif hasattr(value, '__iter__'): + return to_primitive(list(value), level) + elif convert_instances and hasattr(value, '__dict__'): + # Likely an instance of something. Watch for cycles. + # Ignore class member vars. + return to_primitive(value.__dict__, + convert_instances=convert_instances, + level=level + 1) + else: + return value + except TypeError, e: + # Class objects are tricky since they may define something like + # __iter__ defined but it isn't callable as list(). + return unicode(value) + + +def dumps(value): + return json.dumps(value, default=to_primitive) + + +def loads(s): + return json.loads(s) + + +try: + import anyjson +except ImportError: + pass +else: + anyjson._modules.append((__name__, 'dumps', TypeError, + 'loads', ValueError)) + anyjson.force_implementation(__name__) diff --git a/quantum/plugins/cisco/tests/unit/test_cisco_extension.py b/quantum/plugins/cisco/tests/unit/test_cisco_extension.py index 9c447cdac..38e1f0ce1 100644 --- a/quantum/plugins/cisco/tests/unit/test_cisco_extension.py +++ b/quantum/plugins/cisco/tests/unit/test_cisco_extension.py @@ -18,7 +18,6 @@ # Peter Strunk , Cisco Systems, Inc. # Shubhangi Satras , Cisco Systems, Inc. -import json import logging import os.path import unittest @@ -42,6 +41,7 @@ from quantum.extensions.extensions import ( PluginAwareExtensionManager, ) from quantum.manager import QuantumManager +from quantum.openstack.common import jsonutils from quantum.plugins.cisco.db import api as db from quantum.plugins.cisco import l2network_plugin from quantum.plugins.cisco.l2network_plugin import L2Network @@ -108,11 +108,11 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test List Portprofile""" LOG.debug("test_list_portprofile - START") - req_body1 = json.dumps(self.test_port_profile) + req_body1 = jsonutils.dumps(self.test_port_profile) create_response1 = self.test_app.post( self.profile_path, req_body1, content_type=self.contenttype) - req_body2 = json.dumps({ + req_body2 = jsonutils.dumps({ 'portprofile': { 'portprofile_name': 'cisco_test_portprofile2', 'qos_name': 'test-qos2', @@ -156,7 +156,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test create Portprofile""" LOG.debug("test_create_portprofile - START") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post(self.profile_path, req_body, content_type=self.contenttype) self.assertEqual(200, index_response.status_int) @@ -187,7 +187,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test show Portprofile """ LOG.debug("test_show_portprofile - START") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post(self.profile_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize(index_response.body, @@ -226,7 +226,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test update Portprofile""" LOG.debug("test_update_portprofile - START") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post( self.profile_path, req_body, content_type=self.contenttype) @@ -238,7 +238,7 @@ class PortprofileExtensionTest(unittest.TestCase): 'qos_name': 'test-qos1', }, } - rename_req_body = json.dumps(rename_port_profile) + rename_req_body = jsonutils.dumps(rename_port_profile) rename_path_temp = (self.portprofile_path + resp_body['portprofiles']['portprofile']['id']) rename_path = str(rename_path_temp) @@ -263,7 +263,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test update Portprofile Bad Request""" LOG.debug("test_update_portprofileBADRequest - START") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post( self.profile_path, req_body, content_type=self.contenttype) @@ -291,7 +291,7 @@ class PortprofileExtensionTest(unittest.TestCase): 'qos_name': 'test-qos1', }, } - rename_req_body = json.dumps(rename_port_profile) + rename_req_body = jsonutils.dumps(rename_port_profile) update_path_temp = self.portprofile_path + portprofile_id update_path = str(update_path_temp) update_response = self.test_app.put(update_path, rename_req_body, @@ -305,7 +305,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Test delete Portprofile""" LOG.debug("test_delete_portprofile - START") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post( self.profile_path, req_body, content_type=self.contenttype) @@ -406,7 +406,7 @@ class PortprofileExtensionTest(unittest.TestCase): LOG.debug("test_associate_portprofile - START") net_id = self._create_network() port_id = self._create_port(net_id, "ACTIVE") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post( self.profile_path, req_body, content_type=self.contenttype) @@ -418,7 +418,7 @@ class PortprofileExtensionTest(unittest.TestCase): 'port-id': port_id, }, } - req_assign_body = json.dumps(test_port_assign_data) + req_assign_body = jsonutils.dumps(test_port_assign_data) associate_path_temp = ( self.portprofile_path + resp_body['portprofiles']['portprofile']['id'] + @@ -454,7 +454,7 @@ class PortprofileExtensionTest(unittest.TestCase): 'port-id': '1', }, } - req_assign_body = json.dumps(test_port_assign_data) + req_assign_body = jsonutils.dumps(test_port_assign_data) associate_path = (self.portprofile_path + portprofile_id + "/associate_portprofile") @@ -472,7 +472,7 @@ class PortprofileExtensionTest(unittest.TestCase): net_id = self._create_network() port_id = self._create_port(net_id, "ACTIVE") - req_body = json.dumps(self.test_port_profile) + req_body = jsonutils.dumps(self.test_port_profile) index_response = self.test_app.post( self.profile_path, req_body, content_type=self.contenttype) @@ -485,7 +485,7 @@ class PortprofileExtensionTest(unittest.TestCase): 'port-id': port_id, }, } - req_assign_body = json.dumps(test_port_assign_data) + req_assign_body = jsonutils.dumps(test_port_assign_data) associate_path_temp = (self.portprofile_path + resp_body['portprofiles']['portprofile']['id'] + "/associate_portprofile") @@ -582,7 +582,7 @@ class NovatenantExtensionTest(unittest.TestCase): def test_schedule_host(self): """ Test get host""" LOG.debug("test_schedule_host - START") - req_body = json.dumps(self.test_associate_data) + req_body = jsonutils.dumps(self.test_associate_data) host_path = self.novatenants_path + "001/schedule_host" host_response = self.test_app.put( host_path, req_body, @@ -603,7 +603,7 @@ class NovatenantExtensionTest(unittest.TestCase): def test_associate_port(self): """ Test get associate port """ LOG.debug("test_associate_port - START") - req_body = json.dumps(self.test_associate_port_data) + req_body = jsonutils.dumps(self.test_associate_port_data) associate_port_path = self.novatenants_path + "001/associate_port" associate_port_response = self.test_app.put( associate_port_path, req_body, @@ -650,7 +650,7 @@ class QosExtensionTest(unittest.TestCase): """ Test create qos """ LOG.debug("test_create_qos - START") - req_body = json.dumps(self.test_qos_data) + req_body = jsonutils.dumps(self.test_qos_data) index_response = self.test_app.post(self.qos_path, req_body, content_type=self.contenttype) @@ -681,10 +681,10 @@ class QosExtensionTest(unittest.TestCase): """ Test list qoss """ LOG.debug("test_list_qoss - START") - req_body1 = json.dumps(self.test_qos_data) + req_body1 = jsonutils.dumps(self.test_qos_data) create_resp1 = self.test_app.post(self.qos_path, req_body1, content_type=self.contenttype) - req_body2 = json.dumps({ + req_body2 = jsonutils.dumps({ 'qos': { 'qos_name': 'cisco_test_qos2', 'qos_desc': { @@ -721,7 +721,7 @@ class QosExtensionTest(unittest.TestCase): """ Test show qos """ LOG.debug("test_show_qos - START") - req_body = json.dumps(self.test_qos_data) + req_body = jsonutils.dumps(self.test_qos_data) index_response = self.test_app.post(self.qos_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize(index_response.body, @@ -756,12 +756,12 @@ class QosExtensionTest(unittest.TestCase): """ Test update qos """ LOG.debug("test_update_qos - START") - req_body = json.dumps(self.test_qos_data) + req_body = jsonutils.dumps(self.test_qos_data) index_response = self.test_app.post(self.qos_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize(index_response.body, self.contenttype) - rename_req_body = json.dumps({ + rename_req_body = jsonutils.dumps({ 'qos': { 'qos_name': 'cisco_rename_qos', 'qos_desc': { @@ -789,7 +789,7 @@ class QosExtensionTest(unittest.TestCase): """ Test update qos does not exist """ LOG.debug("test_update_qosDNE - START") - rename_req_body = json.dumps({ + rename_req_body = jsonutils.dumps({ 'qos': { 'qos_name': 'cisco_rename_qos', 'qos_desc': { @@ -811,7 +811,7 @@ class QosExtensionTest(unittest.TestCase): """ Test update qos bad request """ LOG.debug("test_update_qosBADRequest - START") - req_body = json.dumps(self.test_qos_data) + req_body = jsonutils.dumps(self.test_qos_data) index_response = self.test_app.post(self.qos_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize(index_response.body, @@ -832,7 +832,7 @@ class QosExtensionTest(unittest.TestCase): """ Test delte qos """ LOG.debug("test_delete_qos - START") - req_body = json.dumps({ + req_body = jsonutils.dumps({ 'qos': { 'qos_name': 'cisco_test_qos', 'qos_desc': { @@ -905,11 +905,11 @@ class CredentialExtensionTest(unittest.TestCase): #Create Credential before listing LOG.debug("test_list_credentials - START") - req_body1 = json.dumps(self.test_credential_data) + req_body1 = jsonutils.dumps(self.test_credential_data) create_response1 = self.test_app.post( self.credential_path, req_body1, content_type=self.contenttype) - req_body2 = json.dumps({ + req_body2 = jsonutils.dumps({ 'credential': { 'credential_name': 'cred9', 'user_name': 'newUser2', @@ -949,7 +949,7 @@ class CredentialExtensionTest(unittest.TestCase): """ Test create credential """ LOG.debug("test_create_credential - START") - req_body = json.dumps(self.test_credential_data) + req_body = jsonutils.dumps(self.test_credential_data) index_response = self.test_app.post( self.credential_path, req_body, content_type=self.contenttype) @@ -979,7 +979,7 @@ class CredentialExtensionTest(unittest.TestCase): """ Test show credential """ LOG.debug("test_show_credential - START") - req_body = json.dumps(self.test_credential_data) + req_body = jsonutils.dumps(self.test_credential_data) index_response = self.test_app.post( self.credential_path, req_body, content_type=self.contenttype) @@ -1015,14 +1015,14 @@ class CredentialExtensionTest(unittest.TestCase): """ Test update credential """ LOG.debug("test_update_credential - START") - req_body = json.dumps(self.test_credential_data) + req_body = jsonutils.dumps(self.test_credential_data) index_response = self.test_app.post( self.credential_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize( index_response.body, self.contenttype) - rename_req_body = json.dumps({ + rename_req_body = jsonutils.dumps({ 'credential': { 'credential_name': 'cred3', 'user_name': 'RenamedUser', @@ -1051,7 +1051,7 @@ class CredentialExtensionTest(unittest.TestCase): """ Test update credential bad request """ LOG.debug("test_update_credBADReq - START") - req_body = json.dumps(self.test_credential_data) + req_body = jsonutils.dumps(self.test_credential_data) index_response = self.test_app.post( self.credential_path, req_body, content_type=self.contenttype) @@ -1070,7 +1070,7 @@ class CredentialExtensionTest(unittest.TestCase): """ Test update credential does not exist""" LOG.debug("test_update_credentialDNE - START") - rename_req_body = json.dumps({ + rename_req_body = jsonutils.dumps({ 'credential': { 'credential_name': 'cred3', 'user_name': 'RenamedUser', @@ -1090,7 +1090,7 @@ class CredentialExtensionTest(unittest.TestCase): """ Test delete credential """ LOG.debug("test_delete_credential - START") - req_body = json.dumps(self.test_credential_data) + req_body = jsonutils.dumps(self.test_credential_data) index_response = self.test_app.post( self.credential_path, req_body, content_type=self.contenttype) @@ -1212,7 +1212,7 @@ class MultiPortExtensionTest(unittest.TestCase): }, }, } - req_body = json.dumps(test_multi_port) + req_body = jsonutils.dumps(test_multi_port) index_response = self.test_app.post(self.multiport_path, req_body, content_type=self.contenttype) resp_body = wsgi.Serializer().deserialize(index_response.body, diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/api_client/request_eventlet.py b/quantum/plugins/nicira/nicira_nvp_plugin/api_client/request_eventlet.py index 355d961e7..2c9571c17 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/api_client/request_eventlet.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/api_client/request_eventlet.py @@ -13,7 +13,6 @@ # under the License. import httplib -import json import logging import time import urllib @@ -22,6 +21,7 @@ import urlparse import eventlet from eventlet import timeout +from quantum.openstack.common import jsonutils from quantum.plugins.nicira.nicira_nvp_plugin.api_client.common import ( _conn_str, ) @@ -332,7 +332,7 @@ class NvpGetApiProvidersRequestEventlet(NvpApiRequestEventlet): try: if self.successful(): ret = [] - body = json.loads(self.value.body) + body = jsonutils.loads(self.value.body) for node in body.get('results', []): for role in node.get('roles', []): if role.get('role') == 'api_provider': diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/nvplib.py b/quantum/plugins/nicira/nicira_nvp_plugin/nvplib.py index 5f3d210bf..42e2b5bd5 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/nvplib.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/nvplib.py @@ -14,10 +14,10 @@ # # @author: Brad Hall, Nicira Networks, Inc. -import json import logging from quantum.common import exceptions as exception +from quantum.openstack.common import jsonutils from quantum.plugins.nicira.nicira_nvp_plugin import NvpApiClient @@ -42,7 +42,7 @@ def check_default_transport_zone(c): "GET", "/ws.v1/transport-zone?uuid=%s" % c.default_tz_uuid, controller=c) - result = json.loads(resp) + result = jsonutils.loads(resp) if int(result["result_count"]) == 0: msg.append("Unable to find zone \"%s\" for controller \"%s\"" % (c.default_tz_uuid, c.name)) @@ -67,7 +67,7 @@ def get_network(controller, net_id): path = "/ws.v1/lswitch/%s" % net_id try: resp_obj = do_single_request("GET", path, controller=controller) - network = json.loads(resp_obj) + network = jsonutils.loads(resp_obj) except NvpApiClient.ResourceNotFound as e: raise exception.NetworkNotFound(net_id=net_id) except NvpApiClient.NvpApiException as e: @@ -86,12 +86,12 @@ def create_lswitch(controller, lswitch_obj): uri = "/ws.v1/lswitch" try: resp_obj = do_single_request("POST", uri, - json.dumps(lswitch_obj), + jsonutils.dumps(lswitch_obj), controller=controller) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - r = json.loads(resp_obj) + r = jsonutils.loads(resp_obj) d = {} d["net-id"] = r["uuid"] d["net-name"] = r["display_name"] @@ -105,15 +105,17 @@ def update_network(controller, network, **kwargs): if "name" in kwargs: lswitch_obj["display_name"] = kwargs["name"] try: - resp_obj = do_single_request( - "PUT", uri, json.dumps(lswitch_obj), controller=controller) + resp_obj = do_single_request("PUT", + uri, + jsonutils.dumps(lswitch_obj), + controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - obj = json.loads(resp_obj) + obj = jsonutils.loads(resp_obj) return obj @@ -128,7 +130,7 @@ def get_all_networks(controller, tenant_id, networks): raise exception.QuantumException() if not resp_obj: return [] - lswitches = json.loads(resp_obj)["results"] + lswitches = jsonutils.loads(resp_obj)["results"] for lswitch in lswitches: net_id = lswitch["uuid"] if net_id not in [x["net-id"] for x in networks]: @@ -148,7 +150,7 @@ def query_networks(controller, tenant_id, fields="*", tags=None): raise exception.QuantumException() if not resp_obj: return [] - lswitches = json.loads(resp_obj)["results"] + lswitches = jsonutils.loads(resp_obj)["results"] nets = [{'net-id': lswitch["uuid"], 'net-name': lswitch["display_name"]} for lswitch in lswitches] @@ -208,7 +210,7 @@ def get_port_stats(controller, network_id, port_id): try: path = "/ws.v1/lswitch/%s/lport/%s/statistic" % (network_id, port_id) resp = do_single_request("GET", path, controller=controller) - stats = json.loads(resp) + stats = jsonutils.loads(resp) except NvpApiClient.ResourceNotFound as e: LOG.error("Port not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network_id) @@ -242,7 +244,7 @@ def query_ports(controller, network, relations=None, fields="*", filters=None): raise exception.NetworkNotFound(net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - return json.loads(resp_obj)["results"] + return jsonutils.loads(resp_obj)["results"] def delete_port(controller, network, port): @@ -260,7 +262,7 @@ def delete_all_ports(controller, ls_uuid): res = do_single_request("GET", "/ws.v1/lswitch/%s/lport?fields=uuid" % ls_uuid, controller=controller) - res = json.loads(res) + res = jsonutils.loads(res) for r in res["results"]: do_single_request( "DELETE", @@ -274,7 +276,7 @@ def get_port(controller, network, port, relations=None): uri += "relations=%s" % relations try: resp_obj = do_single_request("GET", uri, controller=controller) - port = json.loads(resp_obj) + port = jsonutils.loads(resp_obj) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) @@ -292,8 +294,10 @@ def plug_interface(controller, network, port, type, attachment=None): lport_obj["type"] = type try: - resp_obj = do_single_request("PUT", uri, - json.dumps(lport_obj), controller=controller) + resp_obj = do_single_request("PUT", + uri, + jsonutils.dumps(lport_obj), + controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) @@ -307,7 +311,7 @@ def plug_interface(controller, network, port, type, attachment=None): except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - result = json.dumps(resp_obj) + result = jsonutils.dumps(resp_obj) return result @@ -315,14 +319,16 @@ def unplug_interface(controller, network, port): uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "/attachment" lport_obj = {"type": "NoAttachment"} try: - resp_obj = do_single_request( - "PUT", uri, json.dumps(lport_obj), controller=controller) + resp_obj = do_single_request("PUT", + uri, + jsonutils.dumps(lport_obj), + controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - return json.loads(resp_obj) + return jsonutils.loads(resp_obj) def update_port(network, port_id, **params): @@ -339,15 +345,17 @@ def update_port(network, port_id, **params): uri = "/ws.v1/lswitch/" + network + "/lport/" + port_id try: - resp_obj = do_single_request( - "PUT", uri, json.dumps(lport_obj), controller=controller) + resp_obj = do_single_request("PUT", + uri, + jsonutils.dumps(lport_obj), + controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - obj = json.loads(resp_obj) + obj = jsonutils.loads(resp_obj) obj["port-op-status"] = get_port_status(controller, network, obj["uuid"]) return obj @@ -368,15 +376,17 @@ def create_port(tenant, network, port_init_state, **params): path = "/ws.v1/lswitch/" + ls_uuid + "/lport" try: - resp_obj = do_single_request( - "POST", path, json.dumps(lport_obj), controller=controller) + resp_obj = do_single_request("POST", + path, + jsonutils.dumps(lport_obj), + controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() - result = json.loads(resp_obj) + result = jsonutils.loads(resp_obj) result['port-op-status'] = get_port_status(controller, ls_uuid, result['uuid']) return result @@ -398,7 +408,7 @@ def get_port_status(controller, lswitch_id, port_id): "GET", "/ws.v1/lswitch/%s/lport/%s/status" % (lswitch_id, port_id), controller=controller) - r = json.loads(r) + r = jsonutils.loads(r) except NvpApiClient.ResourceNotFound as e: LOG.error("Port not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=lswitch_id) diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_network.py b/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_network.py index 9f2f45920..c8f3ba6c9 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_network.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_network.py @@ -15,12 +15,12 @@ # @author: Somik Behera, Nicira Networks, Inc. # @author: Brad Hall, Nicira Networks, Inc. -import json import logging import os import unittest from quantum.common import exceptions as exception +from quantum.openstack.common import jsonutils from quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin import NvpPlugin from quantum.plugins.nicira.nicira_nvp_plugin import ( NvpApiClient, @@ -56,11 +56,11 @@ class NvpTests(unittest.TestCase): "tags": [{"tag": "plugin-test"}]} try: resp_obj = self.quantum.api_client.request("POST", - post_uri, json.dumps(body)) + post_uri, jsonutils.dumps(body)) except NvpApiClient.NvpApiException as e: print("Unknown API Error: %s" % str(e)) raise exception.QuantumException() - return json.loads(resp_obj)["uuid"] + return jsonutils.loads(resp_obj)["uuid"] def _delete_tz(self, uuid): post_uri = "/ws.v1/transport-zone/%s" % uuid diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_port.py b/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_port.py index 18f2cf135..494915be8 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_port.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/tests/test_port.py @@ -14,12 +14,12 @@ # # @author: Somik Behera, Nicira Networks, Inc. -import json import logging import os import unittest from quantum.common import exceptions as exception +from quantum.openstack.common import jsonutils from quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin import NvpPlugin from quantum.plugins.nicira.nicira_nvp_plugin import ( NvpApiClient, @@ -61,12 +61,13 @@ class NvpTests(unittest.TestCase): post_uri = "/ws.v1/transport-zone" body = {"display_name": name, "tags": [{"tag": "plugin-test"}]} try: - resp_obj = self.quantum.api_client.request( - "POST", post_uri, json.dumps(body)) + resp_obj = self.quantum.api_client.request("POST", + post_uri, + jsonutils.dumps(body)) except NvpApiClient.NvpApiException as e: LOG.error("Unknown API Error: %s" % str(e)) raise exception.QuantumException() - return json.loads(resp_obj)["uuid"] + return jsonutils.loads(resp_obj)["uuid"] def _delete_tz(self, uuid): post_uri = "/ws.v1/transport-zone/%s" % uuid diff --git a/quantum/tests/unit/extensions/foxinsocks.py b/quantum/tests/unit/extensions/foxinsocks.py index a2dcc8435..c458d869c 100644 --- a/quantum/tests/unit/extensions/foxinsocks.py +++ b/quantum/tests/unit/extensions/foxinsocks.py @@ -16,9 +16,9 @@ # under the License. from abc import abstractmethod -import json from quantum.extensions import extensions +from quantum.openstack.common import jsonutils from quantum import wsgi @@ -79,9 +79,9 @@ class Foxinsocks(object): def _goose_handler(req, res): #NOTE: This only handles JSON responses. # You can use content type header to test for XML. - data = json.loads(res.body) + data = jsonutils.loads(res.body) data['FOXNSOX:googoose'] = req.GET.get('chewing') - res.body = json.dumps(data) + res.body = jsonutils.dumps(data) return res req_ext1 = extensions.RequestExtension('GET', '/dummy_resources/:(id)', @@ -91,9 +91,9 @@ class Foxinsocks(object): def _bands_handler(req, res): #NOTE: This only handles JSON responses. # You can use content type header to test for XML. - data = json.loads(res.body) + data = jsonutils.loads(res.body) data['FOXNSOX:big_bands'] = 'Pig Bands!' - res.body = json.dumps(data) + res.body = jsonutils.dumps(data) return res req_ext2 = extensions.RequestExtension('GET', '/dummy_resources/:(id)', diff --git a/quantum/tests/unit/test_api.py b/quantum/tests/unit/test_api.py index 792418d09..eb1ac748a 100644 --- a/quantum/tests/unit/test_api.py +++ b/quantum/tests/unit/test_api.py @@ -16,7 +16,6 @@ # under the License. # @author: Salvatore Orlando, Citrix Systems -import json import unittest from lxml import etree @@ -27,6 +26,7 @@ import quantum.api.networks as nets import quantum.api.ports as ports import quantum.api.versions as versions from quantum.common.test_lib import test_config +from quantum.openstack.common import jsonutils import quantum.tests.unit._test_api as test_api import quantum.tests.unit.testlib_api as testlib @@ -353,7 +353,7 @@ class APIRootTest(unittest.TestCase): def test_root_responds_with_versions_json(self): body = self._test_root_responds_with_versions('application/json') - data = json.loads(body) + data = jsonutils.loads(body) self.assertEquals('versions', data.keys()[0]) def test_root_responds_with_versions_xml(self): diff --git a/quantum/tests/unit/test_extensions.py b/quantum/tests/unit/test_extensions.py index cb8de5b0e..519161221 100644 --- a/quantum/tests/unit/test_extensions.py +++ b/quantum/tests/unit/test_extensions.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -import json import unittest import routes @@ -30,6 +29,7 @@ from quantum.extensions.extensions import ( ExtensionMiddleware, PluginAwareExtensionManager, ) +from quantum.openstack.common import jsonutils from quantum.plugins.sample.SamplePlugin import QuantumEchoPlugin from quantum.tests.unit import BaseTest from quantum.tests.unit.extension_stubs import ( @@ -114,7 +114,8 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.get("/tweedles/some_id/custom_member_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['member_action'], "value") + self.assertEqual(jsonutils.loads(response.body)['member_action'], + "value") def test_resource_extension_for_get_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -125,7 +126,7 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.get("/tweedles/custom_collection_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], "value") + self.assertEqual(jsonutils.loads(response.body)['collection'], "value") def test_resource_extension_for_put_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -137,7 +138,7 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.put("/tweedles/custom_collection_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], 'value') + self.assertEqual(jsonutils.loads(response.body)['collection'], 'value') def test_resource_extension_for_post_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -149,7 +150,7 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.post("/tweedles/custom_collection_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], 'value') + self.assertEqual(jsonutils.loads(response.body)['collection'], 'value') def test_resource_extension_for_delete_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -161,7 +162,7 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.delete("/tweedles/custom_collection_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], 'value') + self.assertEqual(jsonutils.loads(response.body)['collection'], 'value') def test_resource_ext_for_formatted_req_on_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -173,7 +174,7 @@ class ResourceExtensionTest(unittest.TestCase): response = test_app.get("/tweedles/custom_collection_action.json") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], "value") + self.assertEqual(jsonutils.loads(response.body)['collection'], "value") def test_resource_ext_for_nested_resource_custom_collection_action(self): controller = self.ResourceExtensionController() @@ -188,7 +189,7 @@ class ResourceExtensionTest(unittest.TestCase): "/tweedles/custom_collection_action") self.assertEqual(200, response.status_int) - self.assertEqual(json.loads(response.body)['collection'], "value") + self.assertEqual(jsonutils.loads(response.body)['collection'], "value") def test_returns_404_for_non_existant_extension(self): test_app = setup_extensions_test_app(SimpleExtensionManager(None)) @@ -207,7 +208,7 @@ class ActionExtensionTest(unittest.TestCase): def test_extended_action_for_adding_extra_data(self): action_name = 'FOXNSOX:add_tweedle' action_params = dict(name='Beetle') - req_body = json.dumps({action_name: action_params}) + req_body = jsonutils.dumps({action_name: action_params}) response = self.extension_app.post('/dummy_resources/1/action', req_body, content_type='application/json') @@ -216,7 +217,7 @@ class ActionExtensionTest(unittest.TestCase): def test_extended_action_for_deleting_extra_data(self): action_name = 'FOXNSOX:delete_tweedle' action_params = dict(name='Bailey') - req_body = json.dumps({action_name: action_params}) + req_body = jsonutils.dumps({action_name: action_params}) response = self.extension_app.post("/dummy_resources/1/action", req_body, content_type='application/json') @@ -225,7 +226,7 @@ class ActionExtensionTest(unittest.TestCase): def test_returns_404_for_non_existant_action(self): non_existant_action = 'blah_action' action_params = dict(name="test") - req_body = json.dumps({non_existant_action: action_params}) + req_body = jsonutils.dumps({non_existant_action: action_params}) response = self.extension_app.post("/dummy_resources/1/action", req_body, @@ -237,7 +238,7 @@ class ActionExtensionTest(unittest.TestCase): def test_returns_404_for_non_existant_resource(self): action_name = 'add_tweedle' action_params = dict(name='Beetle') - req_body = json.dumps({action_name: action_params}) + req_body = jsonutils.dumps({action_name: action_params}) response = self.extension_app.post("/asdf/1/action", req_body, content_type='application/json', @@ -262,16 +263,16 @@ class RequestExtensionTest(BaseTest): def test_extend_get_resource_response(self): def extend_response_data(req, res): - data = json.loads(res.body) + data = jsonutils.loads(res.body) data['FOXNSOX:extended_key'] = req.GET.get('extended_key') - res.body = json.dumps(data) + res.body = jsonutils.dumps(data) return res app = self._setup_app_with_request_handler(extend_response_data, 'GET') response = app.get("/dummy_resources/1?extended_key=extended_data") self.assertEqual(200, response.status_int) - response_data = json.loads(response.body) + response_data = jsonutils.loads(response.body) self.assertEqual('extended_data', response_data['FOXNSOX:extended_key']) self.assertEqual('knox', response_data['fort']) @@ -281,16 +282,16 @@ class RequestExtensionTest(BaseTest): response = app.get("/dummy_resources/1?chewing=newblue") - response_data = json.loads(response.body) + response_data = jsonutils.loads(response.body) self.assertEqual('newblue', response_data['FOXNSOX:googoose']) self.assertEqual("Pig Bands!", response_data['FOXNSOX:big_bands']) def test_edit_previously_uneditable_field(self): def _update_handler(req, res): - data = json.loads(res.body) + data = jsonutils.loads(res.body) data['uneditable'] = req.params['uneditable'] - res.body = json.dumps(data) + res.body = jsonutils.dumps(data) return res base_app = TestApp(setup_base_app()) diff --git a/quantum/wsgi.py b/quantum/wsgi.py index b1f631b35..77ef3134d 100644 --- a/quantum/wsgi.py +++ b/quantum/wsgi.py @@ -32,7 +32,7 @@ import webob.dec import webob.exc from quantum.common import exceptions as exception -from quantum.common import utils +from quantum.openstack.common import jsonutils LOG = logging.getLogger(__name__) @@ -181,7 +181,7 @@ class JSONDictSerializer(DictSerializer): """Default JSON request body serialization""" def default(self, data): - return utils.dumps(data) + return jsonutils.dumps(data) class XMLDictSerializer(DictSerializer): @@ -354,7 +354,7 @@ class JSONDeserializer(TextDeserializer): def _from_json(self, datastring): try: - return utils.loads(datastring) + return jsonutils.loads(datastring) except ValueError: msg = _("cannot understand JSON") raise exception.MalformedRequestBody(reason=msg) @@ -956,7 +956,7 @@ class Serializer(object): raise exception.InvalidContentType(content_type=content_type) def _from_json(self, datastring): - return utils.loads(datastring) + return jsonutils.loads(datastring) def _from_xml(self, datastring): xmldata = self.metadata.get('application/xml', {}) @@ -987,7 +987,7 @@ class Serializer(object): return result def _to_json(self, data): - return utils.dumps(data) + return jsonutils.dumps(data) def _to_xml(self, data): metadata = self.metadata.get('application/xml', {})