This commit is contained in:
Bert Blommers 2020-03-12 14:26:23 +00:00
parent caebe222d7
commit 71d3941daf
2 changed files with 204 additions and 255 deletions

View File

@ -833,7 +833,7 @@ class DynamoHandler(BaseResponse):
return json.dumps({"TimeToLiveDescription": ttl_spec}) return json.dumps({"TimeToLiveDescription": ttl_spec})
def transact_get_items(self): def transact_get_items(self):
transact_items = self.body['TransactItems'] transact_items = self.body["TransactItems"]
responses = list() responses = list()
if len(transact_items) > TRANSACTION_MAX_ITEMS: if len(transact_items) > TRANSACTION_MAX_ITEMS:
@ -842,26 +842,32 @@ class DynamoHandler(BaseResponse):
request_id = 268435456 request_id = 268435456
for _ in transact_items: for _ in transact_items:
request_id += 1 request_id += 1
hex_request_id = format(request_id, 'x') hex_request_id = format(request_id, "x")
err_list.append('com.amazonaws.dynamodb.v20120810.TransactGetItem@%s' % hex_request_id) err_list.append(
msg += ', '.join(err_list) "com.amazonaws.dynamodb.v20120810.TransactGetItem@%s"
msg += "'] at 'transactItems' failed to satisfy constraint: " \ % hex_request_id
"Member must have length less than or equal to %s" % TRANSACTION_MAX_ITEMS )
msg += ", ".join(err_list)
msg += (
"'] at 'transactItems' failed to satisfy constraint: "
"Member must have length less than or equal to %s"
% TRANSACTION_MAX_ITEMS
)
return self.error('ValidationException', msg) return self.error("ValidationException", msg)
ret_consumed_capacity = self.body.get('ReturnConsumedCapacity', 'NONE') ret_consumed_capacity = self.body.get("ReturnConsumedCapacity", "NONE")
consumed_capacity = dict() consumed_capacity = dict()
for transact_item in transact_items: for transact_item in transact_items:
table_name = transact_item['Get']['TableName'] table_name = transact_item["Get"]["TableName"]
key = transact_item['Get']['Key'] key = transact_item["Get"]["Key"]
try: try:
item = self.dynamodb_backend.get_item(table_name, key) item = self.dynamodb_backend.get_item(table_name, key)
except ValueError: except ValueError:
er = 'com.amazonaws.dynamodb.v20111205#ResourceNotFoundException' er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
return self.error(er, 'Requested resource not found') return self.error(er, "Requested resource not found")
if not item: if not item:
continue continue
@ -870,25 +876,22 @@ class DynamoHandler(BaseResponse):
responses.append(item_describe) responses.append(item_describe)
table_capacity = consumed_capacity.get(table_name, {}) table_capacity = consumed_capacity.get(table_name, {})
table_capacity['TableName'] = table_name table_capacity["TableName"] = table_name
capacity_units = table_capacity.get('CapacityUnits', 0) + 2.0 capacity_units = table_capacity.get("CapacityUnits", 0) + 2.0
table_capacity['CapacityUnits'] = capacity_units table_capacity["CapacityUnits"] = capacity_units
read_capacity_units = table_capacity.get('ReadCapacityUnits', 0) + 2.0 read_capacity_units = table_capacity.get("ReadCapacityUnits", 0) + 2.0
table_capacity['ReadCapacityUnits'] = read_capacity_units table_capacity["ReadCapacityUnits"] = read_capacity_units
consumed_capacity[table_name] = table_capacity consumed_capacity[table_name] = table_capacity
if ret_consumed_capacity == 'INDEXES': if ret_consumed_capacity == "INDEXES":
table_capacity['Table'] = { table_capacity["Table"] = {
'CapacityUnits': capacity_units, "CapacityUnits": capacity_units,
'ReadCapacityUnits': read_capacity_units "ReadCapacityUnits": read_capacity_units,
} }
result = dict() result = dict()
result.update({ result.update({"Responses": responses})
'Responses': responses}) if ret_consumed_capacity != "NONE":
if ret_consumed_capacity != 'NONE': result.update({"ConsumedCapacity": [v for v in consumed_capacity.values()]})
result.update({
'ConsumedCapacity': [v for v in consumed_capacity.values()]
})
return dynamo_json_dump(result) return dynamo_json_dump(result)

View File

