UNPKG

@seasketch/geoprocessing

Version:

Geoprocessing and reporting framework for SeaSketch 2.0

107 lines 4.79 kB
import { WebSocketApi, WebSocketStage } from "aws-cdk-lib/aws-apigatewayv2"; import { WebSocketLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations"; import config from "./config.js"; import { PolicyStatement, Effect } from "aws-cdk-lib/aws-iam"; /** * Create Web Socket API for async functions */ export const createWebSocketApi = (stack) => { if (!stack.projectFunctions.socketFunctions.subscribe || !stack.projectFunctions.socketFunctions.unsubscribe || !stack.projectFunctions.socketFunctions.send) return undefined; // Create web socket with subscribe and unsubscribe routes const webSocketApi = new WebSocketApi(stack, "WebSocketApi", { apiName: `gp-${stack.props.projectName}-socket`, description: `Serves web socket requests for ${stack.props.projectName}.`, connectRouteOptions: { integration: new WebSocketLambdaIntegration("OnConnectIntegration", stack.projectFunctions.socketFunctions.subscribe), }, disconnectRouteOptions: { integration: new WebSocketLambdaIntegration("OnDisconnectIntegration", stack.projectFunctions.socketFunctions.unsubscribe), }, routeSelectionExpression: "$request.body.message", }); // Add sendmessage route webSocketApi.addRoute("sendmessage", { integration: new WebSocketLambdaIntegration(`OnSendIntegration`, stack.projectFunctions.socketFunctions.send), }); // Allow socket lambda functions to manage socket connections const socketExecutePolicy = new PolicyStatement({ effect: Effect.ALLOW, actions: ["execute-api:ManageConnections"], resources: [ `arn:aws:execute-api:${stack.region}:${stack.account}:${webSocketApi.apiId}/*`, ], }); stack.projectFunctions.socketFunctions.send.addToRolePolicy(socketExecutePolicy); stack.projectFunctions.socketFunctions.subscribe.addToRolePolicy(socketExecutePolicy); stack.projectFunctions.socketFunctions.unsubscribe.addToRolePolicy(socketExecutePolicy); /** Create auto-deployed production stage */ createStage(stack, webSocketApi, config.STAGE_NAME); return webSocketApi; }; const createStage = (scope, webSocketApi, stageName) => { // Unlike RestApi, you don't get a default `prod` stage automatically. const stage = new WebSocketStage(scope, "GpSocketApiStage", { autoDeploy: true, stageName, webSocketApi, }); // Manage the log group // new LogGroup(scope, 'ExecutionLogs', { // logGroupName: `/aws/apigateway/${webSocketApi.apiId}/${config.STAGE_NAME}`, // removalPolicy: RemovalPolicy.DESTROY, // retention: RetentionDays.ONE_WEEK, // }); // const log = new LogGroup(scope, 'AccessLogs', { // removalPolicy: RemovalPolicy.DESTROY, // retention: RetentionDays.ONE_WEEK, // }); const cfnStage = stage.node.defaultChild; // cfnStage.accessLogSettings = { // destinationArn: log.logGroupArn, // format: `$context.identity.sourceIp - - [$context.requestTime] "$context.httpMethod $context.routeKey $context.protocol" $context.status $context.responseLength $context.requestId`, // }; cfnStage.defaultRouteSettings = { dataTraceEnabled: true, loggingLevel: "INFO", throttlingBurstLimit: 500, throttlingRateLimit: 1000, }; /* * This role is automatically created by the RestApi construct but not by WebSocketApi. * CfnAccount isn't even available in the `aws-cdk-lib/aws-apigatewayv2` lib so we must import `aws-cdk-lib/aws-apigateway` * to create the CloudWatch role. */ // const cwRole = new Role(scope, "CWRole", { // assumedBy: new ServicePrincipal("apigateway.amazonaws.com"), // managedPolicies: [ // ManagedPolicy.fromAwsManagedPolicyName( // "service-role/AmazonAPIGatewayPushToCloudWatchLogs" // ), // ], // }); // const account = new CfnAccount(scope, "Account", { // cloudWatchRoleArn: cwRole.roleArn, // }); // webSocketApi.node.addDependency(account); return stage; }; /** Setup function access to web socket */ export const setupWebSocketFunctionAccess = (stack) => { if (!stack.socketApi) return; for (const asyncFunctionWithMeta of stack.getAsyncFunctionsWithMeta()) { addAsyncEnv(stack, asyncFunctionWithMeta.startFunc); addAsyncEnv(stack, asyncFunctionWithMeta.runFunc); } }; const addAsyncEnv = (stack, func) => { if (stack.socketApi) { func.addEnvironment("WSS_REF", stack.socketApi.apiId); func.addEnvironment("WSS_REGION", stack.region); func.addEnvironment("WSS_STAGE", config.STAGE_NAME); } }; //# sourceMappingURL=socketApiGateway.js.map