UNPKG

@seasketch/geoprocessing

Version:

Geoprocessing and reporting framework for SeaSketch 2.0

125 lines 5.61 kB
import { Stack } from "aws-cdk-lib"; import { getSyncFunctionMetadata, getAsyncFunctionMetadata, hasClients, isSyncFunctionMetadata, isAsyncFunctionMetadata, } from "../manifest.js"; import { createPublicBuckets, setupBucketFunctionAccess } from "./buckets.js"; import { createClientResources, setupClientFunctionAccess, } from "./clientResources.js"; import { createProjectFunctions } from "./functionResources.js"; import { createTables, setupTableFunctionAccess } from "./dynamodb.js"; import { createRestApi } from "./restApiGateway.js"; import { createWebSocketApi, setupWebSocketFunctionAccess, } from "./socketApiGateway.js"; import { genOutputMeta } from "./outputMeta.js"; import { createLambdaStacks } from "./lambdaResources.js"; import { hasOwnProperty } from "../../client-core.js"; /** * A geoprocessing project is deployed as a single monolithic stack using CloudFormation. * The stack inspects the manifest and creates stack resources * Supports functions being sync or async in executionMode and preprocessor or geoprocessor in purpose * Async + preprocessor combination is not supported * Each project gets one API gateway, s3 bucket, and db table for tracking tasks and function run timeestimates * If async functions also get a socket subscriptions db table and web socket machinery * Each function gets a lambda and rest endpoint for sync mode, or a set of lambdas (start + run) for async mode */ export class GeoprocessingStack extends Stack { props; // Refer to key stack resources using class properties for easy reference, just pass the stack instance around // See types for more info on these resources publicBuckets; tables; projectFunctions; restApi; socketApi; clientBucket; clientDistribution; lambdaStacks; constructor(scope, id, props) { super(scope, id, props); this.props = props; this.lambdaStacks = createLambdaStacks(this, this.props); this.projectFunctions = createProjectFunctions(this); this.publicBuckets = createPublicBuckets(this); // Create client bundle with bucket deploymentand and Cloudfront distribution const { clientBucket, clientDistribution } = createClientResources(this); this.clientBucket = clientBucket; this.clientDistribution = clientDistribution; this.tables = createTables(this); // Create rest endpoints for gp lambdas this.restApi = createRestApi(this); this.socketApi = createWebSocketApi(this); // Provide gp lambdas access to other services setupTableFunctionAccess(this); setupBucketFunctionAccess(this); setupWebSocketFunctionAccess(this); setupClientFunctionAccess(this); genOutputMeta(this); } hasClients() { return hasClients(this.props.manifest); } /** Return metadata for all PreprocessingHandlers and sync GeoprocessingHandlers in manifest */ getSyncFunctionMetas() { return getSyncFunctionMetadata(this.props.manifest); } /** Return metadata for all async GeoprocessingHandlers in manifest */ getAsyncFunctionMetas() { return getAsyncFunctionMetadata(this.props.manifest); } /** Returns true if manifest has sync functions metadata for all PreprocessingHandlers and GeoprocessingHandlers in manifest */ hasSyncFunctions() { return this.getSyncFunctionMetas().length > 0; } hasAsyncFunctions() { return this.getAsyncFunctionMetas().length > 0; } /** aggregate and return sync lambda function meta from lambda stacks */ getSyncFunctionsWithMeta() { return this.lambdaStacks.reduce((acc, curStack) => { const syncFunctions = curStack .getProcessingFunctions() .filter(this.isSyncFunctionWithMeta); return [...acc, ...syncFunctions]; }, []); } /** * @returns run functions across all lambda stacks */ getAsyncRunLambdas() { return this.lambdaStacks.reduce((acc, curStack) => [...acc, ...curStack.getAsyncRunLambdas()], []); } /** * @returns async lambda function meta from all lambda stacks */ getAsyncFunctionsWithMeta() { return this.lambdaStacks.reduce((acc, curStack) => { const asyncFunctions = curStack .getProcessingFunctions() .filter(this.isAsyncFunctionWithMeta); return [...acc, ...asyncFunctions]; }, []); } /** Returns true if sync function with meta and narrows type */ isSyncFunctionWithMeta(funcWithMeta) { return (hasOwnProperty(funcWithMeta, "func") && hasOwnProperty(funcWithMeta, "meta") && isSyncFunctionMetadata(funcWithMeta.meta)); } /** Returns true if async function with meta and narrows type */ isAsyncFunctionWithMeta(funcWithMeta) { return (hasOwnProperty(funcWithMeta, "startFunc") && hasOwnProperty(funcWithMeta, "runFunc") && hasOwnProperty(funcWithMeta, "meta") && isAsyncFunctionMetadata(funcWithMeta.meta)); } getProcessingFunctions() { return this.lambdaStacks.reduce((acc, curStack) => { return [...acc, ...curStack.getProcessingFunctions()]; }, []); } } /** * Returns root lambda handler method pointer in module.function dot notation */ export function getHandlerPointer(funcMeta) { return `${funcMeta.handlerFilename .replace(/\.js$/, "") .replace(/\.ts$/, "")}Handler.handler`; } //# sourceMappingURL=GeoprocessingStack.js.map