Skip to content

Commit 1e23921

Browse files
authored
refactor(events): clean up Events APIs (#2840)
Biggest change is modeling the schedule types. BREAKING CHANGE: * **events**: `EventPattern.detail` is now a map. * **events**: `scheduleExpression: string` is now `schedule: Schedule`.
1 parent d017a14 commit 1e23921

23 files changed

+249
-44
lines changed

packages/@aws-cdk/aws-ecs-patterns/lib/ecs/scheduled-ecs-task.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface ScheduledEc2TaskProps {
2121
*
2222
* @see http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
2323
*/
24-
readonly scheduleExpression: string;
24+
readonly schedule: events.Schedule;
2525

2626
/**
2727
* The CMD value to pass to the container. A string with commands delimited by commas.
@@ -106,7 +106,7 @@ export class ScheduledEc2Task extends cdk.Construct {
106106

107107
// An EventRule that describes the event trigger (in this case a scheduled run)
108108
const eventRule = new events.Rule(this, 'ScheduledEventRule', {
109-
scheduleExpression: props.scheduleExpression,
109+
schedule: props.schedule,
110110
});
111111
eventRule.addTarget(eventRuleTarget);
112112
}

packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.scheduled-ecs-task.lit.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ec2 = require('@aws-cdk/aws-ec2');
22
import ecs = require('@aws-cdk/aws-ecs');
3+
import events = require('@aws-cdk/aws-events');
34
import cdk = require('@aws-cdk/cdk');
45

56
import { ScheduledEc2Task } from '../../lib';
@@ -26,7 +27,7 @@ class EventStack extends cdk.Stack {
2627
memoryLimitMiB: 512,
2728
cpu: 1,
2829
environment: { name: 'TRIGGER', value: 'CloudWatch Events' },
29-
scheduleExpression: 'rate(1 minute)'
30+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
3031
});
3132
/// !hide
3233
}

packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.scheduled-ecs-task.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expect, haveResource } from '@aws-cdk/assert';
22
import ec2 = require('@aws-cdk/aws-ec2');
33
import ecs = require('@aws-cdk/aws-ecs');
4+
import events = require('@aws-cdk/aws-events');
45
import cdk = require('@aws-cdk/cdk');
56
import { Test } from 'nodeunit';
67
import { ScheduledEc2Task } from '../../lib';
@@ -19,7 +20,7 @@ export = {
1920
cluster,
2021
image: ecs.ContainerImage.fromRegistry('henk'),
2122
memoryLimitMiB: 512,
22-
scheduleExpression: 'rate(1 minute)'
23+
schedule: events.Schedule.expression('rate(1 minute)')
2324
});
2425

2526
// THEN
@@ -85,7 +86,7 @@ export = {
8586
memoryLimitMiB: 512,
8687
cpu: 2,
8788
environment: { name: 'TRIGGER', value: 'CloudWatch Events' },
88-
scheduleExpression: 'rate(1 minute)'
89+
schedule: events.Schedule.expression('rate(1 minute)')
8990
});
9091

9192
// THEN
@@ -159,7 +160,7 @@ export = {
159160
cluster,
160161
image: ecs.ContainerImage.fromRegistry('henk'),
161162
memoryReservationMiB: 512,
162-
scheduleExpression: 'rate(1 minute)'
163+
schedule: events.Schedule.expression('rate(1 minute)')
163164
});
164165

165166
// THEN
@@ -208,7 +209,7 @@ export = {
208209
image: ecs.ContainerImage.fromRegistry('henk'),
209210
memoryReservationMiB: 512,
210211
command: ["-c", "4", "amazon.com"],
211-
scheduleExpression: 'rate(1 minute)'
212+
schedule: events.Schedule.expression('rate(1 minute)')
212213
});
213214

214215
// THEN

packages/@aws-cdk/aws-events-targets/test/codebuild/codebuild.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ test('use codebuild project as an eventrule target', () => {
88
// GIVEN
99
const stack = new Stack();
1010
const project = new codebuild.PipelineProject(stack, 'MyProject');
11-
const rule = new events.Rule(stack, 'Rule', { scheduleExpression: 'rate(1 min)' });
11+
const rule = new events.Rule(stack, 'Rule', {
12+
schedule: events.Schedule.expression('rate(1 min)')
13+
});
1214

1315
// WHEN
1416
rule.addTarget(new targets.CodeBuildProject(project));

packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pipeline.addStage({
4343
});
4444

4545
new events.Rule(stack, 'rule', {
46-
scheduleExpression: 'rate(1 minute)',
46+
schedule: events.Schedule.expression('rate(1 minute)'),
4747
targets: [new targets.CodePipeline(pipeline)]
4848
});
4949

packages/@aws-cdk/aws-events-targets/test/codepipeline/pipeline.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ test('use codebuild project as an eventrule target', () => {
3131
artifactBounds: { minInputs: 1, maxInputs: 1 , minOutputs: 1, maxOutputs: 1, }})]
3232
});
3333

34-
const rule = new events.Rule(stack, 'rule', { scheduleExpression: 'rate(1 min)' });
34+
const rule = new events.Rule(stack, 'rule', {
35+
schedule: events.Schedule.expression('rate(1 minute)'),
36+
});
3537

3638
// WHEN
3739
rule.addTarget(new targets.CodePipeline(pipeline));

packages/@aws-cdk/aws-events-targets/test/ecs/event-rule-target.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test("Can use EC2 taskdef as EventRule target", () => {
2121
});
2222

2323
const rule = new events.Rule(stack, 'Rule', {
24-
scheduleExpression: 'rate(1 minute)',
24+
schedule: events.Schedule.expression('rate(1 min)')
2525
});
2626

2727
// WHEN
@@ -69,7 +69,7 @@ test("Can use Fargate taskdef as EventRule target", () => {
6969
});
7070

7171
const rule = new events.Rule(stack, 'Rule', {
72-
scheduleExpression: 'rate(1 minute)',
72+
schedule: events.Schedule.expression('rate(1 min)')
7373
});
7474

7575
// WHEN

packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-ec2-task.lit.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class EventStack extends cdk.Stack {
3232

3333
// An Rule that describes the event trigger (in this case a scheduled run)
3434
const rule = new events.Rule(this, 'Rule', {
35-
scheduleExpression: 'rate(1 minute)',
35+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
3636
});
3737

3838
// Use EcsTask as the target of the Rule

packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-fargate-task.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class EventStack extends cdk.Stack {
2828

2929
// A rule that describes the event trigger (in this case a scheduled run)
3030
const rule = new events.Rule(this, 'Rule', {
31-
scheduleExpression: 'rate(1 minute)',
31+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
3232
});
3333

3434
// Use EcsTask as the target of the Rule

packages/@aws-cdk/aws-events-targets/test/lambda/integ.events.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ const fn = new lambda.Function(stack, 'MyFunc', {
1313
code: lambda.Code.inline(`exports.handler = ${handler.toString()}`)
1414
});
1515

16-
const timer = new events.Rule(stack, 'Timer', { scheduleExpression: 'rate(1 minute)' });
16+
const timer = new events.Rule(stack, 'Timer', {
17+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
18+
});
1719
timer.addTarget(new targets.LambdaFunction(fn));
1820

19-
const timer2 = new events.Rule(stack, 'Timer2', { scheduleExpression: 'rate(2 minutes)' });
21+
const timer2 = new events.Rule(stack, 'Timer2', {
22+
schedule: events.Schedule.rate(2, events.TimeUnit.Minute),
23+
});
2024
timer2.addTarget(new targets.LambdaFunction(fn));
2125

2226
app.synth();

packages/@aws-cdk/aws-events-targets/test/lambda/lambda.test.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ test('use lambda as an event rule target', () => {
88
// GIVEN
99
const stack = new cdk.Stack();
1010
const fn = newTestLambda(stack);
11-
const rule1 = new events.Rule(stack, 'Rule', { scheduleExpression: 'rate(1 minute)' });
12-
const rule2 = new events.Rule(stack, 'Rule2', { scheduleExpression: 'rate(5 minutes)' });
11+
const rule1 = new events.Rule(stack, 'Rule', {
12+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
13+
});
14+
const rule2 = new events.Rule(stack, 'Rule2', {
15+
schedule: events.Schedule.rate(5, events.TimeUnit.Minute),
16+
});
1317

1418
// WHEN
1519
rule1.addTarget(new targets.LambdaFunction(fn));

packages/@aws-cdk/aws-events-targets/test/sns/integ.sns-event-rule-target.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const stack = new cdk.Stack(app, 'aws-cdk-sns-event-target');
1616

1717
const topic = new sns.Topic(stack, 'MyTopic');
1818
const event = new events.Rule(stack, 'EveryMinute', {
19-
scheduleExpression: 'rate(1 minute)'
19+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
2020
});
2121

2222
const queue = new sqs.Queue(stack, 'MyQueue');

packages/@aws-cdk/aws-events-targets/test/sns/sns.test.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('sns topic as an event rule target', () => {
99
const stack = new Stack();
1010
const topic = new sns.Topic(stack, 'MyTopic');
1111
const rule = new events.Rule(stack, 'MyRule', {
12-
scheduleExpression: 'rate(1 hour)',
12+
schedule: events.Schedule.rate(1, events.TimeUnit.Hour),
1313
});
1414

1515
// WHEN
@@ -51,7 +51,9 @@ test('multiple uses of a topic as a target results in a single policy statement'
5151

5252
// WHEN
5353
for (let i = 0; i < 5; ++i) {
54-
const rule = new events.Rule(stack, `Rule${i}`, { scheduleExpression: 'rate(1 hour)' });
54+
const rule = new events.Rule(stack, `Rule${i}`, {
55+
schedule: events.Schedule.rate(1, events.TimeUnit.Hour),
56+
});
5557
rule.addTarget(new targets.SnsTopic(topic));
5658
}
5759

packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const app = new cdk.App();
1313
const stack = new cdk.Stack(app, 'aws-cdk-sqs-event-target');
1414

1515
const event = new events.Rule(stack, 'MyRule', {
16-
scheduleExpression: 'rate(1 minute)',
16+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
1717
});
1818

1919
const queue = new sqs.Queue(stack, 'MyQueue');

packages/@aws-cdk/aws-events-targets/test/sqs/sqs.test.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('sns topic as an event rule target', () => {
99
const stack = new Stack();
1010
const queue = new sqs.Queue(stack, 'MyQueue');
1111
const rule = new events.Rule(stack, 'MyRule', {
12-
scheduleExpression: 'rate(1 hour)',
12+
schedule: events.Schedule.rate(1, events.TimeUnit.Hour),
1313
});
1414

1515
// WHEN
@@ -74,7 +74,9 @@ test('multiple uses of a queue as a target results in multi policy statement bec
7474

7575
// WHEN
7676
for (let i = 0; i < 2; ++i) {
77-
const rule = new events.Rule(stack, `Rule${i}`, { scheduleExpression: 'rate(1 hour)' });
77+
const rule = new events.Rule(stack, `Rule${i}`, {
78+
schedule: events.Schedule.rate(1, events.TimeUnit.Hour),
79+
});
7880
rule.addTarget(new targets.SqsQueue(queue));
7981
}
8082

packages/@aws-cdk/aws-events-targets/test/stepfunctions/statemachine.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test('State machine can be used as Event Rule target', () => {
88
// GIVEN
99
const stack = new cdk.Stack();
1010
const rule = new events.Rule(stack, 'Rule', {
11-
scheduleExpression: 'rate(1 minute)'
11+
schedule: events.Schedule.rate(1, events.TimeUnit.Minute),
1212
});
1313
const stateMachine = new sfn.StateMachine(stack, 'SM', {
1414
definition: new sfn.Wait(stack, 'Hello', { duration: sfn.WaitDuration.seconds(10) })

packages/@aws-cdk/aws-events/lib/event-pattern.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@
3030
export interface EventPattern {
3131
/**
3232
* By default, this is set to 0 (zero) in all events.
33+
*
34+
* @default - No filtering on version
3335
*/
3436
readonly version?: string[];
3537

3638
/**
3739
* A unique value is generated for every event. This can be helpful in
3840
* tracing events as they move through rules to targets, and are processed.
41+
*
42+
* @default - No filtering on id
3943
*/
4044
readonly id?: string[];
4145

@@ -44,6 +48,8 @@ export interface EventPattern {
4448
* that appear in the detail field.
4549
*
4650
* Represents the "detail-type" event field.
51+
*
52+
* @default - No filtering on detail type
4753
*/
4854
readonly detailType?: string[];
4955

@@ -58,11 +64,14 @@ export interface EventPattern {
5864
* CloudFront is aws.cloudfront.
5965
*
6066
* @see http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces
67+
* @default - No filtering on source
6168
*/
6269
readonly source?: string[];
6370

6471
/**
6572
* The 12-digit number identifying an AWS account.
73+
*
74+
* @default - No filtering on account
6675
*/
6776
readonly account?: string[];
6877

@@ -71,11 +80,15 @@ export interface EventPattern {
7180
* the event. If the event spans a time interval, the service might choose
7281
* to report the start time, so this value can be noticeably before the time
7382
* the event is actually received.
83+
*
84+
* @default - No filtering on time
7485
*/
7586
readonly time?: string[];
7687

7788
/**
7889
* Identifies the AWS region where the event originated.
90+
*
91+
* @default - No filtering on region
7992
*/
8093
readonly region?: string[];
8194

@@ -88,12 +101,16 @@ export interface EventPattern {
88101
* instance ARNs, Auto Scaling events include ARNs for both instances and
89102
* Auto Scaling groups, but API calls with AWS CloudTrail do not include
90103
* resource ARNs.
104+
*
105+
* @default - No filtering on resource
91106
*/
92107
readonly resources?: string[];
93108

94109
/**
95110
* A JSON object, whose content is at the discretion of the service
96111
* originating the event.
112+
*
113+
* @default - No filtering on detail
97114
*/
98-
readonly detail?: any;
115+
readonly detail?: {[key: string]: any};
99116
}

packages/@aws-cdk/aws-events/lib/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from './rule';
33
export * from './rule-ref';
44
export * from './target';
55
export * from './event-pattern';
6+
export * from './schedule';
67
export * from './on-event-options';
78

89
// AWS::Events CloudFormation Resources:

packages/@aws-cdk/aws-events/lib/rule.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Construct, Lazy, Resource } from '@aws-cdk/cdk';
22
import { EventPattern } from './event-pattern';
33
import { CfnRule } from './events.generated';
44
import { IRule } from './rule-ref';
5+
import { Schedule } from './schedule';
56
import { IRuleTarget } from './target';
67
import { mergeEventPattern } from './util';
78

@@ -39,7 +40,7 @@ export interface RuleProps {
3940
*
4041
* @default - None.
4142
*/
42-
readonly scheduleExpression?: string;
43+
readonly schedule?: Schedule;
4344

4445
/**
4546
* Describes which events CloudWatch Events routes to the specified target.
@@ -104,7 +105,7 @@ export class Rule extends Resource implements IRule {
104105
this.ruleArn = resource.attrArn;
105106

106107
this.addEventPattern(props.eventPattern);
107-
this.scheduleExpression = props.scheduleExpression;
108+
this.scheduleExpression = props.schedule && props.schedule.expressionString;
108109

109110
for (const target of props.targets || []) {
110111
this.addTarget(target);
@@ -189,7 +190,7 @@ export class Rule extends Resource implements IRule {
189190

190191
protected validate() {
191192
if (Object.keys(this.eventPattern).length === 0 && !this.scheduleExpression) {
192-
return [ `Either 'eventPattern' or 'scheduleExpression' must be defined` ];
193+
return [ `Either 'eventPattern' or 'schedule' must be defined` ];
193194
}
194195

195196
return [ ];

0 commit comments

Comments
 (0)