Ejemplo n.º 1
0
    def test_select_item(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        blob_data1 = bytes(bytearray([1, 2, 3, 4, 5]))
        blob_data2 = bytes(bytearray([5, 4, 3, 2, 1]))

        hash_key = "4.5621201231232132132132132132132142354E126"
        range_key = "range"

        storage.select_item(
            IgnoreArg(), IgnoreArg(), IgnoreArg(),
            select_type=IgnoreArg(), index_name=IgnoreArg(), limit=IgnoreArg(),
            exclusive_start_key=IgnoreArg(), consistent=IgnoreArg(),
            order_type=IgnoreArg(),
        ).AndReturn(
            models.SelectResult(
                items=[
                    {
                        "hash_key": models.AttributeValue(
                            models.ATTRIBUTE_TYPE_NUMBER,
                            decimal.Decimal(hash_key)
                        ),
                        "range_key": models.AttributeValue(
                            models.ATTRIBUTE_TYPE_STRING, range_key
                        ),
                        "value_blob": models.AttributeValue(
                            models.ATTRIBUTE_TYPE_BLOB, blob_data1
                        ),
                        "value_blob_set": models.AttributeValue(
                            models.ATTRIBUTE_TYPE_BLOB_SET,
                            set([blob_data1, blob_data2])
                        )
                    }
                ]
            )
        )

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        items = list(table.query(consistent=False, hash_key__eq=1))

        expected_item = {
            "hash_key": decimal.Decimal(hash_key),
            "range_key": range_key,
            "value_blob": types.Binary(blob_data1),
            "value_blob_set": set([types.Binary(blob_data1),
                                   types.Binary(blob_data2)])
        }

        self.assertEqual(len(items), 1)

        self.assertDictEqual(expected_item, dict(items[0].items()))

        self.storage_mocker.VerifyAll()
Ejemplo n.º 2
0
    def test_select_item(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        blob_data1 = bytes(bytearray([1, 2, 3, 4, 5]))
        blob_data2 = bytes(bytearray([5, 4, 3, 2, 1]))

        hash_key = "4.5621201231232132132132132132132142354E126"
        range_key = "range"

        storage.select_item(
            IgnoreArg(),
            IgnoreArg(),
            IgnoreArg(),
            select_type=IgnoreArg(),
            index_name=IgnoreArg(),
            limit=IgnoreArg(),
            exclusive_start_key=IgnoreArg(),
            consistent=IgnoreArg(),
            order_type=IgnoreArg(),
        ).AndReturn(
            models.SelectResult(items=[{
                "hash_key":
                models.AttributeValue(models.ATTRIBUTE_TYPE_NUMBER,
                                      decimal.Decimal(hash_key)),
                "range_key":
                models.AttributeValue(models.ATTRIBUTE_TYPE_STRING, range_key),
                "value_blob":
                models.AttributeValue(models.ATTRIBUTE_TYPE_BLOB, blob_data1),
                "value_blob_set":
                models.AttributeValue(models.ATTRIBUTE_TYPE_BLOB_SET,
                                      set([blob_data1, blob_data2]))
            }]))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        items = list(table.query(consistent=False, hash_key__eq=1))

        expected_item = {
            "hash_key":
            decimal.Decimal(hash_key),
            "range_key":
            range_key,
            "value_blob":
            types.Binary(blob_data1),
            "value_blob_set":
            set([types.Binary(blob_data1),
                 types.Binary(blob_data2)])
        }

        self.assertEqual(len(items), 1)

        self.assertDictEqual(expected_item, dict(items[0].items()))

        self.storage_mocker.VerifyAll()
Ejemplo n.º 3
0
    def test_update_item(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        hash_key = "4.5621201231232132132132132132132142354E126"
        range_key = "range"

        storage.select_item(
            IgnoreArg(), IgnoreArg(), IgnoreArg(),
            select_type=IgnoreArg(), limit=IgnoreArg(),
            consistent=IgnoreArg()
        ).AndReturn(
            models.SelectResult(
                items=[
                    {
                        "hash_key": models.AttributeValue.number(hash_key),
                        "range_key": models.AttributeValue.str(range_key),
                        "attr_value": models.AttributeValue.str('val')
                    }
                ]
            )
        )

        self.storage_mocker.StubOutWithMock(storage, 'describe_table')

        storage.describe_table(IgnoreArg(), 'test_table').AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'hash_key': models.ATTRIBUTE_TYPE_NUMBER,
                        'range_key': models.ATTRIBUTE_TYPE_STRING
                    },
                    ['hash_key', 'range_key'],
                ),
                models.TableMeta.TABLE_STATUS_ACTIVE
            )
        )

        self.storage_mocker.StubOutWithMock(storage, 'update_item')
        storage.update_item(
            IgnoreArg(), IgnoreArg(),
            key_attribute_map=IgnoreArg(),
            attribute_action_map=IgnoreArg(),
            expected_condition_map=IgnoreArg()).AndReturn(True)

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        item = table.get_item(consistent=False, hash_key=1, range_key="range")

        item['attr_value'] = 'updated'

        item.partial_save()

        self.storage_mocker.VerifyAll()
