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(scheduler-targets): SqsSendMessage Target #27774

Merged
merged 24 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
269b0bd
wip
go-to-k Oct 31, 2023
e397c2c
test: change unit tests
go-to-k Oct 31, 2023
41fbf8b
feat: add bindBaseTargetConfig
go-to-k Oct 31, 2023
48dca93
docs: props comments
go-to-k Oct 31, 2023
32452a6
test: change an unit test
go-to-k Oct 31, 2023
ec9a162
test: wip
go-to-k Oct 31, 2023
e1b18f3
test: add integ tests
go-to-k Oct 31, 2023
d1ab879
add validations and the unit tests
go-to-k Oct 31, 2023
38c443f
docs: WIP in README
go-to-k Oct 31, 2023
173f2ed
chore: change validations and unit tests
go-to-k Nov 1, 2023
13489af
docs: wip in README
go-to-k Nov 1, 2023
4fc9c97
docs: change README and jsdocs
go-to-k Nov 1, 2023
5b2ed77
docs: fix for rosetta in README
go-to-k Nov 1, 2023
97acac6
docs: add default for messageGroupId
go-to-k Nov 1, 2023
736e359
Merge branch 'main' into feat/scheduler-targets-sqs
go-to-k Nov 4, 2023
3bf56da
covered for the review
go-to-k Nov 4, 2023
c585d6c
add a new line in README
go-to-k Nov 4, 2023
276298a
Merge branch 'main' of https://github.com/go-to-k/aws-cdk into feat/s…
go-to-k Nov 12, 2023
3060470
improve unit tests by using fromQueueArn in the same stack
go-to-k Nov 12, 2023
bc9bddc
Merge branch 'main' into feat/scheduler-targets-sqs
vinayak-kukreja Nov 20, 2023
84e77f6
Merge branch 'main' into feat/scheduler-targets-sqs
sumupitchayan Nov 20, 2023
c5bb455
Merge branch 'main' into feat/scheduler-targets-sqs
sumupitchayan Nov 21, 2023
6ad3e0c
Merge branch 'main' into feat/scheduler-targets-sqs
mergify[bot] Nov 21, 2023
84951af
Merge branch 'main' into feat/scheduler-targets-sqs
mergify[bot] Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The following targets are supported:

