config,backend-common: move config subscribe method to the base config interface

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-08-12 12:49:45 +02:00
parent b89f04d9f7
commit 90f25476ac
10 changed files with 33 additions and 41 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config': patch
---
Extended the `Config` interface to have an optional `subscribe` method that can be used be notified of updates to the configuration.
+1 -1
View File
@@ -2,4 +2,4 @@
'@backstage/backend-common': patch
---
Add support for watching configuration through a new `ObservableConfig` type that is now returned by `loadBackendConfig`.
Add support for watching configuration by implementing the `subscribe` method in the configuration returned by `loadBackendConfig`.
+1 -13
View File
@@ -386,25 +386,13 @@ export { isChildPath };
// Warning: (ae-missing-release-tag) "loadBackendConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function loadBackendConfig(options: Options): Promise<ObservableConfig>;
export function loadBackendConfig(options: Options): Promise<Config>;
// Warning: (ae-missing-release-tag) "notFoundHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function notFoundHandler(): RequestHandler;
// Warning: (ae-missing-release-tag) "ObservableConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface ObservableConfig extends Config {
// (undocumented)
subscribe(
onChange: () => void,
): {
unsubscribe: () => void;
};
}
// Warning: (ae-missing-release-tag) "PluginCacheManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
+3 -9
View File
@@ -21,11 +21,7 @@ import { findPaths } from '@backstage/cli-common';
import { Config, ConfigReader, JsonValue } from '@backstage/config';
import { loadConfig } from '@backstage/config-loader';
export interface ObservableConfig extends Config {
subscribe(onChange: () => void): { unsubscribe: () => void };
}
class ObservableConfigProxy implements ObservableConfig {
class ObservableConfigProxy implements Config {
private config: Config = new ConfigReader({});
private readonly subscribers: (() => void)[] = [];
@@ -38,7 +34,7 @@ class ObservableConfigProxy implements ObservableConfig {
try {
subscriber();
} catch (error) {
this.logger.error(`ObservableConfig subscriber threw error, ${error}`);
this.logger.error(`Config subscriber threw error, ${error}`);
}
}
}
@@ -119,9 +115,7 @@ let currentCancelFunc: () => void;
*
* This function should only be called once, during the initialization of the backend.
*/
export async function loadBackendConfig(
options: Options,
): Promise<ObservableConfig> {
export async function loadBackendConfig(options: Options): Promise<Config> {
const args = parseArgs(options.argv);
const configPaths: string[] = [args.config ?? []].flat();
+3
View File
@@ -16,6 +16,9 @@ export type AppConfig = {
//
// @public (undocumented)
export type Config = {
subscribe?(onChange: () => void): {
unsubscribe: () => void;
};
has(key: string): boolean;
keys(): string[];
get<T = JsonValue>(key?: string): T;
+11
View File
@@ -26,6 +26,17 @@ export type AppConfig = {
};
export type Config = {
/**
* Subscribes to the configuration object in order to receive a notification
* whenever any value within the configuration has changed.
*
* This method is optional to implement, and consumers need to check if it is
* implemented before invoking it.
*/
subscribe?(onChange: () => void): {
unsubscribe: () => void;
};
has(key: string): boolean;
keys(): string[];
-1
View File
@@ -21,7 +21,6 @@ import { Knex } from 'knex';
import { Location as Location_2 } from '@backstage/catalog-model';
import { LocationSpec } from '@backstage/catalog-model';
import { Logger as Logger_2 } from 'winston';
import { ObservableConfig } from '@backstage/backend-common';
import { Organizations } from 'aws-sdk';
import { PluginDatabaseManager } from '@backstage/backend-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
resolvePackagePath,
ObservableConfig,
} from '@backstage/backend-common';
import { resolvePackagePath } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import path from 'path';
import { ConfigLocationEntityProvider } from './ConfigLocationEntityProvider';
@@ -83,15 +80,12 @@ describe('ConfigLocationEntityProvider', () => {
},
};
const mockConfig: ObservableConfig = Object.assign(
new ConfigReader(mutableConfigData),
{
subscribe: (s: () => void) => {
subscriber = s;
return { unsubscribe: () => {} };
},
const mockConfig = Object.assign(new ConfigReader(mutableConfigData), {
subscribe: (s: () => void) => {
subscriber = s;
return { unsubscribe: () => {} };
},
);
});
const mockConnection = {
applyMutation: jest.fn(),
@@ -15,14 +15,13 @@
*/
import { Config } from '@backstage/config';
import { ObservableConfig } from '@backstage/backend-common';
import path from 'path';
import { getEntityLocationRef } from './processing/util';
import { EntityProvider, EntityProviderConnection } from './types';
import { locationSpecToLocationEntity } from './util';
export class ConfigLocationEntityProvider implements EntityProvider {
constructor(private readonly config: Config | ObservableConfig) {}
constructor(private readonly config: Config) {}
getProviderName(): string {
return 'ConfigLocationProvider';
@@ -35,7 +34,7 @@ export class ConfigLocationEntityProvider implements EntityProvider {
entities,
});
if ('subscribe' in this.config) {
if (this.config.subscribe) {
let currentKey = JSON.stringify(entities);
this.config.subscribe(() => {
@@ -15,7 +15,6 @@
*/
import {
ObservableConfig,
PluginDatabaseManager,
resolvePackagePath,
UrlReader,
@@ -80,7 +79,7 @@ import { Stitcher } from './stitching/Stitcher';
export type CatalogEnvironment = {
logger: Logger;
database: PluginDatabaseManager;
config: Config | ObservableConfig;
config: Config;
reader: UrlReader;
};