add status check router

This commit is contained in:
Andrew Thauer
2020-07-26 16:11:23 -04:00
parent 88e3581ebc
commit 2a482bd3ef
7 changed files with 124 additions and 5 deletions
+1
View File
@@ -35,6 +35,7 @@
"compression": "^1.7.4",
"cors": "^2.8.5",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"helmet": "^3.22.0",
"morgan": "^1.10.0",
"stoppable": "^1.1.0",
@@ -0,0 +1,56 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import express from 'express';
import * as winston from 'winston';
import request from 'supertest';
import { createStatusCheckRouter } from './createStatusCheckRouter';
describe('createStatusCheckRouter', () => {
const logger = winston.createLogger();
it('gives status 200 when using default path', async () => {
const app = express();
app.use('', await createStatusCheckRouter({ logger }));
const response = await request(app).get('/healthcheck');
expect(response.status).toBe(200);
expect(response.text).toBe(JSON.stringify({ status: 'ok' }));
});
it('gives status 200 when using custom path', async () => {
const app = express();
app.use('', await createStatusCheckRouter({ logger, path: '/ready' }));
const response = await request(app).get('/ready');
expect(response.status).toBe(200);
expect(response.text).toBe(JSON.stringify({ status: 'ok' }));
});
it('gives status 500 when status check throws an error', async () => {
const app = express();
const statusCheck = () => {
throw Error('error!');
};
app.use('', await createStatusCheckRouter({ logger, statusCheck }));
const response = await request(app).get('/healthcheck');
expect(response.status).toBe(500);
});
});
@@ -0,0 +1,38 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Logger } from 'winston';
import Router from 'express-promise-router';
import express from 'express';
import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware';
export interface StatusCheckRouterOptions {
logger: Logger;
path?: string;
statusCheck?: StatusCheck;
}
export async function createStatusCheckRouter(
options: StatusCheckRouterOptions,
): Promise<express.Router> {
const router = Router();
const { path = '/healthcheck', statusCheck } = options;
router.use(path, await statusCheckHandler({ statusCheck }));
router.use(errorHandler());
return router;
}
@@ -15,4 +15,5 @@
*/
export { createServiceBuilder } from './createServiceBuilder';
export { createStatusCheckRouter } from './createStatusCheckRouter';
export type { ServiceBuilder } from './types';
@@ -17,7 +17,7 @@
import { ConfigReader } from '@backstage/config';
import compression from 'compression';
import cors from 'cors';
import express, { Router, RequestHandler } from 'express';
import express, { Router } from 'express';
import helmet from 'helmet';
import { Server } from 'http';
import stoppable from 'stoppable';
@@ -40,7 +40,7 @@ export class ServiceBuilderImpl implements ServiceBuilder {
private host: string | undefined;
private logger: Logger | undefined;
private corsOptions: cors.CorsOptions | undefined;
private routers: [string, Router | RequestHandler][];
private routers: [string, Router][];
// Reference to the module where builder is created - needed for hot module
// reloading
private module: NodeModule;
@@ -92,7 +92,7 @@ export class ServiceBuilderImpl implements ServiceBuilder {
return this;
}
addRouter(root: string, router: Router | RequestHandler): ServiceBuilder {
addRouter(root: string, router: Router): ServiceBuilder {
this.routers.push([root, router]);
return this;
}
+3 -2
View File
@@ -25,12 +25,12 @@
import {
createServiceBuilder,
getRootLogger,
statusCheckHandler,
useHotMemoize,
} from '@backstage/backend-common';
import { ConfigReader, AppConfig } from '@backstage/config';
import { loadConfig } from '@backstage/config-loader';
import knex from 'knex';
import healthcheck from './plugins/healthcheck';
import auth from './plugins/auth';
import catalog from './plugins/catalog';
import identity from './plugins/identity';
@@ -63,6 +63,7 @@ async function main() {
const configReader = ConfigReader.fromConfigs(configs);
const createEnv = makeCreateEnv(configs);
const healthcheckEnv = useHotMemoize(module, () => createEnv('healthcheck'));
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
const authEnv = useHotMemoize(module, () => createEnv('auth'));
@@ -74,7 +75,7 @@ async function main() {
const service = createServiceBuilder(module)
.loadConfig(configReader)
.addRouter('/healthcheck', await statusCheckHandler())
.addRouter('', await healthcheck(healthcheckEnv))
.addRouter('/catalog', await catalog(catalogEnv))
.addRouter('/rollbar', await rollbar(rollbarEnv))
.addRouter('/scaffolder', await scaffolder(scaffolderEnv))
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createStatusCheckRouter } from '@backstage/backend-common';
import { PluginEnvironment } from '../types';
export default async function createRouter({ logger }: PluginEnvironment) {
return await createStatusCheckRouter({ logger, path: '/healthcheck' });
}