Ejemplo n.º 4
0
    def test_update_item(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        hash_key = "4.5621201231232132132132132132132142354E126"
        range_key = "range"

        storage.select_item(
            IgnoreArg(), IgnoreArg(), IgnoreArg(),
            select_type=IgnoreArg(), limit=IgnoreArg(),
            consistent=IgnoreArg()
        ).AndReturn(
            models.SelectResult(
                items=[
                    {
                        "hash_key": models.AttributeValue('N', hash_key),
                        "range_key": models.AttributeValue('S', range_key),
                        "attr_value": models.AttributeValue('S', 'val')
                    }
                ]
            )
        )

        self.storage_mocker.StubOutWithMock(storage, 'describe_table')

        storage.describe_table(IgnoreArg(), 'test_table').AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'hash_key': models.AttributeType('N'),
                        'range_key': models.AttributeType('S')
                    },
                    ['hash_key', 'range_key'],
                ),
                models.TableMeta.TABLE_STATUS_ACTIVE
            )
        )

        self.storage_mocker.StubOutWithMock(storage, 'update_item')
        storage.update_item(
            IgnoreArg(), IgnoreArg(),
            key_attribute_map=IgnoreArg(),
            attribute_action_map=IgnoreArg(),
            expected_condition_map=IgnoreArg()).AndReturn((True, None))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        item = table.get_item(consistent=False, hash_key=1, range_key="range")

        item['attr_value'] = 'updated'

        item.partial_save()

        self.storage_mocker.VerifyAll()
Ejemplo n.º 5
0
    def test_get_item(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        blob_data1 = bytes(bytearray([1, 2, 3, 4, 5]))
        blob_data2 = bytes(bytearray([5, 4, 3, 2, 1]))

        hash_key = "4.5621201231232132132132132132132142354E126"
        range_key = "range"

        storage.select_item(
            IgnoreArg(),
            IgnoreArg(),
            IgnoreArg(),
            select_type=IgnoreArg(),
            limit=IgnoreArg(),
            consistent=IgnoreArg()).AndReturn(
                models.SelectResult(items=[{
                    "hash_key":
                    models.AttributeValue('N', hash_key),
                    "range_key":
                    models.AttributeValue('S', range_key),
                    "value_blob":
                    models.AttributeValue('B', decoded_value=blob_data1),
                    "value_blob_set":
                    models.AttributeValue(
                        'BS', decoded_value={blob_data1, blob_data2})
                }]))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        item = table.get_item(consistent=False, hash_key=1, range_key="range")

        expected_item = {
            "hash_key":
            decimal.Decimal(hash_key),
            "range_key":
            range_key,
            "value_blob":
            types.Binary(blob_data1),
            "value_blob_set":
            set([types.Binary(blob_data1),
                 types.Binary(blob_data2)])
        }

        self.assertDictEqual(expected_item, dict(item.items()))

        self.storage_mocker.VerifyAll()
Ejemplo n.º 6
0
    def process_request(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validate'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                attributes_to_get = validation.validate_set(
                    attributes_to_get, parser.Props.ATTRIBUTES_TO_GET
                )
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)
                select_type = models.SelectType.specific_attributes(
                    attributes_to_get
                )
            else:
                select_type = models.SelectType.all()

            key = body.pop(parser.Props.KEY, None)
            validation.validate_object(key, parser.Props.KEY)

            # parse consistent_read
            consistent_read = body.pop(parser.Props.CONSISTENT_READ, False)
            validation.validate_boolean(consistent_read,
                                        parser.Props.CONSISTENT_READ)

            validation.validate_unexpected_props(body, "body")

            # parse key_attributes
            key_attributes = parser.Parser.parse_item_attributes(key)

            # format conditions to get item
            indexed_condition_map = {
                name: [models.IndexedCondition.eq(value)]
                for name, value in key_attributes.iteritems()
            }

        # get item
        result = storage.select_item(
            req.context, table_name, indexed_condition_map,
            select_type=select_type, limit=2, consistent=consistent_read)

        # format response
        if result.count == 0:
            return {}

        response = {
            parser.Props.ITEM: parser.Parser.format_item_attributes(
                result.items[0])
        }
        return response
