Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

aws_sns: Add support for $or operator in subscription filter policies #30524

Open
2 tasks
ross-bragg-sonarsource opened this issue Jun 11, 2024 · 3 comments
Open
2 tasks
Labels
@aws-cdk/aws-sns Related to Amazon Simple Notification Service effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p3

Comments

@ross-bragg-sonarsource
Copy link

Describe the feature

https://docs.aws.amazon.com/sns/latest/dg/and-or-logic.html#or-operator

I would like to be able to use the "$or" operator for SNS subscription filters to filter out messages based on multiple combinations of message attributes.

Use Case

I would like to create the following filter policy on an SNS subscription:

{
  "$or": [
    {
      "attribute_1": [
        "value_1",
        "value_2"
      ]
    },
    {
      "attribute_1": [
        "value_3"
      ],
      "attribute_2": [
        "value_4"
      ]
    }
  ]
}

However, the filter_policy on an SNS subscription is a Mapping[str, SubscriptionFilter], which doesn't account for the "$or" operator which effectively takes a list of filter policies. https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_sns/Subscription.html

I can get my desired result, but I have to set the filter policy directly:

subscription = self._topic.add_subscription(
    aws_sns_subscriptions.SqsSubscription(
        self._queue,
    )
)

subscription.node.default_child.filter_policy = filter_policy

where filter_policy is the dictionary at the beginning of the section.

I was unable to find if this was already supported in the documentation.

Proposed Solution

No response

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.141.0

Environment details (OS name and version, etc.)

MacOS, Python 3.9.6

@ross-bragg-sonarsource ross-bragg-sonarsource added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jun 11, 2024
@github-actions github-actions bot added the @aws-cdk/aws-sns Related to Amazon Simple Notification Service label Jun 11, 2024
@nmussy
Copy link
Contributor

nmussy commented Jun 12, 2024

I don't think we can forego a typing change to fix this issue, whatever we do will still break the { [attribute: string]: SubscriptionFilter } typing.

The least invasive change would be to add a static SubscriptionFilter.or method to sugarcoat the operator, but it might be worth also adding a static SubscriptionFilter.and method for the sake of consistency? I'm not sure this is the way to go, it does add some unecessary synthax and will require to check that there are no duplicate keys in the and(...filters: { [attribute: string]: SubscriptionFilter }[]) parameters.

type SubscriptionFilterMap = { [attribute: string]: SubscriptionFilter | SubscriptionFilterMap[] };

export interface SubscriptionOptions {
  // ...
  readonly filterPolicy? : SubscriptionFilterMap;
}

export class SubscriptionFilter {
  public static and(...filters: { [attribute: string]: SubscriptionFilter }[]) {
    // TODO check conflicting filter keys
    return Object.assign({}, ...filters);
  }

  public static or(...filters: { [attribute: string]: SubscriptionFilter }[]) {
    return { $or: filters };
  }

  // ...
}

Using the .or operator:

new sns.Subscription(stack, 'Subscription', {
  endpoint: 'endpoint',
  filterPolicy: SubscriptionFilter.or(
    {
      color: sns.SubscriptionFilter.stringFilter({ allowlist: ['red', 'green'] }),
      price: sns.SubscriptionFilter.numericFilter({ allowlist: [100] }),
    },
    {
      color: sns.SubscriptionFilter.stringFilter({ allowlist: ['green'] }),
      price: sns.SubscriptionFilter.numericFilter({ allowlist: [500] }),
    },
    { color: sns.SubscriptionFilter.stringFilter({ allowlist: ['purple'] }) },
  ),
  protocol: sns.SubscriptionProtocol.LAMBDA,
  topic,
});

And also using the .and operator:

new sns.Subscription(stack, 'Subscription', {
  endpoint: 'endpoint',
  filterPolicy: SubscriptionFilter.or(
    SubscriptionFilter.and(
      { color: sns.SubscriptionFilter.stringFilter({ allowlist: ['red', 'green'] }) },
      { price: sns.SubscriptionFilter.numericFilter({ allowlist: [100] }) },
    ),
    SubscriptionFilter.and(
      { color: sns.SubscriptionFilter.stringFilter({ allowlist: ['green'] }) },
      { price: sns.SubscriptionFilter.numericFilter({ allowlist: [500] }) },
    ),
    { color: sns.SubscriptionFilter.stringFilter({ allowlist: ['purple'] }) },
  ),
  protocol: sns.SubscriptionProtocol.LAMBDA,
  topic,
});

Let me know if you can come up with a cleaner solution!

@khushail khushail added effort/medium Medium work item – several days of effort p3 and removed needs-triage This issue or PR still needs to be triaged. labels Jun 17, 2024
@omrib15
Copy link

omrib15 commented Sep 4, 2024

any update on this? I really need to be able to us $or in my filters

@albertodiazdorado
Copy link

It would be lovely if we could do $or filters using CDK, without resorting to CfnSubscription

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
@aws-cdk/aws-sns Related to Amazon Simple Notification Service effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p3
Projects
None yet
Development

No branches or pull requests

5 participants