Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
5.2 kB
1
Indexable
Never
import { SqsToLambda } from "@aws-solutions-constructs/aws-sqs-lambda";
import { ChocolateLambda } from "@lib/constructs/lambda";
import {
  getDefaultLambdaSqsEventSourceProperties,
  getOverprovisionedDeadLetterQueueProperties,
  getOverprovisionedMaxReceiveCount,
  getOverprovisionedQueueProperties,
} from "@lib/resource-defaults/sqs";
import * as cdk from "aws-cdk-lib";
import * as events from "aws-cdk-lib/aws-events";
import * as targets from "aws-cdk-lib/aws-events-targets";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as rds from "aws-cdk-lib/aws-rds";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as sqs from "aws-cdk-lib/aws-sqs";
import { Construct } from "constructs";

import { Environments } from "../environments";

interface FirmCrmReportStackProps extends cdk.NestedStackProps {
  readonly stage: Environments;
  readonly dbConfig: {
    auroraCredentialsArn: string;
    auroraRdsArn: string;
    auroraDbName: string;
    cluster: rds.ServerlessCluster | rds.ServerlessClusterFromSnapshot;
  };
  readonly faFirmReportConfig: {
    executeTimeRule: string;
  };
}

export class FirmCrmReportStack extends cdk.NestedStack {
  config: FirmCrmReportStackProps;
  deadLetterQueue: sqs.Queue;
  queue: sqs.Queue;
  bucket: s3.Bucket;
  lambdaTimeoutInMinutes = 1;
  constructor(
    scope: Construct,
    id: string,
    props: FirmCrmReportStackProps
  ) {
    super(scope, id);
    this.config = props;
    this.bucket = this.createBucket();
    this.deadLetterQueue = this.createDLQ();
    this.queue = this.createQueue(this.deadLetterQueue);
    this.createEnqueueFirmCrmReportHandler();
    this.createFirmCrmReportHandler();
  }

  private createDLQ() {
    const queue = new sqs.Queue(
      this,
      "FirmCrmReportDeadLetterQueue",
      getOverprovisionedDeadLetterQueueProperties()
    );
    return queue;
  }

  private createBucket() {
    const bucket = new s3.Bucket(this, "FirmCrmReportBucket", {
      removalPolicy: cdk.RemovalPolicy.RETAIN,
      enforceSSL: true,
      versioned: true,
    });
    return bucket;
  }

  private createQueue(deadLetterQueue: sqs.Queue) {
    const queue = new sqs.Queue(this, "FirmCrmReportQueue", {
      ...getOverprovisionedQueueProperties(),
      visibilityTimeout: cdk.Duration.minutes(6 * this.lambdaTimeoutInMinutes),
      deadLetterQueue: {
        ...getOverprovisionedMaxReceiveCount(),
        queue: deadLetterQueue,
      },
    });
    return queue;
  }

  private createEnqueueFirmCrmReportHandler() {
    const handler = new ChocolateLambda(
      this,
      "createEnqueueFirmCrmReport",
      {
        account: this.account,
        stage: this.config.stage,
        region: this.region,
        lambdaProps: {
          code: lambda.Code.fromAsset(
            "./dist/lambdas/enqueue-firm-crm-report"
          ),
          environment: {
            NODE_OPTIONS: "--enable-source-maps",
            REGION: this.region,
            AURORA_CREDENTIALS_ARN: this.config.dbConfig.auroraCredentialsArn,
            AURORA_RDS_ARN: this.config.dbConfig.auroraRdsArn,
            AURORA_DB_NAME: this.config.dbConfig.auroraDbName,
            MONTHLY_FA_FIRM_REPORT_QUEUE_URL: this.queue.queueUrl,
          },
          timeout: cdk.Duration.minutes(5),
        },
      }
    ).getLambda();

    this.config.dbConfig.cluster.grantDataApiAccess(handler);

    this.queue.grantSendMessages(handler);

    new events.Rule(this, "EnqueueFaFirmReportScheduleRule", {
      targets: [new targets.LambdaFunction(handler)],
      schedule: events.Schedule.expression(
        this.config.faFirmReportConfig.executeTimeRule
      ),
    });
  }

  private createFirmCrmReportHandler() {
    const chromeLayer = new lambda.LayerVersion(this, "chromeLayer", {
      layerVersionName: "chromeLayer",
      code: lambda.Code.fromAsset("./assets/chromium.zip"),
      compatibleRuntimes: [lambda.Runtime.NODEJS_16_X],
    });

    const handler = new ChocolateLambda(
      this,
      "generateFirmCrmReportHandler",
      {
        account: this.account,
        stage: this.config.stage,
        region: this.region,
        lambdaProps: {
          code: lambda.Code.fromAsset(
            "./dist/lambdas/generate-firm-crm-report"
          ),
          layers: [chromeLayer],
          timeout: cdk.Duration.minutes(this.lambdaTimeoutInMinutes),
          memorySize: 1600,
          environment: {
            NODE_OPTIONS: "--enable-source-maps",
            REGION: this.region,
            STAGE: this.config.stage,
            AURORA_CREDENTIALS_ARN: this.config.dbConfig.auroraCredentialsArn,
            AURORA_RDS_ARN: this.config.dbConfig.auroraRdsArn,
            AURORA_DB_NAME: this.config.dbConfig.auroraDbName,
            BUCKET_NAME: this.bucket.bucketName,
          },
        },
      }
    ).getLambda();

    this.config.dbConfig.cluster.grantDataApiAccess(handler);
    this.bucket.grantPut(handler);

    new SqsToLambda(this, "SqsToFirmCrmReportHandler", {
      existingLambdaObj: handler,
      existingQueueObj: this.queue,
      sqsEventSourceProps: {
        ...getDefaultLambdaSqsEventSourceProperties(),
        batchSize: 1,
      },
    });
  }
}