Ejemplo n.º 7
0
    def process_request(self, req, body, project_id, table_name):
        try:
            validation.validate_params(self.schema, body)
            req.context.tenant = project_id

            # get attributes_to_get
            attributes_to_get = body.get(parser.Props.ATTRIBUTES_TO_GET)

            select_type = (
                models.SelectType.all()
                if attributes_to_get is None else
                models.SelectType.specified_attributes(attributes_to_get)
            )

            # parse key_attributes
            key_attributes = parser.Parser.parse_item_attributes(
                body[parser.Props.KEY]
            )

            # parse consistent_read
            consistent_read = body.get(
                parser.Props.CONSISTENT_READ, False
            )

            # format conditions to get item
            indexed_condition_map = {
                name: [models.IndexedCondition.eq(value)]
                for name, value in key_attributes.iteritems()
            }

        except Exception:
            raise exception.ValidationException()

        try:
            # get item
            result = storage.select_item(
                req.context, table_name, indexed_condition_map,
                select_type=select_type, limit=2, consistent=consistent_read)

            # format response
            if result.count == 0:
                return {}

            response = {
                parser.Props.ITEM: parser.Parser.format_item_attributes(
                    result.items[0])
            }
            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 8
0
    def test_select_item_count(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        storage.select_item(IgnoreArg(),
                            IgnoreArg(),
                            IgnoreArg(),
                            select_type=SelectType.count(),
                            index_name=IgnoreArg(),
                            limit=IgnoreArg(),
                            exclusive_start_key=IgnoreArg(),
                            consistent=IgnoreArg(),
                            order_type=IgnoreArg()).AndReturn(
                                models.SelectResult(count=100500))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        count = table.query_count(consistent=False, hash_key__eq=1)

        self.assertEqual(count, 100500)

        self.storage_mocker.VerifyAll()
Ejemplo n.º 9
0
    def test_select_item_count(self):
        self.storage_mocker.StubOutWithMock(storage, 'select_item')

        storage.select_item(
            IgnoreArg(), IgnoreArg(), IgnoreArg(),
            select_type=SelectType.count(), index_name=IgnoreArg(),
            limit=IgnoreArg(), exclusive_start_key=IgnoreArg(),
            consistent=IgnoreArg(), order_type=IgnoreArg()
        ).AndReturn(
            models.SelectResult(
                count=100500
            )
        )

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        count = table.query_count(consistent=False, hash_key__eq=1)

        self.assertEqual(count, 100500)

        self.storage_mocker.VerifyAll()
Ejemplo n.º 10
0
    def process_request(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        jsonschema.validate(body, self.schema)
        req.context.tenant = project_id

        # get attributes_to_get
        attributes_to_get = body.get(parser.Props.ATTRIBUTES_TO_GET)

        select_type = (
            models.SelectType.all()
            if attributes_to_get is None else
            models.SelectType.specified_attributes(attributes_to_get)
        )

        # parse key_attributes
        key_attributes = parser.Parser.parse_item_attributes(
            body[parser.Props.KEY]
        )

        # parse consistent_read
        consistent_read = body.get(
            parser.Props.CONSISTENT_READ, False
        )

        # format conditions to get item
        indexed_condition_map = {
            name: [models.IndexedCondition.eq(value)]
            for name, value in key_attributes.iteritems()
        }

        # get item
        result = storage.select_item(
            req.context, table_name, indexed_condition_map,
            select_type=select_type, limit=2, consistent=consistent_read)

        # format response
        if result.count == 0:
            return {}

        response = {
            parser.Props.ITEM: parser.Parser.format_item_attributes(
                result.items[0])
        }
        return response
Ejemplo n.º 11
0
    def query(self, req, body, project_id, table_name):
        jsonschema.validate(body, self.schema)
        req.context.tenant = project_id

        # parse select_type
        attributes_to_get = body.get(parser.Props.ATTRIBUTES_TO_GET)

        if attributes_to_get is not None:
            attributes_to_get = frozenset(attributes_to_get)

        select = body.get(parser.Props.SELECT)

        index_name = body.get(parser.Props.INDEX_NAME)

        select_type = parser.Parser.parse_select_type(select,
                                                      attributes_to_get,
                                                      index_name)

        # parse exclusive_start_key_attributes
        exclusive_start_key_attributes = body.get(
            parser.Props.EXCLUSIVE_START_KEY)

        if exclusive_start_key_attributes is not None:
            exclusive_start_key_attributes = (
                parser.Parser.parse_item_attributes(
                    exclusive_start_key_attributes
                )
            )

        # parse indexed_condition_map
        indexed_condition_map = parser.Parser.parse_attribute_conditions(
            body.get(parser.Props.KEY_CONDITIONS))

        # TODO(dukhlov):
        # it would be nice to validate given table_name, key_attributes and
        # attributes_to_get to schema expectation

        consistent_read = body.get(
            parser.Props.CONSISTENT_READ, False)

        limit = body.get(parser.Props.LIMIT)

        order_asc = body.get(parser.Props.SCAN_INDEX_FORWARD)

        if order_asc is None:
            order_type = None
        elif order_asc:
            order_type = models.ORDER_TYPE_ASC
        else:
            order_type = models.ORDER_TYPE_DESC

        # select item
        result = storage.select_item(
            req.context, table_name, indexed_condition_map,
            select_type=select_type, index_name=index_name, limit=limit,
            consistent=consistent_read, order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes
        )

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {
                parser.Props.COUNT: result.count
            }
        else:
            response = {
                parser.Props.COUNT: result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key)
            )

        return response
Ejemplo n.º 12
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # get attributes_to_get
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)

            select_type = (models.SelectType.all()
                           if attributes_to_get is None else
                           models.AttributeToGet.specified(attributes_to_get))

            # parse key_attributes
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get  to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            # format conditions to get item
            indexed_condition_map = {
                name: [models.IndexedCondition.eq(value)]
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            # get item
            result = storage.select_item(self.context,
                                         table_name,
                                         indexed_condition_map,
                                         select_type=select_type,
                                         limit=2,
                                         consistent=consistent_read)

            # format response
            if result.count == 0:
                return {}

            assert result.count == 1

            response = {
                parser.Props.ITEM:
                parser.Parser.format_item_attributes(result.items[0])
            }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 13
0
    def query(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            index_name = body.pop(parser.Props.INDEX_NAME, None)
            if index_name is not None:
                validation.validate_index_name(index_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    if index_name is not None:
                        select = models.SelectType.SELECT_TYPE_ALL_PROJECTED
                    else:
                        select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)

            select_type = models.SelectType(select, attributes_to_get)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)

            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json))
            else:
                exclusive_start_key_attributes = None

            # parse indexed_condition_map
            key_conditions = body.pop(parser.Props.KEY_CONDITIONS, None)
            validation.validate_object(key_conditions,
                                       parser.Props.KEY_CONDITIONS)

            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                key_conditions, condition_class=IndexedCondition)

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = body.pop(parser.Props.CONSISTENT_READ, False)
            validation.validate_boolean(consistent_read,
                                        parser.Props.CONSISTENT_READ)
            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit,
                                                    parser.Props.LIMIT,
                                                    min_val=0)

            scan_forward = body.pop(parser.Props.SCAN_INDEX_FORWARD, None)

            if scan_forward is not None:
                validation.validate_boolean(scan_forward,
                                            parser.Props.SCAN_INDEX_FORWARD)
                order_type = (models.ORDER_TYPE_ASC
                              if scan_forward else models.ORDER_TYPE_DESC)
            else:
                order_type = None

            validation.validate_unexpected_props(body, "body")

        # select item
        result = storage.select_item(
            req.context,
            table_name,
            indexed_condition_map,
            select_type=select_type,
            index_name=index_name,
            limit=limit,
            consistent=consistent_read,
            order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes)

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {parser.Props.COUNT: result.count}
        else:
            response = {
                parser.Props.COUNT:
                result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key))

        return response
