Skip to content

Commit

Permalink
feat(events): make target optional in onXxx() methods (#2921)
Browse files Browse the repository at this point in the history
Make `target` optional in `OnEventOptions` so that it is no required when calling a `onXxx()`
method.

This allows to use "preconfigured" rules in other constructs.

Update `awslint:events-method-signature` to enforce optional `options` parameter in `onXxx()` method signatures.

Closes #2913
  • Loading branch information
jogold authored and Elad Ben-Israel committed Jun 19, 2019
1 parent 661d28c commit ea10f0d
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 32 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-cloudtrail/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export class Trail extends Resource {
*
* Be sure to filter the event further down using an event pattern.
*/
public onCloudTrailEvent(id: string, options: events.OnEventOptions): events.Rule {
public onCloudTrailEvent(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = new events.Rule(this, id, options);
rule.addTarget(options.target);
rule.addEventPattern({
Expand Down
12 changes: 6 additions & 6 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ abstract class ProjectBase extends Resource implements IProject {
*
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html
*/
public onEvent(id: string, options: events.OnEventOptions): events.Rule {
public onEvent(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = new events.Rule(this, id, options);
rule.addTarget(options.target);
rule.addEventPattern({
Expand Down Expand Up @@ -239,7 +239,7 @@ abstract class ProjectBase extends Resource implements IProject {
*
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html
*/
public onStateChange(id: string, options: events.OnEventOptions) {
public onStateChange(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: ['CodeBuild Build State Change'],
Expand All @@ -253,7 +253,7 @@ abstract class ProjectBase extends Resource implements IProject {
*
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html
*/
public onPhaseChange(id: string, options: events.OnEventOptions) {
public onPhaseChange(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: ['CodeBuild Build Phase Change'],
Expand All @@ -267,7 +267,7 @@ abstract class ProjectBase extends Resource implements IProject {
* To access fields from the event in the event target input,
* use the static fields on the `StateChangeEvent` class.
*/
public onBuildStarted(id: string, options: events.OnEventOptions) {
public onBuildStarted(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({
detail: {
Expand All @@ -283,7 +283,7 @@ abstract class ProjectBase extends Resource implements IProject {
* To access fields from the event in the event target input,
* use the static fields on the `StateChangeEvent` class.
*/
public onBuildFailed(id: string, options: events.OnEventOptions) {
public onBuildFailed(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({
detail: {
Expand All @@ -299,7 +299,7 @@ abstract class ProjectBase extends Resource implements IProject {
* To access fields from the event in the event target input,
* use the static fields on the `StateChangeEvent` class.
*/
public onBuildSucceeded(id: string, options: events.OnEventOptions) {
public onBuildSucceeded(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({
detail: {
Expand Down
18 changes: 9 additions & 9 deletions packages/@aws-cdk/aws-codecommit/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
* Defines a CloudWatch event rule which triggers for repository events. Use
* `rule.addEventPattern(pattern)` to specify a filter.
*/
public onEvent(id: string, options: events.OnEventOptions) {
public onEvent(id: string, options: events.OnEventOptions = {}) {
const rule = new events.Rule(this, id, options);
rule.addEventPattern({
source: [ 'aws.codecommit' ],
Expand All @@ -131,7 +131,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
* Defines a CloudWatch event rule which triggers when a "CodeCommit
* Repository State Change" event occurs.
*/
public onStateChange(id: string, options: events.OnEventOptions) {
public onStateChange(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: [ 'CodeCommit Repository State Change' ],
Expand All @@ -143,7 +143,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
* Defines a CloudWatch event rule which triggers when a reference is
* created (i.e. a new branch/tag is created) to the repository.
*/
public onReferenceCreated(id: string, options: events.OnEventOptions) {
public onReferenceCreated(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({ detail: { event: [ 'referenceCreated' ] } });
return rule;
Expand All @@ -153,7 +153,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
* Defines a CloudWatch event rule which triggers when a reference is
* updated (i.e. a commit is pushed to an existing or new branch) from the repository.
*/
public onReferenceUpdated(id: string, options: events.OnEventOptions) {
public onReferenceUpdated(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({ detail: { event: [ 'referenceCreated', 'referenceUpdated' ] } });
return rule;
Expand All @@ -163,7 +163,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
* Defines a CloudWatch event rule which triggers when a reference is
* delete (i.e. a branch/tag is deleted) from the repository.
*/
public onReferenceDeleted(id: string, options: events.OnEventOptions) {
public onReferenceDeleted(id: string, options: events.OnEventOptions = {}) {
const rule = this.onStateChange(id, options);
rule.addEventPattern({ detail: { event: [ 'referenceDeleted' ] } });
return rule;
Expand All @@ -172,7 +172,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
/**
* Defines a CloudWatch event rule which triggers when a pull request state is changed.
*/
public onPullRequestStateChange(id: string, options: events.OnEventOptions) {
public onPullRequestStateChange(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({ detailType: [ 'CodeCommit Pull Request State Change' ] });
return rule;
Expand All @@ -181,7 +181,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
/**
* Defines a CloudWatch event rule which triggers when a comment is made on a pull request.
*/
public onCommentOnPullRequest(id: string, options: events.OnEventOptions) {
public onCommentOnPullRequest(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({ detailType: [ 'CodeCommit Comment on Pull Request' ] });
return rule;
Expand All @@ -190,7 +190,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
/**
* Defines a CloudWatch event rule which triggers when a comment is made on a commit.
*/
public onCommentOnCommit(id: string, options: events.OnEventOptions) {
public onCommentOnCommit(id: string, options: events.OnEventOptions = {}) {
const rule = this.onEvent(id, options);
rule.addEventPattern({ detailType: [ 'CodeCommit Comment on Commit' ] });
return rule;
Expand All @@ -199,7 +199,7 @@ abstract class RepositoryBase extends Resource implements IRepository {
/**
* Defines a CloudWatch event rule which triggers when a commit is pushed to a branch.
*/
public onCommit(id: string, options: OnCommitOptions) {
public onCommit(id: string, options: OnCommitOptions = {}) {
const rule = this.onReferenceUpdated(id, options);
if (options.branches) {
rule.addEventPattern({ detail: { referenceName: options.branches }});
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ abstract class PipelineBase extends Resource implements IPipeline {
* @param id Identifier for this event handler.
* @param options Additional options to pass to the event rule.
*/
public onEvent(id: string, options: events.OnEventOptions): events.Rule {
public onEvent(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = new events.Rule(this, id, options);
rule.addTarget(options.target);
rule.addEventPattern({
Expand All @@ -131,7 +131,7 @@ abstract class PipelineBase extends Resource implements IPipeline {
* @param id Identifier for this event handler.
* @param options Additional options to pass to the event rule.
*/
public onStateChange(id: string, options: events.OnEventOptions): events.Rule {
public onStateChange(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: [ 'CodePipeline Pipeline Execution State Change' ],
Expand Down
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-config/lib/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ abstract class RuleBase extends Resource implements IRule {
* Defines a CloudWatch event rule which triggers for rule events. Use
* `rule.addEventPattern(pattern)` to specify a filter.
*/
public onEvent(id: string, options: events.OnEventOptions) {
public onEvent(id: string, options: events.OnEventOptions = {}) {
const rule = new events.Rule(this, id, options);
rule.addEventPattern({
source: ['aws.config'],
Expand All @@ -80,7 +80,7 @@ abstract class RuleBase extends Resource implements IRule {
/**
* Defines a CloudWatch event rule which triggers for rule compliance events.
*/
public onComplianceChange(id: string, options: events.OnEventOptions): events.Rule {
public onComplianceChange(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: [ 'Config Rules Compliance Change' ],
Expand All @@ -91,7 +91,7 @@ abstract class RuleBase extends Resource implements IRule {
/**
* Defines a CloudWatch event rule which triggers for rule re-evaluation status events.
*/
public onReEvaluationStatus(id: string, options: events.OnEventOptions): events.Rule {
public onReEvaluationStatus(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = this.onEvent(id, options);
rule.addEventPattern({
detailType: [ 'Config Rules Re-evaluation Status' ],
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-ecr/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export abstract class RepositoryBase extends Resource implements IRepository {
* @param id The id of the rule
* @param options Options for adding the rule
*/
public onCloudTrailEvent(id: string, options: events.OnEventOptions): events.Rule {
public onCloudTrailEvent(id: string, options: events.OnEventOptions = {}): events.Rule {
const rule = new events.Rule(this, id, options);
rule.addTarget(options.target);
rule.addEventPattern({
Expand All @@ -158,7 +158,7 @@ export abstract class RepositoryBase extends Resource implements IRepository {
* @param id The id of the rule
* @param options Options for adding the rule
*/
public onCloudTrailImagePushed(id: string, options: OnCloudTrailImagePushedOptions): events.Rule {
public onCloudTrailImagePushed(id: string, options: OnCloudTrailImagePushedOptions = {}): events.Rule {
const rule = this.onCloudTrailEvent(id, options);
rule.addEventPattern({
detail: {
Expand Down
10 changes: 8 additions & 2 deletions packages/@aws-cdk/aws-events/lib/on-event-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import { IRuleTarget } from "./target";
export interface OnEventOptions {
/**
* The target to register for the event
*
* @default - No target is added to the rule. Use `addTarget()` to add a target.
*/
readonly target: IRuleTarget;
readonly target?: IRuleTarget;

/**
* A description of the rule's purpose.
*
* @default - No description
*/
readonly description?: string;

Expand All @@ -29,8 +33,10 @@ export interface OnEventOptions {
* filtering. The filtering implied by what you pass here is added
* on top of that filtering.
*
* @default - No additional filtering based on an event pattern.
*
* @see
* http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CloudWatchEventsandEventPatterns.html
*/
readonly eventPattern?: EventPattern;
}
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-rds/lib/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
* Defines a CloudWatch event rule which triggers for instance events. Use
* `rule.addEventPattern(pattern)` to specify a filter.
*/
public onEvent(id: string, options: events.OnEventOptions) {
public onEvent(id: string, options: events.OnEventOptions = {}) {
const rule = new events.Rule(this, id, options);
rule.addEventPattern({
source: ['aws.rds'],
Expand Down
62 changes: 62 additions & 0 deletions packages/@aws-cdk/aws-rds/test/test.instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,68 @@ export = {
// WHEN
instance.onEvent('InstanceEvent', { target: new targets.LambdaFunction(fn) });

// THEN
expect(stack).to(haveResource('AWS::Events::Rule', {
EventPattern: {
source: [
'aws.rds'
],
resources: [
{
'Fn::Join': [
'',
[
'arn:',
{
Ref: 'AWS::Partition'
},
':rds:',
{
Ref: 'AWS::Region'
},
':',
{
Ref: 'AWS::AccountId'
},
':db:',
{
Ref: 'InstanceC1063A87'
}
]
]
}
]
},
Targets: [
{
Arn: {
'Fn::GetAtt': [
'Function76856677',
'Arn'
],
},
Id: 'Function'
}
]
}));

test.done();
},

'on event without target'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const instance = new rds.DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.Mysql,
instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Small),
masterUsername: 'admin',
vpc
});

// WHEN
instance.onEvent('InstanceEvent');

// THEN
expect(stack).to(haveResource('AWS::Events::Rule', {
EventPattern: {
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ abstract class BucketBase extends Resource implements IBucket {
* @param id The id of the rule
* @param options Options for adding the rule
*/
public onCloudTrailEvent(id: string, options: OnCloudTrailBucketEventOptions): events.Rule {
public onCloudTrailEvent(id: string, options: OnCloudTrailBucketEventOptions = {}): events.Rule {
const rule = new events.Rule(this, id, options);
rule.addTarget(options.target);
rule.addEventPattern({
Expand All @@ -326,7 +326,7 @@ abstract class BucketBase extends Resource implements IBucket {
* @param id The id of the rule
* @param options Options for adding the rule
*/
public onCloudTrailPutObject(id: string, options: OnCloudTrailBucketEventOptions): events.Rule {
public onCloudTrailPutObject(id: string, options: OnCloudTrailBucketEventOptions = {}): events.Rule {
const rule = this.onCloudTrailEvent(id, options);
rule.addEventPattern({
detail: {
Expand Down
9 changes: 8 additions & 1 deletion tools/awslint/lib/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ export class Evaluation<T> {
return this.assert(a.toString() === e.toString() || (a.fqn && e.fqn && a.type!.extends(e.type!)), scope, ` ("${a}" not assignable to "${e}")`);
}

public assertParameterOptional(actual: boolean, expected: boolean, scope: string) {
return this.assert(actual === expected, scope, ` (${scope} should be ${expected ? 'optional' : 'mandatory'})`);
}

public assertSignature(method: reflect.Callable, expectations: MethodSignatureExpectations) {
const scope = method.parentType.fqn + '.' + method.name;
if (expectations.returns && reflect.Method.isMethod(method)) {
Expand All @@ -198,6 +202,9 @@ export class Evaluation<T> {
this.assertTypesEqual(method.system, actual.type, expect.type, pscope);
}
}
if (expect.optional !== undefined) {
this.assertParameterOptional(actual.optional, expect.optional, pscope);
}
}
}
}
Expand Down Expand Up @@ -315,4 +322,4 @@ function typeReferenceFrom(ts: reflect.TypeSystem, x: TypeSpecifier): reflect.Ty

function isTypeReference(x: any): x is reflect.TypeReference {
return x instanceof reflect.TypeReference;
}
}
6 changes: 3 additions & 3 deletions tools/awslint/lib/rules/cloudwatch-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ eventsLinter.add({

eventsLinter.add({
code: 'events-method-signature',
message: `all 'onXxx()' methods should have the CloudWatch Events signature (id: string, options: events.OnEventOptions) => events.Rule`,
message: `all 'onXxx()' methods should have the CloudWatch Events signature (id: string, options: events.OnEventOptions = {}) => events.Rule`,
eval: e => {
for (const method of e.ctx.directEventMethods) {
e.assertSignature(method, {
parameters: [
{ type: 'string' },
{ type: ON_EVENT_OPTIONS_FQN, subtypeAllowed: true },
{ type: ON_EVENT_OPTIONS_FQN, subtypeAllowed: true, optional: true },
],
returns: EVENT_RULE_FQN
});
Expand All @@ -68,4 +68,4 @@ function isDirectEventMethod(m: reflect.Method) {

function isCloudTrailEventMethod(m: reflect.Method) {
return m.name.startsWith('onCloudTrail');
}
}

0 comments on commit ea10f0d

Please sign in to comment.