From 36fafa5d313dd67fc7cd280c20259fe126bab85b Mon Sep 17 00:00:00 2001 From: Daniel Naab Date: Mon, 19 Aug 2024 08:45:22 -0500 Subject: [PATCH] Postgres Terraform config + app wiring --- apps/server-doj/src/index.ts | 16 +++++++-- apps/server-doj/src/server.ts | 27 +++------------ apps/server-doj/tests/integration.test.ts | 6 ++-- apps/server-kansas/src/index.ts | 23 ++++++++++--- apps/server-kansas/src/server.ts | 35 ++++++-------------- apps/server-kansas/tests/integration.test.ts | 18 +++++----- infra/cdktf/src/lib/cloud.gov/node-astro.ts | 17 +++++++++- 7 files changed, 77 insertions(+), 65 deletions(-) diff --git a/apps/server-doj/src/index.ts b/apps/server-doj/src/index.ts index 4c512c62..708f6efa 100644 --- a/apps/server-doj/src/index.ts +++ b/apps/server-doj/src/index.ts @@ -1,10 +1,20 @@ import { createCustomServer } from './server.js'; -import { createPostgresDatabaseContext } from '@atj/database'; const port = process.env.PORT || 4321; -const database = createPostgresDatabaseContext(); -createCustomServer({ db: database }).then((server: any) => +const getCloudGovServerSecrets = () => { + if (process.env.VCAP_SERVICES === undefined) { + throw new Error('VCAP_SERVICES not found'); + } + const services = JSON.parse(process.env.VCAP_SERVICES || '{}'); + return { + //loginGovClientSecret: services['user-provided']?.credentials?.SECRET_LOGIN_GOV_PRIVATE_KEY, + dbUri: services['aws-rds'].credentials.uri as string, + }; +}; + +const secrets = getCloudGovServerSecrets(); +createCustomServer({ dbUri: secrets?.dbUri }).then((server: any) => server.listen(port, () => { console.log(`Server running on http://localhost:${port}`); }) diff --git a/apps/server-doj/src/server.ts b/apps/server-doj/src/server.ts index 1b370128..79c38d82 100644 --- a/apps/server-doj/src/server.ts +++ b/apps/server-doj/src/server.ts @@ -1,21 +1,15 @@ -import { join } from 'path'; import { - type DatabaseContext, createDatabaseGateway, - createFilesystemDatabaseContext, + createPostgresDatabaseContext, } from '@atj/database'; import { createServer } from '@atj/server'; -//const getDirname = () => dirname(fileURLToPath(import.meta.url)); - -const createDevDatabase = async () => { - return createFilesystemDatabaseContext(join(__dirname, '../doj.db')); -}; - export const createCustomServer = async (ctx: { - db: DatabaseContext; + dbUri: string; }): Promise => { - const db = createDatabaseGateway(ctx.db || createDevDatabase()); + const db = createDatabaseGateway( + await createPostgresDatabaseContext(ctx.dbUri) + ); return createServer({ title: 'DOJ Form Service', @@ -28,14 +22,3 @@ export const createCustomServer = async (ctx: { }, }); }; - -/* -const getServerSecrets = () => { - const services = JSON.parse(process.env.VCAP_SERVICES || '{}'); - const loginClientSecret = - services['user-provided']?.credentials?.SECRET_LOGIN_GOV_PRIVATE_KEY; - return { - loginGovClientSecret: loginClientSecret, - }; -}; -*/ diff --git a/apps/server-doj/tests/integration.test.ts b/apps/server-doj/tests/integration.test.ts index 4944b3c2..73d8b3aa 100644 --- a/apps/server-doj/tests/integration.test.ts +++ b/apps/server-doj/tests/integration.test.ts @@ -3,14 +3,16 @@ import { describe, expect, test } from 'vitest'; import { describeDatabase } from '@atj/database/testing'; import { createCustomServer } from '../src/server'; + describe('DOJ Form Service', () => { - test('renders the home page', async () => { + test('avoid "No test suite found in file" error', async () => { expect(true).toBe(true); }); }); + describeDatabase('DOJ Form Service', () => { test('renders the home page', async ({ db }) => { - const app = await createCustomServer({ db: db.ctx }); + const app = await createCustomServer({ dbUri: db.ctx.connectionUri }); const response = await request(app).get('/'); expect(response.ok).toBe(true); expect(response.text).toMatch(/DOJ Form Service/); diff --git a/apps/server-kansas/src/index.ts b/apps/server-kansas/src/index.ts index 82e7c8ce..708f6efa 100644 --- a/apps/server-kansas/src/index.ts +++ b/apps/server-kansas/src/index.ts @@ -1,8 +1,21 @@ -import { createCustomServer } from './server'; +import { createCustomServer } from './server.js'; const port = process.env.PORT || 4321; -const app = await createCustomServer(); -app.listen(port, () => { - console.log(`Server running on http://localhost:${port}`); -}); +const getCloudGovServerSecrets = () => { + if (process.env.VCAP_SERVICES === undefined) { + throw new Error('VCAP_SERVICES not found'); + } + const services = JSON.parse(process.env.VCAP_SERVICES || '{}'); + return { + //loginGovClientSecret: services['user-provided']?.credentials?.SECRET_LOGIN_GOV_PRIVATE_KEY, + dbUri: services['aws-rds'].credentials.uri as string, + }; +}; + +const secrets = getCloudGovServerSecrets(); +createCustomServer({ dbUri: secrets?.dbUri }).then((server: any) => + server.listen(port, () => { + console.log(`Server running on http://localhost:${port}`); + }) +); diff --git a/apps/server-kansas/src/server.ts b/apps/server-kansas/src/server.ts index 43655d98..79c38d82 100644 --- a/apps/server-kansas/src/server.ts +++ b/apps/server-kansas/src/server.ts @@ -1,20 +1,18 @@ -import path, { dirname } from 'path'; -import { fileURLToPath } from 'url'; +import { + createDatabaseGateway, + createPostgresDatabaseContext, +} from '@atj/database'; +import { createServer } from '@atj/server'; -const getDirname = () => dirname(fileURLToPath(import.meta.url)); - -export const createCustomServer = async (): Promise => { - const { createFilesystemDatabaseContext, createDatabaseGateway } = - await import('@atj/database'); - const { createServer } = await import('@atj/server'); - - const dbCtx = await createFilesystemDatabaseContext( - path.join(getDirname(), '../doj.db') +export const createCustomServer = async (ctx: { + dbUri: string; +}): Promise => { + const db = createDatabaseGateway( + await createPostgresDatabaseContext(ctx.dbUri) ); - const db = createDatabaseGateway(dbCtx); return createServer({ - title: 'KS Courts Form Service', + title: 'DOJ Form Service', db, loginGovOptions: { loginGovUrl: 'https://idp.int.identitysandbox.gov', @@ -24,14 +22,3 @@ export const createCustomServer = async (): Promise => { }, }); }; - -/* -const getServerSecrets = () => { - const services = JSON.parse(process.env.VCAP_SERVICES || '{}'); - const loginClientSecret = - services['user-provided']?.credentials?.SECRET_LOGIN_GOV_PRIVATE_KEY; - return { - loginGovClientSecret: loginClientSecret, - }; -}; -*/ diff --git a/apps/server-kansas/tests/integration.test.ts b/apps/server-kansas/tests/integration.test.ts index 97e88fb1..f602bed0 100644 --- a/apps/server-kansas/tests/integration.test.ts +++ b/apps/server-kansas/tests/integration.test.ts @@ -1,18 +1,20 @@ import request from 'supertest'; -import { beforeAll, describe, expect, test } from 'vitest'; +import { describe, expect, test } from 'vitest'; +import { describeDatabase } from '@atj/database/testing'; import { createCustomServer } from '../src/server'; -describe('Kansas State Courts Form Service', () => { - let app: any; - - beforeAll(async () => { - app = await createCustomServer(); +describe('DOJ Form Service', () => { + test('avoid "No test suite found in file" error', async () => { + expect(true).toBe(true); }); +}); - test('renders the home page', async () => { +describeDatabase('Kansas State Courts Form Service', () => { + test('renders the home page', async ({ db }) => { + const app = await createCustomServer({ dbUri: db.ctx.connectionUri }); const response = await request(app).get('/'); expect(response.ok).toBe(true); - expect(response.text).toMatch(/KS Courts Form Service/); + expect(response.text).toMatch(/DOJ Form Service/); }); }); diff --git a/infra/cdktf/src/lib/cloud.gov/node-astro.ts b/infra/cdktf/src/lib/cloud.gov/node-astro.ts index c93a1bc6..3c3915d1 100644 --- a/infra/cdktf/src/lib/cloud.gov/node-astro.ts +++ b/infra/cdktf/src/lib/cloud.gov/node-astro.ts @@ -41,16 +41,31 @@ export class AstroService extends Construct { } ); + const rds = + new cloudfoundry.dataCloudfoundryService.DataCloudfoundryService( + scope, + `${id}-data-aws-rds`, + { + name: 'aws-rds', + } + ); + const dbInstance = new cloudfoundry.serviceInstance.ServiceInstance( this, `${id}-db`, { name: `${id}-db`, - servicePlan: 'micro-psql', + servicePlan: rds.servicePlans.lookup('micro-psql'), space: spaceId, + jsonParams: '{"version": "15"}', lifecycle: { preventDestroy: true, }, + timeouts: { + create: '60m', + update: '60m', + delete: '2h', + }, } );