From 5afb85a175945d5b1cbd571098604000ec92e868 Mon Sep 17 00:00:00 2001 From: Fei Long Wang Date: Thu, 11 Feb 2016 10:20:30 +1300 Subject: [PATCH] Support metadata update issue for v2 Now there is no way to update metadata after queue create. That because we were trying to remove metadata but finally we decided to keep it. As a result, we missed a way to update queue's metadata. This patch fixes it buy supporting PATCH for queue. And a test case is added. APIImpact DocImpact Closes-Bug: #1543900 Change-Id: Iba6d7a0ca5cf7a755c20d9af69d5c52687142dff --- .../wsgi/v2_0/test_queue_lifecycle.py | 17 ++++--- zaqar/transport/wsgi/v2_0/homedoc.py | 2 +- zaqar/transport/wsgi/v2_0/queues.py | 47 +++++++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/zaqar/tests/unit/transport/wsgi/v2_0/test_queue_lifecycle.py b/zaqar/tests/unit/transport/wsgi/v2_0/test_queue_lifecycle.py index b1927ac63..cfa107443 100644 --- a/zaqar/tests/unit/transport/wsgi/v2_0/test_queue_lifecycle.py +++ b/zaqar/tests/unit/transport/wsgi/v2_0/test_queue_lifecycle.py @@ -216,7 +216,6 @@ class TestQueueLifecycleMongoDB(base.V2Base): self.assertEqual(falcon.HTTP_200, self.srmock.status) 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 @@ -226,17 +225,17 @@ class TestQueueLifecycleMongoDB(base.V2Base): # Set meta doc1 = '{"messages": {"ttl": 600}}' - self.simulate_put(xyz_queue_path_metadata, - headers=self.headers, - body=doc1) - self.assertEqual(falcon.HTTP_204, self.srmock.status) + self.simulate_patch(xyz_queue_path_metadata, + headers=self.headers, + body=doc1) + self.assertEqual(falcon.HTTP_200, self.srmock.status) # Update doc2 = '{"messages": {"ttl": 100}}' - self.simulate_put(xyz_queue_path_metadata, - headers=self.headers, - body=doc2) - self.assertEqual(falcon.HTTP_204, self.srmock.status) + self.simulate_patch(xyz_queue_path_metadata, + headers=self.headers, + body=doc2) + self.assertEqual(falcon.HTTP_200, self.srmock.status) # Get result = self.simulate_get(xyz_queue_path_metadata, diff --git a/zaqar/transport/wsgi/v2_0/homedoc.py b/zaqar/transport/wsgi/v2_0/homedoc.py index 1e6c1d64e..2c2ad578b 100644 --- a/zaqar/transport/wsgi/v2_0/homedoc.py +++ b/zaqar/transport/wsgi/v2_0/homedoc.py @@ -41,7 +41,7 @@ JSON_HOME = { 'queue_name': 'param/queue_name', }, 'hints': { - 'allow': ['GET', 'PUT', 'DELETE'], + 'allow': ['GET', 'PUT', 'DELETE', 'PATCH'], 'formats': { 'application/json': {}, }, diff --git a/zaqar/transport/wsgi/v2_0/queues.py b/zaqar/transport/wsgi/v2_0/queues.py index 46076631a..0019ed9b7 100644 --- a/zaqar/transport/wsgi/v2_0/queues.py +++ b/zaqar/transport/wsgi/v2_0/queues.py @@ -109,6 +109,53 @@ class ItemResource(object): resp.status = falcon.HTTP_204 + @acl.enforce("queues:update") + def on_patch(self, req, resp, project_id, queue_name): + """Allows one to update a queue's metadata. + + This method expects the user to submit a JSON object. There is also + strict format checking through the use of + jsonschema. Appropriate errors are returned in each case for + badly formatted input. + + :returns: HTTP | 200,400,503 + """ + LOG.debug(u'PATCH queue - name: %s', queue_name) + 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 + metadata = None + if req.content_length: + document = wsgi_utils.deserialize(req.stream, req.content_length) + metadata = wsgi_utils.sanitize(document, spec=None) + + try: + self._validate.queue_metadata_putting(metadata) + old_metadata = self._queue_controller.get(queue_name, + project=project_id) + old_metadata.update(metadata) + self._queue_controller.set_metadata(queue_name, + old_metadata, + project_id) + resp_dict = self._queue_controller.get(queue_name, + project=project_id) + except storage_errors.DoesNotExist as ex: + LOG.debug(ex) + raise wsgi_errors.HTTPNotFound(ex) + except validation.ValidationFailed as ex: + LOG.debug(ex) + raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) + except Exception as ex: + LOG.exception(ex) + description = _(u'Queue could not be updated.') + raise wsgi_errors.HTTPServiceUnavailable(description) + resp.body = utils.to_json(resp_dict) + class CollectionResource(object):