Merge metadata back into the queue endpoint
During Icehouse, we decided to pull the metadata out of the queue endpoint by adding a new endpoint `/metadata`. This worked well because we didn't have a clear view of what the scope of metadata is. Now that we want to use it and make it a key piece of the queues, we've found that the workflow is not as clear as we'd like. The reason being that some key items of the metadata - flavor, for example - need to be specified during the queue creation and not after. Merging these endpoints together is enough to fix this issue. DocImpact Implements blueprint: api-v1.1-merge-queue-and-metadata Change-Id: Icca1a2b2066a518f8f50cad20e55b39a8bff0f2d
This commit is contained in:
parent
cb1d526032
commit
ba998351c1
@ -47,20 +47,8 @@ class RequestSchema(api.Api):
|
||||
}
|
||||
},
|
||||
|
||||
'queue_set_metadata': {
|
||||
'ref': 'queues/{queue_name}/metadata',
|
||||
'method': 'PUT',
|
||||
'required': ['queue_name'],
|
||||
'properties': {
|
||||
# NOTE(flaper87): Metadata is part
|
||||
# of the request content. No need to
|
||||
# add it here.
|
||||
'queue_name': {'type': 'string'}
|
||||
}
|
||||
},
|
||||
|
||||
'queue_get_metadata': {
|
||||
'ref': 'queues/{queue_name}/metadata',
|
||||
'queue_get': {
|
||||
'ref': 'queues/{queue_name}',
|
||||
'method': 'GET',
|
||||
'required': ['queue_name'],
|
||||
'properties': {
|
||||
|
@ -149,6 +149,17 @@ class Queue(ControllerBase):
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def get(self, name, project=None):
|
||||
"""Base method for queue metadata retrieval.
|
||||
|
||||
:param name: The queue name
|
||||
:param project: Project id
|
||||
|
||||
:returns: Dictionary containing queue metadata
|
||||
:raises: DoesNotExist
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_metadata(self, name, project=None):
|
||||
"""Base method for queue metadata retrieval.
|
||||
|
||||
@ -161,7 +172,7 @@ class Queue(ControllerBase):
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def create(self, name, project=None):
|
||||
def create(self, name, metadata=None, project=None):
|
||||
"""Base method for queue creation.
|
||||
|
||||
:param name: The queue name
|
||||
@ -182,7 +193,6 @@ class Queue(ControllerBase):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def set_metadata(self, name, metadata, project=None):
|
||||
"""Base method for updating a queue metadata.
|
||||
|
||||
|
@ -98,14 +98,6 @@ class QueueController(storage.Queue):
|
||||
# Helpers
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def _get(self, name, project=None, fields={'m': 1, '_id': 0}):
|
||||
queue = self._collection.find_one(_get_scoped_query(name, project),
|
||||
fields=fields)
|
||||
if queue is None:
|
||||
raise errors.QueueDoesNotExist(name, project)
|
||||
|
||||
return queue
|
||||
|
||||
def _get_counter(self, name, project=None):
|
||||
"""Retrieves the current message counter value for a given queue.
|
||||
|
||||
@ -194,6 +186,12 @@ class QueueController(storage.Queue):
|
||||
# Interface
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def get(self, name, project=None):
|
||||
try:
|
||||
return self.get_metadata(name, project)
|
||||
except errors.QueueDoesNotExist:
|
||||
return {}
|
||||
|
||||
def list(self, project=None, marker=None,
|
||||
limit=storage.DEFAULT_QUEUES_PER_PAGE, detailed=False):
|
||||
|
||||
@ -220,12 +218,16 @@ class QueueController(storage.Queue):
|
||||
@utils.raises_conn_error
|
||||
@utils.retries_on_autoreconnect
|
||||
def get_metadata(self, name, project=None):
|
||||
queue = self._get(name, project)
|
||||
queue = self._collection.find_one(_get_scoped_query(name, project),
|
||||
fields={'m': 1, '_id': 0})
|
||||
if queue is None:
|
||||
raise errors.QueueDoesNotExist(name, project)
|
||||
|
||||
return queue.get('m', {})
|
||||
|
||||
@utils.raises_conn_error
|
||||
# @utils.retries_on_autoreconnect
|
||||
def create(self, name, project=None):
|
||||
def create(self, name, metadata=None, project=None):
|
||||
# NOTE(flaper87): If the connection fails after it was called
|
||||
# and we retry to insert the queue, we could end up returning
|
||||
# `False` because of the `DuplicatedKeyError` although the
|
||||
@ -242,7 +244,7 @@ class QueueController(storage.Queue):
|
||||
counter = {'v': 1, 't': 0}
|
||||
|
||||
scoped_name = utils.scope_queue_name(name, project)
|
||||
self._collection.insert({'p_q': scoped_name, 'm': {},
|
||||
self._collection.insert({'p_q': scoped_name, 'm': metadata or {},
|
||||
'c': counter})
|
||||
|
||||
except pymongo.errors.DuplicateKeyError:
|
||||
|
@ -164,7 +164,13 @@ class QueueController(RoutingController):
|
||||
yield it()
|
||||
yield marker_name['next']
|
||||
|
||||
def create(self, name, project=None):
|
||||
def get(self, name, project=None):
|
||||
try:
|
||||
return self.get_metadata(name, project)
|
||||
except errors.QueueDoesNotExist:
|
||||
return {}
|
||||
|
||||
def create(self, name, metadata=None, project=None):
|
||||
self._pool_catalog.register(name, project)
|
||||
|
||||
# NOTE(cpp-cabrera): This should always succeed since we just
|
||||
@ -176,7 +182,9 @@ class QueueController(RoutingController):
|
||||
if not target:
|
||||
raise RuntimeError('Failed to register queue')
|
||||
|
||||
return target.queue_controller.create(name, project)
|
||||
return target.queue_controller.create(name,
|
||||
metadata=metadata,
|
||||
project=project)
|
||||
|
||||
def delete(self, name, project=None):
|
||||
# NOTE(cpp-cabrera): If we fail to find a project/queue in the
|
||||
|
@ -68,13 +68,21 @@ class QueueController(storage.Queue):
|
||||
except utils.NoResult:
|
||||
raise errors.QueueDoesNotExist(name, project)
|
||||
|
||||
def create(self, name, project):
|
||||
def get(self, name, project=None):
|
||||
try:
|
||||
return self.get_metadata(name, project)
|
||||
except errors.QueueDoesNotExist:
|
||||
return {}
|
||||
|
||||
def create(self, name, metadata=None, project=None):
|
||||
if project is None:
|
||||
project = ''
|
||||
|
||||
try:
|
||||
ins = tables.Queues.insert().values(project=project, name=name,
|
||||
metadata=utils.json_encode({}))
|
||||
smeta = utils.json_encode(metadata or {})
|
||||
ins = tables.Queues.insert().values(project=project,
|
||||
name=name,
|
||||
metadata=smeta)
|
||||
res = self.driver.run(ins)
|
||||
except sa.exc.IntegrityError:
|
||||
return False
|
||||
|
@ -16,7 +16,6 @@ from marconi.queues.transport.wsgi.v1_1 import claims
|
||||
from marconi.queues.transport.wsgi.v1_1 import health
|
||||
from marconi.queues.transport.wsgi.v1_1 import homedoc
|
||||
from marconi.queues.transport.wsgi.v1_1 import messages
|
||||
from marconi.queues.transport.wsgi.v1_1 import metadata
|
||||
from marconi.queues.transport.wsgi.v1_1 import ping
|
||||
from marconi.queues.transport.wsgi.v1_1 import pools
|
||||
from marconi.queues.transport.wsgi.v1_1 import queues
|
||||
@ -40,13 +39,11 @@ def public_endpoints(driver):
|
||||
queues.CollectionResource(driver._validate,
|
||||
queue_controller)),
|
||||
('/queues/{queue_name}',
|
||||
queues.ItemResource(queue_controller,
|
||||
queues.ItemResource(driver._validate,
|
||||
queue_controller,
|
||||
message_controller)),
|
||||
('/queues/{queue_name}/stats',
|
||||
stats.Resource(queue_controller)),
|
||||
('/queues/{queue_name}/metadata',
|
||||
metadata.Resource(driver._wsgi_conf, driver._validate,
|
||||
queue_controller)),
|
||||
|
||||
# Messages Endpoints
|
||||
('/queues/{queue_name}/messages',
|
||||
|
@ -41,19 +41,7 @@ JSON_HOME = {
|
||||
'queue_name': 'param/queue_name',
|
||||
},
|
||||
'hints': {
|
||||
'allow': ['PUT', 'DELETE'],
|
||||
'formats': {
|
||||
'application/json': {},
|
||||
},
|
||||
},
|
||||
},
|
||||
'rel/queue-metadata': {
|
||||
'href-template': '/v1.1/queues/{queue_name}/metadata',
|
||||
'href-vars': {
|
||||
'queue_name': 'param/queue_name',
|
||||
},
|
||||
'hints': {
|
||||
'allow': ['GET', 'PUT'],
|
||||
'allow': ['GET', 'PUT', 'DELETE'],
|
||||
'formats': {
|
||||
'application/json': {},
|
||||
},
|
||||
|
@ -174,7 +174,7 @@ class CollectionResource(object):
|
||||
self._validate.message_posting(messages)
|
||||
|
||||
if not self.queue_controller.exists(queue_name, project_id):
|
||||
self.queue_controller.create(queue_name, project_id)
|
||||
self.queue_controller.create(queue_name, project=project_id)
|
||||
|
||||
message_ids = self.message_controller.post(
|
||||
queue_name,
|
||||
|
@ -1,95 +0,0 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import falcon
|
||||
import six
|
||||
|
||||
from marconi.i18n import _
|
||||
import marconi.openstack.common.log as logging
|
||||
from marconi.queues.storage import errors as storage_errors
|
||||
from marconi.queues.transport import utils
|
||||
from marconi.queues.transport import validation
|
||||
from marconi.queues.transport.wsgi import errors as wsgi_errors
|
||||
from marconi.queues.transport.wsgi import utils as wsgi_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Resource(object):
|
||||
__slots__ = ('_wsgi_conf', '_validate', 'queue_ctrl')
|
||||
|
||||
def __init__(self, _wsgi_conf, validate, queue_controller):
|
||||
self._wsgi_conf = _wsgi_conf
|
||||
self._validate = validate
|
||||
self.queue_ctrl = queue_controller
|
||||
|
||||
def on_get(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue metadata GET - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
{'queue': queue_name, 'project': project_id})
|
||||
|
||||
try:
|
||||
resp_dict = self.queue_ctrl.get_metadata(queue_name,
|
||||
project=project_id)
|
||||
|
||||
except storage_errors.DoesNotExist as ex:
|
||||
LOG.debug(ex)
|
||||
raise falcon.HTTPNotFound()
|
||||
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
description = _(u'Queue metadata could not be retrieved.')
|
||||
raise wsgi_errors.HTTPServiceUnavailable(description)
|
||||
|
||||
resp.content_location = req.path
|
||||
resp.body = utils.to_json(resp_dict)
|
||||
# status defaults to 200
|
||||
|
||||
def on_put(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue metadata PUT - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
{'queue': queue_name, 'project': project_id})
|
||||
|
||||
try:
|
||||
# Place JSON size restriction before parsing
|
||||
self._validate.queue_metadata_length(req.content_length)
|
||||
except validation.ValidationFailed as ex:
|
||||
LOG.debug(ex)
|
||||
raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex))
|
||||
|
||||
# Deserialize queue metadata
|
||||
document = wsgi_utils.deserialize(req.stream, req.content_length)
|
||||
metadata = wsgi_utils.sanitize(document, spec=None)
|
||||
|
||||
try:
|
||||
self.queue_ctrl.set_metadata(queue_name,
|
||||
metadata=metadata,
|
||||
project=project_id)
|
||||
|
||||
except validation.ValidationFailed as ex:
|
||||
LOG.debug(ex)
|
||||
raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex))
|
||||
|
||||
except storage_errors.QueueDoesNotExist:
|
||||
raise falcon.HTTPNotFound()
|
||||
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
description = _(u'Metadata could not be updated.')
|
||||
raise wsgi_errors.HTTPServiceUnavailable(description)
|
||||
|
||||
resp.status = falcon.HTTP_204
|
||||
resp.location = req.path
|
@ -18,9 +18,11 @@ import six
|
||||
|
||||
from marconi.i18n import _
|
||||
import marconi.openstack.common.log as logging
|
||||
from marconi.queues.storage import errors as storage_errors
|
||||
from marconi.queues.transport import utils
|
||||
from marconi.queues.transport import validation
|
||||
from marconi.queues.transport.wsgi import errors as wsgi_errors
|
||||
from marconi.queues.transport.wsgi import utils as wsgi_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -28,20 +30,56 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
class ItemResource(object):
|
||||
|
||||
__slots__ = ('queue_controller', 'message_controller')
|
||||
__slots__ = ('validate', 'queue_controller', 'message_controller')
|
||||
|
||||
def __init__(self, queue_controller, message_controller):
|
||||
def __init__(self, validate, queue_controller, message_controller):
|
||||
self.validate = validate
|
||||
self.queue_controller = queue_controller
|
||||
self.message_controller = message_controller
|
||||
|
||||
def on_get(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue metadata GET - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
{'queue': queue_name, 'project': project_id})
|
||||
|
||||
try:
|
||||
resp_dict = self.queue_controller.get(queue_name,
|
||||
project=project_id)
|
||||
|
||||
except storage_errors.DoesNotExist as ex:
|
||||
LOG.debug(ex)
|
||||
raise falcon.HTTPNotFound()
|
||||
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
description = _(u'Queue metadata could not be retrieved.')
|
||||
raise wsgi_errors.HTTPServiceUnavailable(description)
|
||||
|
||||
resp.body = utils.to_json(resp_dict)
|
||||
# status defaults to 200
|
||||
|
||||
def on_put(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue item PUT - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
{'queue': queue_name, 'project': project_id})
|
||||
|
||||
try:
|
||||
created = self.queue_controller.create(
|
||||
queue_name, project=project_id)
|
||||
# Place JSON size restriction before parsing
|
||||
self.validate.queue_metadata_length(req.content_length)
|
||||
except validation.ValidationFailed as ex:
|
||||
LOG.debug(ex)
|
||||
raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex))
|
||||
|
||||
# Deserialize queue metadata
|
||||
metadata = None
|
||||
if req.content_length:
|
||||
document = wsgi_utils.deserialize(req.stream, req.content_length)
|
||||
metadata = wsgi_utils.sanitize(document, spec=None)
|
||||
|
||||
try:
|
||||
created = self.queue_controller.create(queue_name,
|
||||
metadata=metadata,
|
||||
project=project_id)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
@ -122,6 +160,5 @@ class CollectionResource(object):
|
||||
]
|
||||
}
|
||||
|
||||
resp.content_location = req.relative_uri
|
||||
resp.body = utils.to_json(response_body)
|
||||
# status defaults to 200
|
||||
|
@ -61,10 +61,13 @@ class QueueController(storage.Queue):
|
||||
def list(self, project=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get(self, name, project=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_metadata(self, name, project=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def create(self, name, project=None):
|
||||
def create(self, name, metadata=None, project=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def exists(self, name, project=None):
|
||||
|
@ -135,7 +135,9 @@ class QueueControllerTest(ControllerBaseTest):
|
||||
|
||||
def test_queue_lifecycle(self):
|
||||
# Test queue creation
|
||||
created = self.controller.create('test', project=self.project)
|
||||
created = self.controller.create('test',
|
||||
metadata=dict(meta='test_meta'),
|
||||
project=self.project)
|
||||
self.assertTrue(created)
|
||||
|
||||
# Test queue existence
|
||||
@ -147,21 +149,14 @@ class QueueControllerTest(ControllerBaseTest):
|
||||
self.assertEqual(queue['name'], 'test')
|
||||
|
||||
# Test queue metadata retrieval
|
||||
metadata = self.controller.get_metadata('test', project=self.project)
|
||||
self.assertEqual(metadata, {})
|
||||
|
||||
# Test queue update
|
||||
created = self.controller.set_metadata('test', project=self.project,
|
||||
metadata=dict(meta='test_meta'))
|
||||
|
||||
metadata = self.controller.get_metadata('test', project=self.project)
|
||||
metadata = self.controller.get('test', project=self.project)
|
||||
self.assertEqual(metadata['meta'], 'test_meta')
|
||||
|
||||
# Touching an existing queue does not affect metadata
|
||||
created = self.controller.create('test', project=self.project)
|
||||
self.assertFalse(created)
|
||||
|
||||
metadata = self.controller.get_metadata('test', project=self.project)
|
||||
metadata = self.controller.get('test', project=self.project)
|
||||
self.assertEqual(metadata['meta'], 'test_meta')
|
||||
|
||||
client_uuid = uuid.uuid4()
|
||||
@ -216,13 +211,6 @@ class QueueControllerTest(ControllerBaseTest):
|
||||
# Test queue existence
|
||||
self.assertFalse(self.controller.exists('test', project=self.project))
|
||||
|
||||
# Test DoesNotExist exception
|
||||
with testing.expect(storage.errors.DoesNotExist):
|
||||
self.controller.get_metadata('test', project=self.project)
|
||||
|
||||
with testing.expect(storage.errors.DoesNotExist):
|
||||
self.controller.set_metadata('test', '{}', project=self.project)
|
||||
|
||||
def test_stats_for_empty_queue(self):
|
||||
self.addCleanup(self.controller.delete, 'test', project=self.project)
|
||||
created = self.controller.create('test', project=self.project)
|
||||
@ -531,7 +519,7 @@ class MessageControllerTest(ControllerBaseTest):
|
||||
project=self.project)
|
||||
|
||||
def test_pop_message(self):
|
||||
self.queue_controller.create(self.queue_name, self.project)
|
||||
self.queue_controller.create(self.queue_name, project=self.project)
|
||||
messages = [
|
||||
{
|
||||
'ttl': 60,
|
||||
|
@ -28,7 +28,6 @@ class TestMediaType(base.V1_1Base):
|
||||
def test_json_only_endpoints(self):
|
||||
endpoints = (
|
||||
('GET', self.url_prefix + '/queues'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/metadata'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/stats'),
|
||||
('POST', self.url_prefix + '/queues/nonexistent/messages'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/messages/deadbeaf'),
|
||||
|
@ -34,7 +34,6 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
self.queue_path = self.url_prefix + '/queues'
|
||||
self.gumshoe_queue_path = self.queue_path + '/gumshoe'
|
||||
self.fizbat_queue_path = self.queue_path + '/fizbat'
|
||||
self.fizbat_queue_path_metadata = self.fizbat_queue_path + '/metadata'
|
||||
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
@ -59,33 +58,23 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': project_id
|
||||
}
|
||||
gumshoe_queue_path_metadata = self.gumshoe_queue_path + '/metadata'
|
||||
gumshoe_queue_path_stats = self.gumshoe_queue_path + '/stats'
|
||||
|
||||
# Stats are empty - queue not created yet
|
||||
self.simulate_get(gumshoe_queue_path_stats, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# Metadata not found - queue not created yet
|
||||
self.simulate_get(gumshoe_queue_path_metadata, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Create
|
||||
self.simulate_put(self.gumshoe_queue_path, headers=headers)
|
||||
doc = '{"messages": {"ttl": 600}}'
|
||||
self.simulate_put(self.gumshoe_queue_path,
|
||||
headers=headers, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
location = self.srmock.headers_dict['Location']
|
||||
self.assertEqual(location, self.gumshoe_queue_path)
|
||||
|
||||
# Add metadata
|
||||
|
||||
doc = '{"messages": {"ttl": 600}}'
|
||||
self.simulate_put(gumshoe_queue_path_metadata,
|
||||
headers=headers, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Fetch metadata
|
||||
result = self.simulate_get(gumshoe_queue_path_metadata,
|
||||
result = self.simulate_get(self.gumshoe_queue_path,
|
||||
headers=headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
@ -103,10 +92,6 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
self.simulate_get(gumshoe_queue_path_stats, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# Get non-existent metadata
|
||||
self.simulate_get(gumshoe_queue_path_metadata, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_name_restrictions(self):
|
||||
self.simulate_put(self.queue_path + '/Nice-Boat_2',
|
||||
headers=self.headers)
|
||||
@ -151,23 +136,17 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_no_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.simulate_put(self.fizbat_queue_path,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
self.simulate_put(self.fizbat_queue_path, body='',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata, body='',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data('{', '[]', '.', ' ', '')
|
||||
@ddt.data('{', '[]', '.', ' ')
|
||||
def test_bad_metadata(self, document):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
self.simulate_put(self.fizbat_queue_path,
|
||||
headers=self.headers,
|
||||
body=document)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
@ -182,7 +161,7 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
self.simulate_put(self.fizbat_queue_path,
|
||||
headers=self.headers,
|
||||
body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
@ -197,14 +176,11 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
self.simulate_put(self.fizbat_queue_path,
|
||||
headers=self.headers, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_custom_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
# Set
|
||||
doc = '{{"messages": {{"ttl": 600}}, "padding": "{pad}"}}'
|
||||
|
||||
@ -212,21 +188,22 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
padding_len = max_size - (len(doc) - 2)
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
self.simulate_put(self.fizbat_queue_path,
|
||||
headers=self.headers,
|
||||
body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
# Get
|
||||
result = self.simulate_get(self.fizbat_queue_path_metadata,
|
||||
result = self.simulate_get(self.fizbat_queue_path,
|
||||
headers=self.headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(result_doc, jsonutils.loads(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
def test_update_metadata(self):
|
||||
self.skip("This should use patch instead")
|
||||
xyz_queue_path = self.url_prefix + '/queues/xyz'
|
||||
xyz_queue_path_metadata = xyz_queue_path + '/metadata'
|
||||
xyz_queue_path_metadata = xyz_queue_path
|
||||
|
||||
# Create
|
||||
self.simulate_put(xyz_queue_path, headers=self.headers)
|
||||
@ -252,8 +229,6 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
|
||||
self.assertEqual(result_doc, jsonutils.loads(doc2))
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
xyz_queue_path_metadata)
|
||||
|
||||
def test_list(self):
|
||||
arbitrary_number = 644079696574693
|
||||
@ -282,8 +257,7 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
if project_id is not None:
|
||||
altheader['X-Project-ID'] = project_id
|
||||
uri = self.queue_path + '/' + name
|
||||
self.simulate_put(uri, headers=altheader)
|
||||
self.simulate_put(uri + '/metadata', headers=altheader, body=body)
|
||||
self.simulate_put(uri, headers=altheader, body=body)
|
||||
|
||||
create_queue('g1', None, '{"answer": 42}')
|
||||
create_queue('g2', None, '{"answer": 42}')
|
||||
@ -320,24 +294,11 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
[target, params] = result_doc['links'][0]['href'].split('?')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
self.queue_path + '?limit=5')
|
||||
|
||||
# Ensure we didn't pick up the queue from the alt project.
|
||||
queues = result_doc['queues']
|
||||
self.assertEqual(len(queues), 3)
|
||||
|
||||
for queue in queues:
|
||||
self.simulate_get(queue['href'] + '/metadata', headers=header)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
altheader = header.copy()
|
||||
altheader['X-Project-ID'] = 'imnothere'
|
||||
self.simulate_get(queue['href'] + '/metadata', headers=altheader)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
self.assertNotIn('metadata', queue)
|
||||
|
||||
# List with metadata
|
||||
result = self.simulate_get(self.queue_path, headers=header,
|
||||
query_string='detailed=true')
|
||||
@ -347,7 +308,7 @@ class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
[target, params] = result_doc['links'][0]['href'].split('?')
|
||||
|
||||
queue = result_doc['queues'][0]
|
||||
result = self.simulate_get(queue['href'] + '/metadata', headers=header)
|
||||
result = self.simulate_get(queue['href'], headers=header)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(result_doc, queue['metadata'])
|
||||
self.assertEqual(result_doc, {'node': 31})
|
||||
@ -406,7 +367,7 @@ class TestQueueLifecycleFaultyDriver(base.V1_1BaseFaulty):
|
||||
location = ('Location', gumshoe_queue_path)
|
||||
self.assertNotIn(location, self.srmock.headers)
|
||||
|
||||
result = self.simulate_get(gumshoe_queue_path + '/metadata',
|
||||
result = self.simulate_get(gumshoe_queue_path,
|
||||
headers=self.headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
@ -43,7 +43,7 @@ class TestValidation(base.V1_1Base):
|
||||
|
||||
def test_metadata_deserialization(self):
|
||||
# Normal case
|
||||
self.simulate_put(self.queue_path + '/metadata',
|
||||
self.simulate_put(self.queue_path,
|
||||
self.project_id,
|
||||
body='{"timespace": "Shangri-la"}')
|
||||
|
||||
@ -59,7 +59,7 @@ class TestValidation(base.V1_1Base):
|
||||
for tmpl in doc_tmpl, doc_tmpl_ws:
|
||||
gen = '0' * (max_queue_metadata - envelope_length + 1)
|
||||
doc = tmpl.format(gen)
|
||||
self.simulate_put(self.queue_path + '/metadata',
|
||||
self.simulate_put(self.queue_path,
|
||||
self.project_id,
|
||||
body=doc)
|
||||
|
||||
|
@ -167,11 +167,11 @@ class TestInsertQueue(base.V1_1FunctionalTestBase):
|
||||
|
||||
self.assertEqual(result.status_code, 201)
|
||||
|
||||
self.url = self.base_url + '/queues/hasmetadata/metadata'
|
||||
self.url = self.base_url + '/queues/hasmetadata'
|
||||
result = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.assertEqual(result.json(), {})
|
||||
self.assertEqual(result.json(), {"queue": "Has Metadata"})
|
||||
|
||||
test_insert_queue_with_metadata.tags = ['negative']
|
||||
|
||||
@ -250,7 +250,7 @@ class TestQueueMisc(base.V1_1FunctionalTestBase):
|
||||
self.client.put(self.queue_url)
|
||||
self.addCleanup(self.client.delete, self.queue_url)
|
||||
|
||||
result = self.client.get(self.queue_url)
|
||||
result = self.client.head(self.queue_url)
|
||||
self.assertEqual(result.status_code, 405)
|
||||
|
||||
test_check_queue_exists.tags = ['negative']
|
||||
@ -349,7 +349,7 @@ class TestQueueNonExisting(base.V1_1FunctionalTestBase):
|
||||
|
||||
def test_get_metadata(self):
|
||||
"""Get metadata on non existing Queue."""
|
||||
result = self.client.get('/metadata')
|
||||
result = self.client.get('/')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.assertEqual(result.json(), [])
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user