From 541e9cce0e625fed83eec1d5efc1eecf75cd9ef7 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Wed, 24 Jan 2024 08:52:11 -0800 Subject: [PATCH 01/14] testing poc --- .../utilities/data_classes/common.py | 24 ++++++++- .../utilities/data_classes/poc.py | 49 +++++++++++++++++++ .../utilities/data_classes/s3_event.py | 12 ++--- .../utilities/data_classes/sns_event.py | 6 +-- .../utilities/data_classes/sqs_event.py | 9 ++-- 5 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 aws_lambda_powertools/utilities/data_classes/poc.py diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index d2cf57d4af5..49e632a62a0 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -1,7 +1,7 @@ import base64 import json from collections.abc import Mapping -from typing import Any, Callable, Dict, Iterator, List, Optional, overload +from typing import Any, Callable, Dict, Iterator, List, Optional, overload, Type, TypeVar from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer from aws_lambda_powertools.utilities.data_classes.shared_functions import ( @@ -93,6 +93,28 @@ def raw_event(self) -> Dict[str, Any]: """The original raw event dict""" return self._data +class EventWrapper(DictWrapper): + NestedEvent = TypeVar("NestedEvent", bound=DictWrapper) + @property + def nested_event_contents(self): + for record in self["Records"]: + yield record["body"] + + # @property + def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): + if nested_event_content_deserializer is None: + nested_event_content_deserializer = self._json_deserializer + + for content in self.nested_event_contents: + yield nested_event_class(nested_event_content_deserializer(content)) + + # @property + def decode_nested_event(self, nested_event_class, nested_event_content_deserializer = None): + if nested_event_content_deserializer is None: + nested_event_content_deserializer = self._json_deserializer + + for content in self.nested_event_contents: + return nested_event_class(nested_event_content_deserializer(content)) class BaseProxyEvent(DictWrapper): @property diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py new file mode 100644 index 00000000000..141123d4c96 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -0,0 +1,49 @@ +import json + +from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent +# from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage +from aws_lambda_powertools.utilities.data_classes import event_source + + +# @event_source(data_class=SQSEvent) +def lambda_handler(event: SQSEvent, context): + event = SQSEvent(event) + nesteds3event = event.decode_nested_events(S3Event) + for record in event.records: #then how would a for loop work.. + nested_event = record.decode_nested_event(S3Event) #for loop must be for same events inside one event + print(nested_event, nested_event) + + # event = SQSEvent() + # sns_events = event.decode_nested_events(Iterator[SNSEvent]) + # for sns_event in sns_events: + # s3_events = sns_event.decode_nested_events(S3Event) + # for s3_event in s3_events: + # print(s3_event.bucket.name) + + + + +event = SQSEvent({ + "Records": [ + { + "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", + "receiptHandle": "MessageReceiptHandle", + "body": { + "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-01T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id\",\"x-amz-id-2\":\"example-id\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object.txt\",\"size\":1024,\"eTag\":\"example-tag\",\"versionId\":\"1\",\"sequencer\":\"example-sequencer\"}}}]}" + }, + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1523232000000", + "SenderId": "123456789012", + "ApproximateFirstReceiveTimestamp": "1523232000001" + }, + "messageAttributes": {}, + "md5OfBody": "7b270e59b47ff90a553787216d55d91d", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", + "awsRegion": "us-east-1" + } + ] +}) + +lambda_handler(event, {}) diff --git a/aws_lambda_powertools/utilities/data_classes/s3_event.py b/aws_lambda_powertools/utilities/data_classes/s3_event.py index 802f1663edb..1546e86f4d1 100644 --- a/aws_lambda_powertools/utilities/data_classes/s3_event.py +++ b/aws_lambda_powertools/utilities/data_classes/s3_event.py @@ -1,7 +1,7 @@ from typing import Dict, Iterator, Optional from urllib.parse import unquote_plus -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper from aws_lambda_powertools.utilities.data_classes.event_bridge_event import ( EventBridgeEvent, ) @@ -151,7 +151,7 @@ def detail(self) -> S3EventBridgeNotificationDetail: # type: ignore[override] return S3EventBridgeNotificationDetail(self["detail"]) -class S3Bucket(DictWrapper): +class S3Bucket(EventWrapper): @property def name(self) -> str: return self["s3"]["bucket"]["name"] @@ -165,7 +165,7 @@ def arn(self) -> str: return self["s3"]["bucket"]["arn"] -class S3Object(DictWrapper): +class S3Object(EventWrapper): @property def key(self) -> str: """Object key""" @@ -194,7 +194,7 @@ def sequencer(self) -> str: return self["s3"]["object"]["sequencer"] -class S3Message(DictWrapper): +class S3Message(EventWrapper): @property def s3_schema_version(self) -> str: return self["s3"]["s3SchemaVersion"] @@ -237,7 +237,7 @@ def restore_event_data(self) -> S3EventRecordGlacierRestoreEventData: return S3EventRecordGlacierRestoreEventData(self._data) -class S3EventRecord(DictWrapper): +class S3EventRecord(EventWrapper): @property def event_version(self) -> str: """The eventVersion key value contains a major and minor version in the form ..""" @@ -293,7 +293,7 @@ def glacier_event_data(self) -> Optional[S3EventRecordGlacierEventData]: return None if item is None else S3EventRecordGlacierEventData(item) -class S3Event(DictWrapper): +class S3Event(EventWrapper): """S3 event notification Documentation: diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index 5d29d682ef2..cb05a5d7743 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -1,6 +1,6 @@ from typing import Dict, Iterator -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper class SNSMessageAttribute(DictWrapper): @@ -16,7 +16,7 @@ def value(self) -> str: return self["Value"] -class SNSMessage(DictWrapper): +class SNSMessage(EventWrapper): @property def signature_version(self) -> str: """Version of the Amazon SNS signature used.""" @@ -99,7 +99,7 @@ def sns(self) -> SNSMessage: return SNSMessage(self._data["Sns"]) -class SNSEvent(DictWrapper): +class SNSEvent(EventWrapper): """SNS Event Documentation: diff --git a/aws_lambda_powertools/utilities/data_classes/sqs_event.py b/aws_lambda_powertools/utilities/data_classes/sqs_event.py index ffec9854a2e..4737b44bc28 100644 --- a/aws_lambda_powertools/utilities/data_classes/sqs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sqs_event.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Iterator, Optional, Type, TypeVar from aws_lambda_powertools.utilities.data_classes import S3Event -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage @@ -82,10 +82,10 @@ def __getitem__(self, key: str) -> Optional[SQSMessageAttribute]: # type: ignor return None if item is None else SQSMessageAttribute(item) # type: ignore -class SQSRecord(DictWrapper): +class SQSRecord(EventWrapper): """An Amazon SQS message""" - NestedEvent = TypeVar("NestedEvent", bound=DictWrapper) + NestedEvent = TypeVar("NestedEvent", bound=EventWrapper) @property def message_id(self) -> str: @@ -236,7 +236,7 @@ def _decode_nested_event(self, nested_event_class: Type[NestedEvent]) -> NestedE return nested_event_class(self.json_body) -class SQSEvent(DictWrapper): +class SQSEvent(EventWrapper): """SQS Event Documentation: @@ -246,5 +246,6 @@ class SQSEvent(DictWrapper): @property def records(self) -> Iterator[SQSRecord]: + print("in here!!") for record in self["Records"]: yield SQSRecord(data=record, json_deserializer=self._json_deserializer) From 0e76edbb99bd91bb9b97f96c426841e71c40bcf2 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Tue, 26 Mar 2024 15:04:47 -0700 Subject: [PATCH 02/14] Added sample nested test events, parent class for unwrapping, and custom logic for unwrapping some events --- .../utilities/data_classes/common.py | 31 ++- .../data_classes/event_bridge_event.py | 6 + .../data_classes/kinesis_firehose_event.py | 11 +- .../utilities/data_classes/poc.py | 116 ++++---- .../utilities/data_classes/ses_event.py | 11 +- .../utilities/data_classes/sns_event.py | 7 + .../utilities/data_classes/sqs_event.py | 1 - .../utilities/data_classes/test_events.py | 258 ++++++++++++++++++ 8 files changed, 377 insertions(+), 64 deletions(-) create mode 100644 aws_lambda_powertools/utilities/data_classes/test_events.py diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 0add415dc5f..73a28f24c1d 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -94,28 +94,35 @@ def raw_event(self) -> Dict[str, Any]: return self._data class EventWrapper(DictWrapper): + NestedEvent = TypeVar("NestedEvent", bound=DictWrapper) - @property + + def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = None): + """ + Parameters + ---------- + data : Dict[str, Any] + Lambda Event Source Event payload + json_deserializer : Callable, optional + function to deserialize `str`, `bytes`, `bytearray` + containing a JSON document to a Python `obj`, + by default json.loads + """ + super().__init__(data, json_deserializer) + def nested_event_contents(self): for record in self["Records"]: - yield record["body"] + body = record['body'] + yield body + - # @property def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): if nested_event_content_deserializer is None: nested_event_content_deserializer = self._json_deserializer - for content in self.nested_event_contents: + for content in self.nested_event_contents(): yield nested_event_class(nested_event_content_deserializer(content)) - # @property - def decode_nested_event(self, nested_event_class, nested_event_content_deserializer = None): - if nested_event_content_deserializer is None: - nested_event_content_deserializer = self._json_deserializer - - for content in self.nested_event_contents: - return nested_event_class(nested_event_content_deserializer(content)) - class BaseProxyEvent(DictWrapper): @property def headers(self) -> Dict[str, str]: diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index bdbf9d68afa..a8f61126365 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -67,3 +67,9 @@ def detail(self) -> Dict[str, Any]: def replay_name(self) -> Optional[str]: """Identifies whether the event is being replayed and what is the name of the replay.""" return self["replay-name"] + + def nested_event_contents(self): + for record in self["detail"]: + print('record', record, type(record)) + # print('body:', body, type(body)) + yield record diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 3e5db8cb9d8..46dfc94e8ed 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -6,7 +6,7 @@ from typing_extensions import Literal -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper @dataclass(repr=False, order=False, frozen=True) @@ -274,7 +274,7 @@ def build_data_transformation_response( ) -class KinesisFirehoseEvent(DictWrapper): +class KinesisFirehoseEvent(EventWrapper): """Kinesis Data Firehose event Documentation: @@ -306,3 +306,10 @@ def region(self) -> str: def records(self) -> Iterator[KinesisFirehoseRecord]: for record in self["records"]: yield KinesisFirehoseRecord(data=record, json_deserializer=self._json_deserializer) + + def nested_event_contents(self): + for record in self["records"]: + # print('record', record, type(record)) + # body = record[] + # print('body:', body, type(body)) + yield record diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index 141123d4c96..e10668b631c 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -1,49 +1,71 @@ +from typing import Iterator import json +from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, SESEvent, EventBridgeEvent +import test_events -from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent -# from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage -from aws_lambda_powertools.utilities.data_classes import event_source - - -# @event_source(data_class=SQSEvent) -def lambda_handler(event: SQSEvent, context): - event = SQSEvent(event) - nesteds3event = event.decode_nested_events(S3Event) - for record in event.records: #then how would a for loop work.. - nested_event = record.decode_nested_event(S3Event) #for loop must be for same events inside one event - print(nested_event, nested_event) - - # event = SQSEvent() - # sns_events = event.decode_nested_events(Iterator[SNSEvent]) - # for sns_event in sns_events: - # s3_events = sns_event.decode_nested_events(S3Event) - # for s3_event in s3_events: - # print(s3_event.bucket.name) - - - - -event = SQSEvent({ - "Records": [ - { - "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", - "receiptHandle": "MessageReceiptHandle", - "body": { - "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-01T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id\",\"x-amz-id-2\":\"example-id\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object.txt\",\"size\":1024,\"eTag\":\"example-tag\",\"versionId\":\"1\",\"sequencer\":\"example-sequencer\"}}}]}" - }, - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1523232000000", - "SenderId": "123456789012", - "ApproximateFirstReceiveTimestamp": "1523232000001" - }, - "messageAttributes": {}, - "md5OfBody": "7b270e59b47ff90a553787216d55d91d", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", - "awsRegion": "us-east-1" - } - ] -}) - -lambda_handler(event, {}) + +def lambda_handler_sqs_s3(event: SQSEvent = test_events.sqs_s3_event): # sqs(s3) + sqs_event = SQSEvent(event) + s3_event = sqs_event.decode_nested_events(S3Event) + for rec in s3_event: + print('rec:', rec.bucket_name) + # for sqs_record in sqs_event.records: + # # print('body in main:', sqs_record.body) + # # s3_event = sqs_event.decode_nested_events(Iterator[S3Event]) # is this correct format? + # s3_event = sqs_event.decode_nested_events(S3Event) + # for rec in s3_event: + # print('rec:', rec.bucket_name) + # print(next(s3_event).bucket_name) # use this if not inside a for loop + + +def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(sns) + sqs_event = SQSEvent(event) + sns_event = sqs_event.decode_nested_events(SNSEvent) + for rec in sns_event: + print('rec:', type(rec), rec.sns_message) + + +def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3) + sns_event = SNSEvent(event) + s3_event = sns_event.decode_nested_events(S3Event) + for rec in s3_event: + print(type(rec)) + print('rec:', rec.bucket_name) + + +def lambda_handler_sqs_s3_multi(event: SQSEvent = test_events.sqs_s3_multi_event): # sqs(s3, s3) + sqs_event = SQSEvent(event) + s3_event = sqs_event.decode_nested_events(S3Event) + for rec in s3_event: + print('rec:', rec.bucket_name) + + +def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # sqs(sns(s3)) + sqs_event = SQSEvent(event) + sns_event = sqs_event.decode_nested_events(SNSEvent) + for rec in sns_event: + print('rec:', type(rec), rec.sns_message) + # s3_event = sns_event.decode_nested_events(S3Event) + + +def lambda_handler_sns_ses(event: SNSEvent = test_events.sns_ses_event): # sns(ses) + sns_event = SNSEvent(event) + ses_event = sns_event.decode_nested_events(SESEvent) + for rec in ses_event: + print(type(rec)) + print('rec:', rec.get("mail").get('source')) #but can't do rec.mail bc no "Records" key.. + +def lambda_handler_eb_s3(event: EventBridgeEvent = test_events.eb_s3_event): # eventbridge(s3) + eb_event = EventBridgeEvent(event) + s3_event = eb_event.decode_nested_events(S3Event) + for rec in s3_event: + print(type(rec)) + print('rec:', rec) + +lambda_handler_sqs_s3(test_events.sqs_s3_event) +# lambda_handler_sqs_sns(test_events.sqs_sns_event) #not working bc sns doesn't have Records key +lambda_handler_sns_s3(test_events.sns_s3_event) +lambda_handler_sqs_s3_multi(test_events.sqs_s3_multi_event) +# lambda_handler_sqs_sns_s3(test_events.sqs_sns_s3_event) #not working bc sns doesn't have Records key +lambda_handler_sns_ses(test_events.sns_ses_event) +# lambda_handler_eb_s3(test_events.eb_s3_event) #EB returning a str, not dict diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index 2ebc02e22a0..2049bd21a1f 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -1,6 +1,6 @@ from typing import Iterator, List, Optional -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper class SESMailHeader(DictWrapper): @@ -233,7 +233,7 @@ def ses(self) -> SESMessage: return SESMessage(self._data) -class SESEvent(DictWrapper): +class SESEvent(EventWrapper): """Amazon SES to receive message event trigger NOTE: There is a 30-second timeout on RequestResponse invocations. @@ -260,3 +260,10 @@ def mail(self) -> SESMail: @property def receipt(self) -> SESReceipt: return self.record.ses.receipt + + def nested_event_contents(self): + for record in self["Records"]: + # print('record', record, type(record)) + body = record['ses'] + # print('body:', body, type(body)) + yield body diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index cb05a5d7743..4d50de2dc54 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -121,3 +121,10 @@ def record(self) -> SNSEventRecord: def sns_message(self) -> str: """Return the message for the first sns event record""" return self.record.sns.message + + def nested_event_contents(self): + for record in self["Records"]: + # print('record', record, type(record)) + body = record['Sns']['Message'] + # print('body:', body, type(body)) + yield body diff --git a/aws_lambda_powertools/utilities/data_classes/sqs_event.py b/aws_lambda_powertools/utilities/data_classes/sqs_event.py index 4737b44bc28..d3ced279d7c 100644 --- a/aws_lambda_powertools/utilities/data_classes/sqs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sqs_event.py @@ -246,6 +246,5 @@ class SQSEvent(EventWrapper): @property def records(self) -> Iterator[SQSRecord]: - print("in here!!") for record in self["Records"]: yield SQSRecord(data=record, json_deserializer=self._json_deserializer) diff --git a/aws_lambda_powertools/utilities/data_classes/test_events.py b/aws_lambda_powertools/utilities/data_classes/test_events.py new file mode 100644 index 00000000000..81754892913 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_classes/test_events.py @@ -0,0 +1,258 @@ +# kinesis stream -> firehose -> s3 -> lambda: not working ie the event generated is just s3, nothing is nested... + +# s3 -> sns -> firehose -> lambda: sns not sending messages to firehose for some reason :( +# working -> ?? -> working? i see test data in CW + + +# ses -> sns -> lambda = sns(ses) +sns_ses_event = { + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", + "Sns": { + "Type": "Notification", + "MessageId": "14cc1773-477c-51e2-8b02-490f43dd19a3", + "TopicArn": "arn:aws:sns:us-east-1:683517028648:ses-sns", + "Subject": "Amazon SES Email Event Notification", + "Message": "{\"eventType\":\"Send\",\"mail\":{\"timestamp\":\"2024-03-25T23:01:53.733Z\",\"source\":\"seshub@amazon.com\",\"sourceArn\":\"arn:aws:ses:us-east-1:683517028648:identity/seshub@amazon.com\",\"sendingAccountId\":\"683517028648\",\"messageId\":\"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000\",\"destination\":[\"success@simulator.amazonses.com\"],\"headersTruncated\":false,\"headers\":[{\"name\":\"From\",\"value\":\"seshub@amazon.com\"},{\"name\":\"To\",\"value\":\"success@simulator.amazonses.com\"},{\"name\":\"Subject\",\"value\":\"subject test from ses!!!!\"},{\"name\":\"MIME-Version\",\"value\":\"1.0\"},{\"name\":\"Content-Type\",\"value\":\"multipart/alternative; boundary=\\\"----=_Part_467214_1288460597.1711407713733\\\"\"}],\"commonHeaders\":{\"from\":[\"seshub@amazon.com\"],\"to\":[\"success@simulator.amazonses.com\"],\"messageId\":\"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000\",\"subject\":\"subject test from ses!!!!\"},\"tags\":{\"ses:source-tls-version\":[\"TLSv1.3\"],\"ses:operation\":[\"SendEmail\"],\"ses:configuration-set\":[\"my-first-configuration-set\"],\"ses:source-ip\":[\"15.248.7.48\"],\"ses:from-domain\":[\"amazon.com\"],\"ses:caller-identity\":[\"Admin\"]}},\"send\":{}}\n", + "Timestamp": "2024-03-25T23:01:53.935Z", + "SignatureVersion": "1", + "Signature": "DRfrfPLo2KTGw/GweWUe2uGgK8jhwac1OQQq1HJ3Bo7HFEBDp4c6AjUyoYAGQYzKskxXSJBYJyrj9B3WOU7OPisM/b7+eLWjtRNohIM5B/yzrveQRV8W4GwjX0JpdC247VZB9Z01D+M01kVYVwiOO50lS/kpLrAnGksrdmGnF2Z2FQuh6mh8bCpQgoz1xTXUF94hqR6Tuj2R+bYNWxkCEZ18rg8FgrQfaonxiM/R5J1CjMW8P8KAP4nSdeBUAgFBXG8W72V1gSbjIH7a4uOyGZfFPooQZ4EUd9/eC6VlcxvjwwVmy0/x5oE2mHDU/s7NulOafTKTTA/V4/xFp6yqbQ==", + "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", + "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", + "MessageAttributes": {} + } + } + ] +} + + +# s3 -> eventbridge -> sqs -> lambda = sqs(eventbridge(s3)) +sqs_eb_s3_event = { + "Records": [ + { + "messageId": "ee95829a-ba32-471d-9684-34368ab9995e", + "receiptHandle": "AQEBZoMhwYaEfxvSOWGnwMurMIe2sEkwsV9l5e+pDpa2zCtdWLBfbUNxIX5R8O9hx+jAXhpj01bHElvli+LtPNBJarb4V+JEg2Hql3lSdkISTEECrWc8Dm8eX+p+LeyoN9cSnfDUoqQ2rd/BSFt9/vk6ro+w/kM8G1q7Lt1PB6G51LbfzXYA+KYUPLWIeYK2NMDf8TyvC0PbERE6im9H+eqJznyPWNznfziwq7d6ZIpY3GSfRrED/0tfr3FvzIVCVsOBuPHyd5stqcrgkCs2Dt/f7DWYWr1KMSqFDM1u4S7wMIroCVSfe9wsqimLBwaHZcG1zukaW16c51TiRI3zNzOl3cuDZgqPAK1rQKsj3x+VLqxnbyIgx24oIKhh5XqcZfzRbBwX4HDF/Opv8cN16+0yTw==", + "body": "{\"version\":\"0\",\"id\":\"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4\",\"detail-type\":\"Object Created\",\"source\":\"aws.s3\",\"account\":\"683517028648\",\"time\":\"2024-03-26T18:05:54Z\",\"region\":\"us-east-1\",\"resources\":[\"arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"],\"detail\":{\"version\":\"0\",\"bucket\":{\"name\":\"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"},\"object\":{\"key\":\"__init__.py\",\"size\":0,\"etag\":\"d41d8cd98f00b204e9800998ecf8427e\",\"sequencer\":\"0066030E82E2A48DFE\"},\"request-id\":\"HWEZ4KKQMXVWATHJ\",\"requester\":\"683517028648\",\"source-ip-address\":\"15.248.7.0\",\"reason\":\"PutObject\"}}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1711476356070", + "SenderId": "AIDAJXNJGGKNS7OSV23OI", + "ApproximateFirstReceiveTimestamp": "1711476356085" + }, + "messageAttributes": {}, + "md5OfBody": "3fc2529293127eb705317a37dca18ef4", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:s3-eb-sqs-unwrap", + "awsRegion": "us-east-1" + } + ] +} + + + +# s3 -> eventbridge -> lambda = eventbridge(s3) +eb_s3_event = { + "version": "0", + "id": "78eac3e6-798f-c27e-49ec-bbe3be7bab7d", + "detail-type": "Object Created", + "source": "aws.s3", + "account": "683517028648", + "time": "2024-03-20T23:56:16Z", + "region": "us-east-1", + "resources": [ + "arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + ], + "detail": { + "version": "0", + "bucket": { + "name": "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + }, + "object": { + "key": "s3-eb-template.yaml", + "size": 1565, + "etag": "e56e21b1610dd94e9907f82b8d05b934", + "sequencer": "0065FB77A03AD4478F" + }, + "request-id": "SW5MRVMJG8NG1GMZ", + "requester": "683517028648", + "source-ip-address": "72.21.198.69", + "reason": "PutObject" + } +} + + +# in unwrap CF stack: s3 -> sns -> sqs -> lambda = sqs(sns(s3)) +sqs_sns_s3_event = { + "Records": [ + { + "messageId": "45405be4-2278-4eef-a29c-993898bb8917", + "receiptHandle": "AQEBy2gRrluag0E0vWiKlHZhcf6Ymtgkf92PlWtTQ4PKOPdF3NcUqKEzKtKbiTN7d+qy64nN3F97DOQr9b4xegJidHlXlyIwsYxQIpmGfDETCKPS5nchXOWRLIu/a/bpCmaZK/Mv1r6lAaF2gnoX7JaVpdTbExLRBQqOIcb2NRXmfeE0yKZtIT0TV9pstzsAi328KGbr1QMKOV0RKrE1NtQDpa/ixeEUWrZeGqwA7Cwy0BMevfoQKVkO78JrDsn4W/lUt2R+oRF7sB62+onfbIlBPmi+LXV4WeSrB7w1yvnMbVuvfgHDS9F1LEs62wJTNVQz6224s3OBfJZsAaSpW1IzD+UttqFJ3KTadu6HZMbCq+I2An+cQjqZ3zDsEV7Vwm6LH+04RGA3b9edBLgIoMbfcg==", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"53c941f5-1d7a-5f8e-8ffe-1f8110f6e667\",\n \"TopicArn\" : \"arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op\",\n \"Subject\" : \"Amazon S3 Notification\",\n \"Message\" : \"{\\\"Records\\\":[{\\\"eventVersion\\\":\\\"2.1\\\",\\\"eventSource\\\":\\\"aws:s3\\\",\\\"awsRegion\\\":\\\"us-west-2\\\",\\\"eventTime\\\":\\\"2024-03-19T22:01:47.135Z\\\",\\\"eventName\\\":\\\"ObjectCreated:Put\\\",\\\"userIdentity\\\":{\\\"principalId\\\":\\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\\"},\\\"requestParameters\\\":{\\\"sourceIPAddress\\\":\\\"205.251.233.178\\\"},\\\"responseElements\\\":{\\\"x-amz-request-id\\\":\\\"02TFARRDG75KXGG6\\\",\\\"x-amz-id-2\\\":\\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\\"},\\\"s3\\\":{\\\"s3SchemaVersion\\\":\\\"1.0\\\",\\\"configurationId\\\":\\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\\",\\\"bucket\\\":{\\\"name\\\":\\\"unwraptestevents-bucket-683517028648\\\",\\\"ownerIdentity\\\":{\\\"principalId\\\":\\\"A2RRIR5BTZTTF6\\\"},\\\"arn\\\":\\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\\"},\\\"object\\\":{\\\"key\\\":\\\"firehose-s3-template.json\\\",\\\"size\\\":4314,\\\"eTag\\\":\\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\\",\\\"sequencer\\\":\\\"0065FA0B4B104A6DAB\\\"}}}]}\",\n \"Timestamp\" : \"2024-03-19T22:01:48.137Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==\",\n \"SigningCertURL\" : \"https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea\"\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710885708191", + "SenderId": "AIDAIYLAVTDLUXBIEIX46", + "ApproximateFirstReceiveTimestamp": "1710885708202" + }, + "messageAttributes": {}, + "md5OfBody": "2dfc1cc4f8f1240a50d7cdc65c7dd2b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", + "awsRegion": "us-west-2" + } + ] +} + +# s3 -> raw_sns -> sqs -> lambda = sqs(raw_sns(s3)) +sqs_rawsns_s3_event = { + "Records": [ + { + "messageId": "519619da-e529-46d7-b58c-bc054405af0f", + "receiptHandle": "AQEB//A8ci4+iToNBE66jNulMi/7cpVqiC7YkdTnQA0qhTOnWv55SDgxh+CV7WckD1xT3V9zBh2APTr1qtB7i29GepU/lzqFvS2wozjDljP7YHbWHn77hOeCwtfVFbJoqUyEL/+QcFIMZ06AUP0h+SAjJDype/x0WnCGqKd3juaRmECEk4LFc+g1evZ9DIP+Lkw3JM44JHAcgq4+Sm+Pv/dEZXHIoOL8S5mV4f0l+fJk9TDOLGbTCCEuMfWmrQBAVgJt052y0y6my2rAGO2iQdwkONXdPUrbxBSmeb/sDEp4qy4CViKgDzTo+Ii2sLDggKxeRrWaLzdFvv50ebTnLx8RHUsVnAiNv8DsJJOJx3ryw8gKO0o4TaMB8KQ4Zh2hAglgakSwjeMzCrTI7tyF1ML65A==", + "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-west-2\",\"eventTime\":\"2024-03-19T22:57:48.823Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"205.251.233.182\"},\"responseElements\":{\"x-amz-request-id\":\"HQDSXXWNQWRCN3PQ\",\"x-amz-id-2\":\"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\",\"bucket\":{\"name\":\"unwraptestevents-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::unwraptestevents-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"9cc7da5febb07868706f59ab70d89981\",\"sequencer\":\"0065FA186CC08E810D\"}}}]}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710889069948", + "SenderId": "AIDAIYLAVTDLUXBIEIX46", + "ApproximateFirstReceiveTimestamp": "1710889069955" + }, + "messageAttributes": {}, + "md5OfBody": "94ff55fa8f439b3d2e43366d582de0b7", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", + "awsRegion": "us-west-2" + } + ] +} + + +# added more events in Records list: sqs(s3, s3) +sqs_s3_multi_event = { + "Records": [ + { + "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", + "receiptHandle": "MessageReceiptHandle", + "body": "{\"Records\":[" + + "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket11\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + + "]}" + }, + { + "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", + "receiptHandle": "MessageReceiptHandle", + "body": "{\"Records\":[" + + "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket22\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + + "]}" + } + ], + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1523232000000", + "SenderId": "123456789012", + "ApproximateFirstReceiveTimestamp": "1523232000001" + }, + "messageAttributes": {}, + "md5OfBody": "7b270e59b47ff90a553787216d55d91d", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", + "awsRegion": "us-east-1" +} + + +#generated from lambda invoke s3 -> sqs -> lambda == sqs(s3) +sqs_s3_event = { + "Records": [ + { + "messageId": "44103047-3123-4583-aed3-7224000351a8", + "receiptHandle": "AQEBWOm6hlP5TEZ64yvPugVI7LyhkEAvaEfvqfyqheIBcqhKPg5wfb95MC9IYm60od3hlTdgT3lJ7l/8upj8eYsCVglkTYqUKXKqUOgotxiqhyLlJ2AOy0gPc1EL5Uek3e267IB/5XPz9msqZmxuI6/pcT+Ihj/26EXYVxOYEK4YwbhbBNhl5Wp4dn8anV3/LD/vvgRyHtOAK4MlwWgIBFT9wWyJInMcYRVtmAx1ODUMG1CpsB6IB5m11pazNnlV0kOSzjjBDB4QK/euMqpfnCbUB4dLb5WAwZ37pys9xKjypEFS1eHXjSwEG+rG4J8u2UlFDO13FQ8lsOJB96Sx/T7KIqTvhc8VayDPXFArTtT6dlXZlc99gYf8uDDcYRfUPnBK8KZ/pEI6UjQiOVjvgWhIDiu0SxrQ82ytPMxjvizWkv0=", + "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T19:02:45.087Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"15.248.6.8\"},\"responseElements\":{\"x-amz-request-id\":\"ST581J3PW8R8QKVP\",\"x-amz-id-2\":\"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh\",\"bucket\":{\"name\":\"sqs-s3-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"8f6c039f567cc53694be2a275e452743\",\"sequencer\":\"0065F349D4F05B5827\"}}}]}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710442966490", + "SenderId": "AROA4R74ZO52XAB5OD7T4:S3-PROD-END", + "ApproximateFirstReceiveTimestamp": "1710442966494" + }, + "messageAttributes": {}, + "md5OfBody": "1b9d61fd8139b215ec65bd8916ac6872", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-s3-unwrap-Queue-9H8CEZEhJfP7", + "awsRegion": "us-east-1" + } + ] +} + +# generated from invoking lambda with sns -> sqs -> lambda == sqs(sns) +# this does not have a Records key inside the SNS event, or the Sns key. But if SNS sends an event directly to Lambda +# (without having SQS in the middle), it would have a Records and Sns key. That's why it's failing +# even after being casted into a SNS event: it doesn't have a Records or Sns key +sqs_sns_event = { + "Records": [ + { + "messageId": "10ad507c-8389-4585-ae55-11d32ea71997", + "receiptHandle": "AQEB1nupmCFCI3lhVKz3fPFqO5kZKDNpzuflQ96kZwseTe5HRCb3eeY8XoWoyfcSDqNwjXdC/CQBjunectuzr+0mYhwVvo0GxRWF0U1J8/djdoxCACEELa+IxnWYA+2ernXEVPrisgWSf8D+woy02h58ybMzbP8pCxeld/1cqbBOt7vd0QC7pRcXDdFl0KWl0yYi1PTWyy6L5uTz4RIDsL867eh6xtKxKinp/N2Fym5/0/3TkfDLk+RNTVTTMmiRebP7hKSfsmYeAc7tcx8GHRvJdcN11XDPfW76+uQbIb9DtAIQobpQ4sJ2FOAapJ9U5IJ4leTfWjJ+L/L1fKo+vlkWiv9k+ktP9ABP214ylpS8BVzn1dHjBGQ98pryKhE4jPm9J3SDYh/J3LSPxsjtUvF/p15pgvantoOYyobS7OMr9qM=", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"bf5ff648-5111-5dbe-ad4b-a82514ed6a35\",\n \"TopicArn\" : \"arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM\",\n \"Message\" : \"from sns\",\n \"Timestamp\" : \"2024-03-14T18:36:44.233Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"Ne7jvjmincHd06Y19dZss3Xk003RlAm/srm2dt5nLDgwrY0dI56RkH/Dbva9w8xy63EUHyUVfHCYvrXLh/HpsW5nXU9YetK7G5QpfxBeTPnNioPdJi2U3PDA+jJXs0DK4ffonwEMLjbmIETAiWdrN5ollBpL5zh2ZjurMh7TnUGH6/KxsFcWNHTPrGN/v9HSRoFtQdtl9i/zFmBVaXC4dvaZU0cy/gYK5uIIf+YJ+OJoXd7fCxZLVPIwnK148Ws3b/i85UyP0tVguscoknf37bTPwdQuloPOKQHtPZDxUdLjS+uj27LRwiT+1CvGqdgpJ8XV/8tWqujR3FDI3ZL6EQ==\",\n \"SigningCertURL\" : \"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM:42e6130c-54b0-4cec-a8c0-7d0cc356ea4e\"\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710441404272", + "SenderId": "AIDAIT2UOQQY3AUEKVGXU", + "ApproximateFirstReceiveTimestamp": "1710441404278" + }, + "messageAttributes": {}, + "md5OfBody": "fb98571efddcc86ff1767f300518f455", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", + "awsRegion": "us-east-1" + } + ] +} + + +# raw_sns -> sqs -> lambda == sqs(raw_sns) +sqs_rawsns_event = { + "Records": [ + { + "messageId": "c2f72267-c1b4-432b-b35e-c27a337798d1", + "receiptHandle": "AQEB2+Do4Yh7HS58NLu1KQZMi69dTVWByZC140b3YS5Dl5hMjU5RlIkmHaxoyDArEzo1ZtJfOljU2aEZAf0nVkp6zosnWP3gqpueoM5RYeXTaYzQSAidCjMySSNWKnA4xzoI3uDhwcmguXAKxyTcgXd9pdiCQ8bXACZmqdzgL0RoKmgA9bIf0X3YYGlQ3X/ApEgxAyiD+ok1quVOj8jdqXfcJ1fbabwihtLTn6fxkVW6Z25gfrYTj8Ix90LdtWcmXjt/q9aJ30e3RdeVBhtB40C1glVm9R9cBvQQaog6z8yC+6H/eKKym25BRr8MJt9kx/e+8aMNKQowcnI/KYXwqSGRbTeml+5XXT5ANDr9qy1c4XEnl8k9vvozzlyYCjlLKOt+shhRfHULo4fzVunsO7GXpa7BW9ZtFJU31nlNCfLNYfk=", + "body": "this is a raw message", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710887794983", + "SenderId": "AIDAIT2UOQQY3AUEKVGXU", + "ApproximateFirstReceiveTimestamp": "1710887794991" + }, + "messageAttributes": {}, + "md5OfBody": "dbfce666a3bf5ced0e8687d4c0039a74", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", + "awsRegion": "us-east-1" + } + ] +} + + +# generated from invoking lambda with s3 -> sns -> lambda == sns(s3). +sns_s3_event = { + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", + "Sns": { + "Type": "Notification", + "MessageId": "2d44624b-23f8-5e80-99d9-3c265035c5ae", + "TopicArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg", + "Subject": "Amazon S3 Notification", + "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T21:52:13.311Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"15.248.6.24\"},\"responseElements\":{\"x-amz-request-id\":\"53YYXE4TACR6K89G\",\"x-amz-id-2\":\"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2\",\"bucket\":{\"name\":\"s3-sns-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"551277913a5ad93e0db069e673f23376\",\"sequencer\":\"0065F3718D39E6D6DC\"}}}]}", + "Timestamp": "2024-03-14T21:52:13.905Z", + "SignatureVersion": "1", + "Signature": "IJqlNH8ddOX4V10m6IY+3gOK6/+PxxiGLs4PxHiGDcQ58mcCr4+vXCHuJ7jxOvCBHCYev1wF0PCwBhDpwBfstV8vAGEsX7GhJuAZ5jf0uOUMukZvIquy1LQBTdHg0TNq9N83sG0wz2QMp8QLLlkDJMF8nS00EjeDuFwpJxZnRadWcjz4AWXO6JITohyYnFVkDqsK5pOFd3Y1KADjfpRFH2lrljJm3CnA/x6PYVduP5PK83JnDs7LmEnK3cqE7IJhdwW9e824KXmjFBujoiNU9bUnoLiqFMg+UfZfMMJGjtCHIV0ZmnMix7nKZUGDNQe7TKOoDcXLxuAxa6TQNWfKSw==", + "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", + "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", + "MessageAttributes": {} + } + } + ] +} + From c46c544146eaf90658a5c131da519df3eff80234 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Tue, 26 Mar 2024 15:15:35 -0700 Subject: [PATCH 03/14] Extended EventWrapper class in some events --- .../utilities/data_classes/event_bridge_event.py | 4 ++-- .../utilities/data_classes/kinesis_stream_event.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index a8f61126365..712dd979cbb 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -1,9 +1,9 @@ from typing import Any, Dict, List, Optional -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper -class EventBridgeEvent(DictWrapper): +class EventBridgeEvent(EventWrapper): """Amazon EventBridge Event Documentation: diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py index 06eaedb8904..2289eeee14f 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py @@ -6,7 +6,7 @@ from aws_lambda_powertools.utilities.data_classes.cloud_watch_logs_event import ( CloudWatchLogsDecodedData, ) -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper class KinesisStreamRecordPayload(DictWrapper): @@ -95,7 +95,7 @@ def kinesis(self) -> KinesisStreamRecordPayload: return KinesisStreamRecordPayload(self._data) -class KinesisStreamEvent(DictWrapper): +class KinesisStreamEvent(EventWrapper): """Kinesis stream event Documentation: From a0f8bc7080bf2105b0172992843fa6f605a944e8 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Wed, 3 Apr 2024 15:42:15 -0700 Subject: [PATCH 04/14] Added more test events, tried to utilize schemas but wasn't working --- .../utilities/data_classes/common.py | 5 +- .../data_classes/event_bridge_event.py | 7 +- .../utilities/data_classes/poc.py | 66 ++++++---- .../utilities/data_classes/ses_event.py | 11 +- .../utilities/data_classes/sns_event.py | 29 ++++- .../utilities/data_classes/test_events.py | 113 +++++++++++++++++- 6 files changed, 192 insertions(+), 39 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 73a28f24c1d..2340d9228ca 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -111,6 +111,7 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = super().__init__(data, json_deserializer) def nested_event_contents(self): + print('IN COMMON NESTED EVENTS') for record in self["Records"]: body = record['body'] yield body @@ -121,7 +122,9 @@ def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_eve nested_event_content_deserializer = self._json_deserializer for content in self.nested_event_contents(): - yield nested_event_class(nested_event_content_deserializer(content)) + deserialized = nested_event_content_deserializer(content) + casted = nested_event_class(deserialized) + yield casted class BaseProxyEvent(DictWrapper): @property diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index 712dd979cbb..9f9ec4f0e1d 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -1,3 +1,4 @@ +import json from typing import Any, Dict, List, Optional from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper @@ -69,7 +70,5 @@ def replay_name(self) -> Optional[str]: return self["replay-name"] def nested_event_contents(self): - for record in self["detail"]: - print('record', record, type(record)) - # print('body:', body, type(body)) - yield record + print('IN EB NESTED EVENTS') + yield json.dumps(self['detail']) diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index e10668b631c..9a6bed1f293 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -1,6 +1,8 @@ from typing import Iterator import json from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, SESEvent, EventBridgeEvent +from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage +from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord, SESMail, SESMessage import test_events @@ -9,20 +11,21 @@ def lambda_handler_sqs_s3(event: SQSEvent = test_events.sqs_s3_event): # sqs(s3) s3_event = sqs_event.decode_nested_events(S3Event) for rec in s3_event: print('rec:', rec.bucket_name) - # for sqs_record in sqs_event.records: - # # print('body in main:', sqs_record.body) - # # s3_event = sqs_event.decode_nested_events(Iterator[S3Event]) # is this correct format? - # s3_event = sqs_event.decode_nested_events(S3Event) - # for rec in s3_event: - # print('rec:', rec.bucket_name) - # print(next(s3_event).bucket_name) # use this if not inside a for loop - def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(sns) sqs_event = SQSEvent(event) - sns_event = sqs_event.decode_nested_events(SNSEvent) + sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: - print('rec:', type(rec), rec.sns_message) + print('rec:', type(rec)) + print(rec.message) + # try: + # validate(instance=rec, schema=test_events.sns_schema) + # print("JSON object is valid.") + # except jsonschema.exceptions.ValidationError: + # print("JSON object is not valid.") + # # rec = json.dumps(rec) + # asdf = SNSEvent({"Records": {"Sns": rec.records}}) + # print(asdf) def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3) @@ -42,30 +45,49 @@ def lambda_handler_sqs_s3_multi(event: SQSEvent = test_events.sqs_s3_multi_event def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # sqs(sns(s3)) sqs_event = SQSEvent(event) - sns_event = sqs_event.decode_nested_events(SNSEvent) + sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: - print('rec:', type(rec), rec.sns_message) - # s3_event = sns_event.decode_nested_events(S3Event) + print('sns rec:', type(rec), rec) + print('sns message:', rec.message) + + s3_event = rec.decode_nested_events(S3Event) + print('s3 rec:', type(s3_event), s3_event) + # print(s3_event.bucket_name) # not working + print(next(s3_event).bucket_name) # TODO: why isn't it calling snsmessage nested events without this line? def lambda_handler_sns_ses(event: SNSEvent = test_events.sns_ses_event): # sns(ses) sns_event = SNSEvent(event) - ses_event = sns_event.decode_nested_events(SESEvent) + ses_event = sns_event.decode_nested_events(SESMessage) for rec in ses_event: - print(type(rec)) - print('rec:', rec.get("mail").get('source')) #but can't do rec.mail bc no "Records" key.. + print('rec:', type(rec), rec) + print('rec:', rec.get("mail").get('source')) + # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key.. def lambda_handler_eb_s3(event: EventBridgeEvent = test_events.eb_s3_event): # eventbridge(s3) eb_event = EventBridgeEvent(event) s3_event = eb_event.decode_nested_events(S3Event) for rec in s3_event: - print(type(rec)) - print('rec:', rec) + print('type:', type(rec)) + print('rec:', rec.bucket_name) + +def lambda_handler_sqs_eb_s3(event: test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) + sqs_event = SQSEvent(event) + for rec in sqs_event: + eb_event = sqs_event.decode_nested_events(EventBridgeEvent) + for rec in eb_event: + print('rec:', type(rec), rec) + s3_event = rec.decode_nested_events(S3Event) + for r in s3_event: + print(type(r)) + print('rec:', r.bucket_name) + lambda_handler_sqs_s3(test_events.sqs_s3_event) -# lambda_handler_sqs_sns(test_events.sqs_sns_event) #not working bc sns doesn't have Records key +lambda_handler_sqs_sns(test_events.sqs_sns_event) lambda_handler_sns_s3(test_events.sns_s3_event) lambda_handler_sqs_s3_multi(test_events.sqs_s3_multi_event) -# lambda_handler_sqs_sns_s3(test_events.sqs_sns_s3_event) #not working bc sns doesn't have Records key -lambda_handler_sns_ses(test_events.sns_ses_event) -# lambda_handler_eb_s3(test_events.eb_s3_event) #EB returning a str, not dict +lambda_handler_sqs_sns_s3(test_events.sqs_sns_s3_event) +lambda_handler_sns_ses(test_events.sns_ses_event) # not being casted correctly bc no "SES" key but works as dict +# lambda_handler_eb_s3(test_events.eb_s3_event) #the nested s3 event isn't a full s3 event bc doesn't have a Records key at the top level. so can't call the s3 methods on it +# lambda_handler_sqs_eb_s3(test_events.sqs_eb_s3_event) #same as above diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index 2049bd21a1f..43cbf7eba33 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -66,7 +66,7 @@ def reply_to(self) -> Optional[List[str]]: return self.get("replyTo") -class SESMail(DictWrapper): +class SESMail(EventWrapper): @property def timestamp(self) -> str: """String that contains the time at which the email was received, in ISO8601 format.""" @@ -207,7 +207,7 @@ def action(self) -> SESReceiptAction: return SESReceiptAction(self["action"]) -class SESMessage(DictWrapper): +class SESMessage(EventWrapper): @property def mail(self) -> SESMail: return SESMail(self["ses"]["mail"]) @@ -217,7 +217,7 @@ def receipt(self) -> SESReceipt: return SESReceipt(self["ses"]["receipt"]) -class SESEventRecord(DictWrapper): +class SESEventRecord(EventWrapper): @property def event_source(self) -> str: """The AWS service from which the SES event record originated. For SES, this is aws:ses""" @@ -260,10 +260,9 @@ def mail(self) -> SESMail: @property def receipt(self) -> SESReceipt: return self.record.ses.receipt - + def nested_event_contents(self): + print('IN SES NESTED EVENTS') for record in self["Records"]: - # print('record', record, type(record)) body = record['ses'] - # print('body:', body, type(body)) yield body diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index 4d50de2dc54..29939910378 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -1,4 +1,7 @@ from typing import Dict, Iterator +import test_events +import jsonschema +from jsonschema import validate from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper @@ -78,8 +81,17 @@ def subject(self) -> str: """The Subject parameter specified when the notification was published to the topic.""" return self["Subject"] + def nested_event_contents(self): + print('in SNS MESSAGE NESTED EVENT') + yield self.message + # for record in self.message: + # print('record:', record, type(record)) + # # body = record['Sns']['Message'] + # # print('body:', body, type(body)) + # yield record + -class SNSEventRecord(DictWrapper): +class SNSEventRecord(EventWrapper): @property def event_version(self) -> str: """Event version""" @@ -123,8 +135,19 @@ def sns_message(self) -> str: return self.record.sns.message def nested_event_contents(self): + print('in SNS NESTED EVENT') for record in self["Records"]: - # print('record', record, type(record)) body = record['Sns']['Message'] - # print('body:', body, type(body)) yield body + + def check_schema(self): + print(self, type(self)) + try: + validate(instance=self, schema=test_events.sns_schema) + print("JSON object is valid.") + return self + except jsonschema.exceptions.ValidationError: #TODO: or cx needs to tell us to cast to SNSEvent or SNSMessage, we shouldn't have to figure that out ourselves? + print("JSON object is not valid.") + print("event rec:", SNSMessage(self)) + corrected = SNSMessage(self) + return corrected diff --git a/aws_lambda_powertools/utilities/data_classes/test_events.py b/aws_lambda_powertools/utilities/data_classes/test_events.py index 81754892913..a239c3922eb 100644 --- a/aws_lambda_powertools/utilities/data_classes/test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/test_events.py @@ -1,7 +1,51 @@ -# kinesis stream -> firehose -> s3 -> lambda: not working ie the event generated is just s3, nothing is nested... +# kinesis stream -> firehose -> s3 -> lambda: the event generated is just s3, nothing is nested. -# s3 -> sns -> firehose -> lambda: sns not sending messages to firehose for some reason :( -# working -> ?? -> working? i see test data in CW +# s3 -> sns -> firehose -> lambda: sns not sending messages to firehose +# working -> ?? -> working (i see test data in CW) + + +# s3 -> sns -> firehose -> lambda = firehose(sns(s3)) +firehose_sns_s3_event = {} + + +# sns -> firehose -> lambda = firehose(sns) +firehose_sns_event = { + "invocationId": "b1332a68-805c-418f-8bb6-075f5b991134", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", + "region": "us-east-1", + "records": [ + { + "recordId": "49650562840674497170060081706384853755200261109279883266000000", + "approximateArrivalTimestamp": 1711562009882, + "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMWIzZTEyNDQtZWNjOS01NmFiLTliODUtNGMzYWIzOTA4ZWU5IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZSIsIlN1YmplY3QiOiJkZGRkZGRkZGRkZGRkZGRkZGQiLCJNZXNzYWdlIjoiZXdyZXdycXdyZXdyXG5zZGFkXG5hc2RcbmFzZFxuYXNcbmR4IiwiVGltZXN0YW1wIjoiMjAyNC0wMy0yN1QxNzo1MzoyOS44MDRaIiwiVW5zdWJzY3JpYmVVUkwiOiJodHRwczovL3Nucy51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZTo2OTZlMzRhNS1mZDBiLTRhYjQtYjEyMi05ZmZhNzEwYjg5OTUifQo=" + } + ] +} + + +# CW -> firehose -> lambda = firehose(cw) +firehose_cw_event = { + "invocationId": "cbef637e-fb9e-4c48-84c6-0d04f21f347d", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", + "region": "us-east-1", + "records": [ + { + "recordId": "49650562840674497170060081706233738027748410540928532482000000", + "approximateArrivalTimestamp": 1711561691435, + "data": "H4sIAAAAAAAA/zWOwQrCMBAFfyXsuQhRVMxNpHqpFqzgQURiuzbBNinZrUXEf5daPQ5v4M0LaiTSJR6eDYKCVbo77NPkso2zbLmJIQLfOQz9Uvm26DTnJvElQQSVLzfBtw0oGCjjgLoekNor5cE2bL1b24oxEKjT+evFD3Tc4wtsMehsayTWdQNKzqWczuRsISfzcfTP6wOOifjliV+eEiuD+d26UhjUFRvhb6JAYut0/yzWNqDxhCN4n98fsU8ThOwAAAA=" + }, + { + "recordId": "49650562840674497170060081706248245137583787946450878466000000", + "approximateArrivalTimestamp": 1711561718674, + "data": "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" + }, + { + "recordId": "49650562840674497170060081706253080840862247081624993794000000", + "approximateArrivalTimestamp": 1711561727636, + "data": "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" + } + ] +} # ses -> sns -> lambda = sns(ses) @@ -256,3 +300,66 @@ ] } +sns_schema = { + "type": "object", + "properties": { + "Records": { + "type": "array", + "items": { + "type": "object", + "properties": { + "EventSource": { + "type": "string" + }, + "EventVersion": { + "type": "string" + }, + "EventSubscriptionArn": { + "type": "string" + }, + "Sns": { + "type": "object", + "properties": { + "Type": { + "type": "string" + }, + "MessageId": { + "type": "string" + }, + "TopicArn": { + "type": "string" + }, + "Subject": { + "type": "string" + }, + "Message": { + "type": "string" + }, + "Timestamp": { + "type": "string" + }, + "SignatureVersion": { + "type": "string" + }, + "Signature": { + "type": "string" + }, + "SigningCertUrl": { + "type": "string" + }, + "UnsubscribeUrl": { + "type": "string" + }, + "MessageAttributes": { + "type": "object" + } + }, + "required": ["Type", "MessageId", "TopicArn", "Subject", "Message", "Timestamp", "SignatureVersion", "Signature", "SigningCertUrl", "UnsubscribeUrl", "MessageAttributes"] + } + }, + "required": ["EventSource", "EventVersion", "EventSubscriptionArn", "Sns"] + } + } + }, + "required": ["Records"] +} From 11ee8d6df2eee0e27f486ddfb0406922a3fd2c85 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Thu, 4 Apr 2024 13:24:57 -0700 Subject: [PATCH 05/14] Removed code for schemas --- .../utilities/data_classes/common.py | 1 - .../data_classes/event_bridge_event.py | 1 - .../data_classes/kinesis_firehose_event.py | 6 +- .../utilities/data_classes/poc.py | 23 ++--- .../utilities/data_classes/sns_event.py | 19 ----- .../utilities/data_classes/test_events.py | 85 ++----------------- 6 files changed, 14 insertions(+), 121 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 1bc6e4e71aa..76685308eba 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -112,7 +112,6 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = super().__init__(data, json_deserializer) def nested_event_contents(self): - print('IN COMMON NESTED EVENTS') for record in self["Records"]: body = record['body'] yield body diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index 9f9ec4f0e1d..bac5eb39395 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -70,5 +70,4 @@ def replay_name(self) -> Optional[str]: return self["replay-name"] def nested_event_contents(self): - print('IN EB NESTED EVENTS') yield json.dumps(self['detail']) diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 4bb78ba02fe..689ec3dd4b1 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -306,7 +306,5 @@ def records(self) -> Iterator[KinesisFirehoseRecord]: def nested_event_contents(self): for record in self["records"]: - # print('record', record, type(record)) - # body = record[] - # print('body:', body, type(body)) - yield record + body = record['data'] + yield body diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index 9a6bed1f293..9172c292f4a 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -1,14 +1,13 @@ -from typing import Iterator -import json -from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, SESEvent, EventBridgeEvent +from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage -from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord, SESMail, SESMessage +from aws_lambda_powertools.utilities.data_classes.ses_event import SESMessage import test_events - +#TODO: handler for firehose +# TODO: tests + error handling def lambda_handler_sqs_s3(event: SQSEvent = test_events.sqs_s3_event): # sqs(s3) sqs_event = SQSEvent(event) - s3_event = sqs_event.decode_nested_events(S3Event) + s3_event = sqs_event.decode_nested_events(SNSEvent) for rec in s3_event: print('rec:', rec.bucket_name) @@ -18,14 +17,6 @@ def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(s for rec in sns_event: print('rec:', type(rec)) print(rec.message) - # try: - # validate(instance=rec, schema=test_events.sns_schema) - # print("JSON object is valid.") - # except jsonschema.exceptions.ValidationError: - # print("JSON object is not valid.") - # # rec = json.dumps(rec) - # asdf = SNSEvent({"Records": {"Sns": rec.records}}) - # print(asdf) def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3) @@ -59,10 +50,10 @@ def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # def lambda_handler_sns_ses(event: SNSEvent = test_events.sns_ses_event): # sns(ses) sns_event = SNSEvent(event) ses_event = sns_event.decode_nested_events(SESMessage) - for rec in ses_event: + for rec in ses_event: #TODO: how to get the first record without the for loop print('rec:', type(rec), rec) print('rec:', rec.get("mail").get('source')) - # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key.. + # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key def lambda_handler_eb_s3(event: EventBridgeEvent = test_events.eb_s3_event): # eventbridge(s3) eb_event = EventBridgeEvent(event) diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index 29939910378..c3bc2d60f0f 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -82,13 +82,7 @@ def subject(self) -> str: return self["Subject"] def nested_event_contents(self): - print('in SNS MESSAGE NESTED EVENT') yield self.message - # for record in self.message: - # print('record:', record, type(record)) - # # body = record['Sns']['Message'] - # # print('body:', body, type(body)) - # yield record class SNSEventRecord(EventWrapper): @@ -135,19 +129,6 @@ def sns_message(self) -> str: return self.record.sns.message def nested_event_contents(self): - print('in SNS NESTED EVENT') for record in self["Records"]: body = record['Sns']['Message'] yield body - - def check_schema(self): - print(self, type(self)) - try: - validate(instance=self, schema=test_events.sns_schema) - print("JSON object is valid.") - return self - except jsonschema.exceptions.ValidationError: #TODO: or cx needs to tell us to cast to SNSEvent or SNSMessage, we shouldn't have to figure that out ourselves? - print("JSON object is not valid.") - print("event rec:", SNSMessage(self)) - corrected = SNSMessage(self) - return corrected diff --git a/aws_lambda_powertools/utilities/data_classes/test_events.py b/aws_lambda_powertools/utilities/data_classes/test_events.py index a239c3922eb..146951c6b19 100644 --- a/aws_lambda_powertools/utilities/data_classes/test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/test_events.py @@ -1,13 +1,6 @@ -# kinesis stream -> firehose -> s3 -> lambda: the event generated is just s3, nothing is nested. - -# s3 -> sns -> firehose -> lambda: sns not sending messages to firehose -# working -> ?? -> working (i see test data in CW) - - # s3 -> sns -> firehose -> lambda = firehose(sns(s3)) firehose_sns_s3_event = {} - # sns -> firehose -> lambda = firehose(sns) firehose_sns_event = { "invocationId": "b1332a68-805c-418f-8bb6-075f5b991134", @@ -96,7 +89,6 @@ } - # s3 -> eventbridge -> lambda = eventbridge(s3) eb_s3_event = { "version": "0", @@ -128,7 +120,7 @@ } -# in unwrap CF stack: s3 -> sns -> sqs -> lambda = sqs(sns(s3)) +# s3 -> sns -> sqs -> lambda = sqs(sns(s3)) sqs_sns_s3_event = { "Records": [ { @@ -173,7 +165,7 @@ } -# added more events in Records list: sqs(s3, s3) +# sqs(s3, s3) sqs_s3_multi_event = { "Records": [ { @@ -205,7 +197,7 @@ } -#generated from lambda invoke s3 -> sqs -> lambda == sqs(s3) +# s3 -> sqs -> lambda == sqs(s3) sqs_s3_event = { "Records": [ { @@ -227,10 +219,7 @@ ] } -# generated from invoking lambda with sns -> sqs -> lambda == sqs(sns) -# this does not have a Records key inside the SNS event, or the Sns key. But if SNS sends an event directly to Lambda -# (without having SQS in the middle), it would have a Records and Sns key. That's why it's failing -# even after being casted into a SNS event: it doesn't have a Records or Sns key +# sns -> sqs -> lambda == sqs(sns) sqs_sns_event = { "Records": [ { @@ -276,7 +265,7 @@ } -# generated from invoking lambda with s3 -> sns -> lambda == sns(s3). +# s3 -> sns -> lambda == sns(s3). sns_s3_event = { "Records": [ { @@ -299,67 +288,3 @@ } ] } - -sns_schema = { - "type": "object", - "properties": { - "Records": { - "type": "array", - "items": { - "type": "object", - "properties": { - "EventSource": { - "type": "string" - }, - "EventVersion": { - "type": "string" - }, - "EventSubscriptionArn": { - "type": "string" - }, - "Sns": { - "type": "object", - "properties": { - "Type": { - "type": "string" - }, - "MessageId": { - "type": "string" - }, - "TopicArn": { - "type": "string" - }, - "Subject": { - "type": "string" - }, - "Message": { - "type": "string" - }, - "Timestamp": { - "type": "string" - }, - "SignatureVersion": { - "type": "string" - }, - "Signature": { - "type": "string" - }, - "SigningCertUrl": { - "type": "string" - }, - "UnsubscribeUrl": { - "type": "string" - }, - "MessageAttributes": { - "type": "object" - } - }, - "required": ["Type", "MessageId", "TopicArn", "Subject", "Message", "Timestamp", "SignatureVersion", "Signature", "SigningCertUrl", "UnsubscribeUrl", "MessageAttributes"] - } - }, - "required": ["EventSource", "EventVersion", "EventSubscriptionArn", "Sns"] - } - } - }, - "required": ["Records"] -} From 980041f49cc56b5917b97f03cd90dfebb8f0f00d Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Mon, 8 Apr 2024 19:12:25 -0700 Subject: [PATCH 06/14] Added decode for first event and error handling --- .../data_classes/cloud_watch_logs_event.py | 6 +- .../utilities/data_classes/common.py | 30 +++++++-- .../data_classes/event_bridge_event.py | 2 +- .../data_classes/kinesis_firehose_event.py | 4 +- .../{test_events.py => nested_test_events.py} | 12 ++-- .../utilities/data_classes/poc.py | 65 ++++++++++++------- .../utilities/data_classes/ses_event.py | 5 +- .../utilities/data_classes/sns_event.py | 8 +-- 8 files changed, 82 insertions(+), 50 deletions(-) rename aws_lambda_powertools/utilities/data_classes/{test_events.py => nested_test_events.py} (97%) diff --git a/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py b/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py index 7775dd67333..104bb20c77b 100644 --- a/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py @@ -2,10 +2,10 @@ import zlib from typing import Dict, List, Optional -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper -class CloudWatchLogsLogEvent(DictWrapper): +class CloudWatchLogsLogEvent(EventWrapper): @property def get_id(self) -> str: """The ID property is a unique identifier for every log event.""" @@ -72,7 +72,7 @@ def log_events(self) -> List[CloudWatchLogsLogEvent]: return [CloudWatchLogsLogEvent(i) for i in self["logEvents"]] -class CloudWatchLogsEvent(DictWrapper): +class CloudWatchLogsEvent(EventWrapper): """CloudWatch Logs log stream event You can use a Lambda function to monitor and analyze logs from an Amazon CloudWatch Logs log stream. diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 76685308eba..387ca2501af 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -10,6 +10,7 @@ get_multi_value_query_string_values, get_query_string_value, ) +from aws_lambda_powertools.utilities.data_classes.exceptions import ClassTransformationException class DictWrapper(Mapping): @@ -112,19 +113,34 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = super().__init__(data, json_deserializer) def nested_event_contents(self): - for record in self["Records"]: - body = record['body'] - yield body - + records = self.get("Records") + if records is None: + raise KeyError("No 'Records' key found in the event data.") + for record in records: + if not isinstance(record, dict): + raise TypeError(f"Expected each record to be a dictionary, but got {type(record)}.") + body = record.get('body') + if body is not None: + yield body + else: + raise KeyError("No 'body' key found in the record.") def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): if nested_event_content_deserializer is None: nested_event_content_deserializer = self._json_deserializer for content in self.nested_event_contents(): - deserialized = nested_event_content_deserializer(content) - casted = nested_event_class(deserialized) - yield casted + deserialized_data = nested_event_content_deserializer(content) + yield nested_event_class(deserialized_data) + + def decode_nested_event(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): + if nested_event_content_deserializer is None: + nested_event_content_deserializer = self._json_deserializer + + for content in self.nested_event_contents(): + deserialized_data = nested_event_content_deserializer(content) + return nested_event_class(deserialized_data) + class BaseProxyEvent(DictWrapper): @property diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index bac5eb39395..b1c7f2b90af 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -70,4 +70,4 @@ def replay_name(self) -> Optional[str]: return self["replay-name"] def nested_event_contents(self): - yield json.dumps(self['detail']) + yield json.dumps(self.get('detail')) diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 689ec3dd4b1..8178036e10f 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -305,6 +305,6 @@ def records(self) -> Iterator[KinesisFirehoseRecord]: yield KinesisFirehoseRecord(data=record, json_deserializer=self._json_deserializer) def nested_event_contents(self): - for record in self["records"]: - body = record['data'] + for record in self.get("records"): + body = record.get("data") yield body diff --git a/aws_lambda_powertools/utilities/data_classes/test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py similarity index 97% rename from aws_lambda_powertools/utilities/data_classes/test_events.py rename to aws_lambda_powertools/utilities/data_classes/nested_test_events.py index 146951c6b19..2bf877377a0 100644 --- a/aws_lambda_powertools/utilities/data_classes/test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -72,7 +72,7 @@ { "messageId": "ee95829a-ba32-471d-9684-34368ab9995e", "receiptHandle": "AQEBZoMhwYaEfxvSOWGnwMurMIe2sEkwsV9l5e+pDpa2zCtdWLBfbUNxIX5R8O9hx+jAXhpj01bHElvli+LtPNBJarb4V+JEg2Hql3lSdkISTEECrWc8Dm8eX+p+LeyoN9cSnfDUoqQ2rd/BSFt9/vk6ro+w/kM8G1q7Lt1PB6G51LbfzXYA+KYUPLWIeYK2NMDf8TyvC0PbERE6im9H+eqJznyPWNznfziwq7d6ZIpY3GSfRrED/0tfr3FvzIVCVsOBuPHyd5stqcrgkCs2Dt/f7DWYWr1KMSqFDM1u4S7wMIroCVSfe9wsqimLBwaHZcG1zukaW16c51TiRI3zNzOl3cuDZgqPAK1rQKsj3x+VLqxnbyIgx24oIKhh5XqcZfzRbBwX4HDF/Opv8cN16+0yTw==", - "body": "{\"version\":\"0\",\"id\":\"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4\",\"detail-type\":\"Object Created\",\"source\":\"aws.s3\",\"account\":\"683517028648\",\"time\":\"2024-03-26T18:05:54Z\",\"region\":\"us-east-1\",\"resources\":[\"arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"],\"detail\":{\"version\":\"0\",\"bucket\":{\"name\":\"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"},\"object\":{\"key\":\"__init__.py\",\"size\":0,\"etag\":\"d41d8cd98f00b204e9800998ecf8427e\",\"sequencer\":\"0066030E82E2A48DFE\"},\"request-id\":\"HWEZ4KKQMXVWATHJ\",\"requester\":\"683517028648\",\"source-ip-address\":\"15.248.7.0\",\"reason\":\"PutObject\"}}", + "body": "{\"version\":\"0\",\"id\":\"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4\",\"detail-type\":\"Object Created\",\"source\":\"aws.s3\",\"account\":\"683517028648\",\"time\":\"2024-03-26T18:05:54Z\",\"region\":\"us-east-1\",\"resources\":[\"arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"],\"detail\":{\"version\":\"0\",\"bucket\":{\"name\":\"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"},\"object\":{\"key\":\"__init__.py\",\"size\":0,\"etag\":\"d41d8cd98f00b204e9800998ecf8427e\",\"sequencer\":\"0066030E82E2A48DFE\"},\"request-id\":\"HWEZ4KKQMXVWATHJ\",\"requester\":\"683517028648\",\"source-ip-address\":\"00.111.2.3\",\"reason\":\"PutObject\"}}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1711476356070", @@ -114,7 +114,7 @@ }, "request-id": "SW5MRVMJG8NG1GMZ", "requester": "683517028648", - "source-ip-address": "72.21.198.69", + "source-ip-address": "00.11.222.333", "reason": "PutObject" } } @@ -126,7 +126,7 @@ { "messageId": "45405be4-2278-4eef-a29c-993898bb8917", "receiptHandle": "AQEBy2gRrluag0E0vWiKlHZhcf6Ymtgkf92PlWtTQ4PKOPdF3NcUqKEzKtKbiTN7d+qy64nN3F97DOQr9b4xegJidHlXlyIwsYxQIpmGfDETCKPS5nchXOWRLIu/a/bpCmaZK/Mv1r6lAaF2gnoX7JaVpdTbExLRBQqOIcb2NRXmfeE0yKZtIT0TV9pstzsAi328KGbr1QMKOV0RKrE1NtQDpa/ixeEUWrZeGqwA7Cwy0BMevfoQKVkO78JrDsn4W/lUt2R+oRF7sB62+onfbIlBPmi+LXV4WeSrB7w1yvnMbVuvfgHDS9F1LEs62wJTNVQz6224s3OBfJZsAaSpW1IzD+UttqFJ3KTadu6HZMbCq+I2An+cQjqZ3zDsEV7Vwm6LH+04RGA3b9edBLgIoMbfcg==", - "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"53c941f5-1d7a-5f8e-8ffe-1f8110f6e667\",\n \"TopicArn\" : \"arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op\",\n \"Subject\" : \"Amazon S3 Notification\",\n \"Message\" : \"{\\\"Records\\\":[{\\\"eventVersion\\\":\\\"2.1\\\",\\\"eventSource\\\":\\\"aws:s3\\\",\\\"awsRegion\\\":\\\"us-west-2\\\",\\\"eventTime\\\":\\\"2024-03-19T22:01:47.135Z\\\",\\\"eventName\\\":\\\"ObjectCreated:Put\\\",\\\"userIdentity\\\":{\\\"principalId\\\":\\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\\"},\\\"requestParameters\\\":{\\\"sourceIPAddress\\\":\\\"205.251.233.178\\\"},\\\"responseElements\\\":{\\\"x-amz-request-id\\\":\\\"02TFARRDG75KXGG6\\\",\\\"x-amz-id-2\\\":\\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\\"},\\\"s3\\\":{\\\"s3SchemaVersion\\\":\\\"1.0\\\",\\\"configurationId\\\":\\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\\",\\\"bucket\\\":{\\\"name\\\":\\\"unwraptestevents-bucket-683517028648\\\",\\\"ownerIdentity\\\":{\\\"principalId\\\":\\\"A2RRIR5BTZTTF6\\\"},\\\"arn\\\":\\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\\"},\\\"object\\\":{\\\"key\\\":\\\"firehose-s3-template.json\\\",\\\"size\\\":4314,\\\"eTag\\\":\\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\\",\\\"sequencer\\\":\\\"0065FA0B4B104A6DAB\\\"}}}]}\",\n \"Timestamp\" : \"2024-03-19T22:01:48.137Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==\",\n \"SigningCertURL\" : \"https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea\"\n}", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"53c941f5-1d7a-5f8e-8ffe-1f8110f6e667\",\n \"TopicArn\" : \"arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op\",\n \"Subject\" : \"Amazon S3 Notification\",\n \"Message\" : \"{\\\"Records\\\":[{\\\"eventVersion\\\":\\\"2.1\\\",\\\"eventSource\\\":\\\"aws:s3\\\",\\\"awsRegion\\\":\\\"us-west-2\\\",\\\"eventTime\\\":\\\"2024-03-19T22:01:47.135Z\\\",\\\"eventName\\\":\\\"ObjectCreated:Put\\\",\\\"userIdentity\\\":{\\\"principalId\\\":\\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\\"},\\\"requestParameters\\\":{\\\"sourceIPAddress\\\":\\\"000.111.222.333\\\"},\\\"responseElements\\\":{\\\"x-amz-request-id\\\":\\\"02TFARRDG75KXGG6\\\",\\\"x-amz-id-2\\\":\\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\\"},\\\"s3\\\":{\\\"s3SchemaVersion\\\":\\\"1.0\\\",\\\"configurationId\\\":\\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\\",\\\"bucket\\\":{\\\"name\\\":\\\"unwraptestevents-bucket-683517028648\\\",\\\"ownerIdentity\\\":{\\\"principalId\\\":\\\"A2RRIR5BTZTTF6\\\"},\\\"arn\\\":\\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\\"},\\\"object\\\":{\\\"key\\\":\\\"firehose-s3-template.json\\\",\\\"size\\\":4314,\\\"eTag\\\":\\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\\",\\\"sequencer\\\":\\\"0065FA0B4B104A6DAB\\\"}}}]}\",\n \"Timestamp\" : \"2024-03-19T22:01:48.137Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==\",\n \"SigningCertURL\" : \"https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea\"\n}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710885708191", @@ -148,7 +148,7 @@ { "messageId": "519619da-e529-46d7-b58c-bc054405af0f", "receiptHandle": "AQEB//A8ci4+iToNBE66jNulMi/7cpVqiC7YkdTnQA0qhTOnWv55SDgxh+CV7WckD1xT3V9zBh2APTr1qtB7i29GepU/lzqFvS2wozjDljP7YHbWHn77hOeCwtfVFbJoqUyEL/+QcFIMZ06AUP0h+SAjJDype/x0WnCGqKd3juaRmECEk4LFc+g1evZ9DIP+Lkw3JM44JHAcgq4+Sm+Pv/dEZXHIoOL8S5mV4f0l+fJk9TDOLGbTCCEuMfWmrQBAVgJt052y0y6my2rAGO2iQdwkONXdPUrbxBSmeb/sDEp4qy4CViKgDzTo+Ii2sLDggKxeRrWaLzdFvv50ebTnLx8RHUsVnAiNv8DsJJOJx3ryw8gKO0o4TaMB8KQ4Zh2hAglgakSwjeMzCrTI7tyF1ML65A==", - "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-west-2\",\"eventTime\":\"2024-03-19T22:57:48.823Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"205.251.233.182\"},\"responseElements\":{\"x-amz-request-id\":\"HQDSXXWNQWRCN3PQ\",\"x-amz-id-2\":\"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\",\"bucket\":{\"name\":\"unwraptestevents-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::unwraptestevents-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"9cc7da5febb07868706f59ab70d89981\",\"sequencer\":\"0065FA186CC08E810D\"}}}]}", + "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-west-2\",\"eventTime\":\"2024-03-19T22:57:48.823Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"000.111.222.333\"},\"responseElements\":{\"x-amz-request-id\":\"HQDSXXWNQWRCN3PQ\",\"x-amz-id-2\":\"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\",\"bucket\":{\"name\":\"unwraptestevents-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::unwraptestevents-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"9cc7da5febb07868706f59ab70d89981\",\"sequencer\":\"0065FA186CC08E810D\"}}}]}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710889069948", @@ -203,7 +203,7 @@ { "messageId": "44103047-3123-4583-aed3-7224000351a8", "receiptHandle": "AQEBWOm6hlP5TEZ64yvPugVI7LyhkEAvaEfvqfyqheIBcqhKPg5wfb95MC9IYm60od3hlTdgT3lJ7l/8upj8eYsCVglkTYqUKXKqUOgotxiqhyLlJ2AOy0gPc1EL5Uek3e267IB/5XPz9msqZmxuI6/pcT+Ihj/26EXYVxOYEK4YwbhbBNhl5Wp4dn8anV3/LD/vvgRyHtOAK4MlwWgIBFT9wWyJInMcYRVtmAx1ODUMG1CpsB6IB5m11pazNnlV0kOSzjjBDB4QK/euMqpfnCbUB4dLb5WAwZ37pys9xKjypEFS1eHXjSwEG+rG4J8u2UlFDO13FQ8lsOJB96Sx/T7KIqTvhc8VayDPXFArTtT6dlXZlc99gYf8uDDcYRfUPnBK8KZ/pEI6UjQiOVjvgWhIDiu0SxrQ82ytPMxjvizWkv0=", - "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T19:02:45.087Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"15.248.6.8\"},\"responseElements\":{\"x-amz-request-id\":\"ST581J3PW8R8QKVP\",\"x-amz-id-2\":\"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh\",\"bucket\":{\"name\":\"sqs-s3-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"8f6c039f567cc53694be2a275e452743\",\"sequencer\":\"0065F349D4F05B5827\"}}}]}", + "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T19:02:45.087Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"00.111.2.3\"},\"responseElements\":{\"x-amz-request-id\":\"ST581J3PW8R8QKVP\",\"x-amz-id-2\":\"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh\",\"bucket\":{\"name\":\"sqs-s3-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"8f6c039f567cc53694be2a275e452743\",\"sequencer\":\"0065F349D4F05B5827\"}}}]}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710442966490", @@ -277,7 +277,7 @@ "MessageId": "2d44624b-23f8-5e80-99d9-3c265035c5ae", "TopicArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg", "Subject": "Amazon S3 Notification", - "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T21:52:13.311Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"15.248.6.24\"},\"responseElements\":{\"x-amz-request-id\":\"53YYXE4TACR6K89G\",\"x-amz-id-2\":\"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2\",\"bucket\":{\"name\":\"s3-sns-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"551277913a5ad93e0db069e673f23376\",\"sequencer\":\"0065F3718D39E6D6DC\"}}}]}", + "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T21:52:13.311Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"00.111.2.33\"},\"responseElements\":{\"x-amz-request-id\":\"53YYXE4TACR6K89G\",\"x-amz-id-2\":\"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2\",\"bucket\":{\"name\":\"s3-sns-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"551277913a5ad93e0db069e673f23376\",\"sequencer\":\"0065F3718D39E6D6DC\"}}}]}", "Timestamp": "2024-03-14T21:52:13.905Z", "SignatureVersion": "1", "Signature": "IJqlNH8ddOX4V10m6IY+3gOK6/+PxxiGLs4PxHiGDcQ58mcCr4+vXCHuJ7jxOvCBHCYev1wF0PCwBhDpwBfstV8vAGEsX7GhJuAZ5jf0uOUMukZvIquy1LQBTdHg0TNq9N83sG0wz2QMp8QLLlkDJMF8nS00EjeDuFwpJxZnRadWcjz4AWXO6JITohyYnFVkDqsK5pOFd3Y1KADjfpRFH2lrljJm3CnA/x6PYVduP5PK83JnDs7LmEnK3cqE7IJhdwW9e824KXmjFBujoiNU9bUnoLiqFMg+UfZfMMJGjtCHIV0ZmnMix7nKZUGDNQe7TKOoDcXLxuAxa6TQNWfKSw==", diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index 9172c292f4a..c954c6fc8b8 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -1,17 +1,23 @@ -from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent +from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent, KinesisFirehoseEvent from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage from aws_lambda_powertools.utilities.data_classes.ses_event import SESMessage -import test_events +from aws_lambda_powertools.utilities.data_classes.cloud_watch_logs_event import CloudWatchLogsLogEvent +import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events -#TODO: handler for firehose -# TODO: tests + error handling -def lambda_handler_sqs_s3(event: SQSEvent = test_events.sqs_s3_event): # sqs(s3) +# TODO: unit tests + +def lambda_handler_sqs_s3(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) sqs_event = SQSEvent(event) - s3_event = sqs_event.decode_nested_events(SNSEvent) + s3_event = sqs_event.decode_nested_events(S3Event) for rec in s3_event: print('rec:', rec.bucket_name) -def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(sns) +def lambda_handler_sqs_s3_single(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) + sqs_event = SQSEvent(event) + s3_event = sqs_event.decode_nested_event(S3Event) + print('bucket:', s3_event.bucket_name) + +def lambda_handler_sqs_sns(event: SQSEvent = nested_test_events.sqs_sns_event): # sqs(sns) sqs_event = SQSEvent(event) sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: @@ -19,7 +25,7 @@ def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(s print(rec.message) -def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3) +def lambda_handler_sns_s3(event: SNSEvent = nested_test_events.sns_s3_event): # sns(s3) sns_event = SNSEvent(event) s3_event = sns_event.decode_nested_events(S3Event) for rec in s3_event: @@ -27,14 +33,14 @@ def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3) print('rec:', rec.bucket_name) -def lambda_handler_sqs_s3_multi(event: SQSEvent = test_events.sqs_s3_multi_event): # sqs(s3, s3) +def lambda_handler_sqs_s3_multi(event: SQSEvent = nested_test_events.sqs_s3_multi_event): # sqs(s3, s3) sqs_event = SQSEvent(event) s3_event = sqs_event.decode_nested_events(S3Event) for rec in s3_event: print('rec:', rec.bucket_name) -def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # sqs(sns(s3)) +def lambda_handler_sqs_sns_s3(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) sqs_event = SQSEvent(event) sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: @@ -43,26 +49,25 @@ def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # s3_event = rec.decode_nested_events(S3Event) print('s3 rec:', type(s3_event), s3_event) - # print(s3_event.bucket_name) # not working - print(next(s3_event).bucket_name) # TODO: why isn't it calling snsmessage nested events without this line? + print(next(s3_event).bucket_name) -def lambda_handler_sns_ses(event: SNSEvent = test_events.sns_ses_event): # sns(ses) +def lambda_handler_sns_ses(event: SNSEvent = nested_test_events.sns_ses_event): # sns(ses) sns_event = SNSEvent(event) ses_event = sns_event.decode_nested_events(SESMessage) - for rec in ses_event: #TODO: how to get the first record without the for loop + for rec in ses_event: print('rec:', type(rec), rec) print('rec:', rec.get("mail").get('source')) # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key -def lambda_handler_eb_s3(event: EventBridgeEvent = test_events.eb_s3_event): # eventbridge(s3) +def lambda_handler_eb_s3(event: EventBridgeEvent = nested_test_events.eb_s3_event): # eventbridge(s3) eb_event = EventBridgeEvent(event) s3_event = eb_event.decode_nested_events(S3Event) for rec in s3_event: print('type:', type(rec)) print('rec:', rec.bucket_name) -def lambda_handler_sqs_eb_s3(event: test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) +def lambda_handler_sqs_eb_s3(event: nested_test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) sqs_event = SQSEvent(event) for rec in sqs_event: eb_event = sqs_event.decode_nested_events(EventBridgeEvent) @@ -73,12 +78,28 @@ def lambda_handler_sqs_eb_s3(event: test_events.sqs_eb_s3_event): # sqs(eventbri print(type(r)) print('rec:', r.bucket_name) +def lambda_handler_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) + firehose_event = KinesisFirehoseEvent(event) + sns_event = firehose_event.decode_nested_events(SNSEvent) + #just gives back the encrypted data, so can't cast it into SNSEvent, have to decrypt it and then cast it to get the SNSEvent + for rec in sns_event: + print('type:', type(rec), rec) + print('rec:', rec.sns_message) + +def lambda_handler_firehose_cw_event(event = nested_test_events.firehose_cw_event): # firehose(cw) + firehose_event = KinesisFirehoseEvent(event) + cw_event = firehose_event.decode_nested_events(CloudWatchLogsLogEvent) + for rec in cw_event: + print('type:', type(rec), rec) -lambda_handler_sqs_s3(test_events.sqs_s3_event) -lambda_handler_sqs_sns(test_events.sqs_sns_event) -lambda_handler_sns_s3(test_events.sns_s3_event) -lambda_handler_sqs_s3_multi(test_events.sqs_s3_multi_event) -lambda_handler_sqs_sns_s3(test_events.sqs_sns_s3_event) -lambda_handler_sns_ses(test_events.sns_ses_event) # not being casted correctly bc no "SES" key but works as dict +lambda_handler_sqs_s3(nested_test_events.sqs_s3_event) +lambda_handler_sqs_s3_single(nested_test_events.sqs_s3_event) +lambda_handler_sqs_sns(nested_test_events.sqs_sns_event) +lambda_handler_sns_s3(nested_test_events.sns_s3_event) +lambda_handler_sqs_s3_multi(nested_test_events.sqs_s3_multi_event) +lambda_handler_sqs_sns_s3(nested_test_events.sqs_sns_s3_event) +lambda_handler_sns_ses(nested_test_events.sns_ses_event) # not being casted correctly bc no "SES" key but works as dict +# lambda_handler_firehose_sns_event(test_events.firehose_sns_event) # just gives back the encrypted data, so can't cast it +# lambda_handler_firehose_cw_event(test_events.firehose_cw_event) # just gives back the encrypted data, so can't cast it # lambda_handler_eb_s3(test_events.eb_s3_event) #the nested s3 event isn't a full s3 event bc doesn't have a Records key at the top level. so can't call the s3 methods on it # lambda_handler_sqs_eb_s3(test_events.sqs_eb_s3_event) #same as above diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index 43cbf7eba33..eb1df781242 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -262,7 +262,6 @@ def receipt(self) -> SESReceipt: return self.record.ses.receipt def nested_event_contents(self): - print('IN SES NESTED EVENTS') - for record in self["Records"]: - body = record['ses'] + for record in self.get("Records"): + body = record.get('ses') yield body diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index c3bc2d60f0f..c2beea87a4a 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -1,8 +1,4 @@ from typing import Dict, Iterator -import test_events -import jsonschema -from jsonschema import validate - from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper @@ -129,6 +125,6 @@ def sns_message(self) -> str: return self.record.sns.message def nested_event_contents(self): - for record in self["Records"]: - body = record['Sns']['Message'] + for record in self.get("Records"): + body = record.get('Sns').get('Message') yield body From 432d8a6717b557df83a2d90e4c3deda6fabc5203 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Thu, 11 Apr 2024 22:58:06 -0700 Subject: [PATCH 07/14] Fixed EB event unwrapping --- .../utilities/data_classes/common.py | 5 +- .../data_classes/kinesis_firehose_event.py | 3 +- .../data_classes/nested_test_events.py | 6 +- .../utilities/data_classes/poc.py | 77 +++++++++++-------- .../utilities/data_classes/s3_event.py | 6 +- 5 files changed, 54 insertions(+), 43 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 387ca2501af..7a593f0c6c4 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -10,7 +10,6 @@ get_multi_value_query_string_values, get_query_string_value, ) -from aws_lambda_powertools.utilities.data_classes.exceptions import ClassTransformationException class DictWrapper(Mapping): @@ -118,12 +117,12 @@ def nested_event_contents(self): raise KeyError("No 'Records' key found in the event data.") for record in records: if not isinstance(record, dict): - raise TypeError(f"Expected each record to be a dictionary, but got {type(record)}.") + raise TypeError(f"Expected 'Records' to be a dictionary, but got {type(record)}.") body = record.get('body') if body is not None: yield body else: - raise KeyError("No 'body' key found in the record.") + raise KeyError("No 'body' key found in the 'Records' dict.") def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): if nested_event_content_deserializer is None: diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 8178036e10f..bd268cfee67 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -208,7 +208,7 @@ def subsequence_number(self) -> int: return self._metadata["subsequenceNumber"] -class KinesisFirehoseRecord(DictWrapper): +class KinesisFirehoseRecord(EventWrapper): @property def approximate_arrival_timestamp(self) -> int: """The approximate time that the record was inserted into the delivery stream""" @@ -307,4 +307,5 @@ def records(self) -> Iterator[KinesisFirehoseRecord]: def nested_event_contents(self): for record in self.get("records"): body = record.get("data") + body = base64.b64decode(body).decode('utf-8') #TODO: should we decode for them? yield body diff --git a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py index 2bf877377a0..bf2a8ca9f71 100644 --- a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -10,7 +10,7 @@ { "recordId": "49650562840674497170060081706384853755200261109279883266000000", "approximateArrivalTimestamp": 1711562009882, - "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMWIzZTEyNDQtZWNjOS01NmFiLTliODUtNGMzYWIzOTA4ZWU5IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZSIsIlN1YmplY3QiOiJkZGRkZGRkZGRkZGRkZGRkZGQiLCJNZXNzYWdlIjoiZXdyZXdycXdyZXdyXG5zZGFkXG5hc2RcbmFzZFxuYXNcbmR4IiwiVGltZXN0YW1wIjoiMjAyNC0wMy0yN1QxNzo1MzoyOS44MDRaIiwiVW5zdWJzY3JpYmVVUkwiOiJodHRwczovL3Nucy51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZTo2OTZlMzRhNS1mZDBiLTRhYjQtYjEyMi05ZmZhNzEwYjg5OTUifQo=" + "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMWIzZTEyNDQtZWNjOS01NmFiLTliODUtNGMzYWIzOTA4ZWU5IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZSIsIlN1YmplY3QiOiJzbnMgc3ViamVjdCIsIk1lc3NhZ2UiOiJtZXNzYWdlIGZyb20gc25zIiwiVGltZXN0YW1wIjoiMjAyNC0wMy0yN1QxNzo1MzoyOS44MDRaIiwiVW5zdWJzY3JpYmVVUkwiOiJodHRwczovL3Nucy51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZTo2OTZlMzRhNS1mZDBiLTRhYjQtYjEyMi05ZmZhNzEwYjg5OTUifQ==" } ] } @@ -172,14 +172,14 @@ "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": "{\"Records\":[" + - "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket11\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + + "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket1\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + "]}" }, { "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": "{\"Records\":[" + - "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket22\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + + "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket2\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + "]}" } ], diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index c954c6fc8b8..0a60084211b 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -2,95 +2,98 @@ from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage from aws_lambda_powertools.utilities.data_classes.ses_event import SESMessage from aws_lambda_powertools.utilities.data_classes.cloud_watch_logs_event import CloudWatchLogsLogEvent +from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events -# TODO: unit tests + def lambda_handler_sqs_s3(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) sqs_event = SQSEvent(event) s3_event = sqs_event.decode_nested_events(S3Event) for rec in s3_event: - print('rec:', rec.bucket_name) + print('sqs_s3_event bucket:', rec.bucket_name) def lambda_handler_sqs_s3_single(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) sqs_event = SQSEvent(event) s3_event = sqs_event.decode_nested_event(S3Event) - print('bucket:', s3_event.bucket_name) + print('sqs_s3_event_direct bucket:', s3_event.bucket_name) def lambda_handler_sqs_sns(event: SQSEvent = nested_test_events.sqs_sns_event): # sqs(sns) sqs_event = SQSEvent(event) sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: - print('rec:', type(rec)) - print(rec.message) + # print('rec:', type(rec)) + print('sqs_sns_event message:', rec.message) def lambda_handler_sns_s3(event: SNSEvent = nested_test_events.sns_s3_event): # sns(s3) sns_event = SNSEvent(event) s3_event = sns_event.decode_nested_events(S3Event) for rec in s3_event: - print(type(rec)) - print('rec:', rec.bucket_name) + # print(type(rec)) + print('sns_s3_event bucket:', rec.bucket_name) def lambda_handler_sqs_s3_multi(event: SQSEvent = nested_test_events.sqs_s3_multi_event): # sqs(s3, s3) sqs_event = SQSEvent(event) s3_event = sqs_event.decode_nested_events(S3Event) for rec in s3_event: - print('rec:', rec.bucket_name) + print('sqs_s3_multi_event bucket:', rec.bucket_name) def lambda_handler_sqs_sns_s3(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) sqs_event = SQSEvent(event) sns_event = sqs_event.decode_nested_events(SNSMessage) for rec in sns_event: - print('sns rec:', type(rec), rec) - print('sns message:', rec.message) + # print('sns rec:', type(rec), rec) + # print('sns message:', rec.message) s3_event = rec.decode_nested_events(S3Event) - print('s3 rec:', type(s3_event), s3_event) - print(next(s3_event).bucket_name) + # print('s3 rec:', type(s3_event), s3_event) + print('sqs_sns_s3_event bucket:', next(s3_event).bucket_name) def lambda_handler_sns_ses(event: SNSEvent = nested_test_events.sns_ses_event): # sns(ses) sns_event = SNSEvent(event) ses_event = sns_event.decode_nested_events(SESMessage) for rec in ses_event: - print('rec:', type(rec), rec) - print('rec:', rec.get("mail").get('source')) + # print('rec:', type(rec), rec) + print('sns_ses_event email:', rec.get("mail").get('source')) # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key def lambda_handler_eb_s3(event: EventBridgeEvent = nested_test_events.eb_s3_event): # eventbridge(s3) eb_event = EventBridgeEvent(event) - s3_event = eb_event.decode_nested_events(S3Event) + s3_event = eb_event.decode_nested_events(S3EventBridgeNotificationDetail) for rec in s3_event: - print('type:', type(rec)) - print('rec:', rec.bucket_name) + # print('type:', type(rec)) + print('eb_s3_event bucket:', rec.bucket.name) def lambda_handler_sqs_eb_s3(event: nested_test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) sqs_event = SQSEvent(event) for rec in sqs_event: eb_event = sqs_event.decode_nested_events(EventBridgeEvent) for rec in eb_event: - print('rec:', type(rec), rec) - s3_event = rec.decode_nested_events(S3Event) + # print('rec:', type(rec), rec) + s3_event = rec.decode_nested_events(S3EventBridgeNotificationDetail) for r in s3_event: - print(type(r)) - print('rec:', r.bucket_name) + # print(type(r)) + print('sqs_eb_s3_event bucket:', r.bucket.name) def lambda_handler_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) firehose_event = KinesisFirehoseEvent(event) - sns_event = firehose_event.decode_nested_events(SNSEvent) + sns_event = firehose_event.decode_nested_events(SNSMessage) #just gives back the encrypted data, so can't cast it into SNSEvent, have to decrypt it and then cast it to get the SNSEvent for rec in sns_event: - print('type:', type(rec), rec) - print('rec:', rec.sns_message) + print('firehose_sns_event message:', rec.message) + + +# def lambda_handler_firehose_cw_event(event = nested_test_events.firehose_cw_event): # firehose(cw) +# firehose_event = KinesisFirehoseEvent(event) +# cw_event = firehose_event.decode_nested_events(CloudWatchLogsLogEvent) +# for rec in cw_event: +# print('type:', type(rec), rec) + -def lambda_handler_firehose_cw_event(event = nested_test_events.firehose_cw_event): # firehose(cw) - firehose_event = KinesisFirehoseEvent(event) - cw_event = firehose_event.decode_nested_events(CloudWatchLogsLogEvent) - for rec in cw_event: - print('type:', type(rec), rec) lambda_handler_sqs_s3(nested_test_events.sqs_s3_event) lambda_handler_sqs_s3_single(nested_test_events.sqs_s3_event) @@ -99,7 +102,15 @@ def lambda_handler_firehose_cw_event(event = nested_test_events.firehose_cw_even lambda_handler_sqs_s3_multi(nested_test_events.sqs_s3_multi_event) lambda_handler_sqs_sns_s3(nested_test_events.sqs_sns_s3_event) lambda_handler_sns_ses(nested_test_events.sns_ses_event) # not being casted correctly bc no "SES" key but works as dict -# lambda_handler_firehose_sns_event(test_events.firehose_sns_event) # just gives back the encrypted data, so can't cast it -# lambda_handler_firehose_cw_event(test_events.firehose_cw_event) # just gives back the encrypted data, so can't cast it -# lambda_handler_eb_s3(test_events.eb_s3_event) #the nested s3 event isn't a full s3 event bc doesn't have a Records key at the top level. so can't call the s3 methods on it -# lambda_handler_sqs_eb_s3(test_events.sqs_eb_s3_event) #same as above +lambda_handler_eb_s3(nested_test_events.eb_s3_event) +lambda_handler_sqs_eb_s3(nested_test_events.sqs_eb_s3_event) +lambda_handler_firehose_sns_event(nested_test_events.firehose_sns_event) + + + + + + + + +# lambda_handler_firehose_cw_event(nested_test_events.firehose_cw_event) # gives back the encrypted data, and can't be decoded w b64 diff --git a/aws_lambda_powertools/utilities/data_classes/s3_event.py b/aws_lambda_powertools/utilities/data_classes/s3_event.py index 1546e86f4d1..9b92a87dde5 100644 --- a/aws_lambda_powertools/utilities/data_classes/s3_event.py +++ b/aws_lambda_powertools/utilities/data_classes/s3_event.py @@ -19,13 +19,13 @@ def source_ip_address(self) -> str: return self["requestParameters"]["sourceIPAddress"] -class S3EventNotificationEventBridgeBucket(DictWrapper): +class S3EventNotificationEventBridgeBucket(EventWrapper): @property def name(self) -> str: return self["name"] -class S3EventBridgeNotificationObject(DictWrapper): +class S3EventBridgeNotificationObject(EventWrapper): @property def key(self) -> str: """Object key""" @@ -52,7 +52,7 @@ def sequencer(self) -> str: return self["sequencer"] -class S3EventBridgeNotificationDetail(DictWrapper): +class S3EventBridgeNotificationDetail(EventWrapper): @property def version(self) -> str: """Get the detail version""" From 02935e04b4f4884027260f19ac604a48ae8b28da Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 12 Apr 2024 11:36:50 -0700 Subject: [PATCH 08/14] Fixed triple nested to not use iterator --- .../utilities/data_classes/poc.py | 33 +++++++++++-------- .../utilities/data_classes/ses_event.py | 10 +++--- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py index 0a60084211b..20fe800a822 100644 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ b/aws_lambda_powertools/utilities/data_classes/poc.py @@ -1,12 +1,11 @@ from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent, KinesisFirehoseEvent from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage -from aws_lambda_powertools.utilities.data_classes.ses_event import SESMessage +from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord, SESMailCommonHeaders from aws_lambda_powertools.utilities.data_classes.cloud_watch_logs_event import CloudWatchLogsLogEvent from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events - def lambda_handler_sqs_s3(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) sqs_event = SQSEvent(event) s3_event = sqs_event.decode_nested_events(S3Event) @@ -41,21 +40,28 @@ def lambda_handler_sqs_s3_multi(event: SQSEvent = nested_test_events.sqs_s3_mult print('sqs_s3_multi_event bucket:', rec.bucket_name) -def lambda_handler_sqs_sns_s3(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) +def lambda_handler_sqs_sns_s3_direct(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) sqs_event = SQSEvent(event) - sns_event = sqs_event.decode_nested_events(SNSMessage) - for rec in sns_event: - # print('sns rec:', type(rec), rec) - # print('sns message:', rec.message) + sns_event = sqs_event.decode_nested_event(SNSMessage) + s3_event = sns_event.decode_nested_event(S3Event) + print('sqs_sns_s3_direct bucket:', s3_event.bucket_name) - s3_event = rec.decode_nested_events(S3Event) - # print('s3 rec:', type(s3_event), s3_event) - print('sqs_sns_s3_event bucket:', next(s3_event).bucket_name) + +def lambda_handler_sqs_sns_s3(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) + sqs_event = SQSEvent(event) + for rec in sqs_event: + sns_event = sqs_event.decode_nested_events(SNSMessage) + for rec in sns_event: + # print('rec:', type(rec), rec) + s3_event = rec.decode_nested_events(S3Event) + for r in s3_event: + # print(type(r)) + print('sqs_sns_s3 bucket:', r.bucket_name) def lambda_handler_sns_ses(event: SNSEvent = nested_test_events.sns_ses_event): # sns(ses) sns_event = SNSEvent(event) - ses_event = sns_event.decode_nested_events(SESMessage) + ses_event = sns_event.decode_nested_events(SESEventRecord) for rec in ses_event: # print('rec:', type(rec), rec) print('sns_ses_event email:', rec.get("mail").get('source')) @@ -68,6 +74,7 @@ def lambda_handler_eb_s3(event: EventBridgeEvent = nested_test_events.eb_s3_even # print('type:', type(rec)) print('eb_s3_event bucket:', rec.bucket.name) + def lambda_handler_sqs_eb_s3(event: nested_test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) sqs_event = SQSEvent(event) for rec in sqs_event: @@ -79,10 +86,10 @@ def lambda_handler_sqs_eb_s3(event: nested_test_events.sqs_eb_s3_event): # sqs(e # print(type(r)) print('sqs_eb_s3_event bucket:', r.bucket.name) + def lambda_handler_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) firehose_event = KinesisFirehoseEvent(event) sns_event = firehose_event.decode_nested_events(SNSMessage) - #just gives back the encrypted data, so can't cast it into SNSEvent, have to decrypt it and then cast it to get the SNSEvent for rec in sns_event: print('firehose_sns_event message:', rec.message) @@ -94,7 +101,7 @@ def lambda_handler_firehose_sns_event(event = nested_test_events.firehose_sns_ev # print('type:', type(rec), rec) - +lambda_handler_sqs_sns_s3_direct(nested_test_events.sqs_sns_s3_event) lambda_handler_sqs_s3(nested_test_events.sqs_s3_event) lambda_handler_sqs_s3_single(nested_test_events.sqs_s3_event) lambda_handler_sqs_sns(nested_test_events.sqs_sns_event) diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index eb1df781242..7e4a291039a 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -3,7 +3,7 @@ from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper -class SESMailHeader(DictWrapper): +class SESMailHeader(EventWrapper): @property def name(self) -> str: return self["name"] @@ -13,7 +13,7 @@ def value(self) -> str: return self["value"] -class SESMailCommonHeaders(DictWrapper): +class SESMailCommonHeaders(EventWrapper): @property def return_path(self) -> str: """The values in the Return-Path header of the email.""" @@ -111,7 +111,7 @@ def common_headers(self) -> SESMailCommonHeaders: return SESMailCommonHeaders(self["commonHeaders"]) -class SESReceiptStatus(DictWrapper): +class SESReceiptStatus(EventWrapper): @property def status(self) -> str: """Receipt status @@ -120,7 +120,7 @@ def status(self) -> str: return str(self["status"]) -class SESReceiptAction(DictWrapper): +class SESReceiptAction(EventWrapper): @property def get_type(self) -> str: """String that indicates the type of action that was executed. @@ -149,7 +149,7 @@ def invocation_type(self) -> str: return self["invocationType"] -class SESReceipt(DictWrapper): +class SESReceipt(EventWrapper): @property def timestamp(self) -> str: """String that specifies the date and time at which the action was triggered, in ISO 8601 format.""" From ab594f1d859137ef58178b9e64a89eaf4b42239f Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 19 Apr 2024 23:19:12 -0700 Subject: [PATCH 09/14] Adding unit tests --- .../utilities/data_classes/poc.py | 123 ------------------ 1 file changed, 123 deletions(-) delete mode 100644 aws_lambda_powertools/utilities/data_classes/poc.py diff --git a/aws_lambda_powertools/utilities/data_classes/poc.py b/aws_lambda_powertools/utilities/data_classes/poc.py deleted file mode 100644 index 20fe800a822..00000000000 --- a/aws_lambda_powertools/utilities/data_classes/poc.py +++ /dev/null @@ -1,123 +0,0 @@ -from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent, KinesisFirehoseEvent -from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage -from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord, SESMailCommonHeaders -from aws_lambda_powertools.utilities.data_classes.cloud_watch_logs_event import CloudWatchLogsLogEvent -from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail -import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events - - -def lambda_handler_sqs_s3(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) - sqs_event = SQSEvent(event) - s3_event = sqs_event.decode_nested_events(S3Event) - for rec in s3_event: - print('sqs_s3_event bucket:', rec.bucket_name) - -def lambda_handler_sqs_s3_single(event: SQSEvent = nested_test_events.sqs_s3_event): # sqs(s3) - sqs_event = SQSEvent(event) - s3_event = sqs_event.decode_nested_event(S3Event) - print('sqs_s3_event_direct bucket:', s3_event.bucket_name) - -def lambda_handler_sqs_sns(event: SQSEvent = nested_test_events.sqs_sns_event): # sqs(sns) - sqs_event = SQSEvent(event) - sns_event = sqs_event.decode_nested_events(SNSMessage) - for rec in sns_event: - # print('rec:', type(rec)) - print('sqs_sns_event message:', rec.message) - - -def lambda_handler_sns_s3(event: SNSEvent = nested_test_events.sns_s3_event): # sns(s3) - sns_event = SNSEvent(event) - s3_event = sns_event.decode_nested_events(S3Event) - for rec in s3_event: - # print(type(rec)) - print('sns_s3_event bucket:', rec.bucket_name) - - -def lambda_handler_sqs_s3_multi(event: SQSEvent = nested_test_events.sqs_s3_multi_event): # sqs(s3, s3) - sqs_event = SQSEvent(event) - s3_event = sqs_event.decode_nested_events(S3Event) - for rec in s3_event: - print('sqs_s3_multi_event bucket:', rec.bucket_name) - - -def lambda_handler_sqs_sns_s3_direct(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) - sqs_event = SQSEvent(event) - sns_event = sqs_event.decode_nested_event(SNSMessage) - s3_event = sns_event.decode_nested_event(S3Event) - print('sqs_sns_s3_direct bucket:', s3_event.bucket_name) - - -def lambda_handler_sqs_sns_s3(event: SQSEvent = nested_test_events.sqs_sns_s3_event): # sqs(sns(s3)) - sqs_event = SQSEvent(event) - for rec in sqs_event: - sns_event = sqs_event.decode_nested_events(SNSMessage) - for rec in sns_event: - # print('rec:', type(rec), rec) - s3_event = rec.decode_nested_events(S3Event) - for r in s3_event: - # print(type(r)) - print('sqs_sns_s3 bucket:', r.bucket_name) - - -def lambda_handler_sns_ses(event: SNSEvent = nested_test_events.sns_ses_event): # sns(ses) - sns_event = SNSEvent(event) - ses_event = sns_event.decode_nested_events(SESEventRecord) - for rec in ses_event: - # print('rec:', type(rec), rec) - print('sns_ses_event email:', rec.get("mail").get('source')) - # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key - -def lambda_handler_eb_s3(event: EventBridgeEvent = nested_test_events.eb_s3_event): # eventbridge(s3) - eb_event = EventBridgeEvent(event) - s3_event = eb_event.decode_nested_events(S3EventBridgeNotificationDetail) - for rec in s3_event: - # print('type:', type(rec)) - print('eb_s3_event bucket:', rec.bucket.name) - - -def lambda_handler_sqs_eb_s3(event: nested_test_events.sqs_eb_s3_event): # sqs(eventbridge(s3)) - sqs_event = SQSEvent(event) - for rec in sqs_event: - eb_event = sqs_event.decode_nested_events(EventBridgeEvent) - for rec in eb_event: - # print('rec:', type(rec), rec) - s3_event = rec.decode_nested_events(S3EventBridgeNotificationDetail) - for r in s3_event: - # print(type(r)) - print('sqs_eb_s3_event bucket:', r.bucket.name) - - -def lambda_handler_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) - firehose_event = KinesisFirehoseEvent(event) - sns_event = firehose_event.decode_nested_events(SNSMessage) - for rec in sns_event: - print('firehose_sns_event message:', rec.message) - - -# def lambda_handler_firehose_cw_event(event = nested_test_events.firehose_cw_event): # firehose(cw) -# firehose_event = KinesisFirehoseEvent(event) -# cw_event = firehose_event.decode_nested_events(CloudWatchLogsLogEvent) -# for rec in cw_event: -# print('type:', type(rec), rec) - - -lambda_handler_sqs_sns_s3_direct(nested_test_events.sqs_sns_s3_event) -lambda_handler_sqs_s3(nested_test_events.sqs_s3_event) -lambda_handler_sqs_s3_single(nested_test_events.sqs_s3_event) -lambda_handler_sqs_sns(nested_test_events.sqs_sns_event) -lambda_handler_sns_s3(nested_test_events.sns_s3_event) -lambda_handler_sqs_s3_multi(nested_test_events.sqs_s3_multi_event) -lambda_handler_sqs_sns_s3(nested_test_events.sqs_sns_s3_event) -lambda_handler_sns_ses(nested_test_events.sns_ses_event) # not being casted correctly bc no "SES" key but works as dict -lambda_handler_eb_s3(nested_test_events.eb_s3_event) -lambda_handler_sqs_eb_s3(nested_test_events.sqs_eb_s3_event) -lambda_handler_firehose_sns_event(nested_test_events.firehose_sns_event) - - - - - - - - -# lambda_handler_firehose_cw_event(nested_test_events.firehose_cw_event) # gives back the encrypted data, and can't be decoded w b64 From fb0be619093a37eb065fbd7e664f12e3dadbd54a Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 19 Apr 2024 23:20:49 -0700 Subject: [PATCH 10/14] Added unit tests --- tests/unit/data_classes/test_nested_events.py | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 tests/unit/data_classes/test_nested_events.py diff --git a/tests/unit/data_classes/test_nested_events.py b/tests/unit/data_classes/test_nested_events.py new file mode 100644 index 00000000000..b51de1c4842 --- /dev/null +++ b/tests/unit/data_classes/test_nested_events.py @@ -0,0 +1,110 @@ +from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent, KinesisFirehoseEvent +from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage +from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord +from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail +import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events + +def test_sqs_s3(): # sqs(s3) + raw_event = nested_test_events.sqs_s3_event + parsed_event = SQSEvent(raw_event) + + records = list(parsed_event.records) + assert len(records) == 1 + record = records[0] + record_raw = raw_event["Records"][0] + assert record.aws_region == record_raw["awsRegion"] + + s3_event = parsed_event.decode_nested_events(S3Event) + for rec in s3_event: + assert rec.bucket_name == "sqs-s3-unwrap-bucket-683517028648" + +def test_sqs_s3_single(): # sqs(s3) + raw_event = nested_test_events.sqs_s3_event + parsed_event = SQSEvent(raw_event) + + s3_event = parsed_event.decode_nested_event(S3Event) + assert s3_event.bucket_name == "sqs-s3-unwrap-bucket-683517028648" + +def test_sqs_sns(): # sqs(sns) + raw_event = nested_test_events.sqs_sns_event + parsed_event = SQSEvent(raw_event) + + sns_event = parsed_event.decode_nested_events(SNSMessage) + for rec in sns_event: + assert rec.message == "from sns" + +def test_sns_s3(): # sns(s3) + raw_event = nested_test_events.sns_s3_event + parsed_event = SNSEvent(raw_event) + + s3_event = parsed_event.decode_nested_events(S3Event) + for rec in s3_event: + assert rec.bucket_name == "s3-sns-unwrap-bucket-683517028648" + +def test_sqs_s3_multiple_events(): # sqs(s3, s3) + raw_event = nested_test_events.sqs_s3_multi_event + parsed_event = SQSEvent(raw_event) + + s3_event = parsed_event.decode_nested_events(S3Event) + for rec in s3_event: + print('sqs_s3_multi_event bucket:', rec.bucket_name) #TODO: + +def test_sqs_sns_s3_direct(): # sqs(sns(s3)) + raw_event = nested_test_events.sqs_sns_s3_event + parsed_event = SQSEvent(raw_event) + + sns_event = parsed_event.decode_nested_event(SNSMessage) + s3_event = sns_event.decode_nested_event(S3Event) + assert s3_event.bucket_name == "unwraptestevents-bucket-683517028648" + +def test_sqs_sns_s3(): # sqs(sns(s3)) + raw_event = nested_test_events.sqs_sns_s3_event + parsed_event = SQSEvent(raw_event) + + sns_event = parsed_event.decode_nested_events(SNSMessage) + for rec in sns_event: + s3_event = rec.decode_nested_events(S3Event) + for r in s3_event: + assert r.bucket_name == "unwraptestevents-bucket-683517028648" + +def test_sns_ses(): # sns(ses) + raw_event = nested_test_events.sns_ses_event + parsed_event = SNSEvent(raw_event) + ses_event = parsed_event.decode_nested_events(SESEventRecord) + for rec in ses_event: + assert rec.get("mail").get('source') == "seshub@amazon.com" + # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key + +def test_eb_s3(): # eventbridge(s3) + raw_event = nested_test_events.eb_s3_event + parsed_event = EventBridgeEvent(raw_event) + s3_event = parsed_event.decode_nested_events(S3EventBridgeNotificationDetail) + for rec in s3_event: + assert rec.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + + +def test_sqs_eb_s3(): # sqs(eventbridge(s3)) + raw_event = nested_test_events.sqs_eb_s3_event + parsed_event = SQSEvent(raw_event) + + eb_event = parsed_event.decode_nested_events(EventBridgeEvent) + for rec in eb_event: + s3_event = rec.decode_nested_events(S3EventBridgeNotificationDetail) + for r in s3_event: + assert r.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + +def test_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) + raw_event = nested_test_events.firehose_sns_event + parsed_event = KinesisFirehoseEvent(raw_event) + + sns_event = parsed_event.decode_nested_events(SNSMessage) #TODO: add a flag to auto decode? + for rec in sns_event: + assert rec.message == "message from sns" + +def test_firehose_cw_event(): # firehose(cw) + raw_event = nested_test_events.firehose_cw_event + parsed_event = KinesisFirehoseEvent(raw_event) + + # cw_event = parsed_event.decode_nested_events(CloudWatchLogsLogEvent) #TODO: gives back encrypted data, and can't be decoded w b64 + # for rec in cw_event: + # print('type:', type(rec), rec) From ee16fc6e0d0d854910eecbbf9eeb16324d0475ef Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 19 Apr 2024 23:31:13 -0700 Subject: [PATCH 11/14] fix linting --- .../utilities/data_classes/common.py | 24 +- .../data_classes/event_bridge_event.py | 4 +- .../utilities/data_classes/kafka_event.py | 6 +- .../data_classes/kinesis_firehose_event.py | 2 +- .../data_classes/nested_test_events.py | 452 +++++++++--------- .../utilities/data_classes/s3_object_event.py | 6 +- .../utilities/data_classes/ses_event.py | 4 +- .../utilities/data_classes/sns_event.py | 3 +- tests/unit/data_classes/test_nested_events.py | 55 ++- 9 files changed, 289 insertions(+), 267 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 0faf5fb73a2..0bf5e56f536 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -2,7 +2,7 @@ import json from collections.abc import Mapping from functools import cached_property -from typing import Any, Callable, Dict, Iterator, List, Optional, overload, Type, TypeVar +from typing import Any, Callable, Dict, Iterator, List, Optional, Type, TypeVar, overload from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer from aws_lambda_powertools.utilities.data_classes.shared_functions import ( @@ -94,8 +94,8 @@ def raw_event(self) -> Dict[str, Any]: """The original raw event dict""" return self._data -class EventWrapper(DictWrapper): +class EventWrapper(DictWrapper): NestedEvent = TypeVar("NestedEvent", bound=DictWrapper) def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = None): @@ -105,7 +105,7 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = data : Dict[str, Any] Lambda Event Source Event payload json_deserializer : Callable, optional - function to deserialize `str`, `bytes`, `bytearray` + function to deserialize `str`, `bytes`, `bytearray` containing a JSON document to a Python `obj`, by default json.loads """ @@ -118,13 +118,13 @@ def nested_event_contents(self): for record in records: if not isinstance(record, dict): raise TypeError(f"Expected 'Records' to be a dictionary, but got {type(record)}.") - body = record.get('body') + body = record.get("body") if body is not None: yield body else: raise KeyError("No 'body' key found in the 'Records' dict.") - def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): + def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer=None): if nested_event_content_deserializer is None: nested_event_content_deserializer = self._json_deserializer @@ -132,7 +132,7 @@ def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_eve deserialized_data = nested_event_content_deserializer(content) yield nested_event_class(deserialized_data) - def decode_nested_event(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None): + def decode_nested_event(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer=None): if nested_event_content_deserializer is None: nested_event_content_deserializer = self._json_deserializer @@ -219,10 +219,12 @@ def http_method(self) -> str: return self["httpMethod"] @overload - def get_query_string_value(self, name: str, default_value: str) -> str: ... + def get_query_string_value(self, name: str, default_value: str) -> str: + ... @overload - def get_query_string_value(self, name: str, default_value: Optional[str] = None) -> Optional[str]: ... + def get_query_string_value(self, name: str, default_value: Optional[str] = None) -> Optional[str]: + ... def get_query_string_value(self, name: str, default_value: Optional[str] = None) -> Optional[str]: """Get query string value by name @@ -275,7 +277,8 @@ def get_header_value( name: str, default_value: str, case_sensitive: bool = False, - ) -> str: ... + ) -> str: + ... @overload def get_header_value( @@ -283,7 +286,8 @@ def get_header_value( name: str, default_value: Optional[str] = None, case_sensitive: bool = False, - ) -> Optional[str]: ... + ) -> Optional[str]: + ... def get_header_value( self, diff --git a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py index b1c7f2b90af..7c921182f89 100644 --- a/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +++ b/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py @@ -1,7 +1,7 @@ import json from typing import Any, Dict, List, Optional -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper +from aws_lambda_powertools.utilities.data_classes.common import EventWrapper class EventBridgeEvent(EventWrapper): @@ -70,4 +70,4 @@ def replay_name(self) -> Optional[str]: return self["replay-name"] def nested_event_contents(self): - yield json.dumps(self.get('detail')) + yield json.dumps(self.get("detail")) diff --git a/aws_lambda_powertools/utilities/data_classes/kafka_event.py b/aws_lambda_powertools/utilities/data_classes/kafka_event.py index f20c5254730..33e97edcf09 100644 --- a/aws_lambda_powertools/utilities/data_classes/kafka_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kafka_event.py @@ -75,7 +75,8 @@ def get_header_value( name: str, default_value: str, case_sensitive: bool = True, - ) -> str: ... + ) -> str: + ... @overload def get_header_value( @@ -83,7 +84,8 @@ def get_header_value( name: str, default_value: Optional[str] = None, case_sensitive: bool = True, - ) -> Optional[str]: ... + ) -> Optional[str]: + ... def get_header_value( self, diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index bd268cfee67..55454364d14 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -307,5 +307,5 @@ def records(self) -> Iterator[KinesisFirehoseRecord]: def nested_event_contents(self): for record in self.get("records"): body = record.get("data") - body = base64.b64decode(body).decode('utf-8') #TODO: should we decode for them? + body = base64.b64decode(body).decode("utf-8") yield body diff --git a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py index bf2a8ca9f71..eb8799d1d4e 100644 --- a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -3,288 +3,284 @@ # sns -> firehose -> lambda = firehose(sns) firehose_sns_event = { - "invocationId": "b1332a68-805c-418f-8bb6-075f5b991134", - "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", - "region": "us-east-1", - "records": [ - { - "recordId": "49650562840674497170060081706384853755200261109279883266000000", - "approximateArrivalTimestamp": 1711562009882, - "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMWIzZTEyNDQtZWNjOS01NmFiLTliODUtNGMzYWIzOTA4ZWU5IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZSIsIlN1YmplY3QiOiJzbnMgc3ViamVjdCIsIk1lc3NhZ2UiOiJtZXNzYWdlIGZyb20gc25zIiwiVGltZXN0YW1wIjoiMjAyNC0wMy0yN1QxNzo1MzoyOS44MDRaIiwiVW5zdWJzY3JpYmVVUkwiOiJodHRwczovL3Nucy51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZTo2OTZlMzRhNS1mZDBiLTRhYjQtYjEyMi05ZmZhNzEwYjg5OTUifQ==" - } - ] + "invocationId": "b1332a68-805c-418f-8bb6-075f5b991134", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", + "region": "us-east-1", + "records": [ + { + "recordId": "49650562840674497170060081706384853755200261109279883266000000", + "approximateArrivalTimestamp": 1711562009882, + "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMWIzZTEyNDQtZWNjOS01NmFiLTliODUtNGMzYWIzOTA4ZWU5IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZSIsIlN1YmplY3QiOiJzbnMgc3ViamVjdCIsIk1lc3NhZ2UiOiJtZXNzYWdlIGZyb20gc25zIiwiVGltZXN0YW1wIjoiMjAyNC0wMy0yN1QxNzo1MzoyOS44MDRaIiwiVW5zdWJzY3JpYmVVUkwiOiJodHRwczovL3Nucy51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTE6MjAwOTg0MTEyMzg2OnNucy10by1maXJlaG9zZTo2OTZlMzRhNS1mZDBiLTRhYjQtYjEyMi05ZmZhNzEwYjg5OTUifQ==", + }, + ], } # CW -> firehose -> lambda = firehose(cw) firehose_cw_event = { - "invocationId": "cbef637e-fb9e-4c48-84c6-0d04f21f347d", - "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", - "region": "us-east-1", - "records": [ - { - "recordId": "49650562840674497170060081706233738027748410540928532482000000", - "approximateArrivalTimestamp": 1711561691435, - "data": "H4sIAAAAAAAA/zWOwQrCMBAFfyXsuQhRVMxNpHqpFqzgQURiuzbBNinZrUXEf5daPQ5v4M0LaiTSJR6eDYKCVbo77NPkso2zbLmJIQLfOQz9Uvm26DTnJvElQQSVLzfBtw0oGCjjgLoekNor5cE2bL1b24oxEKjT+evFD3Tc4wtsMehsayTWdQNKzqWczuRsISfzcfTP6wOOifjliV+eEiuD+d26UhjUFRvhb6JAYut0/yzWNqDxhCN4n98fsU8ThOwAAAA=" - }, - { - "recordId": "49650562840674497170060081706248245137583787946450878466000000", - "approximateArrivalTimestamp": 1711561718674, - "data": "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" - }, - { - "recordId": "49650562840674497170060081706253080840862247081624993794000000", - "approximateArrivalTimestamp": 1711561727636, - "data": "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" - } - ] + "invocationId": "cbef637e-fb9e-4c48-84c6-0d04f21f347d", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:200984112386:deliverystream/PUT-S3-vqmly", + "region": "us-east-1", + "records": [ + { + "recordId": "49650562840674497170060081706233738027748410540928532482000000", + "approximateArrivalTimestamp": 1711561691435, + "data": "H4sIAAAAAAAA/zWOwQrCMBAFfyXsuQhRVMxNpHqpFqzgQURiuzbBNinZrUXEf5daPQ5v4M0LaiTSJR6eDYKCVbo77NPkso2zbLmJIQLfOQz9Uvm26DTnJvElQQSVLzfBtw0oGCjjgLoekNor5cE2bL1b24oxEKjT+evFD3Tc4wtsMehsayTWdQNKzqWczuRsISfzcfTP6wOOifjliV+eEiuD+d26UhjUFRvhb6JAYut0/yzWNqDxhCN4n98fsU8ThOwAAAA=", + }, + { + "recordId": "49650562840674497170060081706248245137583787946450878466000000", + "approximateArrivalTimestamp": 1711561718674, + "data": "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", + }, + { + "recordId": "49650562840674497170060081706253080840862247081624993794000000", + "approximateArrivalTimestamp": 1711561727636, + "data": "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", + }, + ], } # ses -> sns -> lambda = sns(ses) sns_ses_event = { - "Records": [ - { - "EventSource": "aws:sns", - "EventVersion": "1.0", - "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", - "Sns": { - "Type": "Notification", - "MessageId": "14cc1773-477c-51e2-8b02-490f43dd19a3", - "TopicArn": "arn:aws:sns:us-east-1:683517028648:ses-sns", - "Subject": "Amazon SES Email Event Notification", - "Message": "{\"eventType\":\"Send\",\"mail\":{\"timestamp\":\"2024-03-25T23:01:53.733Z\",\"source\":\"seshub@amazon.com\",\"sourceArn\":\"arn:aws:ses:us-east-1:683517028648:identity/seshub@amazon.com\",\"sendingAccountId\":\"683517028648\",\"messageId\":\"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000\",\"destination\":[\"success@simulator.amazonses.com\"],\"headersTruncated\":false,\"headers\":[{\"name\":\"From\",\"value\":\"seshub@amazon.com\"},{\"name\":\"To\",\"value\":\"success@simulator.amazonses.com\"},{\"name\":\"Subject\",\"value\":\"subject test from ses!!!!\"},{\"name\":\"MIME-Version\",\"value\":\"1.0\"},{\"name\":\"Content-Type\",\"value\":\"multipart/alternative; boundary=\\\"----=_Part_467214_1288460597.1711407713733\\\"\"}],\"commonHeaders\":{\"from\":[\"seshub@amazon.com\"],\"to\":[\"success@simulator.amazonses.com\"],\"messageId\":\"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000\",\"subject\":\"subject test from ses!!!!\"},\"tags\":{\"ses:source-tls-version\":[\"TLSv1.3\"],\"ses:operation\":[\"SendEmail\"],\"ses:configuration-set\":[\"my-first-configuration-set\"],\"ses:source-ip\":[\"15.248.7.48\"],\"ses:from-domain\":[\"amazon.com\"],\"ses:caller-identity\":[\"Admin\"]}},\"send\":{}}\n", - "Timestamp": "2024-03-25T23:01:53.935Z", - "SignatureVersion": "1", - "Signature": "DRfrfPLo2KTGw/GweWUe2uGgK8jhwac1OQQq1HJ3Bo7HFEBDp4c6AjUyoYAGQYzKskxXSJBYJyrj9B3WOU7OPisM/b7+eLWjtRNohIM5B/yzrveQRV8W4GwjX0JpdC247VZB9Z01D+M01kVYVwiOO50lS/kpLrAnGksrdmGnF2Z2FQuh6mh8bCpQgoz1xTXUF94hqR6Tuj2R+bYNWxkCEZ18rg8FgrQfaonxiM/R5J1CjMW8P8KAP4nSdeBUAgFBXG8W72V1gSbjIH7a4uOyGZfFPooQZ4EUd9/eC6VlcxvjwwVmy0/x5oE2mHDU/s7NulOafTKTTA/V4/xFp6yqbQ==", - "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", - "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", - "MessageAttributes": {} - } - } - ] + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", + "Sns": { + "Type": "Notification", + "MessageId": "14cc1773-477c-51e2-8b02-490f43dd19a3", + "TopicArn": "arn:aws:sns:us-east-1:683517028648:ses-sns", + "Subject": "Amazon SES Email Event Notification", + "Message": '{"eventType":"Send","mail":{"timestamp":"2024-03-25T23:01:53.733Z","source":"seshub@amazon.com","sourceArn":"arn:aws:ses:us-east-1:683517028648:identity/seshub@amazon.com","sendingAccountId":"683517028648","messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","destination":["success@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"seshub@amazon.com"},{"name":"To","value":"success@simulator.amazonses.com"},{"name":"Subject","value":"subject test from ses!!!!"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\\"----=_Part_467214_1288460597.1711407713733\\""}],"commonHeaders":{"from":["seshub@amazon.com"],"to":["success@simulator.amazonses.com"],"messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","subject":"subject test from ses!!!!"},"tags":{"ses:source-tls-version":["TLSv1.3"],"ses:operation":["SendEmail"],"ses:configuration-set":["my-first-configuration-set"],"ses:source-ip":["15.248.7.48"],"ses:from-domain":["amazon.com"],"ses:caller-identity":["Admin"]}},"send":{}}\n', + "Timestamp": "2024-03-25T23:01:53.935Z", + "SignatureVersion": "1", + "Signature": "DRfrfPLo2KTGw/GweWUe2uGgK8jhwac1OQQq1HJ3Bo7HFEBDp4c6AjUyoYAGQYzKskxXSJBYJyrj9B3WOU7OPisM/b7+eLWjtRNohIM5B/yzrveQRV8W4GwjX0JpdC247VZB9Z01D+M01kVYVwiOO50lS/kpLrAnGksrdmGnF2Z2FQuh6mh8bCpQgoz1xTXUF94hqR6Tuj2R+bYNWxkCEZ18rg8FgrQfaonxiM/R5J1CjMW8P8KAP4nSdeBUAgFBXG8W72V1gSbjIH7a4uOyGZfFPooQZ4EUd9/eC6VlcxvjwwVmy0/x5oE2mHDU/s7NulOafTKTTA/V4/xFp6yqbQ==", + "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", + "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:ses-sns:a2059001-6ef2-4d4d-a6b8-5c3717210c15", + "MessageAttributes": {}, + }, + }, + ], } # s3 -> eventbridge -> sqs -> lambda = sqs(eventbridge(s3)) sqs_eb_s3_event = { - "Records": [ - { - "messageId": "ee95829a-ba32-471d-9684-34368ab9995e", - "receiptHandle": "AQEBZoMhwYaEfxvSOWGnwMurMIe2sEkwsV9l5e+pDpa2zCtdWLBfbUNxIX5R8O9hx+jAXhpj01bHElvli+LtPNBJarb4V+JEg2Hql3lSdkISTEECrWc8Dm8eX+p+LeyoN9cSnfDUoqQ2rd/BSFt9/vk6ro+w/kM8G1q7Lt1PB6G51LbfzXYA+KYUPLWIeYK2NMDf8TyvC0PbERE6im9H+eqJznyPWNznfziwq7d6ZIpY3GSfRrED/0tfr3FvzIVCVsOBuPHyd5stqcrgkCs2Dt/f7DWYWr1KMSqFDM1u4S7wMIroCVSfe9wsqimLBwaHZcG1zukaW16c51TiRI3zNzOl3cuDZgqPAK1rQKsj3x+VLqxnbyIgx24oIKhh5XqcZfzRbBwX4HDF/Opv8cN16+0yTw==", - "body": "{\"version\":\"0\",\"id\":\"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4\",\"detail-type\":\"Object Created\",\"source\":\"aws.s3\",\"account\":\"683517028648\",\"time\":\"2024-03-26T18:05:54Z\",\"region\":\"us-east-1\",\"resources\":[\"arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"],\"detail\":{\"version\":\"0\",\"bucket\":{\"name\":\"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu\"},\"object\":{\"key\":\"__init__.py\",\"size\":0,\"etag\":\"d41d8cd98f00b204e9800998ecf8427e\",\"sequencer\":\"0066030E82E2A48DFE\"},\"request-id\":\"HWEZ4KKQMXVWATHJ\",\"requester\":\"683517028648\",\"source-ip-address\":\"00.111.2.3\",\"reason\":\"PutObject\"}}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1711476356070", - "SenderId": "AIDAJXNJGGKNS7OSV23OI", - "ApproximateFirstReceiveTimestamp": "1711476356085" - }, - "messageAttributes": {}, - "md5OfBody": "3fc2529293127eb705317a37dca18ef4", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:s3-eb-sqs-unwrap", - "awsRegion": "us-east-1" - } - ] + "Records": [ + { + "messageId": "ee95829a-ba32-471d-9684-34368ab9995e", + "receiptHandle": "AQEBZoMhwYaEfxvSOWGnwMurMIe2sEkwsV9l5e+pDpa2zCtdWLBfbUNxIX5R8O9hx+jAXhpj01bHElvli+LtPNBJarb4V+JEg2Hql3lSdkISTEECrWc8Dm8eX+p+LeyoN9cSnfDUoqQ2rd/BSFt9/vk6ro+w/kM8G1q7Lt1PB6G51LbfzXYA+KYUPLWIeYK2NMDf8TyvC0PbERE6im9H+eqJznyPWNznfziwq7d6ZIpY3GSfRrED/0tfr3FvzIVCVsOBuPHyd5stqcrgkCs2Dt/f7DWYWr1KMSqFDM1u4S7wMIroCVSfe9wsqimLBwaHZcG1zukaW16c51TiRI3zNzOl3cuDZgqPAK1rQKsj3x+VLqxnbyIgx24oIKhh5XqcZfzRbBwX4HDF/Opv8cN16+0yTw==", + "body": '{"version":"0","id":"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4","detail-type":"Object Created","source":"aws.s3","account":"683517028648","time":"2024-03-26T18:05:54Z","region":"us-east-1","resources":["arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"],"detail":{"version":"0","bucket":{"name":"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"},"object":{"key":"__init__.py","size":0,"etag":"d41d8cd98f00b204e9800998ecf8427e","sequencer":"0066030E82E2A48DFE"},"request-id":"HWEZ4KKQMXVWATHJ","requester":"683517028648","source-ip-address":"00.111.2.3","reason":"PutObject"}}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1711476356070", + "SenderId": "AIDAJXNJGGKNS7OSV23OI", + "ApproximateFirstReceiveTimestamp": "1711476356085", + }, + "messageAttributes": {}, + "md5OfBody": "3fc2529293127eb705317a37dca18ef4", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:s3-eb-sqs-unwrap", + "awsRegion": "us-east-1", + }, + ], } # s3 -> eventbridge -> lambda = eventbridge(s3) eb_s3_event = { - "version": "0", - "id": "78eac3e6-798f-c27e-49ec-bbe3be7bab7d", - "detail-type": "Object Created", - "source": "aws.s3", - "account": "683517028648", - "time": "2024-03-20T23:56:16Z", - "region": "us-east-1", - "resources": [ - "arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" - ], - "detail": { "version": "0", - "bucket": { - "name": "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + "id": "78eac3e6-798f-c27e-49ec-bbe3be7bab7d", + "detail-type": "Object Created", + "source": "aws.s3", + "account": "683517028648", + "time": "2024-03-20T23:56:16Z", + "region": "us-east-1", + "resources": ["arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"], + "detail": { + "version": "0", + "bucket": {"name": "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"}, + "object": { + "key": "s3-eb-template.yaml", + "size": 1565, + "etag": "e56e21b1610dd94e9907f82b8d05b934", + "sequencer": "0065FB77A03AD4478F", + }, + "request-id": "SW5MRVMJG8NG1GMZ", + "requester": "683517028648", + "source-ip-address": "00.11.222.333", + "reason": "PutObject", }, - "object": { - "key": "s3-eb-template.yaml", - "size": 1565, - "etag": "e56e21b1610dd94e9907f82b8d05b934", - "sequencer": "0065FB77A03AD4478F" - }, - "request-id": "SW5MRVMJG8NG1GMZ", - "requester": "683517028648", - "source-ip-address": "00.11.222.333", - "reason": "PutObject" - } } # s3 -> sns -> sqs -> lambda = sqs(sns(s3)) sqs_sns_s3_event = { - "Records": [ - { - "messageId": "45405be4-2278-4eef-a29c-993898bb8917", - "receiptHandle": "AQEBy2gRrluag0E0vWiKlHZhcf6Ymtgkf92PlWtTQ4PKOPdF3NcUqKEzKtKbiTN7d+qy64nN3F97DOQr9b4xegJidHlXlyIwsYxQIpmGfDETCKPS5nchXOWRLIu/a/bpCmaZK/Mv1r6lAaF2gnoX7JaVpdTbExLRBQqOIcb2NRXmfeE0yKZtIT0TV9pstzsAi328KGbr1QMKOV0RKrE1NtQDpa/ixeEUWrZeGqwA7Cwy0BMevfoQKVkO78JrDsn4W/lUt2R+oRF7sB62+onfbIlBPmi+LXV4WeSrB7w1yvnMbVuvfgHDS9F1LEs62wJTNVQz6224s3OBfJZsAaSpW1IzD+UttqFJ3KTadu6HZMbCq+I2An+cQjqZ3zDsEV7Vwm6LH+04RGA3b9edBLgIoMbfcg==", - "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"53c941f5-1d7a-5f8e-8ffe-1f8110f6e667\",\n \"TopicArn\" : \"arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op\",\n \"Subject\" : \"Amazon S3 Notification\",\n \"Message\" : \"{\\\"Records\\\":[{\\\"eventVersion\\\":\\\"2.1\\\",\\\"eventSource\\\":\\\"aws:s3\\\",\\\"awsRegion\\\":\\\"us-west-2\\\",\\\"eventTime\\\":\\\"2024-03-19T22:01:47.135Z\\\",\\\"eventName\\\":\\\"ObjectCreated:Put\\\",\\\"userIdentity\\\":{\\\"principalId\\\":\\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\\"},\\\"requestParameters\\\":{\\\"sourceIPAddress\\\":\\\"000.111.222.333\\\"},\\\"responseElements\\\":{\\\"x-amz-request-id\\\":\\\"02TFARRDG75KXGG6\\\",\\\"x-amz-id-2\\\":\\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\\"},\\\"s3\\\":{\\\"s3SchemaVersion\\\":\\\"1.0\\\",\\\"configurationId\\\":\\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\\",\\\"bucket\\\":{\\\"name\\\":\\\"unwraptestevents-bucket-683517028648\\\",\\\"ownerIdentity\\\":{\\\"principalId\\\":\\\"A2RRIR5BTZTTF6\\\"},\\\"arn\\\":\\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\\"},\\\"object\\\":{\\\"key\\\":\\\"firehose-s3-template.json\\\",\\\"size\\\":4314,\\\"eTag\\\":\\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\\",\\\"sequencer\\\":\\\"0065FA0B4B104A6DAB\\\"}}}]}\",\n \"Timestamp\" : \"2024-03-19T22:01:48.137Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==\",\n \"SigningCertURL\" : \"https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea\"\n}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1710885708191", - "SenderId": "AIDAIYLAVTDLUXBIEIX46", - "ApproximateFirstReceiveTimestamp": "1710885708202" - }, - "messageAttributes": {}, - "md5OfBody": "2dfc1cc4f8f1240a50d7cdc65c7dd2b3", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", - "awsRegion": "us-west-2" - } - ] + "Records": [ + { + "messageId": "45405be4-2278-4eef-a29c-993898bb8917", + "receiptHandle": "AQEBy2gRrluag0E0vWiKlHZhcf6Ymtgkf92PlWtTQ4PKOPdF3NcUqKEzKtKbiTN7d+qy64nN3F97DOQr9b4xegJidHlXlyIwsYxQIpmGfDETCKPS5nchXOWRLIu/a/bpCmaZK/Mv1r6lAaF2gnoX7JaVpdTbExLRBQqOIcb2NRXmfeE0yKZtIT0TV9pstzsAi328KGbr1QMKOV0RKrE1NtQDpa/ixeEUWrZeGqwA7Cwy0BMevfoQKVkO78JrDsn4W/lUt2R+oRF7sB62+onfbIlBPmi+LXV4WeSrB7w1yvnMbVuvfgHDS9F1LEs62wJTNVQz6224s3OBfJZsAaSpW1IzD+UttqFJ3KTadu6HZMbCq+I2An+cQjqZ3zDsEV7Vwm6LH+04RGA3b9edBLgIoMbfcg==", + "body": '{\n "Type" : "Notification",\n "MessageId" : "53c941f5-1d7a-5f8e-8ffe-1f8110f6e667",\n "TopicArn" : "arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op",\n "Subject" : "Amazon S3 Notification",\n "Message" : "{\\"Records\\":[{\\"eventVersion\\":\\"2.1\\",\\"eventSource\\":\\"aws:s3\\",\\"awsRegion\\":\\"us-west-2\\",\\"eventTime\\":\\"2024-03-19T22:01:47.135Z\\",\\"eventName\\":\\"ObjectCreated:Put\\",\\"userIdentity\\":{\\"principalId\\":\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\"},\\"requestParameters\\":{\\"sourceIPAddress\\":\\"000.111.222.333\\"},\\"responseElements\\":{\\"x-amz-request-id\\":\\"02TFARRDG75KXGG6\\",\\"x-amz-id-2\\":\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\"},\\"s3\\":{\\"s3SchemaVersion\\":\\"1.0\\",\\"configurationId\\":\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\",\\"bucket\\":{\\"name\\":\\"unwraptestevents-bucket-683517028648\\",\\"ownerIdentity\\":{\\"principalId\\":\\"A2RRIR5BTZTTF6\\"},\\"arn\\":\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\"},\\"object\\":{\\"key\\":\\"firehose-s3-template.json\\",\\"size\\":4314,\\"eTag\\":\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\",\\"sequencer\\":\\"0065FA0B4B104A6DAB\\"}}}]}",\n "Timestamp" : "2024-03-19T22:01:48.137Z",\n "SignatureVersion" : "1",\n "Signature" : "cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==",\n "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea"\n}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710885708191", + "SenderId": "AIDAIYLAVTDLUXBIEIX46", + "ApproximateFirstReceiveTimestamp": "1710885708202", + }, + "messageAttributes": {}, + "md5OfBody": "2dfc1cc4f8f1240a50d7cdc65c7dd2b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", + "awsRegion": "us-west-2", + }, + ], } # s3 -> raw_sns -> sqs -> lambda = sqs(raw_sns(s3)) sqs_rawsns_s3_event = { - "Records": [ - { - "messageId": "519619da-e529-46d7-b58c-bc054405af0f", - "receiptHandle": "AQEB//A8ci4+iToNBE66jNulMi/7cpVqiC7YkdTnQA0qhTOnWv55SDgxh+CV7WckD1xT3V9zBh2APTr1qtB7i29GepU/lzqFvS2wozjDljP7YHbWHn77hOeCwtfVFbJoqUyEL/+QcFIMZ06AUP0h+SAjJDype/x0WnCGqKd3juaRmECEk4LFc+g1evZ9DIP+Lkw3JM44JHAcgq4+Sm+Pv/dEZXHIoOL8S5mV4f0l+fJk9TDOLGbTCCEuMfWmrQBAVgJt052y0y6my2rAGO2iQdwkONXdPUrbxBSmeb/sDEp4qy4CViKgDzTo+Ii2sLDggKxeRrWaLzdFvv50ebTnLx8RHUsVnAiNv8DsJJOJx3ryw8gKO0o4TaMB8KQ4Zh2hAglgakSwjeMzCrTI7tyF1ML65A==", - "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-west-2\",\"eventTime\":\"2024-03-19T22:57:48.823Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"000.111.222.333\"},\"responseElements\":{\"x-amz-request-id\":\"HQDSXXWNQWRCN3PQ\",\"x-amz-id-2\":\"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\",\"bucket\":{\"name\":\"unwraptestevents-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::unwraptestevents-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"9cc7da5febb07868706f59ab70d89981\",\"sequencer\":\"0065FA186CC08E810D\"}}}]}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1710889069948", - "SenderId": "AIDAIYLAVTDLUXBIEIX46", - "ApproximateFirstReceiveTimestamp": "1710889069955" - }, - "messageAttributes": {}, - "md5OfBody": "94ff55fa8f439b3d2e43366d582de0b7", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", - "awsRegion": "us-west-2" - } - ] + "Records": [ + { + "messageId": "519619da-e529-46d7-b58c-bc054405af0f", + "receiptHandle": "AQEB//A8ci4+iToNBE66jNulMi/7cpVqiC7YkdTnQA0qhTOnWv55SDgxh+CV7WckD1xT3V9zBh2APTr1qtB7i29GepU/lzqFvS2wozjDljP7YHbWHn77hOeCwtfVFbJoqUyEL/+QcFIMZ06AUP0h+SAjJDype/x0WnCGqKd3juaRmECEk4LFc+g1evZ9DIP+Lkw3JM44JHAcgq4+Sm+Pv/dEZXHIoOL8S5mV4f0l+fJk9TDOLGbTCCEuMfWmrQBAVgJt052y0y6my2rAGO2iQdwkONXdPUrbxBSmeb/sDEp4qy4CViKgDzTo+Ii2sLDggKxeRrWaLzdFvv50ebTnLx8RHUsVnAiNv8DsJJOJx3ryw8gKO0o4TaMB8KQ4Zh2hAglgakSwjeMzCrTI7tyF1ML65A==", + "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-west-2","eventTime":"2024-03-19T22:57:48.823Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"000.111.222.333"},"responseElements":{"x-amz-request-id":"HQDSXXWNQWRCN3PQ","x-amz-id-2":"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx","bucket":{"name":"unwraptestevents-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::unwraptestevents-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"9cc7da5febb07868706f59ab70d89981","sequencer":"0065FA186CC08E810D"}}}]}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710889069948", + "SenderId": "AIDAIYLAVTDLUXBIEIX46", + "ApproximateFirstReceiveTimestamp": "1710889069955", + }, + "messageAttributes": {}, + "md5OfBody": "94ff55fa8f439b3d2e43366d582de0b7", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-west-2:683517028648:SQSQueue1", + "awsRegion": "us-west-2", + }, + ], } # sqs(s3, s3) sqs_s3_multi_event = { - "Records": [ - { - "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", - "receiptHandle": "MessageReceiptHandle", - "body": "{\"Records\":[" + - "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket1\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + - "]}" + "Records": [ + { + "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", + "receiptHandle": "MessageReceiptHandle", + "body": '{"Records":[' + + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket1","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + + "]}", + }, + { + "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", + "receiptHandle": "MessageReceiptHandle", + "body": '{"Records":[' + + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket2","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + + "]}", + }, + ], + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1523232000000", + "SenderId": "123456789012", + "ApproximateFirstReceiveTimestamp": "1523232000001", }, - { - "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", - "receiptHandle": "MessageReceiptHandle", - "body": "{\"Records\":[" + - "{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-03T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id-3\",\"x-amz-id-2\":\"example-id-3\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket2\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object-3.txt\",\"size\":3072,\"eTag\":\"example-tag-3\",\"versionId\":\"3\",\"sequencer\":\"example-sequencer-3\"}}}" + - "]}" - } - ], - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1523232000000", - "SenderId": "123456789012", - "ApproximateFirstReceiveTimestamp": "1523232000001" - }, - "messageAttributes": {}, - "md5OfBody": "7b270e59b47ff90a553787216d55d91d", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", - "awsRegion": "us-east-1" + "messageAttributes": {}, + "md5OfBody": "7b270e59b47ff90a553787216d55d91d", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", + "awsRegion": "us-east-1", } # s3 -> sqs -> lambda == sqs(s3) sqs_s3_event = { - "Records": [ - { - "messageId": "44103047-3123-4583-aed3-7224000351a8", - "receiptHandle": "AQEBWOm6hlP5TEZ64yvPugVI7LyhkEAvaEfvqfyqheIBcqhKPg5wfb95MC9IYm60od3hlTdgT3lJ7l/8upj8eYsCVglkTYqUKXKqUOgotxiqhyLlJ2AOy0gPc1EL5Uek3e267IB/5XPz9msqZmxuI6/pcT+Ihj/26EXYVxOYEK4YwbhbBNhl5Wp4dn8anV3/LD/vvgRyHtOAK4MlwWgIBFT9wWyJInMcYRVtmAx1ODUMG1CpsB6IB5m11pazNnlV0kOSzjjBDB4QK/euMqpfnCbUB4dLb5WAwZ37pys9xKjypEFS1eHXjSwEG+rG4J8u2UlFDO13FQ8lsOJB96Sx/T7KIqTvhc8VayDPXFArTtT6dlXZlc99gYf8uDDcYRfUPnBK8KZ/pEI6UjQiOVjvgWhIDiu0SxrQ82ytPMxjvizWkv0=", - "body": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T19:02:45.087Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"00.111.2.3\"},\"responseElements\":{\"x-amz-request-id\":\"ST581J3PW8R8QKVP\",\"x-amz-id-2\":\"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh\",\"bucket\":{\"name\":\"sqs-s3-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"8f6c039f567cc53694be2a275e452743\",\"sequencer\":\"0065F349D4F05B5827\"}}}]}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1710442966490", - "SenderId": "AROA4R74ZO52XAB5OD7T4:S3-PROD-END", - "ApproximateFirstReceiveTimestamp": "1710442966494" - }, - "messageAttributes": {}, - "md5OfBody": "1b9d61fd8139b215ec65bd8916ac6872", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-s3-unwrap-Queue-9H8CEZEhJfP7", - "awsRegion": "us-east-1" - } - ] + "Records": [ + { + "messageId": "44103047-3123-4583-aed3-7224000351a8", + "receiptHandle": "AQEBWOm6hlP5TEZ64yvPugVI7LyhkEAvaEfvqfyqheIBcqhKPg5wfb95MC9IYm60od3hlTdgT3lJ7l/8upj8eYsCVglkTYqUKXKqUOgotxiqhyLlJ2AOy0gPc1EL5Uek3e267IB/5XPz9msqZmxuI6/pcT+Ihj/26EXYVxOYEK4YwbhbBNhl5Wp4dn8anV3/LD/vvgRyHtOAK4MlwWgIBFT9wWyJInMcYRVtmAx1ODUMG1CpsB6IB5m11pazNnlV0kOSzjjBDB4QK/euMqpfnCbUB4dLb5WAwZ37pys9xKjypEFS1eHXjSwEG+rG4J8u2UlFDO13FQ8lsOJB96Sx/T7KIqTvhc8VayDPXFArTtT6dlXZlc99gYf8uDDcYRfUPnBK8KZ/pEI6UjQiOVjvgWhIDiu0SxrQ82ytPMxjvizWkv0=", + "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T19:02:45.087Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.3"},"responseElements":{"x-amz-request-id":"ST581J3PW8R8QKVP","x-amz-id-2":"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh","bucket":{"name":"sqs-s3-unwrap-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"8f6c039f567cc53694be2a275e452743","sequencer":"0065F349D4F05B5827"}}}]}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710442966490", + "SenderId": "AROA4R74ZO52XAB5OD7T4:S3-PROD-END", + "ApproximateFirstReceiveTimestamp": "1710442966494", + }, + "messageAttributes": {}, + "md5OfBody": "1b9d61fd8139b215ec65bd8916ac6872", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-s3-unwrap-Queue-9H8CEZEhJfP7", + "awsRegion": "us-east-1", + }, + ], } # sns -> sqs -> lambda == sqs(sns) sqs_sns_event = { - "Records": [ - { - "messageId": "10ad507c-8389-4585-ae55-11d32ea71997", - "receiptHandle": "AQEB1nupmCFCI3lhVKz3fPFqO5kZKDNpzuflQ96kZwseTe5HRCb3eeY8XoWoyfcSDqNwjXdC/CQBjunectuzr+0mYhwVvo0GxRWF0U1J8/djdoxCACEELa+IxnWYA+2ernXEVPrisgWSf8D+woy02h58ybMzbP8pCxeld/1cqbBOt7vd0QC7pRcXDdFl0KWl0yYi1PTWyy6L5uTz4RIDsL867eh6xtKxKinp/N2Fym5/0/3TkfDLk+RNTVTTMmiRebP7hKSfsmYeAc7tcx8GHRvJdcN11XDPfW76+uQbIb9DtAIQobpQ4sJ2FOAapJ9U5IJ4leTfWjJ+L/L1fKo+vlkWiv9k+ktP9ABP214ylpS8BVzn1dHjBGQ98pryKhE4jPm9J3SDYh/J3LSPxsjtUvF/p15pgvantoOYyobS7OMr9qM=", - "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"bf5ff648-5111-5dbe-ad4b-a82514ed6a35\",\n \"TopicArn\" : \"arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM\",\n \"Message\" : \"from sns\",\n \"Timestamp\" : \"2024-03-14T18:36:44.233Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"Ne7jvjmincHd06Y19dZss3Xk003RlAm/srm2dt5nLDgwrY0dI56RkH/Dbva9w8xy63EUHyUVfHCYvrXLh/HpsW5nXU9YetK7G5QpfxBeTPnNioPdJi2U3PDA+jJXs0DK4ffonwEMLjbmIETAiWdrN5ollBpL5zh2ZjurMh7TnUGH6/KxsFcWNHTPrGN/v9HSRoFtQdtl9i/zFmBVaXC4dvaZU0cy/gYK5uIIf+YJ+OJoXd7fCxZLVPIwnK148Ws3b/i85UyP0tVguscoknf37bTPwdQuloPOKQHtPZDxUdLjS+uj27LRwiT+1CvGqdgpJ8XV/8tWqujR3FDI3ZL6EQ==\",\n \"SigningCertURL\" : \"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n \"UnsubscribeURL\" : \"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM:42e6130c-54b0-4cec-a8c0-7d0cc356ea4e\"\n}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1710441404272", - "SenderId": "AIDAIT2UOQQY3AUEKVGXU", - "ApproximateFirstReceiveTimestamp": "1710441404278" - }, - "messageAttributes": {}, - "md5OfBody": "fb98571efddcc86ff1767f300518f455", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", - "awsRegion": "us-east-1" - } - ] + "Records": [ + { + "messageId": "10ad507c-8389-4585-ae55-11d32ea71997", + "receiptHandle": "AQEB1nupmCFCI3lhVKz3fPFqO5kZKDNpzuflQ96kZwseTe5HRCb3eeY8XoWoyfcSDqNwjXdC/CQBjunectuzr+0mYhwVvo0GxRWF0U1J8/djdoxCACEELa+IxnWYA+2ernXEVPrisgWSf8D+woy02h58ybMzbP8pCxeld/1cqbBOt7vd0QC7pRcXDdFl0KWl0yYi1PTWyy6L5uTz4RIDsL867eh6xtKxKinp/N2Fym5/0/3TkfDLk+RNTVTTMmiRebP7hKSfsmYeAc7tcx8GHRvJdcN11XDPfW76+uQbIb9DtAIQobpQ4sJ2FOAapJ9U5IJ4leTfWjJ+L/L1fKo+vlkWiv9k+ktP9ABP214ylpS8BVzn1dHjBGQ98pryKhE4jPm9J3SDYh/J3LSPxsjtUvF/p15pgvantoOYyobS7OMr9qM=", + "body": '{\n "Type" : "Notification",\n "MessageId" : "bf5ff648-5111-5dbe-ad4b-a82514ed6a35",\n "TopicArn" : "arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM",\n "Message" : "from sns",\n "Timestamp" : "2024-03-14T18:36:44.233Z",\n "SignatureVersion" : "1",\n "Signature" : "Ne7jvjmincHd06Y19dZss3Xk003RlAm/srm2dt5nLDgwrY0dI56RkH/Dbva9w8xy63EUHyUVfHCYvrXLh/HpsW5nXU9YetK7G5QpfxBeTPnNioPdJi2U3PDA+jJXs0DK4ffonwEMLjbmIETAiWdrN5ollBpL5zh2ZjurMh7TnUGH6/KxsFcWNHTPrGN/v9HSRoFtQdtl9i/zFmBVaXC4dvaZU0cy/gYK5uIIf+YJ+OJoXd7fCxZLVPIwnK148Ws3b/i85UyP0tVguscoknf37bTPwdQuloPOKQHtPZDxUdLjS+uj27LRwiT+1CvGqdgpJ8XV/8tWqujR3FDI3ZL6EQ==",\n "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM:42e6130c-54b0-4cec-a8c0-7d0cc356ea4e"\n}', + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710441404272", + "SenderId": "AIDAIT2UOQQY3AUEKVGXU", + "ApproximateFirstReceiveTimestamp": "1710441404278", + }, + "messageAttributes": {}, + "md5OfBody": "fb98571efddcc86ff1767f300518f455", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", + "awsRegion": "us-east-1", + }, + ], } # raw_sns -> sqs -> lambda == sqs(raw_sns) sqs_rawsns_event = { - "Records": [ - { - "messageId": "c2f72267-c1b4-432b-b35e-c27a337798d1", - "receiptHandle": "AQEB2+Do4Yh7HS58NLu1KQZMi69dTVWByZC140b3YS5Dl5hMjU5RlIkmHaxoyDArEzo1ZtJfOljU2aEZAf0nVkp6zosnWP3gqpueoM5RYeXTaYzQSAidCjMySSNWKnA4xzoI3uDhwcmguXAKxyTcgXd9pdiCQ8bXACZmqdzgL0RoKmgA9bIf0X3YYGlQ3X/ApEgxAyiD+ok1quVOj8jdqXfcJ1fbabwihtLTn6fxkVW6Z25gfrYTj8Ix90LdtWcmXjt/q9aJ30e3RdeVBhtB40C1glVm9R9cBvQQaog6z8yC+6H/eKKym25BRr8MJt9kx/e+8aMNKQowcnI/KYXwqSGRbTeml+5XXT5ANDr9qy1c4XEnl8k9vvozzlyYCjlLKOt+shhRfHULo4fzVunsO7GXpa7BW9ZtFJU31nlNCfLNYfk=", - "body": "this is a raw message", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1710887794983", - "SenderId": "AIDAIT2UOQQY3AUEKVGXU", - "ApproximateFirstReceiveTimestamp": "1710887794991" - }, - "messageAttributes": {}, - "md5OfBody": "dbfce666a3bf5ced0e8687d4c0039a74", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", - "awsRegion": "us-east-1" - } - ] + "Records": [ + { + "messageId": "c2f72267-c1b4-432b-b35e-c27a337798d1", + "receiptHandle": "AQEB2+Do4Yh7HS58NLu1KQZMi69dTVWByZC140b3YS5Dl5hMjU5RlIkmHaxoyDArEzo1ZtJfOljU2aEZAf0nVkp6zosnWP3gqpueoM5RYeXTaYzQSAidCjMySSNWKnA4xzoI3uDhwcmguXAKxyTcgXd9pdiCQ8bXACZmqdzgL0RoKmgA9bIf0X3YYGlQ3X/ApEgxAyiD+ok1quVOj8jdqXfcJ1fbabwihtLTn6fxkVW6Z25gfrYTj8Ix90LdtWcmXjt/q9aJ30e3RdeVBhtB40C1glVm9R9cBvQQaog6z8yC+6H/eKKym25BRr8MJt9kx/e+8aMNKQowcnI/KYXwqSGRbTeml+5XXT5ANDr9qy1c4XEnl8k9vvozzlyYCjlLKOt+shhRfHULo4fzVunsO7GXpa7BW9ZtFJU31nlNCfLNYfk=", + "body": "this is a raw message", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1710887794983", + "SenderId": "AIDAIT2UOQQY3AUEKVGXU", + "ApproximateFirstReceiveTimestamp": "1710887794991", + }, + "messageAttributes": {}, + "md5OfBody": "dbfce666a3bf5ced0e8687d4c0039a74", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-1:683517028648:sqs-sns-unwrap-Queue-F562gfvOiNHt", + "awsRegion": "us-east-1", + }, + ], } # s3 -> sns -> lambda == sns(s3). sns_s3_event = { - "Records": [ - { - "EventSource": "aws:sns", - "EventVersion": "1.0", - "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", - "Sns": { - "Type": "Notification", - "MessageId": "2d44624b-23f8-5e80-99d9-3c265035c5ae", - "TopicArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg", - "Subject": "Amazon S3 Notification", - "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2024-03-14T21:52:13.311Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\"},\"requestParameters\":{\"sourceIPAddress\":\"00.111.2.33\"},\"responseElements\":{\"x-amz-request-id\":\"53YYXE4TACR6K89G\",\"x-amz-id-2\":\"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2\",\"bucket\":{\"name\":\"s3-sns-unwrap-bucket-683517028648\",\"ownerIdentity\":{\"principalId\":\"A2RRIR5BTZTTF6\"},\"arn\":\"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648\"},\"object\":{\"key\":\"samconfig.toml\",\"size\":221,\"eTag\":\"551277913a5ad93e0db069e673f23376\",\"sequencer\":\"0065F3718D39E6D6DC\"}}}]}", - "Timestamp": "2024-03-14T21:52:13.905Z", - "SignatureVersion": "1", - "Signature": "IJqlNH8ddOX4V10m6IY+3gOK6/+PxxiGLs4PxHiGDcQ58mcCr4+vXCHuJ7jxOvCBHCYev1wF0PCwBhDpwBfstV8vAGEsX7GhJuAZ5jf0uOUMukZvIquy1LQBTdHg0TNq9N83sG0wz2QMp8QLLlkDJMF8nS00EjeDuFwpJxZnRadWcjz4AWXO6JITohyYnFVkDqsK5pOFd3Y1KADjfpRFH2lrljJm3CnA/x6PYVduP5PK83JnDs7LmEnK3cqE7IJhdwW9e824KXmjFBujoiNU9bUnoLiqFMg+UfZfMMJGjtCHIV0ZmnMix7nKZUGDNQe7TKOoDcXLxuAxa6TQNWfKSw==", - "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", - "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", - "MessageAttributes": {} - } - } - ] + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", + "Sns": { + "Type": "Notification", + "MessageId": "2d44624b-23f8-5e80-99d9-3c265035c5ae", + "TopicArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg", + "Subject": "Amazon S3 Notification", + "Message": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T21:52:13.311Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.33"},"responseElements":{"x-amz-request-id":"53YYXE4TACR6K89G","x-amz-id-2":"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L"},"s3":{"s3SchemaVersion":"1.0","configurationId":"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2","bucket":{"name":"s3-sns-unwrap-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"551277913a5ad93e0db069e673f23376","sequencer":"0065F3718D39E6D6DC"}}}]}', + "Timestamp": "2024-03-14T21:52:13.905Z", + "SignatureVersion": "1", + "Signature": "IJqlNH8ddOX4V10m6IY+3gOK6/+PxxiGLs4PxHiGDcQ58mcCr4+vXCHuJ7jxOvCBHCYev1wF0PCwBhDpwBfstV8vAGEsX7GhJuAZ5jf0uOUMukZvIquy1LQBTdHg0TNq9N83sG0wz2QMp8QLLlkDJMF8nS00EjeDuFwpJxZnRadWcjz4AWXO6JITohyYnFVkDqsK5pOFd3Y1KADjfpRFH2lrljJm3CnA/x6PYVduP5PK83JnDs7LmEnK3cqE7IJhdwW9e824KXmjFBujoiNU9bUnoLiqFMg+UfZfMMJGjtCHIV0ZmnMix7nKZUGDNQe7TKOoDcXLxuAxa6TQNWfKSw==", + "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem", + "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg:6b8dee7d-026a-4c2e-b3f2-a2f189e4a402", + "MessageAttributes": {}, + }, + }, + ], } diff --git a/aws_lambda_powertools/utilities/data_classes/s3_object_event.py b/aws_lambda_powertools/utilities/data_classes/s3_object_event.py index dc79b72766f..6a737fba447 100644 --- a/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +++ b/aws_lambda_powertools/utilities/data_classes/s3_object_event.py @@ -79,7 +79,8 @@ def get_header_value( name: str, default_value: str, case_sensitive: bool = False, - ) -> str: ... + ) -> str: + ... @overload def get_header_value( @@ -87,7 +88,8 @@ def get_header_value( name: str, default_value: Optional[str] = None, case_sensitive: bool = False, - ) -> Optional[str]: ... + ) -> Optional[str]: + ... def get_header_value( self, diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index 7e4a291039a..57a68e71ad9 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -1,6 +1,6 @@ from typing import Iterator, List, Optional -from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper +from aws_lambda_powertools.utilities.data_classes.common import EventWrapper class SESMailHeader(EventWrapper): @@ -263,5 +263,5 @@ def receipt(self) -> SESReceipt: def nested_event_contents(self): for record in self.get("Records"): - body = record.get('ses') + body = record.get("ses") yield body diff --git a/aws_lambda_powertools/utilities/data_classes/sns_event.py b/aws_lambda_powertools/utilities/data_classes/sns_event.py index c2beea87a4a..40590e50328 100644 --- a/aws_lambda_powertools/utilities/data_classes/sns_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sns_event.py @@ -1,4 +1,5 @@ from typing import Dict, Iterator + from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper @@ -126,5 +127,5 @@ def sns_message(self) -> str: def nested_event_contents(self): for record in self.get("Records"): - body = record.get('Sns').get('Message') + body = record.get("Sns").get("Message") yield body diff --git a/tests/unit/data_classes/test_nested_events.py b/tests/unit/data_classes/test_nested_events.py index b51de1c4842..6bc26d22fcc 100644 --- a/tests/unit/data_classes/test_nested_events.py +++ b/tests/unit/data_classes/test_nested_events.py @@ -1,10 +1,17 @@ -from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, EventBridgeEvent, KinesisFirehoseEvent -from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage -from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord -from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail import aws_lambda_powertools.utilities.data_classes.nested_test_events as nested_test_events +from aws_lambda_powertools.utilities.data_classes import ( + EventBridgeEvent, + KinesisFirehoseEvent, + S3Event, + SNSEvent, + SQSEvent, +) +from aws_lambda_powertools.utilities.data_classes.s3_event import S3EventBridgeNotificationDetail +from aws_lambda_powertools.utilities.data_classes.ses_event import SESEventRecord +from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage + -def test_sqs_s3(): # sqs(s3) +def test_sqs_s3(): # sqs(s3) raw_event = nested_test_events.sqs_s3_event parsed_event = SQSEvent(raw_event) @@ -18,14 +25,16 @@ def test_sqs_s3(): # sqs(s3) for rec in s3_event: assert rec.bucket_name == "sqs-s3-unwrap-bucket-683517028648" -def test_sqs_s3_single(): # sqs(s3) + +def test_sqs_s3_single(): # sqs(s3) raw_event = nested_test_events.sqs_s3_event parsed_event = SQSEvent(raw_event) s3_event = parsed_event.decode_nested_event(S3Event) assert s3_event.bucket_name == "sqs-s3-unwrap-bucket-683517028648" -def test_sqs_sns(): # sqs(sns) + +def test_sqs_sns(): # sqs(sns) raw_event = nested_test_events.sqs_sns_event parsed_event = SQSEvent(raw_event) @@ -33,7 +42,8 @@ def test_sqs_sns(): # sqs(sns) for rec in sns_event: assert rec.message == "from sns" -def test_sns_s3(): # sns(s3) + +def test_sns_s3(): # sns(s3) raw_event = nested_test_events.sns_s3_event parsed_event = SNSEvent(raw_event) @@ -41,15 +51,17 @@ def test_sns_s3(): # sns(s3) for rec in s3_event: assert rec.bucket_name == "s3-sns-unwrap-bucket-683517028648" -def test_sqs_s3_multiple_events(): # sqs(s3, s3) + +def test_sqs_s3_multiple_events(): # sqs(s3, s3) raw_event = nested_test_events.sqs_s3_multi_event parsed_event = SQSEvent(raw_event) s3_event = parsed_event.decode_nested_events(S3Event) for rec in s3_event: - print('sqs_s3_multi_event bucket:', rec.bucket_name) #TODO: + print("sqs_s3_multi_event bucket:", rec.bucket_name) # TODO: -def test_sqs_sns_s3_direct(): # sqs(sns(s3)) + +def test_sqs_sns_s3_direct(): # sqs(sns(s3)) raw_event = nested_test_events.sqs_sns_s3_event parsed_event = SQSEvent(raw_event) @@ -57,7 +69,8 @@ def test_sqs_sns_s3_direct(): # sqs(sns(s3)) s3_event = sns_event.decode_nested_event(S3Event) assert s3_event.bucket_name == "unwraptestevents-bucket-683517028648" -def test_sqs_sns_s3(): # sqs(sns(s3)) + +def test_sqs_sns_s3(): # sqs(sns(s3)) raw_event = nested_test_events.sqs_sns_s3_event parsed_event = SQSEvent(raw_event) @@ -67,15 +80,17 @@ def test_sqs_sns_s3(): # sqs(sns(s3)) for r in s3_event: assert r.bucket_name == "unwraptestevents-bucket-683517028648" -def test_sns_ses(): # sns(ses) + +def test_sns_ses(): # sns(ses) raw_event = nested_test_events.sns_ses_event parsed_event = SNSEvent(raw_event) ses_event = parsed_event.decode_nested_events(SESEventRecord) for rec in ses_event: - assert rec.get("mail").get('source') == "seshub@amazon.com" + assert rec.get("mail").get("source") == "seshub@amazon.com" # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key -def test_eb_s3(): # eventbridge(s3) + +def test_eb_s3(): # eventbridge(s3) raw_event = nested_test_events.eb_s3_event parsed_event = EventBridgeEvent(raw_event) s3_event = parsed_event.decode_nested_events(S3EventBridgeNotificationDetail) @@ -83,7 +98,7 @@ def test_eb_s3(): # eventbridge(s3) assert rec.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" -def test_sqs_eb_s3(): # sqs(eventbridge(s3)) +def test_sqs_eb_s3(): # sqs(eventbridge(s3)) raw_event = nested_test_events.sqs_eb_s3_event parsed_event = SQSEvent(raw_event) @@ -93,15 +108,17 @@ def test_sqs_eb_s3(): # sqs(eventbridge(s3)) for r in s3_event: assert r.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" -def test_firehose_sns_event(event = nested_test_events.firehose_sns_event): # firehose(sns) + +def test_firehose_sns_event(event=nested_test_events.firehose_sns_event): # firehose(sns) raw_event = nested_test_events.firehose_sns_event parsed_event = KinesisFirehoseEvent(raw_event) - sns_event = parsed_event.decode_nested_events(SNSMessage) #TODO: add a flag to auto decode? + sns_event = parsed_event.decode_nested_events(SNSMessage) # TODO: add a flag to auto decode? for rec in sns_event: assert rec.message == "message from sns" -def test_firehose_cw_event(): # firehose(cw) + +def test_firehose_cw_event(): # firehose(cw) raw_event = nested_test_events.firehose_cw_event parsed_event = KinesisFirehoseEvent(raw_event) From 6a0676cec14d8dbc4d173163021e25eba3303d7c Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Mon, 22 Apr 2024 17:56:41 -0700 Subject: [PATCH 12/14] Fixing unit tests --- .../utilities/data_classes/nested_test_events.py | 4 ++-- tests/unit/data_classes/test_nested_events.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py index eb8799d1d4e..a57cbe3817a 100644 --- a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -168,14 +168,14 @@ "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": '{"Records":[' - + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket1","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket0","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + "]}", }, { "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": '{"Records":[' - + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket2","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + + '{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2023-01-03T00:00:00.000Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:123456789012:example-user"},"requestParameters":{"sourceIPAddress":"127.0.0.1"},"responseElements":{"x-amz-request-id":"example-request-id-3","x-amz-id-2":"example-id-3"},"s3":{"s3SchemaVersion":"1.0","configurationId":"testConfigRule","bucket":{"name":"example-bucket1","ownerIdentity":{"principalId":"EXAMPLE"},"arn":"arn:aws:s3:::example-bucket"},"object":{"key":"example-object-3.txt","size":3072,"eTag":"example-tag-3","versionId":"3","sequencer":"example-sequencer-3"}}}' + "]}", }, ], diff --git a/tests/unit/data_classes/test_nested_events.py b/tests/unit/data_classes/test_nested_events.py index 6bc26d22fcc..3f29763e137 100644 --- a/tests/unit/data_classes/test_nested_events.py +++ b/tests/unit/data_classes/test_nested_events.py @@ -57,8 +57,8 @@ def test_sqs_s3_multiple_events(): # sqs(s3, s3) parsed_event = SQSEvent(raw_event) s3_event = parsed_event.decode_nested_events(S3Event) - for rec in s3_event: - print("sqs_s3_multi_event bucket:", rec.bucket_name) # TODO: + for idx, rec in enumerate(s3_event): + assert rec.bucket_name == "example-bucket"+str(idx) def test_sqs_sns_s3_direct(): # sqs(sns(s3)) @@ -109,7 +109,7 @@ def test_sqs_eb_s3(): # sqs(eventbridge(s3)) assert r.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" -def test_firehose_sns_event(event=nested_test_events.firehose_sns_event): # firehose(sns) +def test_firehose_sns_event(): # firehose(sns) raw_event = nested_test_events.firehose_sns_event parsed_event = KinesisFirehoseEvent(raw_event) @@ -122,6 +122,6 @@ def test_firehose_cw_event(): # firehose(cw) raw_event = nested_test_events.firehose_cw_event parsed_event = KinesisFirehoseEvent(raw_event) - # cw_event = parsed_event.decode_nested_events(CloudWatchLogsLogEvent) #TODO: gives back encrypted data, and can't be decoded w b64 + # cw_event = parsed_event.decode_nested_events(CloudWatchLogsLogEvent) #TODO: gives back encrypted data and can't decode w b64 # for rec in cw_event: # print('type:', type(rec), rec) From 7fb170e3e4506334d9da9f637ba61027d7d66df5 Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 26 Apr 2024 11:43:59 -0700 Subject: [PATCH 13/14] Updating tests --- .../data_classes/nested_test_events.py | 18 +++++++++--------- tests/unit/data_classes/test_nested_events.py | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py index a57cbe3817a..7bfd824f81c 100644 --- a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -53,7 +53,7 @@ "MessageId": "14cc1773-477c-51e2-8b02-490f43dd19a3", "TopicArn": "arn:aws:sns:us-east-1:683517028648:ses-sns", "Subject": "Amazon SES Email Event Notification", - "Message": '{"eventType":"Send","mail":{"timestamp":"2024-03-25T23:01:53.733Z","source":"seshub@amazon.com","sourceArn":"arn:aws:ses:us-east-1:683517028648:identity/seshub@amazon.com","sendingAccountId":"683517028648","messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","destination":["success@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"seshub@amazon.com"},{"name":"To","value":"success@simulator.amazonses.com"},{"name":"Subject","value":"subject test from ses!!!!"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\\"----=_Part_467214_1288460597.1711407713733\\""}],"commonHeaders":{"from":["seshub@amazon.com"],"to":["success@simulator.amazonses.com"],"messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","subject":"subject test from ses!!!!"},"tags":{"ses:source-tls-version":["TLSv1.3"],"ses:operation":["SendEmail"],"ses:configuration-set":["my-first-configuration-set"],"ses:source-ip":["15.248.7.48"],"ses:from-domain":["amazon.com"],"ses:caller-identity":["Admin"]}},"send":{}}\n', + "Message": '{"eventType":"Send","mail":{"timestamp":"2024-03-25T23:01:53.733Z","source":"jsmith@amazon.com","sourceArn":"arn:aws:ses:us-east-1:683517028648:identity/jsmith@amazon.com","sendingAccountId":"683517028648","messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","destination":["success@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"jsmith@amazon.com"},{"name":"To","value":"success@simulator.amazonses.com"},{"name":"Subject","value":"subject test from ses!!!!"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\\"----=_Part_467214_1288460597.1711407713733\\""}],"commonHeaders":{"from":["jsmith@amazon.com"],"to":["success@simulator.amazonses.com"],"messageId":"0100018e77d94dc5-c421e265-f034-4575-9ecc-3ca34038e91f-000000","subject":"subject test from ses!!!!"},"tags":{"ses:source-tls-version":["TLSv1.3"],"ses:operation":["SendEmail"],"ses:configuration-set":["my-first-configuration-set"],"ses:source-ip":["15.248.7.48"],"ses:from-domain":["amazon.com"],"ses:caller-identity":["Admin"]}},"send":{}}\n', "Timestamp": "2024-03-25T23:01:53.935Z", "SignatureVersion": "1", "Signature": "DRfrfPLo2KTGw/GweWUe2uGgK8jhwac1OQQq1HJ3Bo7HFEBDp4c6AjUyoYAGQYzKskxXSJBYJyrj9B3WOU7OPisM/b7+eLWjtRNohIM5B/yzrveQRV8W4GwjX0JpdC247VZB9Z01D+M01kVYVwiOO50lS/kpLrAnGksrdmGnF2Z2FQuh6mh8bCpQgoz1xTXUF94hqR6Tuj2R+bYNWxkCEZ18rg8FgrQfaonxiM/R5J1CjMW8P8KAP4nSdeBUAgFBXG8W72V1gSbjIH7a4uOyGZfFPooQZ4EUd9/eC6VlcxvjwwVmy0/x5oE2mHDU/s7NulOafTKTTA/V4/xFp6yqbQ==", @@ -72,7 +72,7 @@ { "messageId": "ee95829a-ba32-471d-9684-34368ab9995e", "receiptHandle": "AQEBZoMhwYaEfxvSOWGnwMurMIe2sEkwsV9l5e+pDpa2zCtdWLBfbUNxIX5R8O9hx+jAXhpj01bHElvli+LtPNBJarb4V+JEg2Hql3lSdkISTEECrWc8Dm8eX+p+LeyoN9cSnfDUoqQ2rd/BSFt9/vk6ro+w/kM8G1q7Lt1PB6G51LbfzXYA+KYUPLWIeYK2NMDf8TyvC0PbERE6im9H+eqJznyPWNznfziwq7d6ZIpY3GSfRrED/0tfr3FvzIVCVsOBuPHyd5stqcrgkCs2Dt/f7DWYWr1KMSqFDM1u4S7wMIroCVSfe9wsqimLBwaHZcG1zukaW16c51TiRI3zNzOl3cuDZgqPAK1rQKsj3x+VLqxnbyIgx24oIKhh5XqcZfzRbBwX4HDF/Opv8cN16+0yTw==", - "body": '{"version":"0","id":"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4","detail-type":"Object Created","source":"aws.s3","account":"683517028648","time":"2024-03-26T18:05:54Z","region":"us-east-1","resources":["arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"],"detail":{"version":"0","bucket":{"name":"s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"},"object":{"key":"__init__.py","size":0,"etag":"d41d8cd98f00b204e9800998ecf8427e","sequencer":"0066030E82E2A48DFE"},"request-id":"HWEZ4KKQMXVWATHJ","requester":"683517028648","source-ip-address":"00.111.2.3","reason":"PutObject"}}', + "body": '{"version":"0","id":"75012ec5-af4a-7e39-2dd4-a28b7bb8cde4","detail-type":"Object Created","source":"aws.s3","account":"683517028648","time":"2024-03-26T18:05:54Z","region":"us-east-1","resources":["arn:aws:s3:::s3-eb-unwrap-sourcebucket"],"detail":{"version":"0","bucket":{"name":"s3-eb-unwrap-sourcebucket"},"object":{"key":"__init__.py","size":0,"etag":"d41d8cd98f00b204e9800998ecf8427e","sequencer":"0066030E82E2A48DFE"},"request-id":"HWEZ4KKQMXVWATHJ","requester":"683517028648","source-ip-address":"00.111.2.3","reason":"PutObject"}}', "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1711476356070", @@ -98,10 +98,10 @@ "account": "683517028648", "time": "2024-03-20T23:56:16Z", "region": "us-east-1", - "resources": ["arn:aws:s3:::s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"], + "resources": ["arn:aws:s3:::s3-eb-unwrap-sourcebucket"], "detail": { "version": "0", - "bucket": {"name": "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu"}, + "bucket": {"name": "s3-eb-unwrap-sourcebucket"}, "object": { "key": "s3-eb-template.yaml", "size": 1565, @@ -122,7 +122,7 @@ { "messageId": "45405be4-2278-4eef-a29c-993898bb8917", "receiptHandle": "AQEBy2gRrluag0E0vWiKlHZhcf6Ymtgkf92PlWtTQ4PKOPdF3NcUqKEzKtKbiTN7d+qy64nN3F97DOQr9b4xegJidHlXlyIwsYxQIpmGfDETCKPS5nchXOWRLIu/a/bpCmaZK/Mv1r6lAaF2gnoX7JaVpdTbExLRBQqOIcb2NRXmfeE0yKZtIT0TV9pstzsAi328KGbr1QMKOV0RKrE1NtQDpa/ixeEUWrZeGqwA7Cwy0BMevfoQKVkO78JrDsn4W/lUt2R+oRF7sB62+onfbIlBPmi+LXV4WeSrB7w1yvnMbVuvfgHDS9F1LEs62wJTNVQz6224s3OBfJZsAaSpW1IzD+UttqFJ3KTadu6HZMbCq+I2An+cQjqZ3zDsEV7Vwm6LH+04RGA3b9edBLgIoMbfcg==", - "body": '{\n "Type" : "Notification",\n "MessageId" : "53c941f5-1d7a-5f8e-8ffe-1f8110f6e667",\n "TopicArn" : "arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op",\n "Subject" : "Amazon S3 Notification",\n "Message" : "{\\"Records\\":[{\\"eventVersion\\":\\"2.1\\",\\"eventSource\\":\\"aws:s3\\",\\"awsRegion\\":\\"us-west-2\\",\\"eventTime\\":\\"2024-03-19T22:01:47.135Z\\",\\"eventName\\":\\"ObjectCreated:Put\\",\\"userIdentity\\":{\\"principalId\\":\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\"},\\"requestParameters\\":{\\"sourceIPAddress\\":\\"000.111.222.333\\"},\\"responseElements\\":{\\"x-amz-request-id\\":\\"02TFARRDG75KXGG6\\",\\"x-amz-id-2\\":\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\"},\\"s3\\":{\\"s3SchemaVersion\\":\\"1.0\\",\\"configurationId\\":\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\",\\"bucket\\":{\\"name\\":\\"unwraptestevents-bucket-683517028648\\",\\"ownerIdentity\\":{\\"principalId\\":\\"A2RRIR5BTZTTF6\\"},\\"arn\\":\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\"},\\"object\\":{\\"key\\":\\"firehose-s3-template.json\\",\\"size\\":4314,\\"eTag\\":\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\",\\"sequencer\\":\\"0065FA0B4B104A6DAB\\"}}}]}",\n "Timestamp" : "2024-03-19T22:01:48.137Z",\n "SignatureVersion" : "1",\n "Signature" : "cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==",\n "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea"\n}', + "body": '{\n "Type" : "Notification",\n "MessageId" : "53c941f5-1d7a-5f8e-8ffe-1f8110f6e667",\n "TopicArn" : "arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op",\n "Subject" : "Amazon S3 Notification",\n "Message" : "{\\"Records\\":[{\\"eventVersion\\":\\"2.1\\",\\"eventSource\\":\\"aws:s3\\",\\"awsRegion\\":\\"us-west-2\\",\\"eventTime\\":\\"2024-03-19T22:01:47.135Z\\",\\"eventName\\":\\"ObjectCreated:Put\\",\\"userIdentity\\":{\\"principalId\\":\\"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard\\"},\\"requestParameters\\":{\\"sourceIPAddress\\":\\"000.111.222.333\\"},\\"responseElements\\":{\\"x-amz-request-id\\":\\"02TFARRDG75KXGG6\\",\\"x-amz-id-2\\":\\"ZUztk9/z3GbDxV5zE9Q8sN0Hg4LG7axcMUgZ2DWj/bXr2NY5zwFTB6kx2GDHiFtkcejqGJPlbOyWTrwZ0V5P8oHD6b3oS6eF\\"},\\"s3\\":{\\"s3SchemaVersion\\":\\"1.0\\",\\"configurationId\\":\\"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx\\",\\"bucket\\":{\\"name\\":\\"unwraptestevents-bucket\\",\\"ownerIdentity\\":{\\"principalId\\":\\"A2RRIR5BTZTTF6\\"},\\"arn\\":\\"arn:aws:s3:::unwraptestevents-bucket-683517028648\\"},\\"object\\":{\\"key\\":\\"firehose-s3-template.json\\",\\"size\\":4314,\\"eTag\\":\\"e77dffcd1756d6e8e5123ef1e0ce7c54\\",\\"sequencer\\":\\"0065FA0B4B104A6DAB\\"}}}]}",\n "Timestamp" : "2024-03-19T22:01:48.137Z",\n "SignatureVersion" : "1",\n "Signature" : "cVaCtWT+JsLsnXrSRHlBPXKPqPIlEWQaCeecWXme5XoDbHYtDV58i8DHLHAcVjp+G5hmg7FxSjr9notzP4WLtgfMuqbsY0JjaSLl5Yo3dWZIOYgUgTqNj5RupPowbyjoywCUBluKYMduEIJ8ozFU0GdBWfCfcGrj89nUUjmrCn3zt8rTghRL4bT8fQWRhU9q9hKmMjPcSpe57T1Sf2k/LUu52L1bK89pVARA/nfV5nykbF4a4opjIYtSzSP2/COvXgb/8I2bbzlyOmAi8O5tEL4TkDx717o67565/7bbVA8UyuAcXL6VCdQfiI5U+dHdJdkWAWW4g/rEhvCBNW9PzA==",\n "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:683517028648:unwraptestevents-Topic-qit16u4t71Op:90710d0d-3c29-4b4b-aebc-e0622e295dea"\n}', "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710885708191", @@ -144,7 +144,7 @@ { "messageId": "519619da-e529-46d7-b58c-bc054405af0f", "receiptHandle": "AQEB//A8ci4+iToNBE66jNulMi/7cpVqiC7YkdTnQA0qhTOnWv55SDgxh+CV7WckD1xT3V9zBh2APTr1qtB7i29GepU/lzqFvS2wozjDljP7YHbWHn77hOeCwtfVFbJoqUyEL/+QcFIMZ06AUP0h+SAjJDype/x0WnCGqKd3juaRmECEk4LFc+g1evZ9DIP+Lkw3JM44JHAcgq4+Sm+Pv/dEZXHIoOL8S5mV4f0l+fJk9TDOLGbTCCEuMfWmrQBAVgJt052y0y6my2rAGO2iQdwkONXdPUrbxBSmeb/sDEp4qy4CViKgDzTo+Ii2sLDggKxeRrWaLzdFvv50ebTnLx8RHUsVnAiNv8DsJJOJx3ryw8gKO0o4TaMB8KQ4Zh2hAglgakSwjeMzCrTI7tyF1ML65A==", - "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-west-2","eventTime":"2024-03-19T22:57:48.823Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"000.111.222.333"},"responseElements":{"x-amz-request-id":"HQDSXXWNQWRCN3PQ","x-amz-id-2":"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx","bucket":{"name":"unwraptestevents-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::unwraptestevents-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"9cc7da5febb07868706f59ab70d89981","sequencer":"0065FA186CC08E810D"}}}]}', + "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-west-2","eventTime":"2024-03-19T22:57:48.823Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"000.111.222.333"},"responseElements":{"x-amz-request-id":"HQDSXXWNQWRCN3PQ","x-amz-id-2":"EVDoeOaTHawmKSqzPnBHMZNHvWnnHKfAl9Muyg21meD3KvREXeNTC9qdV6ZyJQs1hfKJ+sfUp5koqc3GeAziHnl0UQGDa3CF"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NDE4Zjk0NmMtMTVlMi00ZWNhLWI1NDktYjg0YzBmMzVkYjQx","bucket":{"name":"unwraptestevents-bucket","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::unwraptestevents-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"9cc7da5febb07868706f59ab70d89981","sequencer":"0065FA186CC08E810D"}}}]}', "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710889069948", @@ -199,7 +199,7 @@ { "messageId": "44103047-3123-4583-aed3-7224000351a8", "receiptHandle": "AQEBWOm6hlP5TEZ64yvPugVI7LyhkEAvaEfvqfyqheIBcqhKPg5wfb95MC9IYm60od3hlTdgT3lJ7l/8upj8eYsCVglkTYqUKXKqUOgotxiqhyLlJ2AOy0gPc1EL5Uek3e267IB/5XPz9msqZmxuI6/pcT+Ihj/26EXYVxOYEK4YwbhbBNhl5Wp4dn8anV3/LD/vvgRyHtOAK4MlwWgIBFT9wWyJInMcYRVtmAx1ODUMG1CpsB6IB5m11pazNnlV0kOSzjjBDB4QK/euMqpfnCbUB4dLb5WAwZ37pys9xKjypEFS1eHXjSwEG+rG4J8u2UlFDO13FQ8lsOJB96Sx/T7KIqTvhc8VayDPXFArTtT6dlXZlc99gYf8uDDcYRfUPnBK8KZ/pEI6UjQiOVjvgWhIDiu0SxrQ82ytPMxjvizWkv0=", - "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T19:02:45.087Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.3"},"responseElements":{"x-amz-request-id":"ST581J3PW8R8QKVP","x-amz-id-2":"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh","bucket":{"name":"sqs-s3-unwrap-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::sqs-s3-unwrap-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"8f6c039f567cc53694be2a275e452743","sequencer":"0065F349D4F05B5827"}}}]}', + "body": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T19:02:45.087Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.3"},"responseElements":{"x-amz-request-id":"ST581J3PW8R8QKVP","x-amz-id-2":"bvl3TX3qzBFUe+/0IZNjrCdVI2GfhEAjJDg4G8JxVnT1MNNPlf/BckKG9cAGzenBbZLh72nKxg9KMqYg3+/tg4kpKFhWWi2h"},"s3":{"s3SchemaVersion":"1.0","configurationId":"NmIyMjczNmQtOTg4Ni00ZmMyLWIwNDctYzRmNWQ1NTk2NTlh","bucket":{"name":"sqs-s3-unwrap-bucket","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::sqs-s3-unwrap-bucket"},"object":{"key":"samconfig.toml","size":221,"eTag":"8f6c039f567cc53694be2a275e452743","sequencer":"0065F349D4F05B5827"}}}]}', "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710442966490", @@ -221,7 +221,7 @@ { "messageId": "10ad507c-8389-4585-ae55-11d32ea71997", "receiptHandle": "AQEB1nupmCFCI3lhVKz3fPFqO5kZKDNpzuflQ96kZwseTe5HRCb3eeY8XoWoyfcSDqNwjXdC/CQBjunectuzr+0mYhwVvo0GxRWF0U1J8/djdoxCACEELa+IxnWYA+2ernXEVPrisgWSf8D+woy02h58ybMzbP8pCxeld/1cqbBOt7vd0QC7pRcXDdFl0KWl0yYi1PTWyy6L5uTz4RIDsL867eh6xtKxKinp/N2Fym5/0/3TkfDLk+RNTVTTMmiRebP7hKSfsmYeAc7tcx8GHRvJdcN11XDPfW76+uQbIb9DtAIQobpQ4sJ2FOAapJ9U5IJ4leTfWjJ+L/L1fKo+vlkWiv9k+ktP9ABP214ylpS8BVzn1dHjBGQ98pryKhE4jPm9J3SDYh/J3LSPxsjtUvF/p15pgvantoOYyobS7OMr9qM=", - "body": '{\n "Type" : "Notification",\n "MessageId" : "bf5ff648-5111-5dbe-ad4b-a82514ed6a35",\n "TopicArn" : "arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM",\n "Message" : "from sns",\n "Timestamp" : "2024-03-14T18:36:44.233Z",\n "SignatureVersion" : "1",\n "Signature" : "Ne7jvjmincHd06Y19dZss3Xk003RlAm/srm2dt5nLDgwrY0dI56RkH/Dbva9w8xy63EUHyUVfHCYvrXLh/HpsW5nXU9YetK7G5QpfxBeTPnNioPdJi2U3PDA+jJXs0DK4ffonwEMLjbmIETAiWdrN5ollBpL5zh2ZjurMh7TnUGH6/KxsFcWNHTPrGN/v9HSRoFtQdtl9i/zFmBVaXC4dvaZU0cy/gYK5uIIf+YJ+OJoXd7fCxZLVPIwnK148Ws3b/i85UyP0tVguscoknf37bTPwdQuloPOKQHtPZDxUdLjS+uj27LRwiT+1CvGqdgpJ8XV/8tWqujR3FDI3ZL6EQ==",\n "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM:42e6130c-54b0-4cec-a8c0-7d0cc356ea4e"\n}', + "body": '{\n "Type" : "Notification",\n "MessageId" : "bf5ff648-5111-5dbe-ad4b-a82514ed6a35",\n "TopicArn" : "arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM",\n "Message" : "From SNS",\n "Timestamp" : "2024-03-14T18:36:44.233Z",\n "SignatureVersion" : "1",\n "Signature" : "Ne7jvjmincHd06Y19dZss3Xk003RlAm/srm2dt5nLDgwrY0dI56RkH/Dbva9w8xy63EUHyUVfHCYvrXLh/HpsW5nXU9YetK7G5QpfxBeTPnNioPdJi2U3PDA+jJXs0DK4ffonwEMLjbmIETAiWdrN5ollBpL5zh2ZjurMh7TnUGH6/KxsFcWNHTPrGN/v9HSRoFtQdtl9i/zFmBVaXC4dvaZU0cy/gYK5uIIf+YJ+OJoXd7fCxZLVPIwnK148Ws3b/i85UyP0tVguscoknf37bTPwdQuloPOKQHtPZDxUdLjS+uj27LRwiT+1CvGqdgpJ8XV/8tWqujR3FDI3ZL6EQ==",\n "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem",\n "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:683517028648:sqs-sns-unwrap-Topic-0Wj2eIrU5hrM:42e6130c-54b0-4cec-a8c0-7d0cc356ea4e"\n}', "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1710441404272", @@ -273,7 +273,7 @@ "MessageId": "2d44624b-23f8-5e80-99d9-3c265035c5ae", "TopicArn": "arn:aws:sns:us-east-1:683517028648:s3-sns-unwrap-Topic-7Xaj1echf9dg", "Subject": "Amazon S3 Notification", - "Message": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T21:52:13.311Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.33"},"responseElements":{"x-amz-request-id":"53YYXE4TACR6K89G","x-amz-id-2":"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L"},"s3":{"s3SchemaVersion":"1.0","configurationId":"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2","bucket":{"name":"s3-sns-unwrap-bucket-683517028648","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"551277913a5ad93e0db069e673f23376","sequencer":"0065F3718D39E6D6DC"}}}]}', + "Message": '{"Records":[{"eventVersion":"2.1","eventSource":"aws:s3","awsRegion":"us-east-1","eventTime":"2024-03-14T21:52:13.311Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWS:AROAZ6JGKFEUJYDMQOGIU:seshub-Isengard"},"requestParameters":{"sourceIPAddress":"00.111.2.33"},"responseElements":{"x-amz-request-id":"53YYXE4TACR6K89G","x-amz-id-2":"9jBkdIPJOx97diPIdSkVi3kpoo9d6qk1W11iL4ZIQMJgQm9rbdsywKE3NgkKpDm43RU7sASksILzYlM8rhX/bGncoqXwUQ5L"},"s3":{"s3SchemaVersion":"1.0","configurationId":"MWQyMzI0ZDgtNzE5Yi00NmNiLTlmNDYtNDI3MmM4Mjk0MTc2","bucket":{"name":"s3-sns-unwrap-bucket","ownerIdentity":{"principalId":"A2RRIR5BTZTTF6"},"arn":"arn:aws:s3:::s3-sns-unwrap-bucket-683517028648"},"object":{"key":"samconfig.toml","size":221,"eTag":"551277913a5ad93e0db069e673f23376","sequencer":"0065F3718D39E6D6DC"}}}]}', "Timestamp": "2024-03-14T21:52:13.905Z", "SignatureVersion": "1", "Signature": "IJqlNH8ddOX4V10m6IY+3gOK6/+PxxiGLs4PxHiGDcQ58mcCr4+vXCHuJ7jxOvCBHCYev1wF0PCwBhDpwBfstV8vAGEsX7GhJuAZ5jf0uOUMukZvIquy1LQBTdHg0TNq9N83sG0wz2QMp8QLLlkDJMF8nS00EjeDuFwpJxZnRadWcjz4AWXO6JITohyYnFVkDqsK5pOFd3Y1KADjfpRFH2lrljJm3CnA/x6PYVduP5PK83JnDs7LmEnK3cqE7IJhdwW9e824KXmjFBujoiNU9bUnoLiqFMg+UfZfMMJGjtCHIV0ZmnMix7nKZUGDNQe7TKOoDcXLxuAxa6TQNWfKSw==", diff --git a/tests/unit/data_classes/test_nested_events.py b/tests/unit/data_classes/test_nested_events.py index 3f29763e137..13c1f4fc7c3 100644 --- a/tests/unit/data_classes/test_nested_events.py +++ b/tests/unit/data_classes/test_nested_events.py @@ -23,7 +23,7 @@ def test_sqs_s3(): # sqs(s3) s3_event = parsed_event.decode_nested_events(S3Event) for rec in s3_event: - assert rec.bucket_name == "sqs-s3-unwrap-bucket-683517028648" + assert rec.bucket_name == "sqs-s3-unwrap-bucket" def test_sqs_s3_single(): # sqs(s3) @@ -31,7 +31,7 @@ def test_sqs_s3_single(): # sqs(s3) parsed_event = SQSEvent(raw_event) s3_event = parsed_event.decode_nested_event(S3Event) - assert s3_event.bucket_name == "sqs-s3-unwrap-bucket-683517028648" + assert s3_event.bucket_name == "sqs-s3-unwrap-bucket" def test_sqs_sns(): # sqs(sns) @@ -40,7 +40,7 @@ def test_sqs_sns(): # sqs(sns) sns_event = parsed_event.decode_nested_events(SNSMessage) for rec in sns_event: - assert rec.message == "from sns" + assert rec.message == "From SNS" def test_sns_s3(): # sns(s3) @@ -49,7 +49,7 @@ def test_sns_s3(): # sns(s3) s3_event = parsed_event.decode_nested_events(S3Event) for rec in s3_event: - assert rec.bucket_name == "s3-sns-unwrap-bucket-683517028648" + assert rec.bucket_name == "s3-sns-unwrap-bucket" def test_sqs_s3_multiple_events(): # sqs(s3, s3) @@ -67,7 +67,7 @@ def test_sqs_sns_s3_direct(): # sqs(sns(s3)) sns_event = parsed_event.decode_nested_event(SNSMessage) s3_event = sns_event.decode_nested_event(S3Event) - assert s3_event.bucket_name == "unwraptestevents-bucket-683517028648" + assert s3_event.bucket_name == "unwraptestevents-bucket" def test_sqs_sns_s3(): # sqs(sns(s3)) @@ -78,7 +78,7 @@ def test_sqs_sns_s3(): # sqs(sns(s3)) for rec in sns_event: s3_event = rec.decode_nested_events(S3Event) for r in s3_event: - assert r.bucket_name == "unwraptestevents-bucket-683517028648" + assert r.bucket_name == "unwraptestevents-bucket" def test_sns_ses(): # sns(ses) @@ -86,7 +86,7 @@ def test_sns_ses(): # sns(ses) parsed_event = SNSEvent(raw_event) ses_event = parsed_event.decode_nested_events(SESEventRecord) for rec in ses_event: - assert rec.get("mail").get("source") == "seshub@amazon.com" + assert rec.get("mail").get("source") == "jsmith@amazon.com" # print('rec:', rec.mail) #but can't do rec.mail bc no "SES" key @@ -95,7 +95,7 @@ def test_eb_s3(): # eventbridge(s3) parsed_event = EventBridgeEvent(raw_event) s3_event = parsed_event.decode_nested_events(S3EventBridgeNotificationDetail) for rec in s3_event: - assert rec.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + assert rec.bucket.name == "s3-eb-unwrap-sourcebucket" def test_sqs_eb_s3(): # sqs(eventbridge(s3)) @@ -106,7 +106,7 @@ def test_sqs_eb_s3(): # sqs(eventbridge(s3)) for rec in eb_event: s3_event = rec.decode_nested_events(S3EventBridgeNotificationDetail) for r in s3_event: - assert r.bucket.name == "s3-eb-unwrap-sourcebucket-7mop1gqlyrzu" + assert r.bucket.name == "s3-eb-unwrap-sourcebucket" def test_firehose_sns_event(): # firehose(sns) From 10664381cf7f90cd24efeba032fc1b2481a63b3b Mon Sep 17 00:00:00 2001 From: Seshu Brahma Date: Fri, 26 Apr 2024 12:24:04 -0700 Subject: [PATCH 14/14] Fix some linting --- .../utilities/data_classes/nested_test_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py index 7bfd824f81c..a7f0a1658d9 100644 --- a/aws_lambda_powertools/utilities/data_classes/nested_test_events.py +++ b/aws_lambda_powertools/utilities/data_classes/nested_test_events.py @@ -161,7 +161,7 @@ } -# sqs(s3, s3) +# s3 -> sqs = sqs(s3, s3) sqs_s3_multi_event = { "Records": [ {