Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(sns): add delivery policy to sns subscriptions #30830

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

LaurenceWarne
Copy link
Contributor

@LaurenceWarne LaurenceWarne commented Jul 11, 2024

Issue # (if applicable)

Closes #17576.

Reason for this change

To allow setting of delivery policy for appropriate sns subscriptions.

Description of changes

Subscriptions can now take a new parameter deliveryPolicy which consists of a healthyRetryPolicy, a throttlePolicy, and a requestPolicy (each having the same parameters described here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy).

Description of how you validated changes

New integration test along with unit tests.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added the beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK label Jul 11, 2024
@aws-cdk-automation aws-cdk-automation requested a review from a team July 11, 2024 19:36
@github-actions github-actions bot added effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. p2 labels Jul 11, 2024
* Algorithms which can be used by SNS to calculate the delays associated with all of the retry attempts between the first and last retries in the backoff phase.
*/
export enum BackoffFunction {
/** Arithmetic.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the best doc I've ever written 😅 , the best indicator of to what these each of these do that I found was an image at the very bottom of the doc page here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html - suggestions welcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't come up with a good description either, but I thought it would be good to at least add a link to this diagram, which shows the differences in the behavior of each backoff function.

スクリーンショット 2024-09-21 9 28 24

However, it seems that this diagram doesn't exist in English😓

In Japanese: https://docs.aws.amazon.com/de_de/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy
In English: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html

I would appreciate it if you could consult with the maintainer again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would appreciate it if you could consult with the maintainer again.

As in a CDK maintainer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! After my approval, you need to get approval from the CDK maintainer. I would appreciate it if you could kindly check it at that time!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right np, I thought you might have meant someone in the SNS team or something 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/** The minimum delay for a retry (in seconds). Must be at least 1 and not exceed `maxDelayTarget`.
* @default 20
*/
readonly minDelayTarget: number;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only, this and the next two appear to be mandatory if healthyRetryPolicy is specified, thought I can't find any specific doc for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be correct to assume that if these are not set, it will result in an error during deployment? If so, I am curious when the default values would be set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I recall correctly from testing, it's required if and only if healthyRetryPolicy itself is specified, and so the default values would be set in the case healthyRetryPolicy is not specified (perhaps it's confusing to mention a default in the doc 🤔)

Copy link
Contributor

@badmintoncryer badmintoncryer Sep 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about making these two props optional and explicitly setting the default values documented within the L2 construct? These properties may be required in CloudFormation, but I felt there is no need to make them mandatory in the L2 construct.

readonly minDelayTarget?: Duration;
readonly maxDelayTarget?: Duration;
const minDelayTarget = healthyRetryPolicy.minDelayTarget ?? Duration.seconds(20);
const maxDelayTarget = healthyRetryPolicy.maxDelayTarget ?? Duration.seconds(20);

@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Jul 11, 2024
@pahud
Copy link
Contributor

pahud commented Jul 30, 2024

Hi

This PR has been pending for community review for a while. Please consider posting it on the #contributing channel in cdk.dev. Community members will be on the lookout there as well for possible reviews.

Check How to get your P2 PR community reviewed for more details.

@LaurenceWarne
Copy link
Contributor Author

Thanks, I've posted on the channel.

Copy link
Contributor

@badmintoncryer badmintoncryer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for creating such a wonderful PR! I’ve quickly reviewed it!

Comment on lines 14 to 15
/** Linear.
*/

This comment was marked as resolved.

Comment on lines 11 to 12
/** Linear.
*/

This comment was marked as resolved.

Comment on lines 8 to 9
/** Geometric.
*/

This comment was marked as resolved.

* Algorithms which can be used by SNS to calculate the delays associated with all of the retry attempts between the first and last retries in the backoff phase.
*/
export enum BackoffFunction {
/** Arithmetic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't come up with a good description either, but I thought it would be good to at least add a link to this diagram, which shows the differences in the behavior of each backoff function.

スクリーンショット 2024-09-21 9 28 24

However, it seems that this diagram doesn't exist in English😓

In Japanese: https://docs.aws.amazon.com/de_de/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy
In English: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html

I would appreciate it if you could consult with the maintainer again.

Comment on lines 23 to 25
/** The maximum number of deliveries per second, per subscription.
* @default - no throttling
*/

This comment was marked as resolved.

/** The minimum delay for a retry (in seconds). Must be at least 1 and not exceed `maxDelayTarget`.
* @default 20
*/
readonly minDelayTarget: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be correct to assume that if these are not set, it will result in an error during deployment? If so, I am curious when the default values would be set.

Comment on lines 154 to 156
if (healthyRetryPolicy.minDelayTarget < 1 || healthyRetryPolicy.minDelayTarget > delayTargetLimit) {
throw new Error(`minDelayTarget must be between 1 and ${delayTargetLimit} inclusive`);
}

This comment was marked as resolved.

Comment on lines 157 to 162
if (healthyRetryPolicy.maxDelayTarget < 1 || healthyRetryPolicy.maxDelayTarget > delayTargetLimit) {
throw new Error(`maxDelayTarget must be between 1 and ${delayTargetLimit} inclusive`);
}
if (healthyRetryPolicy.minDelayTarget > healthyRetryPolicy.maxDelayTarget) {
throw new Error('minDelayTarget must not exceed maxDelayTarget');
}

This comment was marked as resolved.

throw new Error('minDelayTarget must not exceed maxDelayTarget');
}
const numRetriesLimit = 100;
if (healthyRetryPolicy.numRetries < 0 || healthyRetryPolicy.numRetries > numRetriesLimit) {

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good catch

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the integer check been added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, forgot to push a commit 😅

@@ -136,6 +144,43 @@ export class Subscription extends Resource {
throw new Error('Subscription role arn is required field for subscriptions with a firehose protocol.');
}

if (props.deliveryPolicy) {

This comment was marked as resolved.

@LaurenceWarne
Copy link
Contributor Author

Thank you for creating such a wonderful PR! I’ve quickly reviewed it!

Thanks for the review! Hopefully I've addressed everything

@aws-cdk-automation aws-cdk-automation removed the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Sep 22, 2024
Copy link
Contributor

@badmintoncryer badmintoncryer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the revisions. I’ve added a few more comments. Once you address those, I plan to approve.

Comment on lines 195 to 206
if (healthyRetryPolicy.numRetries < 0 || healthyRetryPolicy.numRetries > numRetriesLimit) {
throw new Error(`numRetries must be between 0 and ${numRetriesLimit} inclusive`);
}
if (healthyRetryPolicy.numNoDelayRetries && healthyRetryPolicy.numNoDelayRetries < 0) {
throw new Error('numNoDelayRetries must be zero or greater');
}
if (healthyRetryPolicy.numMinDelayRetries && healthyRetryPolicy.numMinDelayRetries < 0) {
throw new Error('numMinDelayRetries must be zero or greater');
}
if (healthyRetryPolicy.numMaxDelayRetries && healthyRetryPolicy.numMaxDelayRetries < 0) {
throw new Error('numMaxDelayRetries must be zero or greater');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cloud you please show the props value like below?

        throw new Error(`numRetries must be between 0 and ${numRetriesLimit} inclusive, got: ${healthyRetryPolicy.numRetries}`);

Copy link
Contributor

@badmintoncryer badmintoncryer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for you contribution! I've approved this, but I kindly request a minor correction.

Comment on lines 225 to 227
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined)? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(),
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined)? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(),
numRetries: (healthyRetryPolicy.numRetries === undefined)? 3: healthyRetryPolicy.numRetries,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined)? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(),
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined)? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(),
numRetries: (healthyRetryPolicy.numRetries === undefined)? 3: healthyRetryPolicy.numRetries,
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined) ? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(),
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined) ? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(),
numRetries: (healthyRetryPolicy.numRetries === undefined) ? 3: healthyRetryPolicy.numRetries,

