Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
feat(cellgeo): add GET __health endpoint
Browse files Browse the repository at this point in the history
Check if API is ready before testing

See #455
  • Loading branch information
coderbyheart committed Oct 22, 2020
1 parent 4b3a58e commit d13b4bd
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 25 deletions.
10 changes: 10 additions & 0 deletions cdk/httpApiHealth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { APIGatewayProxyResult } from 'aws-lambda'

export const handler = (): APIGatewayProxyResult => ({
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'OK' }),
})
2 changes: 2 additions & 0 deletions cdk/prepare-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ConsoleProgressReporter } from '@bifravst/package-layered-lambdas/dist/

export type CDKLambdas = {
createThingGroup: string
httpApiHealth: string
}

export type BifravstLambdas = {
Expand Down Expand Up @@ -152,6 +153,7 @@ export const prepareCDKLambdas = async ({
Bucket: sourceCodeBucketName,
lambdas: {
createThingGroup: path.resolve(rootDir, 'cdk', 'createThingGroup.ts'),
httpApiHealth: path.resolve(rootDir, 'cdk', 'httpApiHealth.ts'),
},
tsConfig: path.resolve(rootDir, 'tsconfig.json'),
}),
Expand Down
73 changes: 53 additions & 20 deletions cdk/resources/CellGeolocationApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as CloudFormation from '@aws-cdk/core'
import * as HttpApi from '@aws-cdk/aws-apigatewayv2'
import * as IAM from '@aws-cdk/aws-iam'
import * as Lambda from '@aws-cdk/aws-lambda'
import { BifravstLambdas } from '../prepare-resources'
import { BifravstLambdas, CDKLambdas } from '../prepare-resources'
import { logToCloudWatch } from './logToCloudWatch'
import { CellGeolocation } from './CellGeolocation'
import { LambdasWithLayer } from './LambdasWithLayer'
Expand All @@ -24,9 +24,11 @@ export class CellGeolocationApi extends CloudFormation.Resource {
{
cellgeo,
lambdas,
cdkLambdas,
}: {
cellgeo: CellGeolocation
lambdas: LambdasWithLayer<BifravstLambdas>
cdkLambdas: LambdasWithLayer<CDKLambdas>
},
) {
super(parent, id)
Expand Down Expand Up @@ -98,7 +100,7 @@ export class CellGeolocationApi extends CloudFormation.Resource {
},
)

this.stage = new HttpApi.CfnStage(this, 'httpApiStage', {
this.stage = new HttpApi.CfnStage(this, 'stage', {
apiId: this.api.ref,
stageName: 'v1',
autoDeploy: true,
Expand All @@ -123,36 +125,70 @@ export class CellGeolocationApi extends CloudFormation.Resource {
},
})

const geolocateIntegration = new HttpApi.CfnIntegration(
// GET __health

const healthCheck = new Lambda.Function(this, 'apiHealth', {
handler: 'index.handler',
runtime: Lambda.Runtime.NODEJS_12_X,
timeout: CloudFormation.Duration.seconds(10),
code: cdkLambdas.lambdas.httpApiHealth,
description: 'HTTP API Health Check',
initialPolicy: [logToCloudWatch],
})

const healthCheckIntegration = new HttpApi.CfnIntegration(
this,
'httpApiAddCellGeolocateIntegration',
'healthCheckIntegration',
{
apiId: this.api.ref,
integrationType: 'AWS_PROXY',
integrationUri: `arn:aws:apigateway:${this.stack.region}:lambda:path/2015-03-31/functions/${geolocateCell.functionArn}/invocations`,
integrationUri: `arn:aws:apigateway:${this.stack.region}:lambda:path/2015-03-31/functions/${healthCheck.functionArn}/invocations`,
integrationMethod: 'POST',
payloadFormatVersion: '1.0',
},
)

const geolocateRoute = new HttpApi.CfnRoute(
const healthCheckRoute = new HttpApi.CfnRoute(this, 'healthCheckRoute', {
apiId: this.api.ref,
routeKey: 'GET /__health',
target: `integrations/${healthCheckIntegration.ref}`,
})

healthCheck.addPermission('invokeByHttpApi', {
principal: new IAM.ServicePrincipal('apigateway.amazonaws.com'),
sourceArn: `arn:aws:execute-api:${this.stack.region}:${this.stack.account}:${this.api.ref}/${this.stage.stageName}/GET/__health`,
})

// GET /cellgeolocation

const geolocateIntegration = new HttpApi.CfnIntegration(
this,
'httpApiCellGeolocateRoute',
'geolocateIntegration',
{
apiId: this.api.ref,
routeKey: 'GET /cellgeolocation',
target: `integrations/${geolocateIntegration.ref}`,
integrationType: 'AWS_PROXY',
integrationUri: `arn:aws:apigateway:${this.stack.region}:lambda:path/2015-03-31/functions/${geolocateCell.functionArn}/invocations`,
integrationMethod: 'POST',
payloadFormatVersion: '1.0',
},
)

const geolocateRoute = new HttpApi.CfnRoute(this, 'geolocateRoute', {
apiId: this.api.ref,
routeKey: 'GET /cellgeolocation',
target: `integrations/${geolocateIntegration.ref}`,
})

geolocateCell.addPermission('invokeByHttpApi', {
principal: new IAM.ServicePrincipal('apigateway.amazonaws.com'),
sourceArn: `arn:aws:execute-api:${this.stack.region}:${this.stack.account}:${this.api.ref}/${this.stage.stageName}/GET/cellgeolocation`,
})

// POST /cellgeolocation

const geolocationIntegration = new HttpApi.CfnIntegration(
this,
'httpApiAddCellGeolocationIntegration',
'geolocationIntegration',
{
apiId: this.api.ref,
integrationType: 'AWS_PROXY',
Expand All @@ -162,26 +198,23 @@ export class CellGeolocationApi extends CloudFormation.Resource {
},
)

const geolocationRoute = new HttpApi.CfnRoute(
this,
'httpApiAddCellGeolocationRoute',
{
apiId: this.api.ref,
routeKey: 'POST /cellgeolocation',
target: `integrations/${geolocationIntegration.ref}`,
},
)
const geolocationRoute = new HttpApi.CfnRoute(this, 'geolocationRoute', {
apiId: this.api.ref,
routeKey: 'POST /cellgeolocation',
target: `integrations/${geolocationIntegration.ref}`,
})

addCellGeolocation.addPermission('invokeByHttpApi', {
principal: new IAM.ServicePrincipal('apigateway.amazonaws.com'),
sourceArn: `arn:aws:execute-api:${this.stack.region}:${this.stack.account}:${this.api.ref}/${this.stage.stageName}/POST/cellgeolocation`,
})

const deployment = new HttpApi.CfnDeployment(this, 'httpApiDeployment', {
const deployment = new HttpApi.CfnDeployment(this, 'deployment', {
apiId: this.api.ref,
stageName: this.stage.stageName,
})
deployment.node.addDependency(this.stage)
deployment.node.addDependency(healthCheckRoute)
deployment.node.addDependency(geolocateRoute)
deployment.node.addDependency(geolocationRoute)
}
Expand Down
11 changes: 7 additions & 4 deletions cdk/stacks/Bifravst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,13 @@ export class BifravstStack extends CloudFormation.Stack {
exportName: `${this.stackName}:thingPolicyArn`,
})

const cdkLambdas = {
lambdas: lambasOnBucket(packedCDKLambdas),
layers: [cloudFormationLayer],
}

const thingGroupLambda = new ThingGroupLambda(this, 'thingGroupLambda', {
cdkLambdas: {
lambdas: lambasOnBucket(packedCDKLambdas),
layers: [cloudFormationLayer],
},
cdkLambdas,
})

new CloudFormation.CfnOutput(this, 'thingGroupLambdaArn', {
Expand Down Expand Up @@ -450,6 +452,7 @@ export class BifravstStack extends CloudFormation.Stack {

const cellGeoApi = new CellGeolocationApi(this, 'cellGeolocationApi', {
lambdas,
cdkLambdas,
cellgeo,
})

Expand Down
13 changes: 13 additions & 0 deletions features/CellGeolocation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ Feature: Cell Geolocation API
And I am run after the "Device: Update Shadow" feature
And the endpoint is "{geolocationApiUrl}"

Scenario: Check API health

When I GET /__health
Then the response status code should be 200
And the response Access-Control-Allow-Origin should be "*"
And the response Content-Type should be "application/json"
And the response should equal this JSON
"""
{
"status": "OK"
}
"""

Scenario: Device enters a cell

Given I store "$floor($random() * 100000000)" into "cellId"
Expand Down
3 changes: 2 additions & 1 deletion features/CellGeolocationPublishApi.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Feature: Cell Geolocation Publish API

Background:

Given the endpoint is "{geolocationApiUrl}"
Given I am run after the "Cell Geolocation API" feature
And the endpoint is "{geolocationApiUrl}"
And I store "$floor($random() * 100000000)" into "cellId"
And I store "$floor($random() * 10000) + 10000" into "mccmnc"
And I store "$floor($random() * 100) + 100" into "area"
Expand Down

0 comments on commit d13b4bd

Please sign in to comment.