|
| 1 | +import * as cdk from '@aws-cdk/core'; |
| 2 | +import lambda = require('@aws-cdk/aws-lambda'); |
| 3 | +import apigw = require('@aws-cdk/aws-apigateway'); |
| 4 | +import sqs = require('@aws-cdk/aws-sqs'); |
| 5 | +import { SqsEventSource } from '@aws-cdk/aws-lambda-event-sources'; |
| 6 | +import dynamodb = require('@aws-cdk/aws-dynamodb'); |
| 7 | + |
| 8 | +export class TheScalableWebhookStack extends cdk.Stack { |
| 9 | + constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { |
| 10 | + super(scope, id, props); |
| 11 | + |
| 12 | + /** |
| 13 | + * Dynamo Setup |
| 14 | + * This is standing in for what is RDS on the diagram due to simpler/cheaper setup |
| 15 | + */ |
| 16 | + const table = new dynamodb.Table(this, 'Messages', { |
| 17 | + partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING } //the key being id means we squash duplicate sqs messages |
| 18 | + }); |
| 19 | + |
| 20 | + /** |
| 21 | + * Queue Setup |
| 22 | + * SQS creation |
| 23 | + */ |
| 24 | + const queue = new sqs.Queue(this, 'RDSPublishQueue', { |
| 25 | + visibilityTimeout: cdk.Duration.seconds(300) |
| 26 | + }); |
| 27 | + |
| 28 | + /** |
| 29 | + * Lambdas |
| 30 | + * Both publisher and subscriber from pattern |
| 31 | + */ |
| 32 | + |
| 33 | + // defines an AWS Lambda resource to publish to our queue |
| 34 | + const sqsPublishLambda = new lambda.Function(this, 'SQSPublishLambdaHandler', { |
| 35 | + runtime: lambda.Runtime.NODEJS_12_X, // execution environment |
| 36 | + code: lambda.Code.asset('lambdas/publish'), // code loaded from the "lambdas/publish" directory |
| 37 | + handler: 'lambda.handler', // file is "lambda", function is "handler" |
| 38 | + environment: { |
| 39 | + queueURL: queue.queueUrl |
| 40 | + } |
| 41 | + }); |
| 42 | + |
| 43 | + queue.grantSendMessages(sqsPublishLambda); |
| 44 | + |
| 45 | + // defines an AWS Lambda resource to pull from our queue |
| 46 | + const sqsSubscribeLambda = new lambda.Function(this, 'SQSSubscribeLambdaHandler', { |
| 47 | + runtime: lambda.Runtime.NODEJS_12_X, // execution environment |
| 48 | + code: lambda.Code.asset('lambdas/subscribe'), // code loaded from the "lambdas/subscribe" directory |
| 49 | + handler: 'lambda.handler', // file is "lambda", function is "handler" |
| 50 | + reservedConcurrentExecutions: 2, // throttle lambda to 2 concurrent invocations |
| 51 | + environment: { |
| 52 | + queueURL: queue.queueUrl, |
| 53 | + tableName: table.tableName |
| 54 | + }, |
| 55 | + }); |
| 56 | + queue.grantConsumeMessages(sqsSubscribeLambda); |
| 57 | + sqsSubscribeLambda.addEventSource(new SqsEventSource(queue, {})); |
| 58 | + table.grantReadWriteData(sqsSubscribeLambda); |
| 59 | + |
| 60 | + |
| 61 | + /** |
| 62 | + * API Gateway Proxy |
| 63 | + * Used to expose the webhook through a URL |
| 64 | + */ |
| 65 | + |
| 66 | + // defines an API Gateway REST API resource backed by our "sqsPublishLambda" function. |
| 67 | + new apigw.LambdaRestApi(this, 'Endpoint', { |
| 68 | + handler: sqsPublishLambda |
| 69 | + }); |
| 70 | + |
| 71 | + } |
| 72 | +} |
0 commit comments