From 64045884baaddc0e297fe2461270ee85f68d8113 Mon Sep 17 00:00:00 2001 From: Karan Shah Date: Thu, 3 Feb 2022 10:54:18 +0000 Subject: [PATCH] Added: - Config management - path rewrite Signed-off-by: Karan Shah --- plugins/airbrake-backend/package.json | 2 ++ .../src/config/ExtractAirbrakeConfig.ts | 26 +++++++++++++++++++ plugins/airbrake-backend/src/config/index.ts | 18 +++++++++++++ .../src/service/router.test.ts | 13 +++++++++- .../airbrake-backend/src/service/router.ts | 23 ++++++++++++++++ .../src/service/standaloneServer.ts | 9 ++++++- 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 plugins/airbrake-backend/src/config/ExtractAirbrakeConfig.ts create mode 100644 plugins/airbrake-backend/src/config/index.ts diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 7fa5e3d464..3f174caee4 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -25,12 +25,14 @@ "@types/express": "*", "express": "^4.17.1", "express-promise-router": "^4.1.0", + "http-proxy-middleware": "^2.0.0", "winston": "^3.2.1", "cross-fetch": "^3.0.6", "yn": "^4.0.0" }, "devDependencies": { "@backstage/cli": "^0.13.1-next.0", + "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "supertest": "^4.0.2", "msw": "^0.35.0" diff --git a/plugins/airbrake-backend/src/config/ExtractAirbrakeConfig.ts b/plugins/airbrake-backend/src/config/ExtractAirbrakeConfig.ts new file mode 100644 index 0000000000..06f5e46e85 --- /dev/null +++ b/plugins/airbrake-backend/src/config/ExtractAirbrakeConfig.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { Config } from '@backstage/config'; + +export type AirbrakeConfig = { + apiKey: string; +}; + +export function extractAirbrakeConfig(config: Config): AirbrakeConfig { + return { + apiKey: config.getString('integrations.airbrake.apiKey'), + }; +} diff --git a/plugins/airbrake-backend/src/config/index.ts b/plugins/airbrake-backend/src/config/index.ts new file mode 100644 index 0000000000..6200baca53 --- /dev/null +++ b/plugins/airbrake-backend/src/config/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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. + */ + +export { extractAirbrakeConfig } from './ExtractAirbrakeConfig'; +export type { AirbrakeConfig } from './ExtractAirbrakeConfig'; diff --git a/plugins/airbrake-backend/src/service/router.test.ts b/plugins/airbrake-backend/src/service/router.test.ts index 8b77a04348..ec21a340a3 100644 --- a/plugins/airbrake-backend/src/service/router.test.ts +++ b/plugins/airbrake-backend/src/service/router.test.ts @@ -17,15 +17,26 @@ import { getVoidLogger } from '@backstage/backend-common'; import express from 'express'; import request from 'supertest'; - +import { ConfigReader } from '@backstage/config'; import { createRouter } from './router'; +import { extractAirbrakeConfig } from '../config'; describe('createRouter', () => { let app: express.Express; beforeAll(async () => { + const config = new ConfigReader({ + integrations: { + airbrake: { + apiKey: 'fakeApiKey', + }, + }, + }); + const airbrakeConfig = extractAirbrakeConfig(config); + const router = await createRouter({ logger: getVoidLogger(), + airbrakeConfig, }); app = express().use(router); }); diff --git a/plugins/airbrake-backend/src/service/router.ts b/plugins/airbrake-backend/src/service/router.ts index 9ceaa47627..77b115f088 100644 --- a/plugins/airbrake-backend/src/service/router.ts +++ b/plugins/airbrake-backend/src/service/router.ts @@ -18,9 +18,12 @@ import { errorHandler } from '@backstage/backend-common'; import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; +import { createProxyMiddleware } from 'http-proxy-middleware'; +import { AirbrakeConfig } from '../config'; export interface RouterOptions { logger: Logger; + airbrakeConfig: AirbrakeConfig; } export async function createRouter( @@ -35,6 +38,26 @@ export async function createRouter( logger.info('PONG!'); response.send({ status: 'ok' }); }); + + router.use( + '/api', + createProxyMiddleware({ + target: 'https://api.airbrake.io/api', + changeOrigin: true, + pathRewrite: path => { + const apiKey = options.airbrakeConfig.apiKey; + + let newPath = path.replace(/.+?(\/api)/, ''); + if (newPath.includes('?')) { + newPath += `&key=${apiKey}`; + } else { + newPath += `?key=${apiKey}`; + } + return newPath; + }, + }), + ); + router.use(errorHandler()); return router; } diff --git a/plugins/airbrake-backend/src/service/standaloneServer.ts b/plugins/airbrake-backend/src/service/standaloneServer.ts index 6287bf9f97..5957dd0b7f 100644 --- a/plugins/airbrake-backend/src/service/standaloneServer.ts +++ b/plugins/airbrake-backend/src/service/standaloneServer.ts @@ -14,10 +14,14 @@ * limitations under the License. */ -import { createServiceBuilder } from '@backstage/backend-common'; +import { + createServiceBuilder, + loadBackendConfig, +} from '@backstage/backend-common'; import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; +import { extractAirbrakeConfig } from '../config'; export interface ServerOptions { port: number; @@ -29,9 +33,12 @@ export async function startStandaloneServer( options: ServerOptions, ): Promise { const logger = options.logger.child({ service: 'airbrake-backend-backend' }); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const airbrakeConfig = extractAirbrakeConfig(config); logger.debug('Starting application server...'); const router = await createRouter({ logger, + airbrakeConfig, }); let service = createServiceBuilder(module)