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()
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()
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()
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()
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()
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
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()
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()
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()
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
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
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()
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
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()
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
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()
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()
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
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
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()