Gracefully handle duplicate rule creation
Previously, creating a second bandwidth limit rule for a policy raised an uncaught exception, which eventually caused 'ServerFault' on the client side. This patch replaces this exception with a NeutronException which leads to a more correct 'Conflict' error instead. Note that the code is implemented in the base object class. This means that future versioned objects will also feature this restriction if their database implies that no duplicate entries can be created. Change-Id: I882d60843e1e651f3f9754746ac670f499431466 Partially-Implements: quantum-qos-api
This commit is contained in:
parent
cc0ae6dd49
commit
75737c5ef0
|
@ -12,6 +12,7 @@
|
|||
|
||||
import abc
|
||||
|
||||
from oslo_db import exception as obj_exc
|
||||
from oslo_versionedobjects import base as obj_base
|
||||
import six
|
||||
|
||||
|
@ -23,6 +24,10 @@ class NeutronObjectUpdateForbidden(exceptions.NeutronException):
|
|||
message = _("Unable to update the following object fields: %(fields)s")
|
||||
|
||||
|
||||
class NeutronObjectDuplicateEntry(exceptions.Conflict):
|
||||
message = _("Failed to create a duplicate object")
|
||||
|
||||
|
||||
def get_updatable_fields(cls, fields):
|
||||
fields = fields.copy()
|
||||
for field in cls.fields_no_update:
|
||||
|
@ -116,7 +121,10 @@ class NeutronDbObject(NeutronObject):
|
|||
|
||||
def create(self):
|
||||
fields = self._get_changed_persistent_fields()
|
||||
db_obj = db_api.create_object(self._context, self.db_model, fields)
|
||||
try:
|
||||
db_obj = db_api.create_object(self._context, self.db_model, fields)
|
||||
except obj_exc.DBDuplicateEntry:
|
||||
raise NeutronObjectDuplicateEntry()
|
||||
self.from_db_object(db_obj)
|
||||
|
||||
def update(self):
|
||||
|
|
|
@ -298,7 +298,7 @@ class QosBandwidthLimitRuleTestJSON(base.BaseAdminNetworkTest):
|
|||
max_kbps=200,
|
||||
max_burst_kbps=1337)
|
||||
|
||||
self.assertRaises(exceptions.ServerFault,
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.create_qos_bandwidth_limit_rule,
|
||||
policy_id=policy['id'],
|
||||
max_kbps=201, max_burst_kbps=1338)
|
||||
|
|
|
@ -14,6 +14,7 @@ import random
|
|||
import string
|
||||
|
||||
import mock
|
||||
from oslo_db import exception as obj_exc
|
||||
from oslo_versionedobjects import base as obj_base
|
||||
from oslo_versionedobjects import fields as obj_fields
|
||||
|
||||
|
@ -154,6 +155,12 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
obj.create()
|
||||
self._check_equal(obj, self.db_obj)
|
||||
|
||||
def test_create_duplicates(self):
|
||||
with mock.patch.object(db_api, 'create_object',
|
||||
side_effect=obj_exc.DBDuplicateEntry):
|
||||
obj = self._test_class(self.context, **self.db_obj)
|
||||
self.assertRaises(base.NeutronObjectDuplicateEntry, obj.create)
|
||||
|
||||
@mock.patch.object(db_api, 'update_object')
|
||||
def test_update_no_changes(self, update_mock):
|
||||
with mock.patch.object(base.NeutronDbObject,
|
||||
|
|
Loading…
Reference in New Issue