Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
    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))
Exemple #4
0
    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)
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
    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)
                }
            ]
        }
Exemple #8
0
    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)
Exemple #9
0
    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)
Exemple #10
0
    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)
Exemple #11
0
 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)
Exemple #12
0
    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)
Exemple #13
0
    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
Exemple #14
0
    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)