/
custom-resource-is-migration-complete.ts
99 lines (83 loc) · 2.81 KB
/
custom-resource-is-migration-complete.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import {
DescribeExecutionCommand,
ExecutionStatus,
SFNClient,
} from "@aws-sdk/client-sfn";
import { CloudFormationCustomResourceEvent } from "aws-lambda";
import { Construct } from "constructs";
import { $AWS, Function, Table } from "functionless";
import { marshall, unmarshall } from "typesafe-dynamodb/lib/marshall";
import { MigrationHistoryItem } from "./migrations-manager";
type MigrationIdStateMachineArnPair = {
migrationId: string;
stateMachineArn: string;
};
export type CustomResourceIsMigrationCompleteCheckerProps = {
migrationIdStateMachinePairs: MigrationIdStateMachineArnPair[];
migrationsHistoryTable: Table<MigrationHistoryItem, "id">;
};
export type ReturnType = { IsComplete: boolean };
export default class CustomResourceIsMigrationCompleteChecker extends Construct {
public readonly function: Function<
CloudFormationCustomResourceEvent,
ReturnType
>;
constructor(
scope: Construct,
id: string,
{
migrationsHistoryTable,
migrationIdStateMachinePairs,
}: CustomResourceIsMigrationCompleteCheckerProps
) {
super(scope, id);
let allDone = true;
this.function = new Function(
scope,
`${id}-MigrationsChecker`,
async (event: CloudFormationCustomResourceEvent): Promise<ReturnType> => {
console.log(event);
const client = new SFNClient({});
for (const migration of migrationIdStateMachinePairs) {
const migrationEntry = await $AWS.DynamoDB.GetItem({
Table: migrationsHistoryTable,
Key: marshall({ id: migration.migrationId }),
});
if (!migrationEntry.Item) {
throw new Error(
`Failed to find migration entry for migrationId: ${migration.migrationId}`
);
}
const item = unmarshall(migrationEntry.Item);
if (
item.status === "ABORTED" ||
item.status === "FAILED" ||
item.status === "SUCCEEDED" ||
item.status === "TIMED_OUT"
) {
continue;
}
const command = new DescribeExecutionCommand({
executionArn: item.executionArn,
});
const response = await client.send(command);
console.log({ migration, response });
if (response.status === "RUNNING") {
allDone = false;
}
await $AWS.DynamoDB.PutItem({
Table: migrationsHistoryTable,
Item: marshall({
id: migration.migrationId,
startedAt: response.startDate?.toISOString()!,
executionArn: response.executionArn!,
status: response.status as ExecutionStatus,
endedAt: response.stopDate?.toISOString(),
}),
});
}
return { IsComplete: allDone };
}
);
}
}