diff --git a/integration/combination/test_function_with_sns.py b/integration/combination/test_function_with_sns.py index 6cc46186f..5dfc1a885 100644 --- a/integration/combination/test_function_with_sns.py +++ b/integration/combination/test_function_with_sns.py @@ -51,3 +51,4 @@ def test_function_with_sns_intrinsics(self): subscription_arn = subscription["SubscriptionArn"] subscription_attributes = sns_client.get_subscription_attributes(SubscriptionArn=subscription_arn) self.assertEqual(subscription_attributes["Attributes"]["FilterPolicy"], '{"price_usd":[{"numeric":["<",100]}]}') + self.assertEqual(subscription_attributes["Attributes"]["FilterPolicyScope"], "MessageAttributes") diff --git a/integration/resources/templates/combination/function_with_sns_intrinsics.yaml b/integration/resources/templates/combination/function_with_sns_intrinsics.yaml index 8b0f72ded..3530c6a4c 100644 --- a/integration/resources/templates/combination/function_with_sns_intrinsics.yaml +++ b/integration/resources/templates/combination/function_with_sns_intrinsics.yaml @@ -30,6 +30,7 @@ Resources: - numeric: - < - 100 + FilterPolicyScope: MessageAttributes Region: Ref: AWS::Region SqsSubscription: true diff --git a/samtranslator/internal/schema_source/aws_serverless_function.py b/samtranslator/internal/schema_source/aws_serverless_function.py index 5c42f04cb..e060b1475 100644 --- a/samtranslator/internal/schema_source/aws_serverless_function.py +++ b/samtranslator/internal/schema_source/aws_serverless_function.py @@ -138,6 +138,7 @@ class SqsSubscription(BaseModel): class SNSEventProperties(BaseModel): FilterPolicy: Optional[PassThroughProp] = snseventproperties("FilterPolicy") + FilterPolicyScope: Optional[PassThroughProp] # TODO: add documentation Region: Optional[PassThroughProp] = snseventproperties("Region") SqsSubscription: Optional[Union[bool, SqsSubscription]] = snseventproperties("SqsSubscription") Topic: PassThroughProp = snseventproperties("Topic") diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 56dd07ac5..ea3315b5a 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -5,7 +5,7 @@ from samtranslator.intrinsics.resolver import IntrinsicsResolver from samtranslator.metrics.method_decorator import cw_timer -from samtranslator.model import PropertyType, ResourceMacro +from samtranslator.model import PassThroughProperty, PropertyType, ResourceMacro from samtranslator.model.cognito import CognitoUserPool from samtranslator.model.eventbridge_utils import EventBridgeRuleUtils from samtranslator.model.events import EventsRule, generate_valid_target_id @@ -486,6 +486,7 @@ class SNS(PushEventSource): "Topic": PropertyType(True, IS_STR), "Region": PropertyType(False, IS_STR), "FilterPolicy": PropertyType(False, dict_of(IS_STR, list_of(one_of(IS_STR, IS_DICT)))), + "FilterPolicyScope": PassThroughProperty(False), "SqsSubscription": PropertyType(False, one_of(IS_BOOL, IS_DICT)), "RedrivePolicy": PropertyType(False, IS_DICT), } @@ -493,6 +494,7 @@ class SNS(PushEventSource): Topic: str Region: Optional[str] FilterPolicy: Optional[Dict[str, Any]] + FilterPolicyScope: Optional[str] SqsSubscription: Optional[Any] RedrivePolicy: Optional[Dict[str, Any]] @@ -518,6 +520,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] self.Topic, self.Region, self.FilterPolicy, + self.FilterPolicyScope, self.RedrivePolicy, function, ) @@ -532,7 +535,14 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] queue_policy = self._inject_sqs_queue_policy(self.Topic, queue_arn, queue_url, function) # type: ignore[no-untyped-call] subscription = self._inject_subscription( - "sqs", queue_arn, self.Topic, self.Region, self.FilterPolicy, self.RedrivePolicy, function + "sqs", + queue_arn, + self.Topic, + self.Region, + self.FilterPolicy, + self.FilterPolicyScope, + self.RedrivePolicy, + function, ) event_source = self._inject_sqs_event_source_mapping(function, role, queue_arn) # type: ignore[no-untyped-call] @@ -560,7 +570,14 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] self.Topic, queue_arn, queue_url, function, queue_policy_logical_id ) subscription = self._inject_subscription( - "sqs", queue_arn, self.Topic, self.Region, self.FilterPolicy, self.RedrivePolicy, function + "sqs", + queue_arn, + self.Topic, + self.Region, + self.FilterPolicy, + self.FilterPolicyScope, + self.RedrivePolicy, + function, ) event_source = self._inject_sqs_event_source_mapping(function, role, queue_arn, batch_size, enabled) # type: ignore[no-untyped-call] @@ -576,6 +593,7 @@ def _inject_subscription( # noqa: too-many-arguments topic: str, region: Optional[str], filterPolicy: Optional[Dict[str, Any]], + filterPolicyScope: Optional[str], redrivePolicy: Optional[Dict[str, Any]], function: Any, ) -> SNSSubscription: @@ -590,6 +608,9 @@ def _inject_subscription( # noqa: too-many-arguments if filterPolicy is not None: subscription.FilterPolicy = filterPolicy + if filterPolicyScope is not None: + subscription.FilterPolicyScope = filterPolicyScope + if redrivePolicy is not None: subscription.RedrivePolicy = redrivePolicy diff --git a/samtranslator/model/sns.py b/samtranslator/model/sns.py index a4650cefb..973d7f8fe 100644 --- a/samtranslator/model/sns.py +++ b/samtranslator/model/sns.py @@ -10,6 +10,7 @@ class SNSSubscription(Resource): "TopicArn": GeneratedProperty(), "Region": GeneratedProperty(), "FilterPolicy": GeneratedProperty(), + "FilterPolicyScope": GeneratedProperty(), "RedrivePolicy": GeneratedProperty(), } diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 107359cb0..ff24a8c41 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -196572,6 +196572,9 @@ "markdownDescription": "The filter policy JSON assigned to the subscription\\. For more information, see [GetSubscriptionAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetSubscriptionAttributes.html) in the Amazon Simple Notification Service API Reference\\. \n*Type*: [SnsFilterPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`FilterPolicy`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy) property of an `AWS::SNS::Subscription` resource\\.", "title": "FilterPolicy" }, + "FilterPolicyScope": { + "$ref": "#/definitions/PassThroughProp" + }, "Region": { "allOf": [ { diff --git a/samtranslator/validator/sam_schema/schema.json b/samtranslator/validator/sam_schema/schema.json index 393004f6b..ac671b999 100644 --- a/samtranslator/validator/sam_schema/schema.json +++ b/samtranslator/validator/sam_schema/schema.json @@ -783,6 +783,9 @@ }, "FilterPolicy": { "type": "object" + }, + "FilterPolicyScope": { + "type": "string" } }, "required": [ diff --git a/schema_source/sam.schema.json b/schema_source/sam.schema.json index fd3ddfa0c..b5982d11c 100644 --- a/schema_source/sam.schema.json +++ b/schema_source/sam.schema.json @@ -2470,6 +2470,9 @@ "markdownDescription": "The filter policy JSON assigned to the subscription\\. For more information, see [GetSubscriptionAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetSubscriptionAttributes.html) in the Amazon Simple Notification Service API Reference\\. \n*Type*: [SnsFilterPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`FilterPolicy`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy) property of an `AWS::SNS::Subscription` resource\\.", "title": "FilterPolicy" }, + "FilterPolicyScope": { + "$ref": "#/definitions/PassThroughProp" + }, "Region": { "allOf": [ { diff --git a/tests/model/eventsources/test_sns_event_source.py b/tests/model/eventsources/test_sns_event_source.py index 12b3b84d3..b2f17660b 100644 --- a/tests/model/eventsources/test_sns_event_source.py +++ b/tests/model/eventsources/test_sns_event_source.py @@ -30,6 +30,7 @@ def test_to_cloudformation_returns_permission_and_subscription_resources(self): self.assertEqual(subscription.Endpoint, "arn:aws:lambda:mock") self.assertIsNone(subscription.Region) self.assertIsNone(subscription.FilterPolicy) + self.assertIsNone(subscription.FilterPolicyScope) self.assertIsNone(subscription.RedrivePolicy) def test_to_cloudformation_passes_the_region(self): @@ -56,6 +57,16 @@ def test_to_cloudformation_passes_the_filter_policy(self): subscription = resources[1] self.assertEqual(subscription.FilterPolicy, filterPolicy) + def test_to_cloudformation_passes_the_filter_policy_scope(self): + filterPolicyScope = "MessageAttributes" + self.sns_event_source.FilterPolicyScope = filterPolicyScope + + resources = self.sns_event_source.to_cloudformation(function=self.function) + self.assertEqual(len(resources), 2) + self.assertEqual(resources[1].resource_type, "AWS::SNS::Subscription") + subscription = resources[1] + self.assertEqual(subscription.FilterPolicyScope, filterPolicyScope) + def test_to_cloudformation_passes_the_redrive_policy(self): redrive_policy = {"deadLetterTargetArn": "arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue"} self.sns_event_source.RedrivePolicy = redrive_policy @@ -89,4 +100,5 @@ def test_to_cloudformation_when_sqs_subscription_disable(self): self.assertEqual(subscription.Endpoint, "arn:aws:lambda:mock") self.assertIsNone(subscription.Region) self.assertIsNone(subscription.FilterPolicy) + self.assertIsNone(subscription.FilterPolicyScope) self.assertIsNone(subscription.RedrivePolicy) diff --git a/tests/translator/input/function_with_sns_event_source_all_parameters.yaml b/tests/translator/input/function_with_sns_event_source_all_parameters.yaml index 51285790d..e2624c75e 100644 --- a/tests/translator/input/function_with_sns_event_source_all_parameters.yaml +++ b/tests/translator/input/function_with_sns_event_source_all_parameters.yaml @@ -25,3 +25,4 @@ Resources: - numeric: - '>=' - 100 + FilterPolicyScope: MessageAttributes diff --git a/tests/translator/input/sns_existing_sqs.yaml b/tests/translator/input/sns_existing_sqs.yaml index c4b5cca4a..3a9f9d231 100644 --- a/tests/translator/input/sns_existing_sqs.yaml +++ b/tests/translator/input/sns_existing_sqs.yaml @@ -23,6 +23,7 @@ Resources: - numeric: - '>=' - 100 + FilterPolicyScope: MessageAttributes Notifications: Type: AWS::SNS::Topic diff --git a/tests/translator/input/sns_intrinsics.yaml b/tests/translator/input/sns_intrinsics.yaml index 103922db4..1b04eac6f 100644 --- a/tests/translator/input/sns_intrinsics.yaml +++ b/tests/translator/input/sns_intrinsics.yaml @@ -31,6 +31,7 @@ Resources: - numeric: - < - 100 + FilterPolicyScope: MessageAttributes Region: Ref: SnsRegion SqsSubscription: true diff --git a/tests/translator/input/sns_outside_sqs.yaml b/tests/translator/input/sns_outside_sqs.yaml index e0d1b8c57..7cf3552c8 100644 --- a/tests/translator/input/sns_outside_sqs.yaml +++ b/tests/translator/input/sns_outside_sqs.yaml @@ -23,6 +23,7 @@ Resources: - numeric: - '>=' - 100 + FilterPolicyScope: MessageAttributes Notifications: Type: AWS::SNS::Topic diff --git a/tests/translator/input/sns_sqs.yaml b/tests/translator/input/sns_sqs.yaml index 768b6c088..6afc3ff71 100644 --- a/tests/translator/input/sns_sqs.yaml +++ b/tests/translator/input/sns_sqs.yaml @@ -18,6 +18,7 @@ Resources: - numeric: - '>=' - 100 + FilterPolicyScope: MessageAttributes Notifications: Type: AWS::SNS::Topic diff --git a/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json b/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json index 4e3684260..12d0a5ff4 100644 --- a/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json @@ -54,6 +54,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "lambda", "Region": "region", "TopicArn": "topicArn" diff --git a/tests/translator/output/aws-cn/sns_existing_sqs.json b/tests/translator/output/aws-cn/sns_existing_sqs.json index 8e46790c5..58d15c888 100644 --- a/tests/translator/output/aws-cn/sns_existing_sqs.json +++ b/tests/translator/output/aws-cn/sns_existing_sqs.json @@ -83,6 +83,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/aws-cn/sns_intrinsics.json b/tests/translator/output/aws-cn/sns_intrinsics.json index 8807e7981..339eeabb0 100644 --- a/tests/translator/output/aws-cn/sns_intrinsics.json +++ b/tests/translator/output/aws-cn/sns_intrinsics.json @@ -73,6 +73,7 @@ } ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "Region": { "Ref": "SnsRegion" diff --git a/tests/translator/output/aws-cn/sns_outside_sqs.json b/tests/translator/output/aws-cn/sns_outside_sqs.json index 64f9208d5..069211b55 100644 --- a/tests/translator/output/aws-cn/sns_outside_sqs.json +++ b/tests/translator/output/aws-cn/sns_outside_sqs.json @@ -68,6 +68,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/aws-cn/sns_sqs.json b/tests/translator/output/aws-cn/sns_sqs.json index 34fa04b7b..c5ce703ea 100644 --- a/tests/translator/output/aws-cn/sns_sqs.json +++ b/tests/translator/output/aws-cn/sns_sqs.json @@ -47,6 +47,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json b/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json index 636851948..4a091f1d0 100644 --- a/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json @@ -54,6 +54,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "lambda", "Region": "region", "TopicArn": "topicArn" diff --git a/tests/translator/output/aws-us-gov/sns_existing_sqs.json b/tests/translator/output/aws-us-gov/sns_existing_sqs.json index 4c47260f9..793cef26b 100644 --- a/tests/translator/output/aws-us-gov/sns_existing_sqs.json +++ b/tests/translator/output/aws-us-gov/sns_existing_sqs.json @@ -83,6 +83,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/aws-us-gov/sns_intrinsics.json b/tests/translator/output/aws-us-gov/sns_intrinsics.json index 1deae3980..c62f5064b 100644 --- a/tests/translator/output/aws-us-gov/sns_intrinsics.json +++ b/tests/translator/output/aws-us-gov/sns_intrinsics.json @@ -73,6 +73,7 @@ } ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "Region": { "Ref": "SnsRegion" diff --git a/tests/translator/output/aws-us-gov/sns_outside_sqs.json b/tests/translator/output/aws-us-gov/sns_outside_sqs.json index fa06c5c32..b1eb14bc7 100644 --- a/tests/translator/output/aws-us-gov/sns_outside_sqs.json +++ b/tests/translator/output/aws-us-gov/sns_outside_sqs.json @@ -68,6 +68,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/aws-us-gov/sns_sqs.json b/tests/translator/output/aws-us-gov/sns_sqs.json index d8ada8336..66f0bcc74 100644 --- a/tests/translator/output/aws-us-gov/sns_sqs.json +++ b/tests/translator/output/aws-us-gov/sns_sqs.json @@ -47,6 +47,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/function_with_sns_event_source_all_parameters.json b/tests/translator/output/function_with_sns_event_source_all_parameters.json index 937c46462..7eb6d06d1 100644 --- a/tests/translator/output/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/function_with_sns_event_source_all_parameters.json @@ -54,6 +54,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "lambda", "Region": "region", "TopicArn": "topicArn" diff --git a/tests/translator/output/sns_existing_sqs.json b/tests/translator/output/sns_existing_sqs.json index b7a5d7518..c1c3c981b 100644 --- a/tests/translator/output/sns_existing_sqs.json +++ b/tests/translator/output/sns_existing_sqs.json @@ -83,6 +83,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/sns_intrinsics.json b/tests/translator/output/sns_intrinsics.json index 0622e3631..d4755e7d3 100644 --- a/tests/translator/output/sns_intrinsics.json +++ b/tests/translator/output/sns_intrinsics.json @@ -73,6 +73,7 @@ } ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "Region": { "Ref": "SnsRegion" diff --git a/tests/translator/output/sns_outside_sqs.json b/tests/translator/output/sns_outside_sqs.json index 56287e55f..61ae792af 100644 --- a/tests/translator/output/sns_outside_sqs.json +++ b/tests/translator/output/sns_outside_sqs.json @@ -68,6 +68,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications" diff --git a/tests/translator/output/sns_sqs.json b/tests/translator/output/sns_sqs.json index 52b69763f..5cb19e0bb 100644 --- a/tests/translator/output/sns_sqs.json +++ b/tests/translator/output/sns_sqs.json @@ -47,6 +47,7 @@ "example_corp" ] }, + "FilterPolicyScope": "MessageAttributes", "Protocol": "sqs", "TopicArn": { "Ref": "Notifications"