8000 add error replacement for DynamoDBStreams v2 (#11887) · localstack/localstack@ac6f897 · GitHub
[go: up one dir, main page]

Skip to content

Commit ac6f897

Browse files
authored
add error replacement for DynamoDBStreams v2 (#11887)
1 parent 7c2d1e3 commit ac6f897

File tree

6 files changed

+53
-3
lines changed

6 files changed

+53
-3
lines changed

localstack-core/localstack/services/dynamodb/utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
r'("TableArn"|"LatestStreamArn"|"StreamArn"|"ShardIterator")\s*:\s*"arn:[a-z-]+:dynamodb:ddblocal:000000000000:([^"]+)"'
3737
)
3838
_ddb_local_region_pattern = re.compile(r'"awsRegion"\s*:\s*"([^"]+)"')
39+
_ddb_local_exception_arn_pattern = re.compile(r'arn:[a-z-]+:dynamodb:ddblocal:000000000000:([^"]+)')
3940

4041

4142
def get_ddb_access_key(account_id: str, region_name: str) -> str:
@@ -318,10 +319,10 @@ def de_dynamize_record(item: dict) -> dict:
318319
def modify_ddblocal_arns(chain, context: RequestContext, response: Response):
319320
"""A service response handler that modifies the dynamodb backend response."""
320321
if response_content := response.get_data(as_text=True):
322+
partition = get_partition(context.region)
321323

322324
def _convert_arn(matchobj):
323325
key = matchobj.group(1)
324-
partition = get_partition(context.region)
325326
table_name = matchobj.group(2)
326327
return f'{key}: "arn:{partition}:dynamodb:{context.region}:{context.account_id}:{table_name}"'
327328

@@ -334,6 +335,11 @@ def _convert_arn(matchobj):
334335
content_replaced = _ddb_local_region_pattern.sub(
335336
f'"awsRegion": "{context.region}"', content_replaced
336337
)
338+
if context.service_exception:
339+
content_replaced = _ddb_local_exception_arn_pattern.sub(
340+
rf"arn:{partition}:dynamodb:{context.region}:{context.account_id}:\g<1>",
341+
content_replaced,
342+
)
337343

338344
if content_replaced != response_content:
339345
response.data = content_replaced

localstack-core/localstack/services/dynamodbstreams/provider.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ def describe_stream(
9292
stream_description = select_from_typed_dict(StreamDescription, stream)
9393
return DescribeStreamOutput(StreamDescription=stream_description)
9494

95-
raise ResourceNotFoundException(f"Stream {stream_arn} was not found.")
95+
raise ResourceNotFoundException(
96+
f"Requested resource not found: Stream: {stream_arn} not found"
97+
)
9698

9799
@handler("GetRecords", expand=False)
98100
def get_records(self, context: RequestContext, payload: GetRecordsInput) -> GetRecordsOutput:

localstack-core/localstack/services/dynamodbstreams/v2/provider.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ def on_after_init(self):
3030
# add response processor specific to ddblocal
3131
handlers.modify_service_response.append(self.service, modify_ddblocal_arns)
3232

33+
def on_before_start(self):
34+
self.server.start_dynamodb()
35+
3336
def forward_request(
3437
self, context: RequestContext, service_request: ServiceRequest = None
3538
) -> ServiceResponse:

tests/aws/services/dynamodbstreams/test_dynamodb_streams.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33

44
import aws_cdk as cdk
55
import pytest
6+
from botocore.exceptions import ClientError
67

78
from localstack import config
89
from localstack.testing.aws.util import is_aws_cloud
910
from localstack.testing.pytest import markers
10-
from localstack.utils.aws import resources
11+
from localstack.utils.aws import arns, resources
1112
from localstack.utils.aws.arns import kinesis_stream_arn
1213
from localstack.utils.aws.queries import kinesis_get_latest_records
1314
from localstack.utils.strings import short_uid
@@ -185,3 +186,22 @@ def _receive_records():
185186
assert len(records[0]["PartitionKey"]) == 32
186187
assert int(records[0]["PartitionKey"], 16)
187188
snapshot.match("result-records", records)
189+
190+
@markers.aws.validated
191+
def test_non_existent_stream(self, aws_client, region_name, account_id, snapshot):
192+
table_name = f"non-existent-{short_uid()}"
193+
snapshot.add_transformer(snapshot.transform.regex(table_name, "<table-name>"))
194+
with pytest.raises(ClientError) as e:
195+
bad_stream_name = arns.dynamodb_stream_arn(
196+
account_id=account_id,
197+
region_name=region_name,
198+
latest_stream_label="2024-11-18T14:36:44.149",
199+
table_name=table_name,
200+
)
201+
aws_client.dynamodbstreams.describe_stream(StreamArn=bad_stream_name)
202+
203+
snapshot.match("non-existent-stream", e.value.response)
204+
message = e.value.response["Error"]["Message"]
205+
# assert that we do not have ddblocal region and default account id
206+
assert f":{account_id}:" in message
207+
assert f":{region_name}" in message

tests/aws/services/dynamodbstreams/test_dynamodb_streams.snapshot.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,21 @@
8181
}
8282
}
8383
}
84+
},
85+
"tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_non_existent_stream": {
86+
"recorded-date": "20-11-2024, 11:02:24",
87+
"recorded-content": {
88+
"non-existent-stream": {
89+
"Error": {
90+
"Code": "ResourceNotFoundException",
91+
"Message": "Requested resource not found: Stream: arn:<partition>:dynamodb:<region>:111111111111:table/<table-name>/stream/2024-11-18T14:36:44.149 not found"
92+
},
93+
"message": "Requested resource not found: Stream: arn:<partition>:dynamodb:<region>:111111111111:table/<table-name>/stream/2024-11-18T14:36:44.149 not found",
94+
"ResponseMetadata": {
95+
"HTTPHeaders": {},
96+
"HTTPStatusCode": 400
97+
}
98+
}
99+
}
84100
}
85101
}

tests/aws/services/dynamodbstreams/test_dynamodb_streams.validation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_enable_kinesis_streaming_destination": {
33
"last_validated_date": "2024-01-30T20:27:32+00:00"
44
},
5+
"tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_non_existent_stream": {
6+
"last_validated_date": "2024-11-20T11:02:24+00:00"
7+
},
58
"tests/aws/services/dynamodbstreams/test_dynamodb_streams.py::TestDynamoDBStreams::test_table_v2_stream": {
69
"last_validated_date": "2024-06-12T21:57:48+00:00"
710
}

0 commit comments

Comments
 (0)
0