From b833984424e4af3190f3d5fa3aa790a5bb1c9eac Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 28 Jan 2021 09:54:19 +0100 Subject: [PATCH] add sync accessor for legacy config --- ...-server.plugininitializercontext.config.md | 1 + ...in-core-server.plugininitializercontext.md | 2 +- .../legacy/legacy_object_to_config_adapter.ts | 2 +- src/core/server/mocks.ts | 5 +- src/core/server/plugins/legacy_config.test.ts | 82 +++++++++++++++++++ src/core/server/plugins/legacy_config.ts | 69 ++++++++++++++++ src/core/server/plugins/plugin_context.ts | 36 ++------ src/core/server/plugins/types.ts | 5 +- src/core/server/server.api.md | 3 +- 9 files changed, 169 insertions(+), 36 deletions(-) create mode 100644 src/core/server/plugins/legacy_config.test.ts create mode 100644 src/core/server/plugins/legacy_config.ts diff --git a/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.config.md b/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.config.md index 8824bf1c92e26..3b5754eb4fa39 100644 --- a/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.config.md +++ b/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.config.md @@ -12,6 +12,7 @@ Accessors for the plugin's configuration config: { legacy: { globalConfig$: Observable; + get: () => SharedGlobalConfig; }; create: () => Observable; get: () => T; diff --git a/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.md b/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.md index e892f4d2b87ea..90a19d53bd5e1 100644 --- a/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.md @@ -16,7 +16,7 @@ export interface PluginInitializerContext | Property | Type | Description | | --- | --- | --- | -| [config](./kibana-plugin-core-server.plugininitializercontext.config.md) | {
legacy: {
globalConfig$: Observable<SharedGlobalConfig>;
};
create: <T = ConfigSchema>() => Observable<T>;
get: <T = ConfigSchema>() => T;
} | Accessors for the plugin's configuration | +| [config](./kibana-plugin-core-server.plugininitializercontext.config.md) | {
legacy: {
globalConfig$: Observable<SharedGlobalConfig>;
get: () => SharedGlobalConfig;
};
create: <T = ConfigSchema>() => Observable<T>;
get: <T = ConfigSchema>() => T;
} | Accessors for the plugin's configuration | | [env](./kibana-plugin-core-server.plugininitializercontext.env.md) | {
mode: EnvironmentMode;
packageInfo: Readonly<PackageInfo>;
instanceUuid: string;
} | | | [logger](./kibana-plugin-core-server.plugininitializercontext.logger.md) | LoggerFactory | instance already bound to the plugin's logging context | | [opaqueId](./kibana-plugin-core-server.plugininitializercontext.opaqueid.md) | PluginOpaqueId | | diff --git a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts index c037c5f0308c8..c12a147fddddc 100644 --- a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts +++ b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts @@ -84,7 +84,7 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter { }; } - private static transformPlugins(configValue: LegacyVars) { + private static transformPlugins(configValue: LegacyVars = {}) { // These properties are the only ones we use from the existing `plugins` config node // since `scanDirs` isn't respected by new platform plugin discovery. return { diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 456119c32963a..b86e2e4c6dedb 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -69,7 +69,10 @@ export function pluginInitializerContextConfigMock(config: T) { }; const mock: jest.Mocked['config']> = { - legacy: { globalConfig$: of(globalConfig) }, + legacy: { + globalConfig$: of(globalConfig), + get: () => globalConfig, + }, create: jest.fn().mockReturnValue(of(config)), get: jest.fn().mockReturnValue(config), }; diff --git a/src/core/server/plugins/legacy_config.test.ts b/src/core/server/plugins/legacy_config.test.ts new file mode 100644 index 0000000000000..fd8234d72bd17 --- /dev/null +++ b/src/core/server/plugins/legacy_config.test.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. + */ + +import { take } from 'rxjs/operators'; +import { ConfigService, Env } from '@kbn/config'; +import { getEnvOptions, rawConfigServiceMock } from '../config/mocks'; +import { getGlobalConfig, getGlobalConfig$ } from './legacy_config'; +import { REPO_ROOT } from '@kbn/utils'; +import { loggingSystemMock } from '../logging/logging_system.mock'; +import { duration } from 'moment'; +import { fromRoot } from '../utils'; +import { ByteSizeValue } from '@kbn/config-schema'; +import { Server } from '../server'; + +describe('Legacy config', () => { + let env: Env; + let logger: ReturnType; + + beforeEach(() => { + env = Env.createDefault(REPO_ROOT, getEnvOptions()); + logger = loggingSystemMock.create(); + }); + + const createConfigService = (rawConfig: Record = {}): ConfigService => { + const rawConfigService = rawConfigServiceMock.create({ rawConfig }); + const server = new Server(rawConfigService, env, logger); + server.setupCoreConfig(); + return server.configService; + }; + + describe('getGlobalConfig', () => { + it('should return the global config', async () => { + const configService = createConfigService(); + await configService.validate(); + + const legacyConfig = getGlobalConfig(configService); + + expect(legacyConfig).toStrictEqual({ + kibana: { + index: '.kibana', + autocompleteTerminateAfter: duration(100000), + autocompleteTimeout: duration(1000), + }, + elasticsearch: { + shardTimeout: duration(30, 's'), + requestTimeout: duration(30, 's'), + pingTimeout: duration(30, 's'), + }, + path: { data: fromRoot('data') }, + savedObjects: { maxImportPayloadBytes: new ByteSizeValue(26214400) }, + }); + }); + }); + + describe('getGlobalConfig$', () => { + it('should return an observable for the global config', async () => { + const configService = createConfigService(); + + const legacyConfig = await getGlobalConfig$(configService).pipe(take(1)).toPromise(); + + expect(legacyConfig).toStrictEqual({ + kibana: { + index: '.kibana', + autocompleteTerminateAfter: duration(100000), + autocompleteTimeout: duration(1000), + }, + elasticsearch: { + shardTimeout: duration(30, 's'), + requestTimeout: duration(30, 's'), + pingTimeout: duration(30, 's'), + }, + path: { data: fromRoot('data') }, + savedObjects: { maxImportPayloadBytes: new ByteSizeValue(26214400) }, + }); + }); + }); +}); diff --git a/src/core/server/plugins/legacy_config.ts b/src/core/server/plugins/legacy_config.ts new file mode 100644 index 0000000000000..748a1e3190640 --- /dev/null +++ b/src/core/server/plugins/legacy_config.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * and the Server Side Public License, v 1; you may not use this file except in + * compliance with, at your election, the Elastic License or the Server Side + * Public License, v 1. + */ + +import { map, shareReplay } from 'rxjs/operators'; +import { combineLatest, Observable } from 'rxjs'; +import { PathConfigType, config as pathConfig } from '@kbn/utils'; +import { pick, deepFreeze } from '@kbn/std'; +import { IConfigService } from '@kbn/config'; + +import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types'; +import { KibanaConfigType, config as kibanaConfig } from '../kibana_config'; +import { + ElasticsearchConfigType, + config as elasticsearchConfig, +} from '../elasticsearch/elasticsearch_config'; +import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config'; + +const createGlobalConfig = ({ + kibana, + elasticsearch, + path, + savedObjects, +}: { + kibana: KibanaConfigType; + elasticsearch: ElasticsearchConfigType; + path: PathConfigType; + savedObjects: SavedObjectsConfigType; +}): SharedGlobalConfig => { + return deepFreeze({ + kibana: pick(kibana, SharedGlobalConfigKeys.kibana), + elasticsearch: pick(elasticsearch, SharedGlobalConfigKeys.elasticsearch), + path: pick(path, SharedGlobalConfigKeys.path), + savedObjects: pick(savedObjects, SharedGlobalConfigKeys.savedObjects), + }); +}; + +export const getGlobalConfig = (configService: IConfigService): SharedGlobalConfig => { + return createGlobalConfig({ + kibana: configService.atPathSync(kibanaConfig.path), + elasticsearch: configService.atPathSync(elasticsearchConfig.path), + path: configService.atPathSync(pathConfig.path), + savedObjects: configService.atPathSync(savedObjectsConfig.path), + }); +}; + +export const getGlobalConfig$ = (configService: IConfigService): Observable => { + return combineLatest([ + configService.atPath(kibanaConfig.path), + configService.atPath(elasticsearchConfig.path), + configService.atPath(pathConfig.path), + configService.atPath(savedObjectsConfig.path), + ]).pipe( + map( + ([kibana, elasticsearch, path, savedObjects]) => + createGlobalConfig({ + kibana, + elasticsearch, + path, + savedObjects, + }), + shareReplay(1) + ) + ); +}; diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 06ab3b29c9260..3b7dc70b9c054 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -6,27 +6,14 @@ * Public License, v 1. */ -import { map, shareReplay } from 'rxjs/operators'; -import { combineLatest } from 'rxjs'; -import { PathConfigType, config as pathConfig } from '@kbn/utils'; -import { pick, deepFreeze } from '@kbn/std'; +import { shareReplay } from 'rxjs/operators'; import type { RequestHandlerContext } from 'src/core/server'; import { CoreContext } from '../core_context'; import { PluginWrapper } from './plugin'; import { PluginsServiceSetupDeps, PluginsServiceStartDeps } from './plugins_service'; -import { - PluginInitializerContext, - PluginManifest, - PluginOpaqueId, - SharedGlobalConfigKeys, -} from './types'; -import { KibanaConfigType, config as kibanaConfig } from '../kibana_config'; -import { - ElasticsearchConfigType, - config as elasticsearchConfig, -} from '../elasticsearch/elasticsearch_config'; +import { PluginInitializerContext, PluginManifest, PluginOpaqueId } from './types'; import { IRouter, RequestHandlerContextProvider } from '../http'; -import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config'; +import { getGlobalConfig, getGlobalConfig$ } from './legacy_config'; import { CoreSetup, CoreStart } from '..'; export interface InstanceInfo { @@ -78,21 +65,8 @@ export function createPluginInitializerContext( */ config: { legacy: { - globalConfig$: combineLatest([ - coreContext.configService.atPath(kibanaConfig.path), - coreContext.configService.atPath(elasticsearchConfig.path), - coreContext.configService.atPath(pathConfig.path), - coreContext.configService.atPath(savedObjectsConfig.path), - ]).pipe( - map(([kibana, elasticsearch, path, savedObjects]) => - deepFreeze({ - kibana: pick(kibana, SharedGlobalConfigKeys.kibana), - elasticsearch: pick(elasticsearch, SharedGlobalConfigKeys.elasticsearch), - path: pick(path, SharedGlobalConfigKeys.path), - savedObjects: pick(savedObjects, SharedGlobalConfigKeys.savedObjects), - }) - ) - ), + globalConfig$: getGlobalConfig$(coreContext.configService), + get: () => getGlobalConfig(coreContext.configService), }, /** diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts index 67d23aa97898a..8858d7bbbda0b 100644 --- a/src/core/server/plugins/types.ts +++ b/src/core/server/plugins/types.ts @@ -307,7 +307,10 @@ export interface PluginInitializerContext { * @remarks Naming not final here, it may be renamed in a near future * @deprecated Accessing configuration values outside of the plugin's config scope is highly discouraged */ - legacy: { globalConfig$: Observable }; + legacy: { + globalConfig$: Observable; + get: () => SharedGlobalConfig; + }; /** * Return an observable of the plugin's configuration * diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 60d0921b30a77..aadd16bde0ee6 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1844,6 +1844,7 @@ export interface PluginInitializerContext { config: { legacy: { globalConfig$: Observable; + get: () => SharedGlobalConfig; }; create: () => Observable; get: () => T; @@ -3138,6 +3139,6 @@ export const validBodyOutput: readonly ["data", "stream"]; // src/core/server/plugins/types.ts:263:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:263:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:368:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create" +// src/core/server/plugins/types.ts:371:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create" ```