Skip to content

Commit

Permalink
Ignore update request when nothing has changed in object.
Browse files Browse the repository at this point in the history
In api client library, do not send update to server if none of the
attributes were updated. In api server, ignore PUTs when there is
no body or empty body.

Change-Id: Ia060380abb737c4ed7c869af15e23375f99fff41
Closes-Bug: #1502237
  • Loading branch information
Hampapur Ajay committed Oct 2, 2015
1 parent 612771f commit 041c2b1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/api-lib/vnc_api.py
Expand Up @@ -376,13 +376,17 @@ def _object_update(self, res_type, obj):
if not obj.uuid:
obj.uuid = self.fq_name_to_id(res_type, obj.get_fq_name())

# Ignore fields with None value in json representation
json_param = json.dumps(obj, default=self._obj_serializer)
json_body = '{"%s":%s}' %(res_type, json_param)
# Generate PUT on object only if some attr was modified
content = None
if obj.get_pending_updates():
# Ignore fields with None value in json representation
json_param = json.dumps(obj, default=self._obj_serializer)
json_body = '{"%s":%s}' %(res_type, json_param)

id = obj.uuid
uri = obj_cls.resource_uri_base[res_type] + '/' + id
content = self._request_server(rest.OP_PUT, uri, data=json_body)

id = obj.uuid
uri = obj_cls.resource_uri_base[res_type] + '/' + id
content = self._request_server(rest.OP_PUT, uri, data=json_body)
for ref_name in obj._pending_ref_updates:
ref_orig = set([(x.get('uuid'),
tuple(x.get('to', [])), x.get('attr'))
Expand Down
20 changes: 20 additions & 0 deletions src/config/api-server/tests/test_crud_basic.py
Expand Up @@ -1614,6 +1614,26 @@ def test_vmi_links_to_native_ri(self):
logger.info("...link to Native RI done.")
# end test_vmi_links_to_native_ri

def test_nop_on_empty_body_update(self):
# library api test
vn_fq_name = VirtualNetwork().fq_name
vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name)
mod_time = vn_obj.id_perms.last_modified
resp = self._vnc_lib.virtual_network_update(vn_obj)
self.assertIsNone(resp)
vn_obj = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name)
self.assertEqual(mod_time, vn_obj.id_perms.last_modified)

# rest api test
listen_ip = self._api_server_ip
listen_port = self._api_server._args.listen_port
url = 'http://%s:%s/virtual-network/%s' %(
listen_ip, listen_port, vn_obj.uuid)
resp = requests.put(url)
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.text, '')
# end test_nop_on_empty_body_update

# end class TestVncCfgApiServer

class TestVncCfgApiServerRequests(test_case.ApiServerTestCase):
Expand Down
7 changes: 7 additions & 0 deletions src/config/api-server/vnc_cfg_api_server.py
Expand Up @@ -556,6 +556,13 @@ def http_resource_read(self, resource_type, id):
def http_resource_update(self, resource_type, id):
r_class = self.get_resource_class(resource_type)
obj_type = resource_type.replace('-', '_')
# Early return if there is no body or an empty body
request = get_request()
if (not hasattr(request, 'json') or
not request.json or
not request.json[resource_type]):
return

obj_dict = get_request().json[resource_type]
try:
self._extension_mgrs['resourceApi'].map_method(
Expand Down

0 comments on commit 041c2b1

Please sign in to comment.