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 '
|
||||
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
|
||||
from pymongo import errors as mongo_error
|
||||
|
||||
from zaqar.common import utils as common_utils
|
||||
from zaqar.storage import base
|
||||
@ -97,13 +98,16 @@ class PoolsController(base.PoolsBase):
|
||||
@utils.raises_conn_error
|
||||
def _create(self, name, weight, uri, group=None, options=None):
|
||||
options = {} if options is None else options
|
||||
self._col.update({'n': name},
|
||||
{'$set': {'n': name,
|
||||
'w': weight,
|
||||
'u': uri,
|
||||
'g': group,
|
||||
'o': options}},
|
||||
upsert=True)
|
||||
try:
|
||||
self._col.update({'n': name},
|
||||
{'$set': {'n': name,
|
||||
'w': weight,
|
||||
'u': uri,
|
||||
'g': group,
|
||||
'o': options}},
|
||||
upsert=True)
|
||||
except mongo_error.DuplicateKeyError:
|
||||
raise errors.PoolAlreadyExists()
|
||||
|
||||
@utils.raises_conn_error
|
||||
def _exists(self, name):
|
||||
|
@ -528,6 +528,13 @@ class MongodbPoolsTests(base.PoolsControllerTest):
|
||||
group=self.pool_group,
|
||||
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
|
||||
class MongodbCatalogueTests(base.CatalogueControllerTest):
|
||||
|
@ -38,9 +38,11 @@ registered, there is an optional field::
|
||||
import falcon
|
||||
import jsonschema
|
||||
from oslo_log import log
|
||||
import six
|
||||
|
||||
from zaqar.common.api.schemas import pools as schema
|
||||
from zaqar.common import utils as common_utils
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors
|
||||
from zaqar.storage import utils as storage_utils
|
||||
from zaqar.transport import utils as transport_utils
|
||||
@ -171,11 +173,16 @@ class Resource(object):
|
||||
raise wsgi_errors.HTTPBadRequestBody(
|
||||
'cannot connect to %s' % data['uri']
|
||||
)
|
||||
self._ctrl.create(pool, weight=data['weight'],
|
||||
uri=data['uri'],
|
||||
options=data.get('options', {}))
|
||||
response.status = falcon.HTTP_201
|
||||
response.location = request.path
|
||||
try:
|
||||
self._ctrl.create(pool, weight=data['weight'],
|
||||
uri=data['uri'],
|
||||
options=data.get('options', {}))
|
||||
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):
|
||||
"""Deregisters a pool.
|
||||
|
@ -186,6 +186,10 @@ class Resource(object):
|
||||
LOG.exception(e)
|
||||
title = _(u'Unable to create pool')
|
||||
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):
|
||||
"""Deregisters a pool.
|
||||
|
@ -190,6 +190,10 @@ class Resource(object):
|
||||
LOG.exception(e)
|
||||
title = _(u'Unable to create pool')
|
||||
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")
|
||||
def on_delete(self, request, response, project_id, pool):
|
||||
|
Loading…
Reference in New Issue
Block a user