Ejemplo n.º 14
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse select_type
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get is not None:
                attributes_to_get = frozenset(attributes_to_get)

            select = self.action_params.get(parser.Props.SELECT, None)

            index_name = self.action_params.get(parser.Props.INDEX_NAME, None)

            select_type = parser.Parser.parse_select_type(
                select, attributes_to_get, index_name)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes = self.action_params.get(
                parser.Props.EXCLUSIVE_START_KEY, None)
            if exclusive_start_key_attributes is not None:
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes))

            # parse indexed_condition_map
            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                self.action_params.get(parser.Props.KEY_CONDITIONS, None))

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            limit = self.action_params.get(parser.Props.LIMIT, None)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            order_asc = self.action_params.get(parser.Props.SCAN_INDEX_FORWARD,
                                               None)

            order_type = (None if order_asc is None else models.ORDER_TYPE_ASC
                          if order_asc else models.ORDER_TYPE_DESC)
        except Exception:
            raise exception.ValidationException()

        try:
            # select item
            result = storage.select_item(
                self.context,
                table_name,
                indexed_condition_map,
                select_type=select_type,
                index_name=index_name,
                limit=limit,
                consistent=consistent_read,
                order_type=order_type,
                exclusive_start_key=exclusive_start_key_attributes)

            # format response
            if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
                response = {parser.Props.COUNT: result.count}
            else:
                response = {
                    parser.Props.COUNT:
                    result.count,
                    parser.Props.ITEMS: [
                        parser.Parser.format_item_attributes(row)
                        for row in result.items
                    ]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            if limit == result.count:
                response[parser.Props.LAST_EVALUATED_KEY] = (
                    parser.Parser.format_item_attributes(
                        result.last_evaluated_key))
            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 15
0
    def __call__(self):
        table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

        # get attributes_to_get
        attributes_to_get = self.action_params.get(
            parser.Props.ATTRIBUTES_TO_GET, None
        )

        select_type = (
            models.SelectType.all()
            if attributes_to_get is None else
            models.AttributeToGet.specified(attributes_to_get)
        )

        # parse key_attributes
        key_attributes = parser.Parser.parse_item_attributes(
            self.action_params[parser.Props.KEY]
        )

        # TODO(dukhlov):
        # it would be nice to validate given table_name, key_attributes and
        # attributes_to_get  to schema expectation

        consistent_read = self.action_params.get(
            parser.Props.CONSISTENT_READ, False
        )

        return_consumed_capacity = self.action_params.get(
            parser.Props.RETURN_CONSUMED_CAPACITY,
            parser.Values.RETURN_CONSUMED_CAPACITY_NONE
        )

        # format conditions to get item
        indexed_condition_map = {
            name: models.IndexedCondition.eq(value)
            for name, value in key_attributes.iteritems()
        }

        # get item
        result = storage.select_item(
            self.context, table_name, indexed_condition_map,
            select_type=select_type, limit=2, consistent=consistent_read)

        # format response
        if result.count == 0:
            return {}

        assert result.count == 1

        response = {
            parser.Props.ITEM: parser.Parser.format_item_attributes(
                result.items[0])
        }

        if (return_consumed_capacity !=
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
            response[parser.Props.CONSUMED_CAPACITY] = (
                parser.Parser.format_consumed_capacity(
                    return_consumed_capacity, None
                )
            )

        return response
Ejemplo n.º 16
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse select_type
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None
            )
            if attributes_to_get is not None:
                attributes_to_get = frozenset(attributes_to_get)

            select = self.action_params.get(
                parser.Props.SELECT, None
            )

            index_name = self.action_params.get(parser.Props.INDEX_NAME, None)

            select_type = parser.Parser.parse_select_type(select,
                                                          attributes_to_get,
                                                          index_name)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes = self.action_params.get(
                parser.Props.EXCLUSIVE_START_KEY, None
            )
            if exclusive_start_key_attributes is not None:
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes
                    )
                )

            # parse indexed_condition_map
            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                self.action_params.get(parser.Props.KEY_CONDITIONS, None)
            )

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False
            )

            limit = self.action_params.get(parser.Props.LIMIT, None)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE
            )

            order_asc = self.action_params.get(
                parser.Props.SCAN_INDEX_FORWARD, None
            )

            order_type = (
                None if order_asc is None else
                models.ORDER_TYPE_ASC if order_asc else
                models.ORDER_TYPE_DESC
            )
        except Exception:
            raise exception.ValidationException()

        try:
            # select item
            result = storage.select_item(
                self.context, table_name, indexed_condition_map,
                select_type=select_type, index_name=index_name, limit=limit,
                consistent=consistent_read, order_type=order_type,
                exclusive_start_key=exclusive_start_key_attributes
            )

            # format response
            if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
                response = {
                    parser.Props.COUNT: result.items
                }
            else:
                response = {
                    parser.Props.COUNT: len(result.items),
                    parser.Props.ITEMS: [
                        parser.Parser.format_item_attributes(row)
                        for row in result.items
                    ]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None
                    )
                )

            if limit == len(result.items):
                response[parser.Props.LAST_EVALUATED_KEY] = (
                    parser.Parser.format_item_attributes(
                        result.last_evaluated_key)
                )
            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 17
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})
                )
            )

            #parse attribute updates
            attribute_updates = parser.Parser.parse_attribute_updates(
                self.action_params.get(parser.Props.ATTRIBUTE_UPDATES, {})
            )

            # parse key
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY]
            )

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE
            )

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE
            )

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE
            )

            select_result = None

            indexed_condition_map_for_select = {
                name: models.IndexedCondition.eq(value)
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:

            if return_values in (parser.Values.RETURN_VALUES_UPDATED_OLD,
                                 parser.Values.RETURN_VALUES_ALL_OLD):

                select_result = storage.select_item(
                    self.context, table_name,
                    indexed_condition_map_for_select)

            # update item
            result = storage.update_item(
                self.context,
                table_name,
                key_attribute_map=key_attributes,
                attribute_action_map=attribute_updates,
                expected_condition_map=expected_item_conditions)

            if not result:
                raise exception.AWSErrorResponseException()

            if return_values in (parser.Values.RETURN_VALUES_UPDATED_NEW,
                                 parser.Values.RETURN_VALUES_ALL_NEW):

                select_result = storage.select_item(
                    self.context, table_name,
                    indexed_condition_map_for_select)

            # format response
            response = {}

            if return_values != parser.Values.RETURN_VALUES_NONE:
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(
                        select_result.items[0])
                )

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key")
                        )
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None
                    )
                )

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 18
0
    def query(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            index_name = body.pop(parser.Props.INDEX_NAME, None)
            if index_name is not None:
                validation.validate_index_name(index_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    if index_name is not None:
                        select = models.SelectType.SELECT_TYPE_ALL_PROJECTED
                    else:
                        select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)

            select_type = models.SelectType(select, attributes_to_get)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)

            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json
                    )
                )
            else:
                exclusive_start_key_attributes = None

            # parse indexed_condition_map
            key_conditions = body.pop(parser.Props.KEY_CONDITIONS, None)
            validation.validate_object(key_conditions,
                                       parser.Props.KEY_CONDITIONS)

            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                key_conditions, condition_class=IndexedCondition
            )

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = body.pop(parser.Props.CONSISTENT_READ, False)
            validation.validate_boolean(consistent_read,
                                        parser.Props.CONSISTENT_READ)
            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit, parser.Props.LIMIT,
                                                    min_val=0)

            scan_forward = body.pop(parser.Props.SCAN_INDEX_FORWARD, None)

            if scan_forward is not None:
                validation.validate_boolean(scan_forward,
                                            parser.Props.SCAN_INDEX_FORWARD)
                order_type = (
                    models.ORDER_TYPE_ASC if scan_forward else
                    models.ORDER_TYPE_DESC
                )
            else:
                order_type = None

            validation.validate_unexpected_props(body, "body")

        # select item
        result = storage.select_item(
            req.context, table_name, indexed_condition_map,
            select_type=select_type, index_name=index_name, limit=limit,
            consistent=consistent_read, order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes
        )

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {
                parser.Props.COUNT: result.count
            }
        else:
            response = {
                parser.Props.COUNT: result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key)
            )

        return response
