Exemplo n.º 1
0
    def claim_update(self, req):
        """Updates a claim

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')
        claim_id = req._body.get('claim_id')

        LOG.debug(
            u'Claim update - claim: %(claim_id)s, '
            u'queue: %(queue_name)s, project:%(project_id)s' % {
                'queue_name': queue_name,
                'project_id': project_id,
                'claim_id': claim_id
            })

        self._claim_patch_spec = (
            ('ttl', int, self._defaults.claim_ttl),
            ('grace', int, self._defaults.claim_grace),
        )

        # Read claim metadata (e.g., TTL) and raise appropriate
        # HTTP errors as needed.
        metadata = api_utils.sanitize(req._body, self._claim_patch_spec)

        try:
            self._validate.claim_updating(metadata)
            self._claim_controller.update(queue_name,
                                          claim_id=claim_id,
                                          metadata=metadata,
                                          project=project_id)
            headers = {'status': 204}
            body = _('Claim %s updated.') % claim_id
            return response.Response(req, body, headers)
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            error = _('Claim %s does not exist.') % claim_id
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers, error)
Exemplo n.º 2
0
    def claim_update(self, req):
        """Updates a claim

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')
        claim_id = req._body.get('claim_id')

        LOG.debug(u'Claim update - claim: %(claim_id)s, '
                  u'queue: %(queue_name)s, project:%(project_id)s' %
                  {'queue_name': queue_name,
                   'project_id': project_id,
                   'claim_id': claim_id})

        self._claim_patch_spec = (
            ('ttl', int, self._defaults.claim_ttl),
            ('grace', int, self._defaults.claim_grace),
        )

        # Read claim metadata (e.g., TTL) and raise appropriate
        # HTTP errors as needed.
        metadata = api_utils.sanitize(req._body, self._claim_patch_spec)

        try:
            self._validate.claim_updating(metadata)
            self._claim_controller.update(queue_name,
                                          claim_id=claim_id,
                                          metadata=metadata,
                                          project=project_id)
            headers = {'status': 204}
            body = _('Claim %s updated.') % claim_id
            return response.Response(req, body, headers)
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            error = _('Claim %s does not exist.') % claim_id
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers, error)
Exemplo n.º 3
0
    def claim_create(self, req):
        """Creates a claim

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(u'Claims create - queue: %(queue)s, '
                  u'project: %(project)s',
                  {'queue': queue_name, 'project': project_id})

        self._claim_post_spec = (
            ('ttl', int, self._defaults.claim_ttl),
            ('grace', int, self._defaults.claim_grace),
        )

        # Claim some messages

        # NOTE(vkmc): We build a dict with the ttl and grace
        # This is the metadata the storage is waiting for
        kwargs = api_utils.get_headers(req)
        # Read claim metadata (e.g., ttl) and raise appropriate
        # errors as needed.
        metadata = api_utils.sanitize(kwargs, self._claim_post_spec)

        limit = (None if kwargs.get('limit') is None
                 else kwargs.get('limit'))

        claim_options = {} if limit is None else {'limit': limit}

        try:
            self._validate.claim_creation(metadata, limit=limit)
        except (ValueError, validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        cid, msgs = self._claim_controller.create(
            queue_name,
            metadata=metadata,
            project=project_id,
            **claim_options)

        # Buffer claimed messages
        # TODO(vkmc): optimize, along with serialization (below)
        resp_msgs = list(msgs)

        # Serialize claimed messages, if any. This logic assumes
        # the storage driver returned well-formed messages.
        if len(resp_msgs) != 0:
            resp_msgs = [api_utils.format_message(msg, cid)
                         for msg in resp_msgs]

            headers = {'status': 201}
            body = {'claim_id': cid, 'messages': resp_msgs}
        else:
            headers = {'status': 204}
            body = {'claim_id': cid}

        return response.Response(req, body, headers)
Exemplo n.º 4
0
    def message_post(self, req):
        """Post a set of messages to a queue

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(u'Messages post - queue:  %(queue)s, '
                  u'project: %(project)s',
                  {'queue': queue_name, 'project': project_id})

        messages = req._body.get('messages')

        if messages is None:
            ex = _(u'Invalid request.')
            error = _(u'No messages were found in the request body.')
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers, error)

        try:
            # Place JSON size restriction before parsing
            self._validate.message_length(len(str(messages)))
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        _message_post_spec = (
            ('ttl', int, self._defaults.message_ttl),
            ('body', '*', None),
        )

        try:
            messages = api_utils.sanitize(messages,
                                          _message_post_spec,
                                          doctype=list)
        except api_errors.BadRequest as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            client_uuid = api_utils.get_client_uuid(req)

            self._validate.message_posting(messages)

            if not self._queue_controller.exists(queue_name, project_id):
                self._validate.queue_identification(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 (api_errors.BadRequest, validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.MessageConflict as ex:
            LOG.exception(ex)
            error = _(u'No messages could be enqueued.')
            headers = {'status': 500}
            return api_utils.error_response(req, ex, headers, error)

        # Prepare the response
        headers = {'status': 201}
        body = {'message_ids': message_ids}

        return response.Response(req, body, headers)
Exemplo n.º 5
0
    def message_post(self, req):
        """Post a set of messages to a queue

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(u'Messages post - queue:  %(queue)s, '
                  u'project: %(project)s',
                  {'queue': queue_name, 'project': project_id})

        messages = req._body.get('messages')

        if messages is None:
            ex = _(u'Invalid request.')
            error = _(u'No messages were found in the request body.')
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers, error)

        try:
            # NOTE(flwang): Replace 'exists' with 'get_metadata' won't impact
            # the performance since both of them will call
            # collection.find_one()
            queue_meta = None
            try:
                queue_meta = self._queue_controller.get_metadata(queue_name,
                                                                 project_id)
            except storage_errors.DoesNotExist as ex:
                self._validate.queue_identification(queue_name, project_id)
                self._queue_controller.create(queue_name, project=project_id)
                # NOTE(flwang): Queue is created in lazy mode, so no metadata
                # set.
                queue_meta = {}

            queue_max_msg_size = queue_meta.get('_max_messages_post_size',
                                                None)
            queue_default_ttl = queue_meta.get('_default_message_ttl', None)

            # TODO(flwang): To avoid any unexpected regression issue, we just
            # leave the _message_post_spec attribute of class as it's. It
            # should be removed in Newton release.
            if queue_default_ttl:
                _message_post_spec = (('ttl', int, queue_default_ttl),
                                      ('body', '*', None),)
            else:
                _message_post_spec = (('ttl', int, self._defaults.message_ttl),
                                      ('body', '*', None),)
            # Place JSON size restriction before parsing
            self._validate.message_length(len(str(messages)),
                                          max_msg_post_size=queue_max_msg_size)
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            messages = api_utils.sanitize(messages,
                                          _message_post_spec,
                                          doctype=list)
        except api_errors.BadRequest as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            client_uuid = api_utils.get_client_uuid(req)

            self._validate.message_posting(messages)

            message_ids = self._message_controller.post(
                queue_name,
                messages=messages,
                project=project_id,
                client_uuid=client_uuid)
        except (api_errors.BadRequest, validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.MessageConflict as ex:
            LOG.exception(ex)
            error = _(u'No messages could be enqueued.')
            headers = {'status': 500}
            return api_utils.error_response(req, ex, headers, error)

        # Prepare the response
        headers = {'status': 201}
        body = {'message_ids': message_ids}

        return response.Response(req, body, headers)
Exemplo n.º 6
0
    def claim_create(self, req):
        """Creates a claim

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(u'Claims create - queue: %(queue)s, '
                  u'project: %(project)s',
                  {'queue': queue_name, 'project': project_id})

        self._claim_post_spec = (
            ('ttl', int, self._defaults.claim_ttl),
            ('grace', int, self._defaults.claim_grace),
        )

        # Claim some messages

        # NOTE(vkmc): We build a dict with the ttl and grace
        # This is the metadata the storage is waiting for
        kwargs = api_utils.get_headers(req)
        # Read claim metadata (e.g., ttl) and raise appropriate
        # errors as needed.
        metadata = api_utils.sanitize(kwargs, self._claim_post_spec)

        limit = (None if kwargs.get('limit') is None
                 else kwargs.get('limit'))

        claim_options = {} if limit is None else {'limit': limit}

        try:
            self._validate.claim_creation(metadata, limit=limit)
        except (ValueError, validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        cid, msgs = self._claim_controller.create(
            queue_name,
            metadata=metadata,
            project=project_id,
            **claim_options)

        # Buffer claimed messages
        # TODO(vkmc): optimize, along with serialization (below)
        resp_msgs = list(msgs)

        # Serialize claimed messages, if any. This logic assumes
        # the storage driver returned well-formed messages.
        if len(resp_msgs) != 0:
            resp_msgs = [api_utils.format_message(msg, cid)
                         for msg in resp_msgs]

            headers = {'status': 201}
            body = {'claim_id': cid, 'messages': resp_msgs}
        else:
            headers = {'status': 204}
            body = {'claim_id': cid}

        return response.Response(req, body, headers)
Exemplo n.º 7
0
    def message_post(self, req):
        """Post a set of messages to a queue

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(u'Messages post - queue:  %(queue)s, '
                  u'project: %(project)s',
                  {'queue': queue_name, 'project': project_id})

        messages = req._body.get('messages')

        if messages is None:
            ex = _(u'Invalid request.')
            error = _(u'No messages were found in the request body.')
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers, error)

        try:
            # NOTE(flwang): Replace 'exists' with 'get_metadata' won't impact
            # the performance since both of them will call
            # collection.find_one()
            queue_meta = None
            try:
                queue_meta = self._queue_controller.get_metadata(queue_name,
                                                                 project_id)
            except storage_errors.DoesNotExist as ex:
                self._validate.queue_identification(queue_name, project_id)
                self._queue_controller.create(queue_name, project=project_id)
                # NOTE(flwang): Queue is created in lazy mode, so no metadata
                # set.
                queue_meta = {}

            queue_max_msg_size = queue_meta.get('_max_messages_post_size',
                                                None)
            queue_default_ttl = queue_meta.get('_default_message_ttl')

            if queue_default_ttl:
                _message_post_spec = (('ttl', int, queue_default_ttl),
                                      ('body', '*', None),)
            else:
                _message_post_spec = (('ttl', int, self._defaults.message_ttl),
                                      ('body', '*', None),)
            # Place JSON size restriction before parsing
            self._validate.message_length(len(str(messages)),
                                          max_msg_post_size=queue_max_msg_size)
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            messages = api_utils.sanitize(messages,
                                          _message_post_spec,
                                          doctype=list)
        except api_errors.BadRequest as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            self._validate.client_id_uuid_safe(req._headers.get('Client-ID'))
            client_uuid = api_utils.get_client_uuid(req)

            self._validate.message_posting(messages)

            message_ids = self._message_controller.post(
                queue_name,
                messages=messages,
                project=project_id,
                client_uuid=client_uuid)
        except (ValueError, api_errors.BadRequest,
                validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.MessageConflict as ex:
            LOG.exception(ex)
            error = _(u'No messages could be enqueued.')
            headers = {'status': 500}
            return api_utils.error_response(req, ex, headers, error)

        # Prepare the response
        headers = {'status': 201}
        body = {'message_ids': message_ids}

        return response.Response(req, body, headers)
Exemplo n.º 8
0
    def message_post(self, req):
        """Post a set of messages to a queue

        :param req: Request instance ready to be sent.
        :type req: `api.common.Request`
        :return: resp: Response instance
        :type: resp: `api.common.Response`
        """
        project_id = req._headers.get('X-Project-ID')
        queue_name = req._body.get('queue_name')

        LOG.debug(
            u'Messages post - queue:  %(queue)s, '
            u'project: %(project)s', {
                'queue': queue_name,
                'project': project_id
            })

        messages = req._body.get('messages')

        if messages is None:
            ex = _(u'Invalid request.')
            error = _(u'No messages were found in the request body.')
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers, error)

        try:
            # Place JSON size restriction before parsing
            self._validate.message_length(len(str(messages)))
        except validation.ValidationFailed as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        _message_post_spec = (
            ('ttl', int, self._defaults.message_ttl),
            ('body', '*', None),
        )

        try:
            messages = api_utils.sanitize(messages,
                                          _message_post_spec,
                                          doctype=list)
        except api_errors.BadRequest as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)

        try:
            client_uuid = api_utils.get_client_uuid(req)

            self._validate.message_posting(messages)

            if not self._queue_controller.exists(queue_name, project_id):
                self._validate.queue_identification(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 (api_errors.BadRequest, validation.ValidationFailed) as ex:
            LOG.debug(ex)
            headers = {'status': 400}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.DoesNotExist as ex:
            LOG.debug(ex)
            headers = {'status': 404}
            return api_utils.error_response(req, ex, headers)
        except storage_errors.MessageConflict as ex:
            LOG.exception(ex)
            error = _(u'No messages could be enqueued.')
            headers = {'status': 500}
            return api_utils.error_response(req, ex, headers, error)

        # Prepare the response
        headers = {'status': 201}
        body = {'message_ids': message_ids}

        return response.Response(req, body, headers)