@LaurenceWarne
Copy link
Contributor Author

Thank you for you contribution! I've approved this, but I kindly request a minor correction.

👍 And thanks again, I really appreciate you taking the time 🙂

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Sep 25, 2024
Copy link
Contributor

@GavinZZ GavinZZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing! Left some feedback.

});

}

private renderDeliveryPolicy(deliveryPolicy: DeliveryPolicy, protocol: SubscriptionProtocol): any {
if (protocol !== SubscriptionProtocol.HTTP && protocol !== SubscriptionProtocol.HTTPS) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
if (protocol !== SubscriptionProtocol.HTTP && protocol !== SubscriptionProtocol.HTTPS) {
if (![SubscriptionProtocol.HTTP, SubscriptionProtocol.HTTPS].includes(protocol)) {

const minDelayTarget = healthyRetryPolicy.minDelayTarget;
const maxDelayTarget = healthyRetryPolicy.maxDelayTarget;
if (minDelayTarget !== undefined) {
if (minDelayTarget.toMilliseconds() % 1000 !== 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can directly use toSeconds() which will check if it's a integer second

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it, but I thought this would be better as the error toSeconds raises doesn't have the same context we can add here?

}
}

const numRetriesLimit = 100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good intention to not use the magic value and define it explicitly. But given the number of validations, I actually think it's more readable to directly use the value like 100 and 3600 in the if condition checks. What do you think?

Copy link
Contributor Author

@LaurenceWarne LaurenceWarne Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer it how it is now? I agree it might be more readable, but I'd prefer keeping hard-coding to a minimum to make refactors safer/simplier, etc

}
return {
healthyRetryPolicy: healthyRetryPolicy ? {
// minDelayTarget, maxDelayTarget and numRetries are (empirically) mandatory when healthyRetryPolicy is specified,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain what you meant by empirically mandatory)? I do see that they do have default values set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does #30830 (comment) answer your question (also see last comment in that thread as well as to why they're optional)?

Comment on lines +228 to +230
numNoDelayRetries: healthyRetryPolicy.numNoDelayRetries,
numMinDelayRetries: healthyRetryPolicy.numMinDelayRetries,
numMaxDelayRetries: healthyRetryPolicy.numMaxDelayRetries,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these have default values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to #30830 (comment) question, I guess it would depend on your view on that 😅?

My thinking was that if Cloudformation doesn't require these to be specified when healthyRetryPolicy is specified, we can omit them here and have Cloudformation figure the defaults for us?

@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Oct 10, 2024
@mergify mergify bot dismissed GavinZZ’s stale review October 14, 2024 18:44

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 442d8c9
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. p2 pr/needs-maintainer-review This PR needs a review from a Core Team Member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(sns): Allow delivery retry policy configuration of HTTPS subscription on SNS topic
5 participants