def on_get(self, req, resp, project_id, queue_name, message_id): try: message = self._message_controller.get( queue_name, message_id, project=project_id) queue_meta = self._queue_controller.get_metadata(queue_name, project_id) # Decrypt messages if queue_meta.get('_enable_encrypt_messages', False): self._encryptor.message_decrypted([message]) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except Exception: description = _(u'Message could not be retrieved.') LOG.exception(description) raise wsgi_errors.HTTPServiceUnavailable(description) # Prepare response message['href'] = req.path message = wsgi_utils.format_message_v1_1(message, req.path.rsplit('/', 2)[0], message['claim_id']) resp.body = utils.to_json(message)
def on_get(self, request, response, project_id, flavor): """Returns a JSON object for a single flavor entry: :: {"pool": "", "pool_list": [], capabilities: {...}} :returns: HTTP | [200, 404] """ LOG.debug(u'GET flavor - name: %s', flavor) data = None try: data = self._ctrl.get(flavor, project=project_id) capabilities = self._pools_ctrl.capabilities(flavor=data) data['capabilities'] = [ str(cap).split('.')[-1] for cap in capabilities ] pool_list =\ list(self._pools_ctrl.get_pools_by_flavor(flavor=data)) pool_name_list = [] if len(pool_list) > 0: pool_name_list = [x['name'] for x in pool_list] data['pool_list'] = pool_name_list except errors.FlavorDoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) data['href'] = request.path response.body = transport_utils.to_json(data)
def on_patch(self, request, response, project_id, flavor): """Allows one to update a flavors's pool and/or capabilities. This method expects the user to submit a JSON object containing at least one of: 'pool_group', 'capabilities'. If none are found, the request is flagged as bad. 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] """ LOG.debug(u'PATCH flavor - name: %s', flavor) data = wsgi_utils.load(request) EXPECT = ('capabilities') if not any([(field in data) for field in EXPECT]): LOG.debug(u'PATCH flavor, bad params') raise wsgi_errors.HTTPBadRequestBody( '`capabilities` needs ' 'to be specified' ) for field in EXPECT: wsgi_utils.validate(self._validators[field], data) fields = common_utils.fields(data, EXPECT, pred=lambda v: v is not None) try: self._ctrl.update(flavor, project=project_id, **fields) except errors.FlavorDoesNotExist as ex: LOG.exception(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex))
def on_get(self, request, response, project_id, flavor): """Returns a JSON object for a single flavor entry: :: {"pool_group": "", capabilities: {...}} :returns: HTTP | [200, 404] """ LOG.debug(u'GET flavor - name: %s', flavor) data = None detailed = request.get_param_as_bool('detailed') or False try: data = self._ctrl.get(flavor, project=project_id, detailed=detailed) # NOTE(wanghao): remove this in Newton. data['pool'] = data['pool_group'] except errors.FlavorDoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) data['href'] = request.path response.body = transport_utils.to_json(data)
def on_post(self, req, resp, project_id, queue_name): client_uuid = wsgi_helpers.get_client_uuid(req) try: # Place JSON size restriction before parsing self._validate.message_length(req.content_length) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) # Deserialize and validate the incoming messages document = wsgi_utils.deserialize(req.stream, req.content_length) if 'messages' not in document: description = _(u'No messages were found in the request body.') raise wsgi_errors.HTTPBadRequestAPI(description) messages = wsgi_utils.sanitize(document['messages'], self._message_post_spec, doctype=wsgi_utils.JSONArray) try: self._validate.message_posting(messages) if not self._queue_controller.exists(queue_name, project_id): self._queue_controller.create(queue_name, project=project_id) message_ids = self._message_controller.post( queue_name, messages=messages, project=project_id, client_uuid=client_uuid) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except storage_errors.MessageConflict: description = _(u'No messages could be enqueued.') LOG.exception(description) raise wsgi_errors.HTTPServiceUnavailable(description) except Exception: description = _(u'Messages could not be enqueued.') LOG.exception(description) raise wsgi_errors.HTTPServiceUnavailable(description) # Prepare the response ids_value = ','.join(message_ids) resp.location = req.path + '?ids=' + ids_value hrefs = [req.path + '/' + id for id in message_ids] body = {'resources': hrefs} resp.body = utils.to_json(body) resp.status = falcon.HTTP_201
def on_post(self, req, resp, project_id, queue_name): client_uuid = wsgi_helpers.get_client_uuid(req) try: # Place JSON size restriction before parsing self._validate.message_length(req.content_length) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) # Deserialize and validate the request body document = wsgi_utils.deserialize(req.stream, req.content_length) messages = wsgi_utils.sanitize(document, MESSAGE_POST_SPEC, doctype=wsgi_utils.JSONArray) try: self._validate.message_posting(messages) message_ids = self._message_controller.post( queue_name, messages=messages, project=project_id, client_uuid=client_uuid) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except storage_errors.MessageConflict as ex: LOG.exception(ex) description = _(u'No messages could be enqueued.') raise wsgi_errors.HTTPServiceUnavailable(description) except Exception as ex: LOG.exception(ex) description = _(u'Messages could not be enqueued.') raise wsgi_errors.HTTPServiceUnavailable(description) # Prepare the response ids_value = ','.join(message_ids) resp.location = req.path + '?ids=' + ids_value hrefs = [req.path + '/' + id for id in message_ids] # NOTE(kgriffs): As of the Icehouse release, drivers are # no longer allowed to enqueue a subset of the messages # submitted by the client; it's all or nothing. Therefore, # 'partial' is now always False in the v1.0 API, and the # field has been removed in v1.1. body = {'resources': hrefs, 'partial': False} resp.body = utils.to_json(body) resp.status = falcon.HTTP_201
def _get(self, req, project_id, queue_name): client_uuid = wsgi_helpers.get_client_uuid(req) kwargs = {} # NOTE(kgriffs): This syntax ensures that # we don't clobber default values with None. req.get_param('marker', store=kwargs) req.get_param_as_int('limit', store=kwargs) req.get_param_as_bool('echo', store=kwargs) req.get_param_as_bool('include_claimed', store=kwargs) try: self._validate.message_listing(**kwargs) results = self._message_controller.list( queue_name, project=project_id, client_uuid=client_uuid, **kwargs) # Buffer messages cursor = next(results) messages = list(cursor) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except Exception: description = _(u'Messages could not be listed.') LOG.exception(description) raise wsgi_errors.HTTPServiceUnavailable(description) if not messages: return None # Found some messages, so prepare the response kwargs['marker'] = next(results) base_path = req.path.rsplit('/', 1)[0] messages = [wsgi_utils.format_message_v1( m, base_path) for m in messages] return { 'messages': messages, 'links': [ { 'rel': 'next', 'href': req.path + falcon.to_query_str(kwargs) } ] }
def on_get(self, req, resp, project_id, queue_name): try: resp_dict = self._queue_controller.get(queue_name, project=project_id) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) 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)
def on_patch(self, request, response, project_id, pool): """Allows one to update a pool's weight, uri, and/or options. This method expects the user to submit a JSON object containing at least one of: 'uri', 'weight', 'flavor', 'options'.If none are found, the request is flagged as bad. 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 """ LOG.debug(u'PATCH pool - name: %s', pool) data = wsgi_utils.load(request) EXPECT = ('weight', 'uri', 'flavor', 'options') if not any([(field in data) for field in EXPECT]): LOG.debug(u'PATCH pool, bad params') raise wsgi_errors.HTTPBadRequestBody( 'One of `uri`, `weight`, `flavor`,' ' or `options` needs ' 'to be specified' ) for field in EXPECT: wsgi_utils.validate(self._validators[field], data) conf = self._ctrl.driver.conf if 'uri' in data and not storage_utils.can_connect(data['uri'], conf=conf): raise wsgi_errors.HTTPBadRequestBody( 'cannot connect to %s' % data['uri'] ) fields = common_utils.fields(data, EXPECT, pred=lambda v: v is not None) resp_data = None try: self._ctrl.update(pool, **fields) resp_data = self._ctrl.get(pool, False) except errors.PoolDoesNotExist as ex: LOG.exception('Pool "%s" does not exist', pool) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) resp_data['href'] = request.path response.body = transport_utils.to_json(resp_data)
def on_get(self, req, resp, project_id, queue_name, message_id): try: message = self._message_controller.get(queue_name, message_id, project=project_id) except storage_errors.DoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except Exception as ex: LOG.exception(ex) description = _(u'Message could not be retrieved.') raise wsgi_errors.HTTPServiceUnavailable(description) resp.content_location = req.relative_uri message = wsgi_utils.format_message_v1(message, req.path.rsplit('/', 2)[0]) resp.body = utils.to_json(message)
def _on_patch_by_group(self, request, response, project_id, flavor, pool_group): LOG.debug(u'PATCH flavor - name: %s by group', flavor) resp_data = None try: flvor_obj = {} flvor_obj['pool_group'] = pool_group capabilities = self._pools_ctrl.capabilities(flavor=flvor_obj) self._ctrl.update(flavor, project=project_id, pool_group=pool_group, capabilities=capabilities) resp_data = self._ctrl.get(flavor, project=project_id) resp_data['capabilities'] = [ str(cap).split('.')[-1] for cap in capabilities ] except errors.FlavorDoesNotExist as ex: LOG.exception(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) resp_data['href'] = request.path response.body = transport_utils.to_json(resp_data)
def on_get(self, req, resp, project_id, queue_name): ids = req.get_param_as_list('ids') if ids is None: response = self._get(req, project_id, queue_name) else: response = self._get_by_id(req.path.rsplit('/', 1)[0], project_id, queue_name, ids) if response is None: # NOTE(TheSriram): Trying to get a message by id, should # return the message if its present, otherwise a 404 since # the message might have been deleted. msg = _(u'No messages with IDs: {ids} found in the queue {queue} ' u'for project {project}.') description = msg.format(queue=queue_name, project=project_id, ids=ids) raise wsgi_errors.HTTPNotFound(description) else: resp.body = utils.to_json(response)
def on_put(self, req, resp, project_id, queue_name): try: # Place JSON size restriction before parsing self._validate.queue_metadata_length(req.content_length) # Deserialize queue metadata document = wsgi_utils.deserialize(req.stream, req.content_length) metadata = wsgi_utils.sanitize(document) # Restrict setting any reserved queue attributes for key in metadata: if key.startswith('_'): description = _(u'Reserved queue attributes in metadata ' u'(which names start with "_") can not be ' u'set in API v1.') raise validation.ValidationFailed(description) except validation.ValidationFailed as ex: LOG.debug(ex) raise wsgi_errors.HTTPBadRequestAPI(six.text_type(ex)) 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 as ex: raise wsgi_errors.HTTPNotFound(six.text_type(ex)) except Exception: description = _(u'Metadata could not be updated.') LOG.exception(description) raise wsgi_errors.HTTPServiceUnavailable(description) resp.status = falcon.HTTP_204 resp.location = req.path
def _on_patch_by_pool_list(self, request, response, project_id, flavor, pool_list): if len(pool_list) == 0: response.status = falcon.HTTP_400 response.location = request.path raise falcon.HTTPBadRequest(_('Unable to create'), 'Bad Request') # NOTE(gengchc2): If the flavor does not exist, return try: self._ctrl.get(flavor, project=project_id) except errors.FlavorDoesNotExist as ex: LOG.debug(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) flavor_obj = {} flavor_obj['name'] = flavor # NOTE(gengchc2): Get the pools list with flavor. pool_list_old = list( self._pools_ctrl.get_pools_by_flavor(flavor=flavor_obj)) # NOTE(gengchc2): Check if the new pool in the pool_list exist. try: self._check_pools_exists(pool_list) except errors.PoolDoesNotExist as ex: LOG.exception(ex) description = (_(u'Flavor %(flavor)s cant be updated, ' 'error:%(msg)s') % dict(flavor=flavor, msg=str(ex))) raise falcon.HTTPBadRequest(_('updatefail'), description) capabilities = self._pools_ctrl.capabilities(name=pool_list[0]) try: self._ctrl.update(flavor, project=project_id, capabilities=capabilities) resp_data = self._ctrl.get(flavor, project=project_id) resp_data['capabilities'] = [ str(cap).split('.')[-1] for cap in capabilities ] except errors.FlavorDoesNotExist as ex: LOG.exception(ex) raise wsgi_errors.HTTPNotFound(six.text_type(ex)) # (gengchc) Update flavor field in new pool list. try: self._update_pools_by_flavor(flavor, pool_list) except errors.ConnectionError as ex: LOG.exception(ex) description = (_(u'Flavor %(flavor)s could not be updated, ' 'error:%(msg)s') % dict(flavor=flavor, msg=str(ex))) raise falcon.HTTPBadRequest(_('Unable to create'), description) # (gengchc) Remove flavor from old pool list. try: pool_list_removed = [] for pool_old in pool_list_old: if pool_old['name'] not in pool_list: pool_list_removed.append(pool_old['name']) self._clean_pools_by_flavor(flavor, pool_list_removed) except errors.ConnectionError as ex: LOG.exception(ex) description = (_(u'Flavor %(flavor)s could not be updated, ' 'error:%(msg)s') % dict(flavor=flavor, msg=str(ex))) raise falcon.HTTPBadRequest(_('Unable to create'), description) resp_data['pool_list'] = pool_list resp_data['href'] = request.path response.body = transport_utils.to_json(resp_data)