import * as cdk from "@aws-cdk/core"; import * as events from "@aws-cdk/aws-events"; import * as eventsTargets from "@aws-cdk/aws-events-targets"; import { Function as Func, FunctionDefinition } from "./Function"; import { Permissions } from "./util/permission"; export interface CronProps { readonly job: FunctionDefinition | CronJobProps; readonly schedule?: string | cdk.Duration | events.CronOptions; readonly eventsRule?: events.RuleProps; } export interface CronJobProps { readonly function: FunctionDefinition; readonly jobProps?: eventsTargets.LambdaFunctionProps; } export class Cron extends cdk.Construct { public readonly eventsRule: events.Rule; public readonly jobFunction: Func; constructor(scope: cdk.Construct, id: string, props: CronProps) { super(scope, id); const { // Topic props schedule, eventsRule, // Function props job, } = props; /////////////////////////// // Create Rule /////////////////////////// const eventsRuleProps = (eventsRule || {}) as events.RuleProps; // Validate: cannot set eventsRule.schedule if (eventsRuleProps.schedule) { throw new Error( `Do not configure the "eventsRule.schedule". Use the "schedule" to configure the Cron schedule.` ); } // Validate: schedule is set if (!schedule) { throw new Error(`No schedule defined for the "${id}" Cron`); } // Configure Schedule let propSchedule: events.Schedule; if ( typeof schedule === "string" && (schedule.startsWith("rate(") || schedule.startsWith("cron(")) ) { propSchedule = events.Schedule.expression(schedule); } else if (schedule instanceof cdk.Duration) { propSchedule = events.Schedule.rate(schedule); } else { propSchedule = events.Schedule.cron(schedule as events.CronOptions); } this.eventsRule = new events.Rule(this, "Rule", { schedule: propSchedule, ...eventsRuleProps, }); /////////////////////////// // Create Targets /////////////////////////// if (!job) { throw new Error(`No job defined for the "${id}" Cron`); } // normalize job let jobFunction, jobProps; if ((job as CronJobProps).function) { jobFunction = (job as CronJobProps).function; jobProps = (job as CronJobProps).jobProps; } else { jobFunction = job as FunctionDefinition; jobProps = {}; } // create function this.jobFunction = Func.fromDefinition(this, "Job", jobFunction); this.eventsRule.addTarget( new eventsTargets.LambdaFunction(this.jobFunction, jobProps) ); } attachPermissions(permissions: Permissions): void { this.jobFunction.attachPermissions(permissions); } }