From b2f5e6e0c0ba0e36f110f4a64850b14227d056cf Mon Sep 17 00:00:00 2001 From: Rafal Wilinski Date: Mon, 8 Aug 2022 23:04:18 +0200 Subject: [PATCH] refactor: fix modularization --- package.json | 3 +- src/custom-resource-migrations-runner.ts | 60 ++++++++++++++----- .../migrations/20220801-add-attribute.ts | 14 ++--- src/examples/test-stack.ts | 2 +- src/migration.ts | 6 ++ src/migrations-manager.ts | 34 +++-------- 6 files changed, 66 insertions(+), 53 deletions(-) diff --git a/package.json b/package.json index 61ab86b..4f4d9c9 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ }, "dependencies": { "@aws-cdk/aws-appsync-alpha": "^2.35.0-alpha.0", + "@types/aws-lambda": "^8.10.101", "aws-cdk-lib": "^2.1.0", "constructs": "^10.0.5", "functionless": "^0.19.4", @@ -102,4 +103,4 @@ } }, "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." -} \ No newline at end of file +} diff --git a/src/custom-resource-migrations-runner.ts b/src/custom-resource-migrations-runner.ts index a2f36a7..34d3cdd 100644 --- a/src/custom-resource-migrations-runner.ts +++ b/src/custom-resource-migrations-runner.ts @@ -1,12 +1,24 @@ -import { CloudFormationCustomResourceEvent } from "aws-lambda"; +import { Table as cdkTable } from "aws-cdk-lib/aws-dynamodb"; +import { + CloudFormationCustomResourceEvent, + CloudFormationCustomResourceResponse, + CloudFormationCustomResourceSuccessResponse, + CloudFormationCustomResourceFailedResponse, +} from "aws-lambda"; import { Construct } from "constructs"; -import { $AWS, Function } from "functionless"; +import { $AWS, Function, Table } from "functionless"; +import { MigrationHistoryItem } from "./migrations-manager"; export type CustomResourceMigrationsRunnerProps = { migrationFiles: string[]; + migrationsHistoryTable: Table; }; export default class CustomResourceMigrationsRunner extends Construct { + public readonly function: Function< + CloudFormationCustomResourceEvent, + CloudFormationCustomResourceResponse + >; constructor( scope: Construct, id: string, @@ -14,28 +26,46 @@ export default class CustomResourceMigrationsRunner extends Construct { ) { super(scope, id); - new Function( + const migrationsHistoryTable = Table.fromTable( + cdkTable.fromTableArn( + scope, + "MigrationsHistoryTable", + props.migrationsHistoryTable.tableArn + ) + ); + + this.function = new Function( scope, `${id}-MigrationsRunner`, async (event: CloudFormationCustomResourceEvent) => { console.log(event); - const migrations = await $AWS.DynamoDB.Scan({ - Table: migrationsHistoryTable, - }); + try { + const migrations = await $AWS.DynamoDB.Scan({ + Table: migrationsHistoryTable, + }); + + console.log({ migrations }); - console.log({ migrations }); + const migrationsToRun = props.migrationFiles.filter( + (migrationFile) => + !(migrations.Items ?? []).find( + (migration) => migration.id.S === migrationFile + ) + ); - const migrationsToRun = props.migrationFiles.filter( - (migrationFile) => - !(migrations.Items ?? []).find( - (migration) => migration.id.S === migrationFile - ) - ); + console.log({ migrationsToRun }); - console.log({ migrationsToRun }); + // todo: Start the migrations - // todo: Start the migrations + return { + Status: "SUCCESS", + } as CloudFormationCustomResourceSuccessResponse; + } catch (error) { + return { + Status: "FAILED", + } as CloudFormationCustomResourceFailedResponse; + } } ); } diff --git a/src/examples/migrations/20220801-add-attribute.ts b/src/examples/migrations/20220801-add-attribute.ts index a24e08f..2582c4a 100644 --- a/src/examples/migrations/20220801-add-attribute.ts +++ b/src/examples/migrations/20220801-add-attribute.ts @@ -1,14 +1,7 @@ import { Table as cdkTable } from "aws-cdk-lib/aws-dynamodb"; -import { Construct } from "constructs"; import { $AWS, Table } from "functionless"; import { unmarshall, marshall } from "typesafe-dynamodb/lib/marshall"; -import { MigrationProps, Migration } from "../../migration"; - -export type MigrationFunction = ( - scope: Construct, - id: string, - props: MigrationProps -) => Migration; +import { Migration, MigrationFunction } from "../.."; const tableArn = "arn:aws:dynamodb:us-east-1:085108115628:table/TestStack-TableCD117FA1-ZVV3ZWUOWPO"; @@ -20,16 +13,17 @@ export const migration: MigrationFunction = (scope, migrationName) => { }); const table = Table.fromTable( - cdkTable.fromTableArn(scope, "SubjectTable", tableArn) + cdkTable.fromTableArn(scope, "TargetTable", tableArn) ); // Actual migration code goes here. // For each item in the table migrationDefinition.scan(async ({ result }) => { for (const i of result.Items as any[]) { - // Do the following: + // Do the following await $AWS.DynamoDB.PutItem({ Table: table, + // Add migratedAt attribute to the item Item: marshall({ ...unmarshall(i), migratedAt: Date.now() }), }); } diff --git a/src/examples/test-stack.ts b/src/examples/test-stack.ts index eb0924c..d3f9e5f 100755 --- a/src/examples/test-stack.ts +++ b/src/examples/test-stack.ts @@ -1,6 +1,6 @@ import { App, CfnOutput, Stack } from "aws-cdk-lib"; import { AttributeType, BillingMode, Table } from "aws-cdk-lib/aws-dynamodb"; -import { MigrationsManager } from "../app"; +import { MigrationsManager } from "../"; const app = new App(); diff --git a/src/migration.ts b/src/migration.ts index f783266..2f62ddb 100644 --- a/src/migration.ts +++ b/src/migration.ts @@ -94,3 +94,9 @@ export class Migration extends NestedStack { ); } } + +export type MigrationFunction = ( + scope: Construct, + id: string, + props: MigrationProps +) => Migration; diff --git a/src/migrations-manager.ts b/src/migrations-manager.ts index 8ee2056..cb13254 100644 --- a/src/migrations-manager.ts +++ b/src/migrations-manager.ts @@ -2,9 +2,9 @@ import * as fs from "fs"; import * as path from "path"; import { aws_dynamodb, CustomResource } from "aws-cdk-lib"; import { Provider } from "aws-cdk-lib/custom-resources"; -import { CloudFormationCustomResourceEvent } from "aws-lambda"; import { Construct } from "constructs"; -import { $AWS, Table, Function } from "functionless"; +import { Table } from "functionless"; +import CustomResourceMigrationsRunner from "./custom-resource-migrations-runner"; export type MigrationManagerProps = { /** @@ -45,10 +45,10 @@ export class MigrationsManager extends Construct { const migrationsDir = path.resolve(props.migrationsDir); const migrationFiles = fs.readdirSync(migrationsDir); - let migrationStacks = []; for (const migrationFile of migrationFiles) { + // Cannot use dynamic imports here due to synchronous nature of CDKs synthesis process // eslint-disable-next-line @typescript-eslint/no-require-imports const migrationStack = require(path.resolve( migrationsDir, @@ -58,35 +58,17 @@ export class MigrationsManager extends Construct { migrationStacks.push(migrationStack.migration(this, migrationFile)); } - const onEventHandler = new Function( + const onEventHandler = new CustomResourceMigrationsRunner( this, - "OnEventHandler", - async (event: CloudFormationCustomResourceEvent) => { - console.log(event); - - const migrations = await $AWS.DynamoDB.Scan({ - Table: migrationsHistoryTable, - }); - - console.log({ migrations }); - - const migrationsToRun = migrationFiles.filter( - (migrationFile) => - !(migrations.Items ?? []).find( - (migration) => migration.id.S === migrationFile - ) - ); - - console.log({ migrationsToRun }); - - // todo: Start the migrations - } + "MigrationsRunner", + { migrationsHistoryTable, migrationFiles } ); const migrationsProvider = new Provider(this, "MigrationsProvider", { - onEventHandler: onEventHandler.resource, + onEventHandler: onEventHandler.function.resource, }); + // Ensure migrations provider is ran after all nested stacks are created migrationStacks.map((stack) => migrationsProvider.node.addDependency(stack) );