Ejemplo n.º 19
0
    def query(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        jsonschema.validate(body, self.schema)
        req.context.tenant = project_id

        # parse select_type
        attributes_to_get = body.get(parser.Props.ATTRIBUTES_TO_GET)

        if attributes_to_get is not None:
            attributes_to_get = frozenset(attributes_to_get)

        select = body.get(parser.Props.SELECT)

        index_name = body.get(parser.Props.INDEX_NAME)

        select_type = parser.Parser.parse_select_type(select,
                                                      attributes_to_get,
                                                      index_name)

        # parse exclusive_start_key_attributes
        exclusive_start_key_attributes = body.get(
            parser.Props.EXCLUSIVE_START_KEY)

        if exclusive_start_key_attributes is not None:
            exclusive_start_key_attributes = (
                parser.Parser.parse_item_attributes(
                    exclusive_start_key_attributes))

        # parse indexed_condition_map
        indexed_condition_map = parser.Parser.parse_attribute_conditions(
            body.get(parser.Props.KEY_CONDITIONS))

        # TODO(dukhlov):
        # it would be nice to validate given table_name, key_attributes and
        # attributes_to_get to schema expectation

        consistent_read = body.get(parser.Props.CONSISTENT_READ, False)

        limit = body.get(parser.Props.LIMIT)

        order_asc = body.get(parser.Props.SCAN_INDEX_FORWARD)

        if order_asc is None:
            order_type = None
        elif order_asc:
            order_type = models.ORDER_TYPE_ASC
        else:
            order_type = models.ORDER_TYPE_DESC

        # select item
        result = storage.select_item(
            req.context,
            table_name,
            indexed_condition_map,
            select_type=select_type,
            index_name=index_name,
            limit=limit,
            consistent=consistent_read,
            order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes)

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {parser.Props.COUNT: result.count}
        else:
            response = {
                parser.Props.COUNT:
                result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key))

        return response
Ejemplo n.º 20
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})))

            #parse attribute updates
            attribute_updates = parser.Parser.parse_attribute_updates(
                self.action_params.get(parser.Props.ATTRIBUTE_UPDATES, {}))

            # parse key
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE)

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            select_result = None

            indexed_condition_map_for_select = {
                name: models.IndexedCondition.eq(value)
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            if return_values in (parser.Values.RETURN_VALUES_UPDATED_OLD,
                                 parser.Values.RETURN_VALUES_ALL_OLD):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # update item
            result = storage.update_item(
                self.context,
                table_name,
                key_attribute_map=key_attributes,
                attribute_action_map=attribute_updates,
                expected_condition_map=expected_item_conditions)

            if not result:
                raise exception.AWSErrorResponseException()

            if return_values in (parser.Values.RETURN_VALUES_UPDATED_NEW,
                                 parser.Values.RETURN_VALUES_ALL_NEW):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # format response
            response = {}

            if return_values != parser.Values.RETURN_VALUES_NONE:
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(
                        select_result.items[0]))

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key"))
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()