Make deepcopy of update body in API layer
This adjusts the update handler in the API layer to pass a deepcopy
of the original update body to ensure that the original is used on
any generated retry requests.
Without this update handlers that modified the body as they processed
it (e.g. the external gateway update for routers) would be missing
data on a retry request.
This adds a test case for the bug that was caused by this.
Closes-Bug: #1584920
Change-Id: I88fb9d45eb82ef48e0d865decdcc7fad1c5fb361
(cherry picked from commit 5109d16bc5
)
This commit is contained in:
parent
bff727bc19
commit
483ceec083
|
@ -580,7 +580,8 @@ class Controller(object):
|
|||
|
||||
@db_api.retry_db_errors
|
||||
def _update(self, request, id, body, **kwargs):
|
||||
body = Controller.prepare_request_body(request.context, body, False,
|
||||
body = Controller.prepare_request_body(request.context,
|
||||
copy.deepcopy(body), False,
|
||||
self._resource, self._attr_info,
|
||||
allow_bulk=self._allow_bulk)
|
||||
action = self._plugin_handlers[self.UPDATE]
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
import testscenarios
|
||||
|
@ -389,6 +390,19 @@ class ExtGwModeIntTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase,
|
|||
expected_code=expected_code,
|
||||
neutron_context=neutron_context)
|
||||
|
||||
def test_router_gateway_set_retry(self):
|
||||
with self.router() as r, self.subnet() as s:
|
||||
ext_net_id = s['subnet']['network_id']
|
||||
self._set_net_external(ext_net_id)
|
||||
with mock.patch.object(
|
||||
l3_db.L3_NAT_dbonly_mixin, '_validate_gw_info',
|
||||
side_effect=[db_exc.RetryRequest(None), ext_net_id]):
|
||||
self._set_router_external_gateway(r['router']['id'],
|
||||
ext_net_id)
|
||||
res = self._show('routers', r['router']['id'])['router']
|
||||
self.assertEqual(ext_net_id,
|
||||
res['external_gateway_info']['network_id'])
|
||||
|
||||
def test_router_create_with_gwinfo_invalid_ext_ip(self):
|
||||
with self.subnet() as s:
|
||||
self._set_net_external(s['subnet']['network_id'])
|
||||
|
|
Loading…
Reference in New Issue