Skip to content

Commit

Permalink
feat: Add HOSTING_MODE env variable to adjust the plugin to the des…
Browse files Browse the repository at this point in the history
…ired hosting (#116)

Possible values:
- `STANDARD` (default) - The plugin server runs as a usual webserver app
that listens to HTTP requests.
- `AWS_LAMBDA` - The plugin server initializes and exports a handler
that AWS Lambda uses to handle requests.

BREAKING CHANGE:
The `startPluginServer()` function is renamed to `setupPluginServer()`
because, in the `AWS_LAMBDA` hosting mode, this function does not start
the plugin server but just initializes the server and prepares the
handler function for Lambda.
  • Loading branch information
machulav committed Apr 17, 2024
1 parent d9738f3 commit 9469187
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 23 deletions.
4 changes: 2 additions & 2 deletions apps/docs/docs/sdk/api-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ The [plugin definition validation schema](https://github.com/connery-io/connery/

The [action context types](https://github.com/connery-io/connery/blob/main/packages/connery/src/types/context.ts) define the structure of the context object that is passed to each action.

## `startPluginServer` function
## `setupPluginServer` function

The [`startPluginServer` function](https://github.com/connery-io/connery/blob/main/packages/connery/src/api/index.ts) is used to start a plugin server based on a plugin definition.
The [`setupPluginServer` function](https://github.com/connery-io/connery/blob/main/packages/connery/src/api/index.ts) is used to set up a plugin server based on a plugin definition.
13 changes: 13 additions & 0 deletions apps/docs/docs/sdk/plugin-server/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ Required: Yes.

The API key that the plugin server will use to validate incoming requests.

### `HOSTING_MODE`

Required: No.

Default: `STANDARD`.

The hosting mode adjusts the behavior of the plugin server to the specific environment where it is running.

Available values:

- `STANDARD` - Use this mode to run the plugin server as a standalone application or in a container.
- `AWS_LAMBDA` - Use this mode to run the plugin server in AWS Lambda.

### `CONFIG_<configurationParameterKey>`

Required: Depends on the configuration parameter validation rules in the plugin definition.
Expand Down
3 changes: 3 additions & 0 deletions packages/connery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"@codegenie/serverless-express": "^4.14.0",
"@inquirer/prompts": "^3.0.0",
"@nestjs/common": "^9.4.3",
"@nestjs/config": "^2.3.4",
"@nestjs/core": "^9.4.3",
"@nestjs/platform-express": "^9.4.3",
"@nestjs/swagger": "^7.3.0",
"@types/express": "^4.17.21",
"aws-lambda": "^1.0.7",
"chalk": "^5.3.0",
"commander": "^11.0.0",
"node-plop": "^0.31.1",
Expand All @@ -36,6 +38,7 @@
"zod-validation-error": "^1.3.1"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.137",
"@types/jest": "28.1.8",
"@types/node": "^16.18.36",
"@types/supertest": "^2.0.12",
Expand Down
51 changes: 39 additions & 12 deletions packages/connery/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,58 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { INestApplication } from '@nestjs/common';
import { PluginConfigService } from './services/plugin-config.service.js';
import { logAdditionalData, logError, logSuccess } from '../cli/shared.js'; // TODO move this out of CLI and share between CLI and SDK
import serverlessExpress from '@codegenie/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';

export async function startPluginServer(pluginDefinition: PluginDefinition) {
export async function setupPluginServer(pluginDefinition: PluginDefinition): Promise<Handler> {
try {
const app = await NestFactory.create(AppModule, {
cors: true,
logger: false,
});
const app = await configureServer(pluginDefinition);

initPlugin(app, pluginDefinition);
await initOpeApiSpec(app);
if (process.env.HOSTING_MODE === 'AWS_LAMBDA') {
await app.init();
const expressApp = app.getHttpAdapter().getInstance();
const server = serverlessExpress({ app: expressApp });

app.useGlobalFilters(new AllExceptionsFilter());
// TODO: cache the server
logSuccess('The plugin server is configured to AWS_LAMBDA hosting mode and ready to handle requests.');

await app.listen(4201);
logSuccess('The plugin server is up and running.');
logAdditionalData('You can access it in a browser at http://localhost:4201.');
return async (event: any, context: Context, callback: Callback) => {
return server(event, context, callback);
};
} else if (process.env.HOSTING_ENV === 'STANDARD' || !process.env.HOSTING_MODE) {
await app.listen(4201);

logSuccess('The plugin server is up and running.');
logAdditionalData('You can access it in a browser at http://localhost:4201.');

return async () =>
console.log(
'The plugin server is running in a standard mode (HOSTING_ENV=STANDARD). The event handler is ignored.',
);
} else {
throw new Error(`Unsupported hosting environment: ${process.env.HOSTING_ENV}`);
}
} catch (error: any) {
logError(error);
throw error;
}
}

function initPlugin(app: INestApplication, pluginDefinition: PluginDefinition) {
async function configureServer(pluginDefinition: PluginDefinition): Promise<INestApplication> {
const app = await NestFactory.create(AppModule, { cors: true, logger: false });

// Init plugin
const plugin = new Plugin(pluginDefinition);
const pluginService = app.get(PluginService);
pluginService.plugin = plugin;

// Init OpenAPI spec
await initOpeApiSpec(app);

// Global filters
app.useGlobalFilters(new AllExceptionsFilter());

return app;
}

async function initOpeApiSpec(app: INestApplication) {
Expand Down
5 changes: 3 additions & 2 deletions packages/connery/src/cli/init/templates/src/index.ts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default `import { PluginDefinition, startPluginServer } from 'connery';
export default `import { PluginDefinition, setupPluginServer } from 'connery';
import sampleAction from './actions/sampleAction.js';
const pluginDefinition: PluginDefinition = {
Expand All @@ -14,5 +14,6 @@ const pluginDefinition: PluginDefinition = {
],
};
startPluginServer(pluginDefinition);
const handler = await setupPluginServer(pluginDefinition);
export default handler;
`;
2 changes: 1 addition & 1 deletion packages/connery/src/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './types/definition.js';
export * from './types/context.js';
export { startPluginServer } from './api/index.js';
export { setupPluginServer } from './api/index.js';
Loading

0 comments on commit 9469187

Please sign in to comment.