1. `targets.LambdaInvoke`: [Invoke an AWS Lambda function](#invoke-a-lambda-function))
2. `targets.StepFunctionsStartExecution`: [Start an AWS Step Function](#start-an-aws-step-function)
3. `targets.SqsSendMessage`: [Send a Message to an Amazon SQS Queue](#send-a-message-to-sqs-queue)

## Invoke a Lambda function

Expand Down Expand Up @@ -102,3 +103,32 @@ new Schedule(this, 'Schedule', {
}),
});
```

## Send A Message To SQS Queue

Use the `SqsSendMessage` target to send a message to SQS Queue.

The code snippet below creates an event rule with a SQS Queue as a target
called every hour by Event Bridge Scheduler with a custom payload.

Contains the `messageGroupId` to use when the target is a FIFO queue. If you specify
a FIFO queue as a target, the queue must have content-based deduplication enabled.

```ts
const payload = 'test';
const messageGroupId = 'id';
const queue = new sqs.Queue(this, 'MyQueue', {
fifo: true,
contentBasedDeduplication: true,
});

const target = new targets.SqsSendMessage(queue, {
input: ScheduleTargetInput.fromText(payload),
messageGroupId,
});

new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.minutes(1)),
target
});
```
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-scheduler-targets-alpha/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './target';
export * from './lambda-invoke';
export * from './stepfunctions-start-execution';
export * from './stepfunctions-start-execution';
export * from './sqs-send-message';
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ISchedule, IScheduleTarget, ScheduleTargetConfig } from '@aws-cdk/aws-scheduler-alpha';
import { Names } from 'aws-cdk-lib';
import { IRole } from 'aws-cdk-lib/aws-iam';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { ScheduleTargetBase, ScheduleTargetBaseProps } from './target';
import { sameEnvDimension } from './util';

/**
* Properties for a SQS Queue Target
*/
export interface SqsSendMessageProps extends ScheduleTargetBaseProps {
/**
* The FIFO message group ID to use as the target.
*
* This must be specified when the target is a FIFO queue. If you specify
* a FIFO queue as a target, the queue must have content-based deduplication enabled.
*
* A length of `messageGroupId` must be between 1 and 128.
*
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-scheduler-schedule-sqsparameters.html#cfn-scheduler-schedule-sqsparameters-messagegroupid
*
* @default - no message group ID
*/
readonly messageGroupId?: string;
}

/**
* Use an Amazon SQS Queue as a target for AWS EventBridge Scheduler.
*/
export class SqsSendMessage extends ScheduleTargetBase implements IScheduleTarget {
constructor(
private readonly queue: sqs.IQueue,
private readonly props: SqsSendMessageProps,
) {
super(props, queue.queueArn);

if (props.messageGroupId !== undefined) {
if (props.messageGroupId.length < 1 || props.messageGroupId.length > 128 ) {
throw new Error(`messageGroupId length must be between 1 and 128, got ${props.messageGroupId.length}`);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@laurelmay laurelmay Nov 3, 2023

Choose a reason for hiding this comment

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

I don't think tokens ever get this long but maybe:

Suggested change
if (props.messageGroupId.length < 1 || props.messageGroupId.length > 128 ) {
throw new Error(`messageGroupId length must be between 1 and 128, got ${props.messageGroupId.length}`);
}
if (!Token.isUnresolved(props.messageGroupId) && (props.messageGroupId.length < 1 || props.messageGroupId.length > 128)) {
throw new Error(`messageGroupId length must be between 1 and 128, got ${props.messageGroupId.length}`);
}

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'll do that just in case.

if (!queue.fifo) {
throw new Error('target must be a FIFO queue if messageGroupId is specified');
}
Comment on lines +41 to +43
Copy link
Contributor Author

Choose a reason for hiding this comment

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

CFn occurs a following error when the queue is not FIFO queue if messageGroupId is specified. So added this validation.

ROLLBACK_COMPLETE: Resource handler returned message: "Invalid request provided: Parameters MessageGroupId not valid for the target.

if (!(queue.node.defaultChild as sqs.CfnQueue).contentBasedDeduplication) {
throw new Error('contentBasedDeduplication must be true if the target is a FIFO queue');
}
Comment on lines +44 to +46
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 you specify an Amazon SQS FIFO queue as a target, the queue must have content-based deduplication enabled.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-scheduler-schedule-target.html#cfn-scheduler-schedule-target-sqsparameters

} else if (queue.fifo) {
throw new Error('messageGroupId must be specified if the target is a FIFO queue');
}
Comment on lines +47 to +49
Copy link
Contributor Author

Choose a reason for hiding this comment

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

}

protected addTargetActionToRole(schedule: ISchedule, role: IRole): void {
if (!sameEnvDimension(this.queue.env.region, schedule.env.region)) {
throw new Error(`Cannot assign queue in region ${this.queue.env.region} to the schedule ${Names.nodeUniqueId(schedule.node)} in region ${schedule.env.region}. Both the schedule and the queue must be in the same region.`);
}

if (!sameEnvDimension(this.queue.env.account, schedule.env.account)) {
throw new Error(`Cannot assign queue in account ${this.queue.env.account} to the schedule ${Names.nodeUniqueId(schedule.node)} in account ${schedule.env.region}. Both the schedule and the queue must be in the same account.`);
}

if (this.props.role && !sameEnvDimension(this.props.role.env.account, this.queue.env.account)) {
throw new Error(`Cannot grant permission to execution role in account ${this.props.role.env.account} to invoke target ${Names.nodeUniqueId(this.queue.node)} in account ${this.queue.env.account}. Both the target and the execution role must be in the same account.`);
}

this.queue.grant(role, 'sqs:SendMessage');
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
this.queue.grant(role, 'sqs:SendMessage');
this.queue.grantSendMessages(role);

Would this be better? It handles the case where the queue uses KMS encryption and grants a few other permissions. But I'm not sure that's necessary for this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Certainly, I'll leave it at that.

}

protected bindBaseTargetConfig(_schedule: ISchedule): ScheduleTargetConfig {
return {
...super.bindBaseTargetConfig(_schedule),
sqsParameters: {
messageGroupId: this.props.messageGroupId,
},
};
}
}
Loading
Loading