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

feat(cb2-9857): add minimum version service #1

Merged
merged 19 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,7 @@ dist
# MAC files
.DS_Store


# Output files
.aws-sam/**
*Function.zip
local.zip
12,092 changes: 7,383 additions & 4,709 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
"lint:ci": "eslint '*/**/*.ts'",
"test": "jest --coverage",
"test:ci": "jest --ci",
"build": "npm run build:prod",
"build:dev": "NODE_ENV=development webpack-cli --config webpack/webpack.development.js",
"watch:dev": "NODE_ENV=development webpack-cli --config webpack/webpack.development.watch.js",
"build:prod": "webpack-cli --config webpack/webpack.production.js",
"start:dev": "sam local start-api",
"invoke": "sam local invoke"
"invoke": "sam local invoke",
"tools-setup": "echo 'move on'",
"test-i": "echo 'no integration tests'",
"package": "npm run build:prod"
},
"contributors": [
{
Expand All @@ -22,7 +26,7 @@
],
"license": "MIT",
"dependencies": {
"aws-sdk": "^2.1354.0"
"@aws-sdk/client-ssm": "^3.478.0"
},
"devDependencies": {
"@dvsa/eslint-config-ts": "^3.0.0",
Expand Down
20 changes: 20 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#----- Default SonarQube server
sonar.host.url=http://localhost:9000

# must be unique in a given SonarQube instance
sonar.projectKey=org.sonarqube:cvs-svc-minimum-application-version

# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=cvs-svc-minimum-application-version
sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8

# Path is relative to the sonar-project.properties file. Replace “\” by “/” on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=src
sonar.exclusions=tests/*, .dynamodb/*, .nyc_output/*, .scannerwork/*, coverage/*, *.d.ts
sonar.ts.tslint.configPath=tslint.json
sonar.ts.tslint.outputPath=.reports/lint_issues.json
sonar.ts.tslintconfigpath=tslint.json
sonar.tslint.reportPaths=.reports/lint_issues.json
sonar.typescript.lcov.reportPaths=coverage/lcov.info
13 changes: 0 additions & 13 deletions src/handler/cloudWatchEvent.ts

This file was deleted.

52 changes: 35 additions & 17 deletions src/handler/get.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
import type { APIGatewayProxyResult } from 'aws-lambda';
import 'dotenv/config';
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import logger from '../util/logger';

// eslint-disable-next-line @typescript-eslint/require-await
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
if (!event.queryStringParameters) {
return {
statusCode: 400,
body: JSON.stringify({
message: 'Missing query string parameters',
}),
};
}
export const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'GET,OPTIONS',
};

const queryParams = event.queryStringParameters;
export const handler = async (): Promise<APIGatewayProxyResult> => {
try {
logger.info('min version endpoint called');
let minVersion;

logger.info(queryParams);
// cannot call ssm locally so this is a workaround.
if (process.env.AWS_SAM_LOCAL) {
minVersion = '1.0';
} else {
const paramName = `${process.env.ENVIRONMENT ?? 'develop'}_vta_minimum_app_version`;
const client = new SSMClient();
const command = new GetParameterCommand({ Name: paramName, WithDecryption: false });
const response = await client.send(command);
logger.info('response from ssm');
minVersion = response.Parameter?.Value;
}

return {
statusCode: 200,
body: JSON.stringify({ queryParams }),
};
return {
statusCode: 200,
body: JSON.stringify(minVersion),
headers,
};
} catch (error) {
logger.error(error);
return {
statusCode: 500,
body: JSON.stringify('Error fetching min version'),
headers,
};
}
};
24 changes: 0 additions & 24 deletions src/handler/post.ts

This file was deleted.

42 changes: 1 addition & 41 deletions template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,53 +12,13 @@ Resources:
GetLambdaApi:
Type: Api
Properties:
Path: /
Path: /minimum-version
Method: get

PostLambdaFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: src/handler/
Handler: post.handler
Runtime: nodejs18.x
Events:
PostLambdaApi:
Type: Api
Properties:
Path: /
Method: post

CWEventLambdaFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: src/handler/
Handler: cloudWatchEvent.handler
Runtime: nodejs18.x
Events:
CWEventLambdaSchedule:
Type: Schedule
Properties:
Schedule: 'rate(1 minute)'
# Schedule: 'cron(1 * * * ? *)'

Outputs:
GetLambdaApi:
Description: "API Gateway endpoint URL for GetLambdaFunction on dev stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Dev/"
GetLambdaFunction:
Description: "Get Lambda Function ARN"
Value: !GetAtt GetLambdaFunction.Arn

PostLambdaApi:
Description: "API Gateway endpoint URL for GetLambdaFunction on dev stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Dev/"
PostLambdaFunction:
Description: "Post Lambda Function ARN"
Value: !GetAtt PostLambdaFunction.Arn

CWEventLambdaSchedule:
Description: "CloudWatch Event schedule for CloudWatchEventLambdaFunction"
Value: "rate(1 minute)"
CWEventLambdaFunction:
Description: "CloudWatch Event Lambda Function ARN"
Value: !GetAtt CWEventLambdaFunction.Arn
17 changes: 0 additions & 17 deletions tests/handler/cloudWatchEvent.test.ts

This file was deleted.

49 changes: 22 additions & 27 deletions tests/handler/get.test.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
import type {
APIGatewayProxyEvent, APIGatewayProxyResult, APIGatewayEventRequestContext,
} from 'aws-lambda';
import { v4 } from 'uuid';
import { handler } from '../../src/handler/get';
/* eslint-disable import/first */
const mockSend = jest.fn();
const mockGetParameterCommand = jest.fn();

