Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TM-1249] Research service documentation #8

Merged
merged 10 commits into from
Oct 30, 2024
3 changes: 1 addition & 2 deletions .env.local.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
DOCKER_HOST=unix://$HOME/.docker/run/docker.sock

USER_SERVICE_PORT=4010
JOB_SERVICE_PORT=4020
RESEARCH_SERVICE_PORT=4030

DB_HOST=localhost
DB_PORT=3360
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/deploy-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ on:
type: choice
required: true
options:
- user-service
- job-service
- research-service
- user-service
env:
description: 'Deployment target environment'
type: choice
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Repository for the Microservices API backend of the TerraMatch service
* On Linux systems, the DOCKER_HOST value should be `unix:///var/run/docker.sock` instead of what's in the sample.
* To run all services:
* `nx run-many -t serve`
* The default maximum number of services it can run in parallel is 3. To run all of the services at once, use something like
`nx run-many --parallel=100 -t serve`, or you can cherry-pick which services you want to run instead with
`nx run-many -t serve --projects user-service jobs-service`.
* In `.env` in your `wri-terramatch-website` repository, set your BE connection URL correctly by noting the config
in `.env.local.sample` for local development.
* The `NEXT_PUBLIC_API_BASE_URL` still points at the PHP BE directly
Expand All @@ -38,6 +41,7 @@ and main branches.
* In your local web repo, follow directions in `README.md` for setting up a new service.
* For deployment to AWS:
* Add a Dockerfile in the new app directory. A simple copy and modify from user-service is sufficient
* Add the new service name to the "service" workflow input options in `deploy-service.yml`
* In AWS:
* Add ECR repositories for each env (follow the naming scheme from user-service, e.g. `terramatch-microservices/foo-service-staging`, etc)
* Set the repo to Immutable
Expand Down
18 changes: 18 additions & 0 deletions apps/research-service-e2e/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
19 changes: 19 additions & 0 deletions apps/research-service-e2e/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable */
export default {
displayName: 'research-service-e2e',
preset: '../../jest.preset.js',
globalSetup: '<rootDir>/src/support/global-setup.ts',
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
},
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/research-service-e2e',
};
17 changes: 17 additions & 0 deletions apps/research-service-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "research-service-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"implicitDependencies": ["research-service"],
"targets": {
"e2e": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"],
"options": {
"jestConfig": "apps/research-service-e2e/jest.config.ts",
"passWithNoTests": true
},
"dependsOn": ["research-service:build"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import axios from 'axios';

describe('GET /api', () => {
it('should return a message', async () => {
const res = await axios.get(`/api`);

expect(res.status).toBe(200);
expect(res.data).toEqual({ message: 'Hello API' });
});
});
10 changes: 10 additions & 0 deletions apps/research-service-e2e/src/support/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */
var __TEARDOWN_MESSAGE__: string;

module.exports = async function () {
// Start services that that the app needs to run (e.g. database, docker-compose, etc.).
console.log('\nSetting up...\n');

// Hint: Use `globalThis` to pass variables to global teardown.
globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n';
};
7 changes: 7 additions & 0 deletions apps/research-service-e2e/src/support/global-teardown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable */

module.exports = async function () {
// Put clean up logic here (e.g. stopping services, docker-compose, etc.).
// Hint: `globalThis` is shared between setup and teardown.
console.log(globalThis.__TEARDOWN_MESSAGE__);
};
10 changes: 10 additions & 0 deletions apps/research-service-e2e/src/support/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */

import axios from 'axios';

module.exports = async function () {
// Configure axios for tests to use.
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ?? '3000';
axios.defaults.baseURL = `http://${host}:${port}`;
};
13 changes: 13 additions & 0 deletions apps/research-service-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
],
"compilerOptions": {
"esModuleInterop": true
}
}
9 changes: 9 additions & 0 deletions apps/research-service-e2e/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["jest.config.ts", "src/**/*.ts"]
}
18 changes: 18 additions & 0 deletions apps/research-service/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
15 changes: 15 additions & 0 deletions apps/research-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM terramatch-microservices-base:nx-base AS builder

ARG BUILD_FLAG
WORKDIR /app/builder
COPY . .
RUN npx nx build research-service ${BUILD_FLAG}

FROM terramatch-microservices-base:nx-base

ARG NODE_ENV
WORKDIR /app
COPY --from=builder /app/builder ./
ENV NODE_ENV=${NODE_ENV}

CMD ["node", "./dist/apps/research-service/main.js"]
11 changes: 11 additions & 0 deletions apps/research-service/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'research-service',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/research-service',
};
26 changes: 26 additions & 0 deletions apps/research-service/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "research-service",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/research-service/src",
"projectType": "application",
"tags": [],
"targets": {
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"dependsOn": ["build"],
"options": {
"buildTarget": "research-service:build",
"runBuildTargetDependencies": false
},
"configurations": {
"development": {
"buildTarget": "research-service:build:development"
},
"production": {
"buildTarget": "research-service:build:production"
}
}
}
}
}
12 changes: 12 additions & 0 deletions apps/research-service/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { DatabaseModule } from '@terramatch-microservices/database';
import { CommonModule } from '@terramatch-microservices/common';
import { HealthModule } from './health/health.module';
import { SitePolygonsController } from './site-polygons/site-polygons.controller';

@Module({
imports: [DatabaseModule, CommonModule, HealthModule],
controllers: [SitePolygonsController],
providers: [],
})
export class AppModule {}
Empty file.
32 changes: 32 additions & 0 deletions apps/research-service/src/health/health.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Controller, Get } from '@nestjs/common';
import {
HealthCheck,
HealthCheckService,
SequelizeHealthIndicator,
} from '@nestjs/terminus';
import { NoBearerAuth } from '@terramatch-microservices/common/guards';
import { ApiExcludeController } from '@nestjs/swagger';
import { User } from '@terramatch-microservices/database/entities';

@Controller('health')
@ApiExcludeController()
export class HealthController {
constructor(
private readonly health: HealthCheckService,
private readonly db: SequelizeHealthIndicator
) {}

@Get()
@HealthCheck()
@NoBearerAuth
async check() {
const connection = await User.sequelize.connectionManager.getConnection({ type: 'read' });
try {
return this.health.check([
() => this.db.pingCheck('database', { connection }),
]);
} finally {
User.sequelize.connectionManager.releaseConnection(connection);
}
}
}
9 changes: 9 additions & 0 deletions apps/research-service/src/health/health.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HealthController } from './health.controller';

@Module({
imports: [TerminusModule],
controllers: [HealthController],
})
export class HealthModule {}
31 changes: 31 additions & 0 deletions apps/research-service/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Logger, ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';

import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { TMLogService } from '@terramatch-microservices/common/util/tm-log.service';

async function bootstrap() {
const app = await NestFactory.create(AppModule);

const config = new DocumentBuilder()
.setTitle('TerraMatch Research Service')
.setDescription('APIs related to needs for the data research team.')
.setVersion('1.0')
.addTag('research-service')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('research-service/documentation/api', app, document);

app.useGlobalPipes(new ValidationPipe());
app.useLogger(app.get(TMLogService));

const port = process.env.NODE_ENV === 'production'
? 80
: process.env.RESEARCH_SERVICE_PROXY_PORT ?? 4030;
await app.listen(port);

Logger.log(`TerraMatch Research Service is running on: http://localhost:${port}`);
}

bootstrap();
Loading