Skip to content

Commit

Permalink
Merge of #3535
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Jul 20, 2023
2 parents ce24a6a + 9a5bef3 commit 162be83
Show file tree
Hide file tree
Showing 6 changed files with 775 additions and 1 deletion.
5 changes: 5 additions & 0 deletions libs/wingsdk/src/target-awscdk/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Bucket } from "./bucket";
import { Counter } from "./counter";
import { Function } from "./function";
import { Queue } from "./queue";
import { Schedule } from "./schedule";
import { Secret } from "./secret";
import { TestRunner } from "./test-runner";
import { CdkTokens } from "./tokens";
Expand All @@ -20,6 +21,7 @@ import {
QUEUE_FQN,
SECRET_FQN,
TOPIC_FQN,
SCHEDULE_FQN,
} from "../cloud";
import { App as CoreApp, AppProps, preSynthesizeAllConstructs } from "../core";
import { PluginManager } from "../core/plugin-manager";
Expand Down Expand Up @@ -145,6 +147,9 @@ export class App extends CoreApp {
case COUNTER_FQN:
return new Counter(scope, id, args[0]);

case SCHEDULE_FQN:
return new Schedule(scope, id, args[0]);

case QUEUE_FQN:
return new Queue(scope, id, args[0]);

Expand Down
1 change: 1 addition & 0 deletions libs/wingsdk/src/target-awscdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from "./bucket";
export * from "./counter";
export * from "./function";
export * from "./queue";
export * from "./schedule";
export * from "./secret";
119 changes: 119 additions & 0 deletions libs/wingsdk/src/target-awscdk/schedule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { join } from "path";
import { Duration } from "aws-cdk-lib";
import { Rule, Schedule as EventSchedule } from "aws-cdk-lib/aws-events";
import {
LambdaFunction,
addLambdaPermission,
} from "aws-cdk-lib/aws-events-targets";
import { Construct } from "constructs";
import { Function } from "./function";
import * as cloud from "../cloud";
import * as core from "../core";
import { convertBetweenHandlers } from "../shared/convert";
import { Resource } from "../std";

/**
* AWS implementation of `cloud.Schedule`.
*
* @inflight `@winglang/sdk.cloud.IScheduleClient`
*/
export class Schedule extends cloud.Schedule {
private readonly scheduleExpression: EventSchedule;
private readonly rule: Rule;

constructor(scope: Construct, id: string, props: cloud.ScheduleProps = {}) {
super(scope, id, props);

const { rate, cron } = props;

/*
* The schedule cron string is Unix cron format: [minute] [hour] [day of month] [month] [day of week]
* AWS EventBridge Schedule uses a 6 field format which includes year: [minute] [hour] [day of month] [month] [day of week] [year]
* https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html#cron-based
*
* We append * to the cron string for year field.
*/
if (cron) {
const cronArr = cron.split(" ");
let cronOpt: { [k: string]: string } = {
minute: cronArr[0],
hour: cronArr[1],
month: cronArr[3],
year: "*",
};
if (cronArr[2] !== "?") {
cronOpt.day = cronArr[2];
}
if (cronArr[4] !== "?") {
cronOpt.weekDay = cronArr[4];
}

this.scheduleExpression = EventSchedule.cron(cronOpt);
} else {
this.scheduleExpression = EventSchedule.rate(
Duration.minutes(rate!.minutes)
);
}

this.rule = new Rule(this, "Schedule", {
enabled: true,
schedule: this.scheduleExpression,
});
}

public onTick(
inflight: cloud.IScheduleOnTickHandler,
props?: cloud.ScheduleOnTickProps | undefined
): cloud.Function {
const hash = inflight.node.addr.slice(-8);
const functionHandler = convertBetweenHandlers(
this.node.scope!, // ok since we're not a tree root
`${this.node.id}-OnTickHandler-${hash}`,
inflight,
join(
__dirname.replace("target-awscdk", "shared-aws"),
"schedule.ontick.inflight.js"
),
"ScheduleOnTickHandlerClient"
);

const fn = Function._newFunction(
this.node.scope!, // ok since we're not a tree root
`${this.node.id}-SetConsumer-${hash}`,
functionHandler,
props
);

// TODO: remove this constraint by adding generic permission APIs to cloud.Function
if (!(fn instanceof Function)) {
throw new Error(
"Schedule only supports creating awscdk.Function right now"
);
}

this.rule.addTarget(new LambdaFunction(fn._function));
addLambdaPermission(this.rule, fn._function);

Resource.addConnection({
from: this,
to: fn,
relationship: "on_tick",
});

return fn;
}

/** @internal */
public _toInflight(): core.Code {
return core.InflightClient.for(
__dirname.replace("target-awscdk", "shared-aws"),
__filename,
"ScheduleClient",
[`process.env["${this.envName()}"]`]
);
}

private envName(): string {
return `SCHEDULE_EVENT_${this.node.addr.slice(-8)}`;
}
}
Loading

0 comments on commit 162be83

Please sign in to comment.