From 44c8816db51ca1d10f153fa3491cd962999aeaec Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 30 Sep 2020 11:40:22 +0200 Subject: [PATCH] backend-common: add UrlReaders for constructing a reader from config --- packages/backend-common/src/index.ts | 1 + .../backend-common/src/reading/UrlReaders.ts | 89 +++++++++++++++++++ packages/backend-common/src/reading/index.ts | 1 + 3 files changed, 91 insertions(+) create mode 100644 packages/backend-common/src/reading/UrlReaders.ts diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts index 7074040655..e968edef69 100644 --- a/packages/backend-common/src/index.ts +++ b/packages/backend-common/src/index.ts @@ -20,6 +20,7 @@ export * from './discovery'; export * from './errors'; export * from './logging'; export * from './middleware'; +export * from './reading'; export * from './service'; export * from './paths'; export * from './hot'; diff --git a/packages/backend-common/src/reading/UrlReaders.ts b/packages/backend-common/src/reading/UrlReaders.ts new file mode 100644 index 0000000000..5aa6432cfc --- /dev/null +++ b/packages/backend-common/src/reading/UrlReaders.ts @@ -0,0 +1,89 @@ +/* + * 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 { Config } from '@backstage/config'; +import { GithubUrlReader } from './GithubUrlReader'; +import { UrlReader } from './types'; +import { UrlReaderHostMux } from './UrlReaderHostMux'; + +export type ReaderFactoryOptions = { + config: Config; + logger: Logger; +}; +export type ReaderFactory = (options: ReaderFactoryOptions) => UrlReader; + +/** + * UrlReaders provide various utilities related to the UrlReader interface. + */ +export class UrlReaders { + /** + * Creates a new UrlReaders instance without any known types. + */ + static empty({ logger }: { logger: Logger }) { + return new UrlReaders(new Map(), logger); + } + + /** + * Creates a new UrlReaders instance that includes factories for all types + * implemented in this package. + */ + static default({ logger }: { logger: Logger }) { + return new UrlReaders( + new Map([['github', GithubUrlReader.factory]]), + logger, + ); + } + + private constructor( + private readonly factories: Map, + private readonly logger: Logger, + ) {} + + /** + * Constructs a new UrlReader using the provided configuration. Any encountered + * reader type needs to have a registered factory, or an error will be thrown. + */ + createWithConfig(config: Config): UrlReader { + const readerItems = config.getOptionalConfigArray('readers.byHost') ?? []; + const mux = new UrlReaderHostMux(); + + for (const readerItem of readerItems) { + const type = readerItem.getString('type'); + const host = readerItem.getString('host'); + const readerConfig = readerItem.getConfig('config'); + + const factory = this.factories.get(type); + if (!factory) { + throw new Error(`Failed to create reader for unknown type '${type}'`); + } + const reader = factory({ + config: readerConfig, + logger: this.logger, + }); + + mux.register(host, reader); + } + + return mux; + } + + /** + * Register a UrlReader factory for a given type + */ + register(type: string, factory: ReaderFactory) { + this.factories.set(type, factory); + } +} diff --git a/packages/backend-common/src/reading/index.ts b/packages/backend-common/src/reading/index.ts index c632613934..ad493c34fd 100644 --- a/packages/backend-common/src/reading/index.ts +++ b/packages/backend-common/src/reading/index.ts @@ -15,3 +15,4 @@ */ export type { UrlReader } from './types'; +export { UrlReaders } from './UrlReaders';