diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index 52bcfe83f8c91..521ee980cb8f7 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -1,4 +1,5 @@ import { App, Construct, Lazy, Resource, Stack, Token } from '@aws-cdk/core'; +import { IEventBus } from './event-bus'; import { EventPattern } from './event-pattern'; import { CfnEventBusPolicy, CfnRule } from './events.generated'; import { IRule } from './rule-ref'; @@ -68,6 +69,13 @@ export interface RuleProps { * @default - No targets. */ readonly targets?: IRuleTarget[]; + + /** + * The event bus to associate with this rule. + * + * @default - The default event bus. + */ + readonly eventBus?: IEventBus; } /** @@ -100,15 +108,22 @@ export class Rule extends Resource implements IRule { super(scope, id, { physicalName: props.ruleName, }); + + if (props.eventBus && props.schedule) { + throw new Error(`Cannot associate rule with 'eventBus' when using 'schedule'`); + } + this.description = props.description; + this.scheduleExpression = props.schedule && props.schedule.expressionString; const resource = new CfnRule(this, 'Resource', { name: this.physicalName, description: this.description, state: props.enabled == null ? 'ENABLED' : (props.enabled ? 'ENABLED' : 'DISABLED'), - scheduleExpression: Lazy.stringValue({ produce: () => this.scheduleExpression }), + scheduleExpression: this.scheduleExpression, eventPattern: Lazy.anyValue({ produce: () => this._renderEventPattern() }), targets: Lazy.anyValue({ produce: () => this.renderTargets() }), + eventBusName: props.eventBus && props.eventBus.eventBusName, }); this.ruleArn = this.getResourceArnAttribute(resource.attrArn, { @@ -119,7 +134,6 @@ export class Rule extends Resource implements IRule { this.ruleName = this.getResourceNameAttribute(resource.ref); this.addEventPattern(props.eventPattern); - this.scheduleExpression = props.schedule && props.schedule.expressionString; for (const target of props.targets || []) { this.addTarget(target); @@ -346,10 +360,10 @@ export class Rule extends Resource implements IRule { protected validate() { if (Object.keys(this.eventPattern).length === 0 && !this.scheduleExpression) { - return [ `Either 'eventPattern' or 'schedule' must be defined` ]; + return [`Either 'eventPattern' or 'schedule' must be defined`]; } - return [ ]; + return []; } private renderTargets() { diff --git a/packages/@aws-cdk/aws-events/test/test.rule.ts b/packages/@aws-cdk/aws-events/test/test.rule.ts index c92b38bd509c0..f861ffcb4e2fe 100644 --- a/packages/@aws-cdk/aws-events/test/test.rule.ts +++ b/packages/@aws-cdk/aws-events/test/test.rule.ts @@ -4,7 +4,7 @@ import { ServicePrincipal } from '@aws-cdk/aws-iam'; import cdk = require('@aws-cdk/core'); import { CfnResource, Stack } from '@aws-cdk/core'; import { Test } from 'nodeunit'; -import { EventField, IRule, IRuleTarget, RuleTargetConfig, RuleTargetInput, Schedule } from '../lib'; +import { EventBus, EventField, IRule, IRuleTarget, RuleTargetConfig, RuleTargetInput, Schedule } from '../lib'; import { Rule } from '../lib/rule'; // tslint:disable:object-literal-key-quotes @@ -490,6 +490,43 @@ export = { test.done(); }, + 'associate rule with event bus'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const eventBus = new EventBus(stack, 'EventBus'); + + // WHEN + new Rule(stack, 'MyRule', { + eventPattern: { + detail: ['detail'] + }, + eventBus, + }); + + // THEN + expect(stack).to(haveResource('AWS::Events::Rule', { + EventBusName: { + Ref: 'EventBus7B8748AA' + } + })); + + test.done(); + }, + + 'throws with eventBus and schedule'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'MyStack'); + const eventBus = new EventBus(stack, 'EventBus'); + + // THEN + test.throws(() => new Rule(stack, 'MyRule', { + schedule: Schedule.rate(cdk.Duration.minutes(10)), + eventBus, + }), /Cannot associate rule with 'eventBus' when using 'schedule'/); + test.done(); + }, + 'for cross-account targets': { 'requires that the source stack specify a concrete account'(test: Test) { const app = new cdk.App();