Skip to content

Commit

Permalink
feat(scheduler-targets): SqsSendMessage Target (#27774)
Browse files Browse the repository at this point in the history
This PR adds `SqsSendMessage` Target for EventBridge Scheduler.

Closes #27458.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
go-to-k authored Nov 21, 2023
1 parent 6004a17 commit 80c1d26
Show file tree
Hide file tree
Showing 14 changed files with 35,514 additions and 0 deletions.
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 @@ -27,6 +27,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.CodeBuildStartBuild`: [Start a CodeBuild job](#start-a-codebuild-job)
4. `targets.SqsSendMessage`: [Send a Message to an Amazon SQS Queue](#send-a-message-to-sqs-queue)

## Invoke a Lambda function

Expand Down Expand Up @@ -121,3 +122,32 @@ new Schedule(this, 'Schedule', {
target: new targets.CodeBuildStartBuild(project),
});
```

## 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
});
```
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './target';
export * from './lambda-invoke';
export * from './stepfunctions-start-execution';
export * from './codebuild-start-build';
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, Token } 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 (!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}`);
}
if (!queue.fifo) {
throw new Error('target must be a FIFO queue if messageGroupId is specified');
}
if (!(queue.node.defaultChild as sqs.CfnQueue).contentBasedDeduplication) {
throw new Error('contentBasedDeduplication must be true if the target is a FIFO queue');
}
} else if (queue.fifo) {
throw new Error('messageGroupId must be specified if the target is a FIFO queue');
}
}

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.grantSendMessages(role);
}

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

0 comments on commit 80c1d26

Please sign in to comment.