Fix 500 error when create pools in wsgi v2.
When create a pool with a url which is already exist in db, pymongo will raise a DuplicateKeyError error. Zaqar-wsgi don't catch it. APIImpact Change-Id: I487a372533c5e8de9edd5796e0039320d2d55b6a Closes-bug: #1540246
This commit is contained in:
parent
9b77a5bd78
commit
ad47f1bcfc
@ -191,3 +191,8 @@ class PoolCapabilitiesMismatch(ExceptionBase):
|
|||||||
|
|
||||||
msg_format = (u'The pool being added does not '
|
msg_format = (u'The pool being added does not '
|
||||||
u'support the minimum set of capabilities')
|
u'support the minimum set of capabilities')
|
||||||
|
|
||||||
|
|
||||||
|
class PoolAlreadyExists(Conflict):
|
||||||
|
|
||||||
|
msg_format = u'The database URI is in use by another pool.'
|
||||||
|
@ -23,6 +23,7 @@ Schema:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
from pymongo import errors as mongo_error
|
||||||
|
|
||||||
from zaqar.common import utils as common_utils
|
from zaqar.common import utils as common_utils
|
||||||
from zaqar.storage import base
|
from zaqar.storage import base
|
||||||
@ -97,13 +98,16 @@ class PoolsController(base.PoolsBase):
|
|||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def _create(self, name, weight, uri, group=None, options=None):
|
def _create(self, name, weight, uri, group=None, options=None):
|
||||||
options = {} if options is None else options
|
options = {} if options is None else options
|
||||||
self._col.update({'n': name},
|
try:
|
||||||
{'$set': {'n': name,
|
self._col.update({'n': name},
|
||||||
'w': weight,
|
{'$set': {'n': name,
|
||||||
'u': uri,
|
'w': weight,
|
||||||
'g': group,
|
'u': uri,
|
||||||
'o': options}},
|
'g': group,
|
||||||
upsert=True)
|
'o': options}},
|
||||||
|
upsert=True)
|
||||||
|
except mongo_error.DuplicateKeyError:
|
||||||
|
raise errors.PoolAlreadyExists()
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def _exists(self, name):
|
def _exists(self, name):
|
||||||
|
@ -528,6 +528,13 @@ class MongodbPoolsTests(base.PoolsControllerTest):
|
|||||||
group=self.pool_group,
|
group=self.pool_group,
|
||||||
options={})
|
options={})
|
||||||
|
|
||||||
|
def test_duplicate_uri(self):
|
||||||
|
with testing.expect(errors.PoolAlreadyExists):
|
||||||
|
# The url 'localhost' is used in setUp(). So reusing the uri
|
||||||
|
# 'localhost' here will raise PoolAlreadyExists.
|
||||||
|
self.pools_controller.create(str(uuid.uuid1()), 100, 'localhost',
|
||||||
|
group=str(uuid.uuid1()), options={})
|
||||||
|
|
||||||
|
|
||||||
@testing.requires_mongodb
|
@testing.requires_mongodb
|
||||||
class MongodbCatalogueTests(base.CatalogueControllerTest):
|
class MongodbCatalogueTests(base.CatalogueControllerTest):
|
||||||
|
@ -38,9 +38,11 @@ registered, there is an optional field::
|
|||||||
import falcon
|
import falcon
|
||||||
import jsonschema
|
import jsonschema
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
import six
|
||||||
|
|
||||||
from zaqar.common.api.schemas import pools as schema
|
from zaqar.common.api.schemas import pools as schema
|
||||||
from zaqar.common import utils as common_utils
|
from zaqar.common import utils as common_utils
|
||||||
|
from zaqar.i18n import _
|
||||||
from zaqar.storage import errors
|
from zaqar.storage import errors
|
||||||
from zaqar.storage import utils as storage_utils
|
from zaqar.storage import utils as storage_utils
|
||||||
from zaqar.transport import utils as transport_utils
|
from zaqar.transport import utils as transport_utils
|
||||||
@ -171,11 +173,16 @@ class Resource(object):
|
|||||||
raise wsgi_errors.HTTPBadRequestBody(
|
raise wsgi_errors.HTTPBadRequestBody(
|
||||||
'cannot connect to %s' % data['uri']
|
'cannot connect to %s' % data['uri']
|
||||||
)
|
)
|
||||||
self._ctrl.create(pool, weight=data['weight'],
|
try:
|
||||||
uri=data['uri'],
|
self._ctrl.create(pool, weight=data['weight'],
|
||||||
options=data.get('options', {}))
|
uri=data['uri'],
|
||||||
response.status = falcon.HTTP_201
|
options=data.get('options', {}))
|
||||||
response.location = request.path
|
response.status = falcon.HTTP_201
|
||||||
|
response.location = request.path
|
||||||
|
except errors.PoolAlreadyExists as e:
|
||||||
|
LOG.exception(e)
|
||||||
|
title = _(u'Unable to create pool')
|
||||||
|
raise falcon.HTTPConflict(title, six.text_type(e))
|
||||||
|
|
||||||
def on_delete(self, request, response, project_id, pool):
|
def on_delete(self, request, response, project_id, pool):
|
||||||
"""Deregisters a pool.
|
"""Deregisters a pool.
|
||||||
|
@ -186,6 +186,10 @@ class Resource(object):
|
|||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
title = _(u'Unable to create pool')
|
title = _(u'Unable to create pool')
|
||||||
raise falcon.HTTPBadRequest(title, six.text_type(e))
|
raise falcon.HTTPBadRequest(title, six.text_type(e))
|
||||||
|
except errors.PoolAlreadyExists as e:
|
||||||
|
LOG.exception(e)
|
||||||
|
title = _(u'Unable to create pool')
|
||||||
|
raise falcon.HTTPConflict(title, six.text_type(e))
|
||||||
|
|
||||||
def on_delete(self, request, response, project_id, pool):
|
def on_delete(self, request, response, project_id, pool):
|
||||||
"""Deregisters a pool.
|
"""Deregisters a pool.
|
||||||
|
@ -190,6 +190,10 @@ class Resource(object):
|
|||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
title = _(u'Unable to create pool')
|
title = _(u'Unable to create pool')
|
||||||
raise falcon.HTTPBadRequest(title, six.text_type(e))
|
raise falcon.HTTPBadRequest(title, six.text_type(e))
|
||||||
|
except errors.PoolAlreadyExists as e:
|
||||||
|
LOG.exception(e)
|
||||||
|
title = _(u'Unable to create pool')
|
||||||
|
raise falcon.HTTPConflict(title, six.text_type(e))
|
||||||
|
|
||||||
@acl.enforce("pools:delete")
|
@acl.enforce("pools:delete")
|
||||||
def on_delete(self, request, response, project_id, pool):
|
def on_delete(self, request, response, project_id, pool):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user