@ -3798,267 +3798,213 @@ def test_query_catches_when_no_filters():
@mock_dynamodb2 @mock_dynamodb2
def test_invalid_transact_get_items(): def test_invalid_transact_get_items():
dynamodb = boto3.resource('dynamodb', region_name='us-east-1') dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
dynamodb.create_table( dynamodb.create_table(
TableName='test1', TableName="test1",
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}], KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{'AttributeName': 'id', 'AttributeType': 'S'}], AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5} ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
table = dynamodb.Table("test1")
table.put_item(
Item={"id": "1", "val": "1",}
) )
table = dynamodb.Table('test1')
table.put_item(Item={
'id': '1',
'val': '1',
})
table.put_item(Item={ table.put_item(
'id': '1', Item={"id": "1", "val": "2",}
'val': '2', )
})
client = boto3.client('dynamodb', region_name='us-east-1') client = boto3.client("dynamodb", region_name="us-east-1")
with assert_raises(ClientError) as ex: with assert_raises(ClientError) as ex:
client.transact_get_items(TransactItems=[ client.transact_get_items(
{'Get': {'Key': {'id': {'S': '1'}}, 'TableName': 'test1'}} for i in range(26) TransactItems=[
]) {"Get": {"Key": {"id": {"S": "1"}}, "TableName": "test1"}}
for i in range(26)
]
)
ex.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400) ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.exception.response['Error']['Message'].should.match( ex.exception.response["Error"]["Message"].should.match(
r'failed to satisfy constraint: Member must have length less than or equal to 25', re.I r"failed to satisfy constraint: Member must have length less than or equal to 25",
re.I,
) )
with assert_raises(ClientError) as ex: with assert_raises(ClientError) as ex:
client.transact_get_items(TransactItems=[ client.transact_get_items(
{ TransactItems=[
'Get': { {"Get": {"Key": {"id": {"S": "1"},}, "TableName": "test1"}},
'Key': { {"Get": {"Key": {"id": {"S": "1"},}, "TableName": "non_exists_table"}},
'id': {'S': '1'}, ]
}, )
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
},
'TableName': 'non_exists_table'
}
}
])
ex.exception.response['Error']['Code'].should.equal('ResourceNotFoundException') ex.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
ex.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400) ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.exception.response['Error']['Message'].should.equal( ex.exception.response["Error"]["Message"].should.equal(
'Requested resource not found' "Requested resource not found"
) )
@mock_dynamodb2 @mock_dynamodb2
def test_valid_transact_get_items(): def test_valid_transact_get_items():
dynamodb = boto3.resource('dynamodb', region_name='us-east-1') dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
dynamodb.create_table( dynamodb.create_table(
TableName='test1', TableName="test1",
KeySchema=[ KeySchema=[
{'AttributeName': 'id', 'KeyType': 'HASH'}, {"AttributeName": "id", "KeyType": "HASH"},
{'AttributeName': 'sort_key', 'KeyType': 'RANGE'}, {"AttributeName": "sort_key", "KeyType": "RANGE"},
], ],
AttributeDefinitions=[ AttributeDefinitions=[
{'AttributeName': 'id', 'AttributeType': 'S'}, {"AttributeName": "id", "AttributeType": "S"},
{'AttributeName': 'sort_key', 'AttributeType': 'S'}, {"AttributeName": "sort_key", "AttributeType": "S"},
], ],
ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5} ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
table1 = dynamodb.Table("test1")
table1.put_item(
Item={"id": "1", "sort_key": "1",}
) )
table1 = dynamodb.Table('test1')
table1.put_item(Item={
'id': '1',
'sort_key': '1',
})
table1.put_item(Item={ table1.put_item(
'id': '1', Item={"id": "1", "sort_key": "2",}
'sort_key': '2', )
})
dynamodb.create_table( dynamodb.create_table(
TableName='test2', TableName="test2",
KeySchema=[ KeySchema=[
{'AttributeName': 'id', 'KeyType': 'HASH'}, {"AttributeName": "id", "KeyType": "HASH"},
{'AttributeName': 'sort_key', 'KeyType': 'RANGE'}, {"AttributeName": "sort_key", "KeyType": "RANGE"},
], ],
AttributeDefinitions=[ AttributeDefinitions=[
{'AttributeName': 'id', 'AttributeType': 'S'}, {"AttributeName": "id", "AttributeType": "S"},
{'AttributeName': 'sort_key', 'AttributeType': 'S'}, {"AttributeName": "sort_key", "AttributeType": "S"},
], ],
ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5} ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
table2 = dynamodb.Table("test2")
table2.put_item(
Item={"id": "1", "sort_key": "1",}
) )
table2 = dynamodb.Table('test2')
table2.put_item(Item={
'id': '1',
'sort_key': '1',
})
client = boto3.client('dynamodb', region_name='us-east-1') client = boto3.client("dynamodb", region_name="us-east-1")
res = client.transact_get_items(TransactItems=[ res = client.transact_get_items(
TransactItems=[
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "non_exists_key"}, "sort_key": {"S": "2"}},
"TableName": "test1",
}
},
]
)
res["Responses"][0]["Item"].should.equal({"id": {"S": "1"}, "sort_key": {"S": "1"}})
len(res["Responses"]).should.equal(1)
res = client.transact_get_items(
TransactItems=[
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "2"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test2",
}
},
]
)
res["Responses"][0]["Item"].should.equal({"id": {"S": "1"}, "sort_key": {"S": "1"}})
res["Responses"][1]["Item"].should.equal({"id": {"S": "1"}, "sort_key": {"S": "2"}})
res["Responses"][2]["Item"].should.equal({"id": {"S": "1"}, "sort_key": {"S": "1"}})
res = client.transact_get_items(
TransactItems=[
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "2"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test2",
}
},
],
ReturnConsumedCapacity="TOTAL",
)
res["ConsumedCapacity"][0].should.equal(
{"TableName": "test1", "CapacityUnits": 4.0, "ReadCapacityUnits": 4.0}
)
res["ConsumedCapacity"][1].should.equal(
{"TableName": "test2", "CapacityUnits": 2.0, "ReadCapacityUnits": 2.0}
)
res = client.transact_get_items(
TransactItems=[
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "2"}},
"TableName": "test1",
}
},
{
"Get": {
"Key": {"id": {"S": "1"}, "sort_key": {"S": "1"}},
"TableName": "test2",
}
},
],
ReturnConsumedCapacity="INDEXES",
)
res["ConsumedCapacity"][0].should.equal(
{ {
'Get': { "TableName": "test1",
'Key': { "CapacityUnits": 4.0,
'id': {'S': '1'}, "ReadCapacityUnits": 4.0,
'sort_key': {'S': '1'} "Table": {"CapacityUnits": 4.0, "ReadCapacityUnits": 4.0,},
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': 'non_exists_key'},
'sort_key': {'S': '2'}
},
'TableName': 'test1'
}
} }
]) )
res['Responses'][0]['Item'].should.equal({
'id': {'S': '1'},
'sort_key': {'S': '1'}
})
len(res['Responses']).should.equal(1)
res = client.transact_get_items(TransactItems=[ res["ConsumedCapacity"][1].should.equal(
{ {
'Get': { "TableName": "test2",
'Key': { "CapacityUnits": 2.0,
'id': {'S': '1'}, "ReadCapacityUnits": 2.0,
'sort_key': {'S': '1'} "Table": {"CapacityUnits": 2.0, "ReadCapacityUnits": 2.0,},
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '2'}
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '1'}
},
'TableName': 'test2'
}
},
])
res['Responses'][0]['Item'].should.equal({
'id': {'S': '1'},
'sort_key': {'S': '1'}
})
res['Responses'][1]['Item'].should.equal({
'id': {'S': '1'},
'sort_key': {'S': '2'}
})
res['Responses'][2]['Item'].should.equal({
'id': {'S': '1'},
'sort_key': {'S': '1'}
})
res = client.transact_get_items(TransactItems=[
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '1'}
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '2'}
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '1'}
},
'TableName': 'test2'
}
},
], ReturnConsumedCapacity='TOTAL')
res['ConsumedCapacity'][0].should.equal({
'TableName': 'test1',
'CapacityUnits': 4.0,
'ReadCapacityUnits': 4.0
})
res['ConsumedCapacity'][1].should.equal({
'TableName': 'test2',
'CapacityUnits': 2.0,
'ReadCapacityUnits': 2.0
})
res = client.transact_get_items(TransactItems=[
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '1'}
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '2'}
},
'TableName': 'test1'
}
},
{
'Get': {
'Key': {
'id': {'S': '1'},
'sort_key': {'S': '1'}
},
'TableName': 'test2'
}
},
], ReturnConsumedCapacity='INDEXES')
res['ConsumedCapacity'][0].should.equal({
'TableName': 'test1',
'CapacityUnits': 4.0,
'ReadCapacityUnits': 4.0,
'Table': {
'CapacityUnits': 4.0,
'ReadCapacityUnits': 4.0,
} }
}) )
res['ConsumedCapacity'][1].should.equal({
'TableName': 'test2',
'CapacityUnits': 2.0,
'ReadCapacityUnits': 2.0,
'Table': {
'CapacityUnits': 2.0,
'ReadCapacityUnits': 2.0,
}
})