jest.mock('../../src/util/logger.ts');
const mockSsmSend = jest.fn(() => ({
send: mockSend,
}));

describe('Test Get Lambda Function', () => {
test('should return 200 with the query parameters', async () => {
const queryStringParameters: Record<string, string> = { message: 'Hello world!' };
const requestContext: APIGatewayEventRequestContext = <APIGatewayEventRequestContext> { requestId: v4() };
const headers: Record<string, string> = {};
const eventMock: APIGatewayProxyEvent = <APIGatewayProxyEvent> {
queryStringParameters,
requestContext,
headers,
};
jest.mock('@aws-sdk/client-ssm', () => ({
SSMClient: mockSsmSend,
GetParameterCommand: mockGetParameterCommand,
}));

const res: APIGatewayProxyResult = await handler(eventMock);
import { handler, headers } from '../../src/handler/get';

expect(res.statusCode).toBe(200);
expect(res.body).toEqual(JSON.stringify({ queryParams: queryStringParameters }));
describe('get endpoint', () => {
it('should return for non-local endpoint with mocked functions', async () => {
mockSend.mockImplementation(() => Promise.resolve({ Parameter: { Value: '1.0' } }));
const result = await handler();
// eslint-disable-next-line no-useless-escape
expect(result).toEqual({ statusCode: 200, body: '\"1.0\"', headers });
});

test('should return 400 if no query string parameters are provided', async () => {
const eventMock: APIGatewayProxyEvent = <APIGatewayProxyEvent> {};
const result = await handler(eventMock);

expect(result.statusCode).toBe(400);
expect(result.body).toStrictEqual(JSON.stringify({
message: 'Missing query string parameters',
}));
it('should return for local endpoint', async () => {
process.env.AWS_SAM_LOCAL = 'true';
const result = await handler();
// eslint-disable-next-line no-useless-escape
expect(result).toEqual({ statusCode: 200, body: '\"1.0\"', headers });
});
});
35 changes: 0 additions & 35 deletions tests/handler/post.test.ts

This file was deleted.

9 changes: 5 additions & 4 deletions webpack/webpack.production.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ const archiver = require('archiver');
const branchName = require('current-git-branch');

const LAMBDA_NAME = 'GetLambdaFunction';
const OUTPUT_FOLDER = './dist'
const REPO_NAME = 'dvsa-lambda-starter';
const BRANCH_NAME = branchName().replace(/\//g,"-");
const OUTPUT_FOLDER = './'
const REPO_NAME = 'cvs-svc-minimum-application-version';
const BRANCH_NAME = branchName().replace(/\//g, "-");
const COMMIT_HASH = process.env.ZIP_NAME ? process.env.ZIP_NAME : 'local';

class BundlePlugin {
constructor(params) {
Expand Down Expand Up @@ -65,7 +66,7 @@ module.exports = env => {
{
inputPath: `.aws-sam/build/${LAMBDA_NAME}`,
outputPath: `${OUTPUT_FOLDER}`,
outputName: `${REPO_NAME}-${BRANCH_NAME}-${commit}`,
outputName: `${COMMIT_HASH}`,
}
],
}),
Expand Down