From 8ba14bf3517ac674f5e0d5bfc344254b02a1dfb8 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:48:39 +0200 Subject: [PATCH 1/8] remove LoggingConfig class --- src/core/server/logging/index.ts | 2 +- src/core/server/logging/logger.test.ts | 2 +- .../server/logging/logging_config.test.ts | 54 +++++++--------- src/core/server/logging/logging_config.ts | 36 +++++------ .../server/logging/logging_service.test.ts | 62 ++++++++----------- src/core/server/logging/logging_service.ts | 5 +- 6 files changed, 70 insertions(+), 91 deletions(-) diff --git a/src/core/server/logging/index.ts b/src/core/server/logging/index.ts index aa23a11e39b44..cde85c2600ffc 100644 --- a/src/core/server/logging/index.ts +++ b/src/core/server/logging/index.ts @@ -22,6 +22,6 @@ export { LoggerFactory } from './logger_factory'; export { LogRecord } from './log_record'; export { LogLevel } from './log_level'; /** @internal */ -export { LoggingConfig, config } from './logging_config'; +export { config, LoggingConfigType } from './logging_config'; /** @internal */ export { LoggingService } from './logging_service'; diff --git a/src/core/server/logging/logger.test.ts b/src/core/server/logging/logger.test.ts index 928b37a3f510e..40c310c4e94c7 100644 --- a/src/core/server/logging/logger.test.ts +++ b/src/core/server/logging/logger.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { LoggingConfig } from '.'; +import { LoggingConfig } from './logging_config'; import { Appender } from './appenders/appenders'; import { LogLevel } from './log_level'; import { BaseLogger } from './logger'; diff --git a/src/core/server/logging/logging_config.test.ts b/src/core/server/logging/logging_config.test.ts index f21b5aaf3c1a7..8eb79ac46e499 100644 --- a/src/core/server/logging/logging_config.test.ts +++ b/src/core/server/logging/logging_config.test.ts @@ -17,18 +17,15 @@ * under the License. */ -import { LoggingConfig } from '.'; +import { LoggingConfig, config } from './logging_config'; test('`schema` creates correct schema with defaults.', () => { - const loggingConfigSchema = LoggingConfig.schema; - expect(loggingConfigSchema.validate({})).toMatchSnapshot(); + expect(config.schema.validate({})).toMatchSnapshot(); }); test('`schema` throws if `root` logger does not have appenders configured.', () => { - const loggingConfigSchema = LoggingConfig.schema; - expect(() => - loggingConfigSchema.validate({ + config.schema.validate({ root: { appenders: [], }, @@ -50,21 +47,19 @@ test('`getLoggerContext()` returns correct joined context name.', () => { }); test('correctly fills in default `appenders` config.', () => { - const loggingConfigSchema = LoggingConfig.schema; - const config = new LoggingConfig(loggingConfigSchema.validate({})); + const configValue = new LoggingConfig(config.schema.validate({})); - expect(config.appenders.size).toBe(1); + expect(configValue.appenders.size).toBe(1); - expect(config.appenders.get('default')).toEqual({ + expect(configValue.appenders.get('default')).toEqual({ kind: 'console', layout: { kind: 'pattern', highlight: true }, }); }); test('correctly fills in custom `appenders` config.', () => { - const loggingConfigSchema = LoggingConfig.schema; - const config = new LoggingConfig( - loggingConfigSchema.validate({ + const configValue = new LoggingConfig( + config.schema.validate({ appenders: { console: { kind: 'console', @@ -79,19 +74,19 @@ test('correctly fills in custom `appenders` config.', () => { }) ); - expect(config.appenders.size).toBe(3); + expect(configValue.appenders.size).toBe(3); - expect(config.appenders.get('default')).toEqual({ + expect(configValue.appenders.get('default')).toEqual({ kind: 'console', layout: { kind: 'pattern', highlight: true }, }); - expect(config.appenders.get('console')).toEqual({ + expect(configValue.appenders.get('console')).toEqual({ kind: 'console', layout: { kind: 'pattern' }, }); - expect(config.appenders.get('file')).toEqual({ + expect(configValue.appenders.get('file')).toEqual({ kind: 'file', layout: { kind: 'pattern' }, path: 'path', @@ -99,11 +94,10 @@ test('correctly fills in custom `appenders` config.', () => { }); test('correctly fills in default `loggers` config.', () => { - const loggingConfigSchema = LoggingConfig.schema; - const config = new LoggingConfig(loggingConfigSchema.validate({})); + const configValue = new LoggingConfig(config.schema.validate({})); - expect(config.loggers.size).toBe(1); - expect(config.loggers.get('root')).toEqual({ + expect(configValue.loggers.size).toBe(1); + expect(configValue.loggers.get('root')).toEqual({ appenders: ['default'], context: 'root', level: 'info', @@ -111,9 +105,8 @@ test('correctly fills in default `loggers` config.', () => { }); test('correctly fills in custom `loggers` config.', () => { - const loggingConfigSchema = LoggingConfig.schema; - const config = new LoggingConfig( - loggingConfigSchema.validate({ + const configValue = new LoggingConfig( + config.schema.validate({ appenders: { file: { kind: 'file', @@ -140,23 +133,23 @@ test('correctly fills in custom `loggers` config.', () => { }) ); - expect(config.loggers.size).toBe(4); - expect(config.loggers.get('root')).toEqual({ + expect(configValue.loggers.size).toBe(4); + expect(configValue.loggers.get('root')).toEqual({ appenders: ['default'], context: 'root', level: 'info', }); - expect(config.loggers.get('plugins')).toEqual({ + expect(configValue.loggers.get('plugins')).toEqual({ appenders: ['file'], context: 'plugins', level: 'warn', }); - expect(config.loggers.get('plugins.pid')).toEqual({ + expect(configValue.loggers.get('plugins.pid')).toEqual({ appenders: ['file'], context: 'plugins.pid', level: 'trace', }); - expect(config.loggers.get('http')).toEqual({ + expect(configValue.loggers.get('http')).toEqual({ appenders: ['default'], context: 'http', level: 'error', @@ -164,8 +157,7 @@ test('correctly fills in custom `loggers` config.', () => { }); test('fails if loggers use unknown appenders.', () => { - const loggingConfigSchema = LoggingConfig.schema; - const validateConfig = loggingConfigSchema.validate({ + const validateConfig = config.schema.validate({ loggers: [ { appenders: ['unknown'], diff --git a/src/core/server/logging/logging_config.ts b/src/core/server/logging/logging_config.ts index de85bde3959df..84d707a3247e6 100644 --- a/src/core/server/logging/logging_config.ts +++ b/src/core/server/logging/logging_config.ts @@ -61,38 +61,34 @@ const createLoggerSchema = schema.object({ level: createLevelSchema, }); -const loggingSchema = schema.object({ - appenders: schema.mapOf(schema.string(), Appenders.configSchema, { - defaultValue: new Map(), - }), - loggers: schema.arrayOf(createLoggerSchema, { - defaultValue: [], - }), - root: schema.object({ - appenders: schema.arrayOf(schema.string(), { - defaultValue: [DEFAULT_APPENDER_NAME], - minSize: 1, - }), - level: createLevelSchema, - }), -}); - /** @internal */ export type LoggerConfigType = TypeOf; export const config = { path: 'logging', - schema: loggingSchema, + schema: schema.object({ + appenders: schema.mapOf(schema.string(), Appenders.configSchema, { + defaultValue: new Map(), + }), + loggers: schema.arrayOf(createLoggerSchema, { + defaultValue: [], + }), + root: schema.object({ + appenders: schema.arrayOf(schema.string(), { + defaultValue: [DEFAULT_APPENDER_NAME], + minSize: 1, + }), + level: createLevelSchema, + }), + }), }; -type LoggingConfigType = TypeOf; +export type LoggingConfigType = TypeOf; /** * Describes the config used to fully setup logging subsystem. * @internal */ export class LoggingConfig { - public static schema = loggingSchema; - /** * Helper method that joins separate string context parts into single context string. * In case joined context is an empty string, `root` context name is returned. diff --git a/src/core/server/logging/logging_service.test.ts b/src/core/server/logging/logging_service.test.ts index ee56b777b63b2..380488ff9f62d 100644 --- a/src/core/server/logging/logging_service.test.ts +++ b/src/core/server/logging/logging_service.test.ts @@ -29,7 +29,7 @@ let mockConsoleLog: jest.SpyInstance; import { createWriteStream } from 'fs'; const mockCreateWriteStream = (createWriteStream as unknown) as jest.Mock; -import { LoggingConfig, LoggingService } from '.'; +import { LoggingService, config } from '.'; let service: LoggingService; beforeEach(() => { @@ -68,12 +68,10 @@ test('flushes memory buffer logger and switches to real logger once config is pr // Switch to console appender with `info` level, so that `trace` message won't go through. service.upgrade( - new LoggingConfig( - LoggingConfig.schema.validate({ - appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, - root: { level: 'info' }, - }) - ) + config.schema.validate({ + appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, + root: { level: 'info' }, + }) ); expect(mockConsoleLog.mock.calls).toMatchSnapshot('buffered messages'); @@ -99,18 +97,16 @@ test('appends records via multiple appenders.', () => { expect(mockCreateWriteStream).not.toHaveBeenCalled(); service.upgrade( - new LoggingConfig( - LoggingConfig.schema.validate({ - appenders: { - default: { kind: 'console', layout: { kind: 'pattern' } }, - file: { kind: 'file', layout: { kind: 'pattern' }, path: 'path' }, - }, - loggers: [ - { appenders: ['file'], context: 'tests', level: 'warn' }, - { context: 'tests.child', level: 'error' }, - ], - }) - ) + config.schema.validate({ + appenders: { + default: { kind: 'console', layout: { kind: 'pattern' } }, + file: { kind: 'file', layout: { kind: 'pattern' }, path: 'path' }, + }, + loggers: [ + { appenders: ['file'], context: 'tests', level: 'warn' }, + { context: 'tests.child', level: 'error' }, + ], + }) ); // Now all logs should added to configured appenders. @@ -120,11 +116,9 @@ test('appends records via multiple appenders.', () => { test('uses `root` logger if context is not specified.', () => { service.upgrade( - new LoggingConfig( - LoggingConfig.schema.validate({ - appenders: { default: { kind: 'console', layout: { kind: 'pattern' } } }, - }) - ) + config.schema.validate({ + appenders: { default: { kind: 'console', layout: { kind: 'pattern' } } }, + }) ); const rootLogger = service.get(); @@ -135,12 +129,10 @@ test('uses `root` logger if context is not specified.', () => { test('`stop()` disposes all appenders.', async () => { service.upgrade( - new LoggingConfig( - LoggingConfig.schema.validate({ - appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, - root: { level: 'info' }, - }) - ) + config.schema.validate({ + appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, + root: { level: 'info' }, + }) ); const bufferDisposeSpy = jest.spyOn((service as any).bufferAppender, 'dispose'); @@ -156,12 +148,10 @@ test('asLoggerFactory() only allows to create new loggers.', () => { const logger = service.asLoggerFactory().get('test', 'context'); service.upgrade( - new LoggingConfig( - LoggingConfig.schema.validate({ - appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, - root: { level: 'all' }, - }) - ) + config.schema.validate({ + appenders: { default: { kind: 'console', layout: { kind: 'json' } } }, + root: { level: 'all' }, + }) ); logger.trace('buffered trace message'); diff --git a/src/core/server/logging/logging_service.ts b/src/core/server/logging/logging_service.ts index 7934ed4afe76e..e340e769ac20e 100644 --- a/src/core/server/logging/logging_service.ts +++ b/src/core/server/logging/logging_service.ts @@ -22,7 +22,7 @@ import { LogLevel } from './log_level'; import { BaseLogger, Logger } from './logger'; import { LoggerAdapter } from './logger_adapter'; import { LoggerFactory } from './logger_factory'; -import { LoggerConfigType, LoggingConfig } from './logging_config'; +import { LoggingConfigType, LoggerConfigType, LoggingConfig } from './logging_config'; /** * Service that is responsible for maintaining loggers and logger appenders. @@ -56,7 +56,8 @@ export class LoggingService implements LoggerFactory { * Updates all current active loggers with the new config values. * @param config New config instance. */ - public upgrade(config: LoggingConfig) { + public upgrade(rawConfig: LoggingConfigType) { + const config = new LoggingConfig(rawConfig); // Config update is asynchronous and may require some time to complete, so we should invalidate // config so that new loggers will be using BufferAppender until newly configured appenders are ready. this.config = undefined; From 9a6b7a0f49dde00e07a3bafe310dde781b7f73e0 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:49:41 +0200 Subject: [PATCH 2/8] get rid of ElasticsearchConfig class --- .../elasticsearch_config.test.ts | 60 +++++++------- .../elasticsearch/elasticsearch_config.ts | 78 +++++++++---------- .../elasticsearch_service.test.ts | 12 ++- .../elasticsearch/elasticsearch_service.ts | 72 ++++++++--------- 4 files changed, 110 insertions(+), 112 deletions(-) diff --git a/src/core/server/elasticsearch/elasticsearch_config.test.ts b/src/core/server/elasticsearch/elasticsearch_config.test.ts index b97370eafa040..1a6a8929cd6a0 100644 --- a/src/core/server/elasticsearch/elasticsearch_config.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_config.test.ts @@ -17,11 +17,11 @@ * under the License. */ -import { ElasticsearchConfig } from './elasticsearch_config'; +import { ElasticsearchConfig, config } from './elasticsearch_config'; test('set correct defaults', () => { - const config = new ElasticsearchConfig(ElasticsearchConfig.schema.validate({})); - expect(config).toMatchInlineSnapshot(` + const configValue = new ElasticsearchConfig(config.schema.validate({})); + expect(configValue).toMatchInlineSnapshot(` ElasticsearchConfig { "apiVersion": "master", "customHeaders": Object {}, @@ -51,58 +51,58 @@ ElasticsearchConfig { }); test('#hosts accepts both string and array of strings', () => { - let config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ hosts: 'http://some.host:1234' }) + let configValue = new ElasticsearchConfig( + config.schema.validate({ hosts: 'http://some.host:1234' }) ); - expect(config.hosts).toEqual(['http://some.host:1234']); + expect(configValue.hosts).toEqual(['http://some.host:1234']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ hosts: ['http://some.host:1234'] }) + configValue = new ElasticsearchConfig( + config.schema.validate({ hosts: ['http://some.host:1234'] }) ); - expect(config.hosts).toEqual(['http://some.host:1234']); + expect(configValue.hosts).toEqual(['http://some.host:1234']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ + configValue = new ElasticsearchConfig( + config.schema.validate({ hosts: ['http://some.host:1234', 'https://some.another.host'], }) ); - expect(config.hosts).toEqual(['http://some.host:1234', 'https://some.another.host']); + expect(configValue.hosts).toEqual(['http://some.host:1234', 'https://some.another.host']); }); test('#requestHeadersWhitelist accepts both string and array of strings', () => { - let config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ requestHeadersWhitelist: 'token' }) + let configValue = new ElasticsearchConfig( + config.schema.validate({ requestHeadersWhitelist: 'token' }) ); - expect(config.requestHeadersWhitelist).toEqual(['token']); + expect(configValue.requestHeadersWhitelist).toEqual(['token']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ requestHeadersWhitelist: ['token'] }) + configValue = new ElasticsearchConfig( + config.schema.validate({ requestHeadersWhitelist: ['token'] }) ); - expect(config.requestHeadersWhitelist).toEqual(['token']); + expect(configValue.requestHeadersWhitelist).toEqual(['token']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ + configValue = new ElasticsearchConfig( + config.schema.validate({ requestHeadersWhitelist: ['token', 'X-Forwarded-Proto'], }) ); - expect(config.requestHeadersWhitelist).toEqual(['token', 'X-Forwarded-Proto']); + expect(configValue.requestHeadersWhitelist).toEqual(['token', 'X-Forwarded-Proto']); }); test('#ssl.certificateAuthorities accepts both string and array of strings', () => { - let config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ ssl: { certificateAuthorities: 'some-path' } }) + let configValue = new ElasticsearchConfig( + config.schema.validate({ ssl: { certificateAuthorities: 'some-path' } }) ); - expect(config.ssl.certificateAuthorities).toEqual(['some-path']); + expect(configValue.ssl.certificateAuthorities).toEqual(['some-path']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ ssl: { certificateAuthorities: ['some-path'] } }) + configValue = new ElasticsearchConfig( + config.schema.validate({ ssl: { certificateAuthorities: ['some-path'] } }) ); - expect(config.ssl.certificateAuthorities).toEqual(['some-path']); + expect(configValue.ssl.certificateAuthorities).toEqual(['some-path']); - config = new ElasticsearchConfig( - ElasticsearchConfig.schema.validate({ + configValue = new ElasticsearchConfig( + config.schema.validate({ ssl: { certificateAuthorities: ['some-path', 'another-path'] }, }) ); - expect(config.ssl.certificateAuthorities).toEqual(['some-path', 'another-path']); + expect(configValue.ssl.certificateAuthorities).toEqual(['some-path', 'another-path']); }); diff --git a/src/core/server/elasticsearch/elasticsearch_config.ts b/src/core/server/elasticsearch/elasticsearch_config.ts index a2b3e03e2cbec..fb585a8d67262 100644 --- a/src/core/server/elasticsearch/elasticsearch_config.ts +++ b/src/core/server/elasticsearch/elasticsearch_config.ts @@ -24,53 +24,51 @@ const hostURISchema = schema.uri({ scheme: ['http', 'https'] }); export const DEFAULT_API_VERSION = 'master'; -const configSchema = schema.object({ - sniffOnStart: schema.boolean({ defaultValue: false }), - sniffInterval: schema.oneOf([schema.duration(), schema.literal(false)], { defaultValue: false }), - sniffOnConnectionFault: schema.boolean({ defaultValue: false }), - hosts: schema.oneOf([hostURISchema, schema.arrayOf(hostURISchema, { minSize: 1 })], { - defaultValue: 'http://localhost:9200', - }), - preserveHost: schema.boolean({ defaultValue: true }), - username: schema.maybe(schema.string()), - password: schema.maybe(schema.string()), - requestHeadersWhitelist: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], { - defaultValue: ['authorization'], - }), - customHeaders: schema.recordOf(schema.string(), schema.string(), { defaultValue: {} }), - shardTimeout: schema.duration({ defaultValue: '30s' }), - requestTimeout: schema.duration({ defaultValue: '30s' }), - pingTimeout: schema.duration({ defaultValue: schema.siblingRef('requestTimeout') }), - startupTimeout: schema.duration({ defaultValue: '5s' }), - logQueries: schema.boolean({ defaultValue: false }), - ssl: schema.object({ - verificationMode: schema.oneOf( - [schema.literal('none'), schema.literal('certificate'), schema.literal('full')], - { defaultValue: 'full' } - ), - certificateAuthorities: schema.maybe( - schema.oneOf([schema.string(), schema.arrayOf(schema.string(), { minSize: 1 })]) - ), - certificate: schema.maybe(schema.string()), - key: schema.maybe(schema.string()), - keyPassphrase: schema.maybe(schema.string()), - alwaysPresentCertificate: schema.boolean({ defaultValue: true }), - }), - apiVersion: schema.string({ defaultValue: DEFAULT_API_VERSION }), - healthCheck: schema.object({ delay: schema.duration({ defaultValue: 2500 }) }), -}); - -export type ElasticsearchConfigType = TypeOf; +export type ElasticsearchConfigType = TypeOf; type SslConfigSchema = ElasticsearchConfigType['ssl']; export const config = { path: 'elasticsearch', - schema: configSchema, + schema: schema.object({ + sniffOnStart: schema.boolean({ defaultValue: false }), + sniffInterval: schema.oneOf([schema.duration(), schema.literal(false)], { + defaultValue: false, + }), + sniffOnConnectionFault: schema.boolean({ defaultValue: false }), + hosts: schema.oneOf([hostURISchema, schema.arrayOf(hostURISchema, { minSize: 1 })], { + defaultValue: 'http://localhost:9200', + }), + preserveHost: schema.boolean({ defaultValue: true }), + username: schema.maybe(schema.string()), + password: schema.maybe(schema.string()), + requestHeadersWhitelist: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], { + defaultValue: ['authorization'], + }), + customHeaders: schema.recordOf(schema.string(), schema.string(), { defaultValue: {} }), + shardTimeout: schema.duration({ defaultValue: '30s' }), + requestTimeout: schema.duration({ defaultValue: '30s' }), + pingTimeout: schema.duration({ defaultValue: schema.siblingRef('requestTimeout') }), + startupTimeout: schema.duration({ defaultValue: '5s' }), + logQueries: schema.boolean({ defaultValue: false }), + ssl: schema.object({ + verificationMode: schema.oneOf( + [schema.literal('none'), schema.literal('certificate'), schema.literal('full')], + { defaultValue: 'full' } + ), + certificateAuthorities: schema.maybe( + schema.oneOf([schema.string(), schema.arrayOf(schema.string(), { minSize: 1 })]) + ), + certificate: schema.maybe(schema.string()), + key: schema.maybe(schema.string()), + keyPassphrase: schema.maybe(schema.string()), + alwaysPresentCertificate: schema.boolean({ defaultValue: true }), + }), + apiVersion: schema.string({ defaultValue: DEFAULT_API_VERSION }), + healthCheck: schema.object({ delay: schema.duration({ defaultValue: 2500 }) }), + }), }; export class ElasticsearchConfig { - public static schema = configSchema; - /** * The interval between health check requests Kibana sends to the Elasticsearch. */ diff --git a/src/core/server/elasticsearch/elasticsearch_service.test.ts b/src/core/server/elasticsearch/elasticsearch_service.test.ts index 41e72a11a7ee1..901ab78130480 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.test.ts @@ -33,13 +33,11 @@ import { ElasticsearchService } from './elasticsearch_service'; let elasticsearchService: ElasticsearchService; const configService = configServiceMock.create(); configService.atPath.mockReturnValue( - new BehaviorSubject( - new ElasticsearchConfig({ - hosts: ['http://1.2.3.4'], - healthCheck: {}, - ssl: {}, - } as any) - ) + new BehaviorSubject({ + hosts: ['http://1.2.3.4'], + healthCheck: {}, + ssl: {}, + } as any) ); let env: Env; diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index 4ede7d6af1453..b3faab892bd97 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -24,7 +24,7 @@ import { CoreContext } from '../core_context'; import { Logger } from '../logging'; import { ClusterClient } from './cluster_client'; import { ElasticsearchClientConfig } from './elasticsearch_client_config'; -import { ElasticsearchConfig } from './elasticsearch_config'; +import { ElasticsearchConfig, ElasticsearchConfigType } from './elasticsearch_config'; /** @internal */ interface CoreClusterClients { @@ -48,49 +48,51 @@ export interface ElasticsearchServiceSetup { /** @internal */ export class ElasticsearchService implements CoreService { private readonly log: Logger; + private readonly config$: Observable; private subscription?: Subscription; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('elasticsearch-service'); + this.config$ = coreContext.configService + .atPath('elasticsearch') + .pipe(map(rawConfig => new ElasticsearchConfig(rawConfig))); } public async setup(): Promise { this.log.debug('Setting up elasticsearch service'); - const clients$ = this.coreContext.configService - .atPath('elasticsearch', ElasticsearchConfig) - .pipe( - filter(() => { - if (this.subscription !== undefined) { - this.log.error('Clients cannot be changed after they are created'); - return false; - } - - return true; - }), - switchMap( - config => - new Observable(subscriber => { - this.log.debug(`Creating elasticsearch clients`); - - const coreClients = { - config, - adminClient: this.createClusterClient('admin', config), - dataClient: this.createClusterClient('data', config), - }; - - subscriber.next(coreClients); - - return () => { - this.log.debug(`Closing elasticsearch clients`); - - coreClients.adminClient.close(); - coreClients.dataClient.close(); - }; - }) - ), - publishReplay(1) - ) as ConnectableObservable; + const clients$ = this.config$.pipe( + filter(() => { + if (this.subscription !== undefined) { + this.log.error('Clients cannot be changed after they are created'); + return false; + } + + return true; + }), + switchMap( + config => + new Observable(subscriber => { + this.log.debug(`Creating elasticsearch clients`); + + const coreClients = { + config, + adminClient: this.createClusterClient('admin', config), + dataClient: this.createClusterClient('data', config), + }; + + subscriber.next(coreClients); + + return () => { + this.log.debug(`Closing elasticsearch clients`); + + coreClients.adminClient.close(); + coreClients.dataClient.close(); + }; + }) + ), + publishReplay(1) + ) as ConnectableObservable; this.subscription = clients$.connect(); From 3134c2275eab68779e7e5dedbee659abb31756db Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:50:32 +0200 Subject: [PATCH 3/8] get rid of PluginsConfig class --- .../discovery/plugins_discovery.test.ts | 12 ++++++---- src/core/server/plugins/plugin_context.ts | 19 ++++++--------- src/core/server/plugins/plugins_config.ts | 23 ++++++++----------- src/core/server/plugins/plugins_service.ts | 13 ++++++----- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/core/server/plugins/discovery/plugins_discovery.test.ts b/src/core/server/plugins/discovery/plugins_discovery.test.ts index 16fa4a18804d3..6e174e03cfcb1 100644 --- a/src/core/server/plugins/discovery/plugins_discovery.test.ts +++ b/src/core/server/plugins/discovery/plugins_discovery.test.ts @@ -26,7 +26,7 @@ import { Config, ConfigService, Env, ObjectToConfigAdapter } from '../../config' import { getEnvOptions } from '../../config/__mocks__/env'; import { loggingServiceMock } from '../../logging/logging_service.mock'; import { PluginWrapper } from '../plugin'; -import { PluginsConfig, config } from '../plugins_config'; +import { PluginsConfig, PluginsConfigType, config } from '../plugins_config'; import { discover } from './plugins_discovery'; const TEST_PLUGIN_SEARCH_PATHS = { @@ -123,11 +123,15 @@ test('properly iterates through plugin search locations', async () => { ); await configService.setSchema(config.path, config.schema); - const pluginsConfig = await configService - .atPath('plugins', PluginsConfig) + const rawConfig = await configService + .atPath('plugins') .pipe(first()) .toPromise(); - const { plugin$, error$ } = discover(pluginsConfig, { configService, env, logger }); + const { plugin$, error$ } = discover(new PluginsConfig(rawConfig, env), { + configService, + env, + logger, + }); const plugins = await plugin$.pipe(toArray()).toPromise(); expect(plugins).toHaveLength(4); diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index f216ae6d6fb5e..1c1fe03161e62 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -17,9 +17,8 @@ * under the License. */ -import { Type } from '@kbn/config-schema'; import { Observable } from 'rxjs'; -import { ConfigWithSchema, EnvironmentMode } from '../config'; +import { EnvironmentMode } from '../config'; import { CoreContext } from '../core_context'; import { ClusterClient } from '../elasticsearch'; import { HttpServiceSetup } from '../http'; @@ -36,12 +35,8 @@ export interface PluginInitializerContext { env: { mode: EnvironmentMode }; logger: LoggerFactory; config: { - create: , Config>( - ConfigClass: ConfigWithSchema - ) => Observable; - createIfExists: , Config>( - ConfigClass: ConfigWithSchema - ) => Observable; + create: () => Observable; + createIfExists: () => Observable; }; } @@ -113,11 +108,11 @@ export function createPluginInitializerContext( * @param ConfigClass A class (not an instance of a class) that contains a * static `schema` that we validate the config at the given `path` against. */ - create(ConfigClass) { - return coreContext.configService.atPath(pluginManifest.configPath, ConfigClass); + create() { + return coreContext.configService.atPath(pluginManifest.configPath); }, - createIfExists(ConfigClass) { - return coreContext.configService.optionalAtPath(pluginManifest.configPath, ConfigClass); + createIfExists() { + return coreContext.configService.optionalAtPath(pluginManifest.configPath); }, }, }; diff --git a/src/core/server/plugins/plugins_config.ts b/src/core/server/plugins/plugins_config.ts index d2c258faab308..3075c5a393f63 100644 --- a/src/core/server/plugins/plugins_config.ts +++ b/src/core/server/plugins/plugins_config.ts @@ -20,26 +20,23 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { Env } from '../config'; -const pluginsSchema = schema.object({ - initialize: schema.boolean({ defaultValue: true }), +export type PluginsConfigType = TypeOf; - /** - * Defines an array of directories where another plugin should be loaded from. - * Should only be used in a development environment. - */ - paths: schema.arrayOf(schema.string(), { defaultValue: [] }), -}); - -export type PluginsConfigType = TypeOf; export const config = { path: 'plugins', - schema: pluginsSchema, + schema: schema.object({ + initialize: schema.boolean({ defaultValue: true }), + + /** + * Defines an array of directories where another plugin should be loaded from. + * Should only be used in a development environment. + */ + paths: schema.arrayOf(schema.string(), { defaultValue: [] }), + }), }; /** @internal */ export class PluginsConfig { - public static schema = pluginsSchema; - /** * Indicates whether or not plugins should be initialized. */ diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index e26f0f5d22c10..95d3f26fff91e 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -18,7 +18,7 @@ */ import { Observable } from 'rxjs'; -import { filter, first, mergeMap, tap, toArray } from 'rxjs/operators'; +import { filter, first, map, mergeMap, tap, toArray } from 'rxjs/operators'; import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; import { ElasticsearchServiceSetup } from '../elasticsearch/elasticsearch_service'; @@ -26,7 +26,7 @@ import { HttpServiceSetup } from '../http/http_service'; import { Logger } from '../logging'; import { discover, PluginDiscoveryError, PluginDiscoveryErrorType } from './discovery'; import { DiscoveredPlugin, DiscoveredPluginInternal, PluginWrapper, PluginName } from './plugin'; -import { PluginsConfig } from './plugins_config'; +import { PluginsConfig, PluginsConfigType } from './plugins_config'; import { PluginsSystem } from './plugins_system'; /** @public */ @@ -56,19 +56,20 @@ export interface PluginsServiceStartDeps {} // eslint-disable-line @typescript-e export class PluginsService implements CoreService { private readonly log: Logger; private readonly pluginsSystem: PluginsSystem; + private readonly config$: Observable; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('plugins-service'); this.pluginsSystem = new PluginsSystem(coreContext); + this.config$ = coreContext.configService + .atPath('plugins') + .pipe(map(rawConfig => new PluginsConfig(rawConfig, coreContext.env))); } public async setup(deps: PluginsServiceSetupDeps) { this.log.debug('Setting up plugins service'); - const config = await this.coreContext.configService - .atPath('plugins', PluginsConfig) - .pipe(first()) - .toPromise(); + const config = await this.config$.pipe(first()).toPromise(); const { error$, plugin$ } = discover(config, this.coreContext); await this.handleDiscoveryErrors(error$); From d481a046aec61db7ccc812eb81b71da77473a279 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:50:53 +0200 Subject: [PATCH 4/8] get rid of HttpConfig Class --- src/core/server/http/http_config.test.ts | 45 ++++----- src/core/server/http/http_config.ts | 122 +++++++++++------------ src/core/server/http/http_service.ts | 8 +- src/core/server/http/ssl_config.ts | 7 +- 4 files changed, 84 insertions(+), 98 deletions(-) diff --git a/src/core/server/http/http_config.test.ts b/src/core/server/http/http_config.test.ts index 54d28ef921fcf..35f3db9fb97c6 100644 --- a/src/core/server/http/http_config.test.ts +++ b/src/core/server/http/http_config.test.ts @@ -17,25 +17,25 @@ * under the License. */ -import { HttpConfig } from '.'; +import { config } from '.'; test('has defaults for config', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = {}; expect(httpSchema.validate(obj)).toMatchSnapshot(); }); test('accepts valid hostnames', () => { - const { host: host1 } = HttpConfig.schema.validate({ host: 'www.example.com' }); - const { host: host2 } = HttpConfig.schema.validate({ host: '8.8.8.8' }); - const { host: host3 } = HttpConfig.schema.validate({ host: '::1' }); - const { host: host4 } = HttpConfig.schema.validate({ host: 'localhost' }); + const { host: host1 } = config.schema.validate({ host: 'www.example.com' }); + const { host: host2 } = config.schema.validate({ host: '8.8.8.8' }); + const { host: host3 } = config.schema.validate({ host: '::1' }); + const { host: host4 } = config.schema.validate({ host: 'localhost' }); expect({ host1, host2, host3, host4 }).toMatchSnapshot('valid host names'); }); test('throws if invalid hostname', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { host: 'asdf$%^', }; @@ -43,16 +43,15 @@ test('throws if invalid hostname', () => { }); test('can specify max payload as string', () => { - const httpSchema = HttpConfig.schema; const obj = { maxPayload: '2mb', }; - const config = httpSchema.validate(obj); - expect(config.maxPayload.getValueInBytes()).toBe(2 * 1024 * 1024); + const configValue = config.schema.validate(obj); + expect(configValue.maxPayload.getValueInBytes()).toBe(2 * 1024 * 1024); }); test('throws if basepath is missing prepended slash', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { basePath: 'foo', }; @@ -60,7 +59,7 @@ test('throws if basepath is missing prepended slash', () => { }); test('throws if basepath appends a slash', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { basePath: '/foo/', }; @@ -68,7 +67,7 @@ test('throws if basepath appends a slash', () => { }); test('throws if basepath is not specified, but rewriteBasePath is set', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { rewriteBasePath: true, }; @@ -77,7 +76,7 @@ test('throws if basepath is not specified, but rewriteBasePath is set', () => { describe('with TLS', () => { test('throws if TLS is enabled but `key` is not specified', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { ssl: { certificate: '/path/to/certificate', @@ -88,7 +87,7 @@ describe('with TLS', () => { }); test('throws if TLS is enabled but `certificate` is not specified', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { ssl: { enabled: true, @@ -99,7 +98,7 @@ describe('with TLS', () => { }); test('throws if TLS is enabled but `redirectHttpFromPort` is equal to `port`', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const obj = { port: 1234, ssl: { @@ -113,7 +112,6 @@ describe('with TLS', () => { }); test('can specify single `certificateAuthority` as a string', () => { - const httpSchema = HttpConfig.schema; const obj = { ssl: { certificate: '/path/to/certificate', @@ -123,12 +121,11 @@ describe('with TLS', () => { }, }; - const config = httpSchema.validate(obj); - expect(config.ssl.certificateAuthorities).toBe('/authority/'); + const configValue = config.schema.validate(obj); + expect(configValue.ssl.certificateAuthorities).toBe('/authority/'); }); test('can specify several `certificateAuthorities`', () => { - const httpSchema = HttpConfig.schema; const obj = { ssl: { certificate: '/path/to/certificate', @@ -138,12 +135,12 @@ describe('with TLS', () => { }, }; - const config = httpSchema.validate(obj); - expect(config.ssl.certificateAuthorities).toEqual(['/authority/1', '/authority/2']); + const configValue = config.schema.validate(obj); + expect(configValue.ssl.certificateAuthorities).toEqual(['/authority/1', '/authority/2']); }); test('accepts known protocols`', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const singleKnownProtocol = { ssl: { certificate: '/path/to/certificate', @@ -170,7 +167,7 @@ describe('with TLS', () => { }); test('should accept known protocols`', () => { - const httpSchema = HttpConfig.schema; + const httpSchema = config.schema; const singleUnknownProtocol = { ssl: { diff --git a/src/core/server/http/http_config.ts b/src/core/server/http/http_config.ts index 1848070b2a56f..4d2279e90abed 100644 --- a/src/core/server/http/http_config.ts +++ b/src/core/server/http/http_config.ts @@ -19,83 +19,75 @@ import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema'; import { Env } from '../config'; -import { SslConfig } from './ssl_config'; +import { SslConfig, sslSchema } from './ssl_config'; const validBasePathRegex = /(^$|^\/.*[^\/]$)/; const match = (regex: RegExp, errorMsg: string) => (str: string) => regex.test(str) ? undefined : errorMsg; -const createHttpSchema = schema.object( - { - autoListen: schema.boolean({ defaultValue: true }), - basePath: schema.maybe( - schema.string({ - validate: match(validBasePathRegex, "must start with a slash, don't end with one"), - }) - ), - cors: schema.conditional( - schema.contextRef('dev'), - true, - schema.object( - { - origin: schema.arrayOf(schema.string()), - }, - { - defaultValue: { - origin: ['*://localhost:9876'], // karma test server +export const config = { + path: 'server', + schema: schema.object( + { + autoListen: schema.boolean({ defaultValue: true }), + basePath: schema.maybe( + schema.string({ + validate: match(validBasePathRegex, "must start with a slash, don't end with one"), + }) + ), + cors: schema.conditional( + schema.contextRef('dev'), + true, + schema.object( + { + origin: schema.arrayOf(schema.string()), }, - } + { + defaultValue: { + origin: ['*://localhost:9876'], // karma test server + }, + } + ), + schema.boolean({ defaultValue: false }) ), - schema.boolean({ defaultValue: false }) - ), - host: schema.string({ - defaultValue: 'localhost', - hostname: true, - }), - maxPayload: schema.byteSize({ - defaultValue: '1048576b', - }), - port: schema.number({ - defaultValue: 5601, - }), - rewriteBasePath: schema.boolean({ defaultValue: false }), - ssl: SslConfig.schema, - }, - { - validate: config => { - if (!config.basePath && config.rewriteBasePath) { - return 'cannot use [rewriteBasePath] when [basePath] is not specified'; - } - - if ( - config.ssl.enabled && - config.ssl.redirectHttpFromPort !== undefined && - config.ssl.redirectHttpFromPort === config.port - ) { - return ( - 'Kibana does not accept http traffic to [port] when ssl is ' + - 'enabled (only https is allowed), so [ssl.redirectHttpFromPort] ' + - `cannot be configured to the same value. Both are [${config.port}].` - ); - } + host: schema.string({ + defaultValue: 'localhost', + hostname: true, + }), + maxPayload: schema.byteSize({ + defaultValue: '1048576b', + }), + port: schema.number({ + defaultValue: 5601, + }), + rewriteBasePath: schema.boolean({ defaultValue: false }), + ssl: sslSchema, }, - } -); - -export type HttpConfigType = TypeOf; + { + validate: rawConfig => { + if (!rawConfig.basePath && rawConfig.rewriteBasePath) { + return 'cannot use [rewriteBasePath] when [basePath] is not specified'; + } -export const config = { - path: 'server', - schema: createHttpSchema, + if ( + rawConfig.ssl.enabled && + rawConfig.ssl.redirectHttpFromPort !== undefined && + rawConfig.ssl.redirectHttpFromPort === rawConfig.port + ) { + return ( + 'Kibana does not accept http traffic to [port] when ssl is ' + + 'enabled (only https is allowed), so [ssl.redirectHttpFromPort] ' + + `cannot be configured to the same value. Both are [${rawConfig.port}].` + ); + } + }, + } + ), }; +export type HttpConfigType = TypeOf; export class HttpConfig { - /** - * @internal - */ - public static schema = createHttpSchema; - public autoListen: boolean; public host: string; public port: number; @@ -118,6 +110,6 @@ export class HttpConfig { this.basePath = rawConfig.basePath; this.rewriteBasePath = rawConfig.rewriteBasePath; this.publicDir = env.staticFilesDir; - this.ssl = new SslConfig(rawConfig.ssl); + this.ssl = new SslConfig(rawConfig.ssl || {}); } } diff --git a/src/core/server/http/http_service.ts b/src/core/server/http/http_service.ts index ea172b881f546..3a9fcb7be54e7 100644 --- a/src/core/server/http/http_service.ts +++ b/src/core/server/http/http_service.ts @@ -18,12 +18,12 @@ */ import { Observable, Subscription } from 'rxjs'; -import { first } from 'rxjs/operators'; +import { first, map } from 'rxjs/operators'; import { CoreService } from '../../types'; import { Logger } from '../logging'; import { CoreContext } from '../core_context'; -import { HttpConfig } from './http_config'; +import { HttpConfig, HttpConfigType } from './http_config'; import { HttpServer, HttpServerSetup } from './http_server'; import { HttpsRedirectServer } from './https_redirect_server'; @@ -46,7 +46,9 @@ export class HttpService implements CoreService('server') + .pipe(map(rawConfig => new HttpConfig(rawConfig, coreContext.env))); this.httpServer = new HttpServer(coreContext.logger.get('http', 'server')); this.httpsRedirectServer = new HttpsRedirectServer( diff --git a/src/core/server/http/ssl_config.ts b/src/core/server/http/ssl_config.ts index 7db0a95ca7760..bab3e1d12615c 100644 --- a/src/core/server/http/ssl_config.ts +++ b/src/core/server/http/ssl_config.ts @@ -30,7 +30,7 @@ const protocolMap = new Map([ ['TLSv1.2', cryptoConstants.SSL_OP_NO_TLSv1_2], ]); -const sslSchema = schema.object( +export const sslSchema = schema.object( { certificate: schema.maybe(schema.string()), certificateAuthorities: schema.maybe( @@ -62,11 +62,6 @@ const sslSchema = schema.object( type SslConfigType = TypeOf; export class SslConfig { - /** - * @internal - */ - public static schema = sslSchema; - public enabled: boolean; public redirectHttpFromPort: number | undefined; public key: string | undefined; From 9c75d625140f8b47dfc649c74fcce7858b34b5c2 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:51:39 +0200 Subject: [PATCH 5/8] update ConfigService --- .../__snapshots__/config_service.test.ts.snap | 16 ++-- src/core/server/config/config_service.test.ts | 74 +++++++------------ src/core/server/config/config_service.ts | 26 ++----- src/core/server/config/config_with_schema.ts | 47 ------------ src/core/server/config/index.ts | 1 - src/core/server/dev/dev_config.ts | 20 ++--- 6 files changed, 45 insertions(+), 139 deletions(-) delete mode 100644 src/core/server/config/config_with_schema.ts diff --git a/src/core/server/config/__snapshots__/config_service.test.ts.snap b/src/core/server/config/__snapshots__/config_service.test.ts.snap index 9327b80dc79a0..1f5c442e1ae2f 100644 --- a/src/core/server/config/__snapshots__/config_service.test.ts.snap +++ b/src/core/server/config/__snapshots__/config_service.test.ts.snap @@ -1,14 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`correctly passes context 1`] = ` -ExampleClassWithSchema { - "value": Object { - "branchRef": "feature-v1", - "buildNumRef": 100, - "buildShaRef": "feature-v1-build-sha", - "devRef": true, - "prodRef": false, - "versionRef": "v1", - }, +Object { + "branchRef": "feature-v1", + "buildNumRef": 100, + "buildShaRef": "feature-v1-build-sha", + "devRef": true, + "prodRef": false, + "versionRef": "v1", } `; diff --git a/src/core/server/config/config_service.test.ts b/src/core/server/config/config_service.test.ts index 27c9473c16324..61da9af7baa7c 100644 --- a/src/core/server/config/config_service.test.ts +++ b/src/core/server/config/config_service.test.ts @@ -19,12 +19,12 @@ /* eslint-disable max-classes-per-file */ -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { first } from 'rxjs/operators'; import { mockPackage } from './config_service.test.mocks'; -import { schema, Type, TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; import { ConfigService, Env, ObjectToConfigAdapter } from '.'; import { loggingServiceMock } from '../logging/logging_service.mock'; @@ -34,21 +34,17 @@ const emptyArgv = getEnvOptions(); const defaultEnv = new Env('/kibana', emptyArgv); const logger = loggingServiceMock.create(); -class ExampleClassWithStringSchema { - public static schema = schema.string(); - - constructor(readonly value: string) {} -} - test('returns config at path as observable', async () => { const config$ = new BehaviorSubject(new ObjectToConfigAdapter({ key: 'foo' })); const configService = new ConfigService(config$, defaultEnv, logger); - await configService.setSchema('key', schema.string()); + const stringSchema = schema.string(); + await configService.setSchema('key', stringSchema); - const configs = configService.atPath('key', ExampleClassWithStringSchema); - const exampleConfig = await configs.pipe(first()).toPromise(); + const value$ = configService.atPath('key'); + expect(value$).toBeInstanceOf(Observable); - expect(exampleConfig.value).toBe('foo'); + const value = await value$.pipe(first()).toPromise(); + expect(value).toBe('foo'); }); test('throws if config at path does not match schema', async () => { @@ -70,9 +66,9 @@ test('re-validate config when updated', async () => { configService.setSchema('key', schema.string()); const valuesReceived: any[] = []; - await configService.atPath('key', ExampleClassWithStringSchema).subscribe( - config => { - valuesReceived.push(config.value); + await configService.atPath('key').subscribe( + value => { + valuesReceived.push(value); }, error => { valuesReceived.push(error); @@ -93,10 +89,10 @@ test("returns undefined if fetching optional config at a path that doesn't exist const config$ = new BehaviorSubject(new ObjectToConfigAdapter({})); const configService = new ConfigService(config$, defaultEnv, logger); - const configs = configService.optionalAtPath('unique-name', ExampleClassWithStringSchema); - const exampleConfig = await configs.pipe(first()).toPromise(); + const value$ = configService.optionalAtPath('unique-name'); + const value = await value$.pipe(first()).toPromise(); - expect(exampleConfig).toBeUndefined(); + expect(value).toBeUndefined(); }); test('returns observable config at optional path if it exists', async () => { @@ -104,11 +100,10 @@ test('returns observable config at optional path if it exists', async () => { const configService = new ConfigService(config$, defaultEnv, logger); await configService.setSchema('value', schema.string()); - const configs = configService.optionalAtPath('value', ExampleClassWithStringSchema); - const exampleConfig: any = await configs.pipe(first()).toPromise(); + const value$ = configService.optionalAtPath('value'); + const value: any = await value$.pipe(first()).toPromise(); - expect(exampleConfig).toBeDefined(); - expect(exampleConfig.value).toBe('bar'); + expect(value).toBe('bar'); }); test("does not push new configs when reloading if config at path hasn't changed", async () => { @@ -117,8 +112,8 @@ test("does not push new configs when reloading if config at path hasn't changed" await configService.setSchema('key', schema.string()); const valuesReceived: any[] = []; - configService.atPath('key', ExampleClassWithStringSchema).subscribe(config => { - valuesReceived.push(config.value); + configService.atPath('key').subscribe(value => { + valuesReceived.push(value); }); config$.next(new ObjectToConfigAdapter({ key: 'value' })); @@ -132,8 +127,8 @@ test('pushes new config when reloading and config at path has changed', async () await configService.setSchema('key', schema.string()); const valuesReceived: any[] = []; - configService.atPath('key', ExampleClassWithStringSchema).subscribe(config => { - valuesReceived.push(config.value); + configService.atPath('key').subscribe(value => { + valuesReceived.push(value); }); config$.next(new ObjectToConfigAdapter({ key: 'new value' })); @@ -142,12 +137,10 @@ test('pushes new config when reloading and config at path has changed', async () }); test("throws error if 'schema' is not defined for a key", async () => { - class ExampleClass {} - const config$ = new BehaviorSubject(new ObjectToConfigAdapter({ key: 'value' })); const configService = new ConfigService(config$, defaultEnv, logger); - const configs = configService.atPath('key', ExampleClass as any); + const configs = configService.atPath('key'); await expect(configs.pipe(first()).toPromise()).rejects.toMatchInlineSnapshot( `[Error: No validation schema has been defined for key]` @@ -188,15 +181,8 @@ test('tracks unhandled paths', async () => { const config$ = new BehaviorSubject(new ObjectToConfigAdapter(initialConfig)); const configService = new ConfigService(config$, defaultEnv, logger); - configService.atPath('foo', createClassWithSchema(schema.string())); - configService.atPath( - ['bar', 'deep2'], - createClassWithSchema( - schema.object({ - key: schema.string(), - }) - ) - ); + configService.atPath('foo'); + configService.atPath(['bar', 'deep2']); const unused = await configService.getUnusedPaths(); @@ -235,9 +221,9 @@ test('correctly passes context', async () => { }); const configService = new ConfigService(config$, env, logger); await configService.setSchema('foo', schemaDefinition); - const configs = configService.atPath('foo', createClassWithSchema(schemaDefinition)); + const value$ = configService.atPath('foo'); - expect(await configs.pipe(first()).toPromise()).toMatchSnapshot(); + expect(await value$.pipe(first()).toPromise()).toMatchSnapshot(); }); test('handles enabled path, but only marks the enabled path as used', async () => { @@ -306,11 +292,3 @@ test('treats config as enabled if config path is not present in config', async ( const unusedPaths = await configService.getUnusedPaths(); expect(unusedPaths).toEqual([]); }); - -function createClassWithSchema(s: Type) { - return class ExampleClassWithSchema { - public static schema = s; - - constructor(readonly value: TypeOf) {} - }; -} diff --git a/src/core/server/config/config_service.ts b/src/core/server/config/config_service.ts index dd3be624ebf51..4053a7d8ea8fb 100644 --- a/src/core/server/config/config_service.ts +++ b/src/core/server/config/config_service.ts @@ -22,7 +22,7 @@ import { isEqual } from 'lodash'; import { Observable } from 'rxjs'; import { distinctUntilChanged, first, map } from 'rxjs/operators'; -import { Config, ConfigPath, ConfigWithSchema, Env } from '.'; +import { Config, ConfigPath, Env } from '.'; import { Logger, LoggerFactory } from '../logging'; /** @internal */ @@ -73,14 +73,9 @@ export class ConfigService { * against the static `schema` on the given `ConfigClass`. * * @param path - The path to the desired subset of the config. - * @param ConfigClass - A class (not an instance of a class) that contains a - * static `schema` that we validate the config at the given `path` against. */ - public atPath, TConfig>( - path: ConfigPath, - ConfigClass: ConfigWithSchema - ) { - return this.validateConfig(path).pipe(map(config => this.createConfig(config, ConfigClass))); + public atPath(path: ConfigPath) { + return this.validateConfig(path) as Observable; } /** @@ -89,15 +84,11 @@ export class ConfigService { * * {@link ConfigService.atPath} */ - public optionalAtPath, TConfig>( - path: ConfigPath, - ConfigClass: ConfigWithSchema - ) { + public optionalAtPath(path: ConfigPath) { return this.getDistinctConfig(path).pipe( map(config => { if (config === undefined) return undefined; - const validatedConfig = this.validate(path, config); - return this.createConfig(validatedConfig, ConfigClass); + return this.validate(path, config) as TSchema; }) ); } @@ -156,13 +147,6 @@ export class ConfigService { ); } - private createConfig, TConfig>( - validatedConfig: unknown, - ConfigClass: ConfigWithSchema - ) { - return new ConfigClass(validatedConfig, this.env); - } - private validateConfig(path: ConfigPath) { return this.getDistinctConfig(path).pipe(map(config => this.validate(path, config))); } diff --git a/src/core/server/config/config_with_schema.ts b/src/core/server/config/config_with_schema.ts deleted file mode 100644 index 1c392b93b6a75..0000000000000 --- a/src/core/server/config/config_with_schema.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you 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. - */ - -// TODO inline all of these -import { Type, TypeOf } from '@kbn/config-schema'; -import { Env } from './env'; - -/** - * Interface that defines the static side of a config class. - * - * (Remember that a class has two types: the type of the static side and the - * type of the instance side, see https://www.typescriptlang.org/docs/handbook/interfaces.html#difference-between-the-static-and-instance-sides-of-classes) - * - * This can't be used to define the config class because of how interfaces work - * in TypeScript, but it can be used to ensure we have a config class that - * matches whenever it's used. - */ -export interface ConfigWithSchema, Config> { - /** - * Any config class must define a schema that validates the config, based on - * the injected `schema` helper. - */ - schema: S; - - /** - * @param validatedConfig The result of validating the static `schema` above. - * @param env An instance of the `Env` class that defines environment specific - * variables. - */ - new (validatedConfig: TypeOf, env: Env): Config; -} diff --git a/src/core/server/config/index.ts b/src/core/server/config/index.ts index 3c7bce831cdf9..4f8f44b5cc7f6 100644 --- a/src/core/server/config/index.ts +++ b/src/core/server/config/index.ts @@ -24,4 +24,3 @@ export { ObjectToConfigAdapter } from './object_to_config_adapter'; export { CliArgs } from './env'; export { Env, EnvironmentMode, PackageInfo } from './env'; -export { ConfigWithSchema } from './config_with_schema'; diff --git a/src/core/server/dev/dev_config.ts b/src/core/server/dev/dev_config.ts index 6c99025da3fc0..1fb84e2e6625d 100644 --- a/src/core/server/dev/dev_config.ts +++ b/src/core/server/dev/dev_config.ts @@ -19,24 +19,18 @@ import { schema, TypeOf } from '@kbn/config-schema'; -const createDevSchema = schema.object({ - basePathProxyTarget: schema.number({ - defaultValue: 5603, - }), -}); - export const config = { path: 'dev', - schema: createDevSchema, + schema: schema.object({ + basePathProxyTarget: schema.number({ + defaultValue: 5603, + }), + }), }; -export type DevConfigType = TypeOf; -export class DevConfig { - /** - * @internal - */ - public static schema = createDevSchema; +export type DevConfigType = TypeOf; +export class DevConfig { public basePathProxyTargetPort: number; /** From bf963c704d56b22c92eb85a5672f2a98a41fde8d Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:52:10 +0200 Subject: [PATCH 6/8] update LegacyService --- src/core/server/dev/index.ts | 2 +- .../__snapshots__/legacy_service.test.ts.snap | 76 +++++-------------- src/core/server/legacy/legacy_service.test.ts | 28 +++++-- src/core/server/legacy/legacy_service.ts | 24 +++--- src/core/server/root/index.ts | 4 +- 5 files changed, 56 insertions(+), 78 deletions(-) diff --git a/src/core/server/dev/index.ts b/src/core/server/dev/index.ts index cccd6b1c5d07f..d55ae05b239fc 100644 --- a/src/core/server/dev/index.ts +++ b/src/core/server/dev/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { DevConfig, config } from './dev_config'; +export { config, DevConfig, DevConfigType } from './dev_config'; diff --git a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap index 82192eda44a80..bc7e8f72c4d61 100644 --- a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap +++ b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap @@ -1,62 +1,24 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`once LegacyService is set up in \`devClusterMaster\` mode creates ClusterManager with base path proxy.: cluster manager with base path proxy 1`] = ` -Array [ - Array [ - Object { - "basePath": true, - "dev": true, - "open": false, - "optimize": false, - "quiet": true, - "repl": false, - "silent": false, - "watch": false, - }, - Object { - "server": Object { - "autoListen": true, - }, - }, - BasePathProxyServer { - "devConfig": Object { - "basePathProxyTargetPort": 100500, - }, - "httpConfig": Object { - "basePath": "/abc", - "maxPayload": ByteSizeValue { - "valueInBytes": 1073741824, - }, - }, - "httpsAgent": undefined, - "log": Object { - "context": Array [ - "server", - ], - "debug": [MockFunction] { - "calls": Array [ - Array [ - "starting legacy service", - ], - ], - "results": Array [ - Object { - "type": "return", - "value": undefined, - }, - ], - }, - "error": [MockFunction], - "fatal": [MockFunction], - "info": [MockFunction], - "log": [MockFunction], - "trace": [MockFunction], - "warn": [MockFunction], - }, - "server": undefined, - }, - ], -] +exports[`once LegacyService is set up in \`devClusterMaster\` mode creates ClusterManager with base path proxy.: cli args. cluster manager with base path proxy 1`] = ` +Object { + "basePath": true, + "dev": true, + "open": false, + "optimize": false, + "quiet": true, + "repl": false, + "silent": false, + "watch": false, +} +`; + +exports[`once LegacyService is set up in \`devClusterMaster\` mode creates ClusterManager with base path proxy.: config. cluster manager with base path proxy 1`] = ` +Object { + "server": Object { + "autoListen": true, + }, +} `; exports[`once LegacyService is set up in \`devClusterMaster\` mode creates ClusterManager without base path proxy.: cluster manager without base path proxy 1`] = ` diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index a63e4a44a3910..a259d546488df 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -32,7 +32,7 @@ import { Config, Env, ObjectToConfigAdapter } from '../config'; import { getEnvOptions } from '../config/__mocks__/env'; import { configServiceMock } from '../config/config_service.mock'; import { ElasticsearchServiceSetup } from '../elasticsearch'; -import { HttpServiceStart } from '../http'; +import { HttpServiceStart, BasePathProxyServer } from '../http'; import { loggingServiceMock } from '../logging/logging_service.mock'; import { DiscoveredPlugin, DiscoveredPluginInternal } from '../plugins'; import { PluginsServiceSetup, PluginsServiceStart } from '../plugins/plugins_service'; @@ -41,7 +41,6 @@ import { LegacyPlatformProxy } from './legacy_platform_proxy'; const MockKbnServer: jest.Mock = KbnServer as any; const MockLegacyPlatformProxy: jest.Mock = LegacyPlatformProxy as any; -let legacyService: LegacyService; let env: Env; let config$: BehaviorSubject; let setupDeps: { @@ -97,8 +96,6 @@ beforeEach(() => { configService.getConfig$.mockReturnValue(config$); configService.getUsedPaths.mockResolvedValue(['foo.bar']); - - legacyService = new LegacyService({ env, logger, configService: configService as any }); }); afterEach(() => { @@ -107,6 +104,7 @@ afterEach(() => { describe('once LegacyService is set up with connection info', () => { test('register proxy route.', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -115,6 +113,7 @@ describe('once LegacyService is set up with connection info', () => { test('proxy route responds with `503` if `kbnServer` is not ready yet.', async () => { configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true })); + const legacyService = new LegacyService({ env, logger, configService: configService as any }); const kbnServerListen$ = new Subject(); MockKbnServer.prototype.listen = jest.fn(() => { @@ -172,6 +171,7 @@ describe('once LegacyService is set up with connection info', () => { test('creates legacy kbnServer and calls `listen`.', async () => { configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true })); + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -200,6 +200,7 @@ describe('once LegacyService is set up with connection info', () => { test('creates legacy kbnServer but does not call `listen` if `autoListen: false`.', async () => { configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: false })); + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -228,6 +229,7 @@ describe('once LegacyService is set up with connection info', () => { test('creates legacy kbnServer and closes it if `listen` fails.', async () => { configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true })); MockKbnServer.prototype.listen.mockRejectedValue(new Error('something failed')); + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingSnapshot(); @@ -239,6 +241,7 @@ describe('once LegacyService is set up with connection info', () => { test('throws if fails to retrieve initial config.', async () => { configService.getConfig$.mockReturnValue(throwError(new Error('something failed'))); + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingSnapshot(); @@ -248,6 +251,7 @@ describe('once LegacyService is set up with connection info', () => { }); test('reconfigures logging configuration if new config is received.', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -262,6 +266,7 @@ describe('once LegacyService is set up with connection info', () => { }); test('logs error if re-configuring fails.', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -280,6 +285,7 @@ describe('once LegacyService is set up with connection info', () => { }); test('logs error if config service fails.', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -295,6 +301,7 @@ describe('once LegacyService is set up with connection info', () => { }); test('proxy route abandons request processing and forwards it to the legacy Kibana', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); const mockResponseToolkit = { response: jest.fn(), abandon: Symbol('abandon') }; const mockRequest = { raw: { req: { a: 1 }, res: { b: 2 } } }; @@ -327,7 +334,10 @@ describe('once LegacyService is set up without connection info', () => { contracts: new Map(), }, }; + let legacyService: LegacyService; beforeEach(async () => { + legacyService = new LegacyService({ env, logger, configService: configService as any }); + await legacyService.setup(setupDeps); await legacyService.start(disabledHttpStartDeps); }); @@ -425,13 +435,17 @@ describe('once LegacyService is set up in `devClusterMaster` mode', () => { }, }); - expect(MockClusterManager.create.mock.calls).toMatchSnapshot( - 'cluster manager with base path proxy' - ); + expect(MockClusterManager.create).toBeCalledTimes(1); + + const [[cliArgs, config, basePathProxy]] = MockClusterManager.create.mock.calls; + expect(cliArgs).toMatchSnapshot('cli args. cluster manager with base path proxy'); + expect(config).toMatchSnapshot('config. cluster manager with base path proxy'); + expect(basePathProxy).toBeInstanceOf(BasePathProxyServer); }); }); test('Cannot start without setup phase', async () => { + const legacyService = new LegacyService({ env, logger, configService: configService as any }); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot( `"Legacy service is not setup yet."` ); diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index 8ca561569ee5e..1eeaeaf0701d9 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -18,14 +18,14 @@ */ import { Server as HapiServer } from 'hapi'; -import { combineLatest, ConnectableObservable, EMPTY, Subscription } from 'rxjs'; +import { combineLatest, ConnectableObservable, EMPTY, Observable, Subscription } from 'rxjs'; import { first, map, mergeMap, publishReplay, tap } from 'rxjs/operators'; import { CoreService } from '../../types'; import { CoreSetup, CoreStart } from '../../server'; import { Config } from '../config'; import { CoreContext } from '../core_context'; -import { DevConfig } from '../dev'; -import { BasePathProxyServer, HttpConfig } from '../http'; +import { DevConfig, DevConfigType } from '../dev'; +import { BasePathProxyServer, HttpConfig, HttpConfigType } from '../http'; import { Logger } from '../logging'; import { LegacyPlatformProxy } from './legacy_platform_proxy'; @@ -51,12 +51,20 @@ function getLegacyRawConfig(config: Config) { /** @internal */ export class LegacyService implements CoreService { private readonly log: Logger; + private readonly devConfig$: Observable; + private readonly httpConfig$: Observable; private kbnServer?: LegacyKbnServer; private configSubscription?: Subscription; private setupDeps?: CoreSetup; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('legacy-service'); + this.devConfig$ = coreContext.configService + .atPath('dev') + .pipe(map(rawConfig => new DevConfig(rawConfig))); + this.httpConfig$ = coreContext.configService + .atPath('server') + .pipe(map(rawConfig => new HttpConfig(rawConfig, coreContext.env))); } public async setup(setupDeps: CoreSetup) { this.setupDeps = setupDeps; @@ -111,10 +119,7 @@ export class LegacyService implements CoreService { private async createClusterManager(config: Config) { const basePathProxy$ = this.coreContext.env.cliArgs.basePath - ? combineLatest( - this.coreContext.configService.atPath('dev', DevConfig), - this.coreContext.configService.atPath('server', HttpConfig) - ).pipe( + ? combineLatest(this.devConfig$, this.httpConfig$).pipe( first(), map( ([devConfig, httpConfig]) => @@ -158,10 +163,7 @@ export class LegacyService implements CoreService { require('../../../cli/repl').startRepl(kbnServer); } - const httpConfig = await this.coreContext.configService - .atPath('server', HttpConfig) - .pipe(first()) - .toPromise(); + const httpConfig = await this.httpConfig$.pipe(first()).toPromise(); if (httpConfig.autoListen) { try { diff --git a/src/core/server/root/index.ts b/src/core/server/root/index.ts index ff4c9da4bcc9a..ac6ef79483280 100644 --- a/src/core/server/root/index.ts +++ b/src/core/server/root/index.ts @@ -21,7 +21,7 @@ import { ConnectableObservable, Observable, Subscription } from 'rxjs'; import { first, map, publishReplay, switchMap, tap } from 'rxjs/operators'; import { Config, Env } from '../config'; -import { Logger, LoggerFactory, LoggingConfig, LoggingService } from '../logging'; +import { Logger, LoggerFactory, LoggingConfigType, LoggingService } from '../logging'; import { Server } from '../server'; /** @@ -98,7 +98,7 @@ export class Root { // Stream that maps config updates to logger updates, including update failures. const update$ = configService.getConfig$().pipe( // always read the logging config when the underlying config object is re-read - switchMap(() => configService.atPath('logging', LoggingConfig)), + switchMap(() => configService.atPath('logging')), map(config => this.loggingService.upgrade(config)), // This specifically console.logs because we were not able to configure the logger. // eslint-disable-next-line no-console From d811ff1104f24d534846ec6b1610e686e1fe3bea Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sun, 19 May 2019 16:52:27 +0200 Subject: [PATCH 7/8] update testbed plugin --- src/plugins/testbed/server/config.ts | 33 ---------------------------- src/plugins/testbed/server/index.ts | 22 +++++++++++-------- 2 files changed, 13 insertions(+), 42 deletions(-) delete mode 100644 src/plugins/testbed/server/config.ts diff --git a/src/plugins/testbed/server/config.ts b/src/plugins/testbed/server/config.ts deleted file mode 100644 index 1b2fa7ea329f5..0000000000000 --- a/src/plugins/testbed/server/config.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you 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 { schema, TypeOf } from '@kbn/config-schema'; - -/** @internal */ -export class TestBedConfig { - public static schema = schema.object({ - secret: schema.string({ defaultValue: 'Not really a secret :/' }), - }); - - public readonly secret: string; - - constructor(config: TypeOf) { - this.secret = config.secret; - } -} diff --git a/src/plugins/testbed/server/index.ts b/src/plugins/testbed/server/index.ts index 538d3a3d07c9b..6d708a42fc76a 100644 --- a/src/plugins/testbed/server/index.ts +++ b/src/plugins/testbed/server/index.ts @@ -18,6 +18,7 @@ */ import { map, mergeMap } from 'rxjs/operators'; +import { schema, TypeOf } from '@kbn/config-schema'; import { Logger, @@ -26,7 +27,14 @@ import { PluginSetupContext, PluginStartContext, } from 'kibana/server'; -import { TestBedConfig } from './config'; + +export const config = { + schema: schema.object({ + secret: schema.string({ defaultValue: 'Not really a secret :/' }), + }), +}; + +type ConfigType = TypeOf; class Plugin { private readonly log: Logger; @@ -43,10 +51,10 @@ class Plugin { ); return { - data$: this.initializerContext.config.create(TestBedConfig).pipe( - map(config => { - this.log.debug(`I've got value from my config: ${config.secret}`); - return `Some exposed data derived from config: ${config.secret}`; + data$: this.initializerContext.config.create().pipe( + map(configValue => { + this.log.debug(`I've got value from my config: ${configValue.secret}`); + return `Some exposed data derived from config: ${configValue.secret}`; }) ), pingElasticsearch$: setupContext.elasticsearch.adminClient$.pipe( @@ -76,7 +84,3 @@ class Plugin { export const plugin = (initializerContext: PluginInitializerContext) => new Plugin(initializerContext); - -export const config = { - schema: TestBedConfig.schema, -}; From 79dab983d872001c85bb5f9e6e1726c19acd97ee Mon Sep 17 00:00:00 2001 From: restrry Date: Sun, 19 May 2019 18:31:17 +0200 Subject: [PATCH 8/8] update docs --- ...bana-plugin-server.configservice.atpath.md | 25 ----------------- ...-plugin-server.configservice.getconfig$.md | 17 ------------ ...gin-server.configservice.getunusedpaths.md | 15 ----------- ...lugin-server.configservice.getusedpaths.md | 15 ----------- ...in-server.configservice.isenabledatpath.md | 22 --------------- .../kibana-plugin-server.configservice.md | 24 ----------------- ...gin-server.configservice.optionalatpath.md | 27 ------------------- ...a-plugin-server.configservice.setschema.md | 25 ----------------- .../server/kibana-plugin-server.corestart.md | 1 + ...ugin-server.discoveredplugin.configpath.md | 13 +++++++++ ...ibana-plugin-server.discoveredplugin.id.md | 13 +++++++++ .../kibana-plugin-server.discoveredplugin.md | 23 ++++++++++++++++ ...server.discoveredplugin.optionalplugins.md | 13 +++++++++ ...server.discoveredplugin.requiredplugins.md | 13 +++++++++ .../core/server/kibana-plugin-server.md | 4 ++- ...-server.plugininitializercontext.config.md | 4 +-- ...-plugin-server.plugininitializercontext.md | 2 +- ...in-server.pluginsservicesetup.contracts.md | 11 ++++++++ ...ibana-plugin-server.pluginsservicesetup.md | 20 ++++++++++++++ ...in-server.pluginsservicesetup.uiplugins.md | 14 ++++++++++ ...in-server.pluginsservicestart.contracts.md | 11 ++++++++ ...ibana-plugin-server.pluginsservicestart.md | 19 +++++++++++++ src/core/server/server.api.md | 11 ++++---- 23 files changed, 162 insertions(+), 180 deletions(-) delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.atpath.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.getconfig$.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.getunusedpaths.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.getusedpaths.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.isenabledatpath.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.optionalatpath.md delete mode 100644 docs/development/core/server/kibana-plugin-server.configservice.setschema.md create mode 100644 docs/development/core/server/kibana-plugin-server.discoveredplugin.configpath.md create mode 100644 docs/development/core/server/kibana-plugin-server.discoveredplugin.id.md create mode 100644 docs/development/core/server/kibana-plugin-server.discoveredplugin.md create mode 100644 docs/development/core/server/kibana-plugin-server.discoveredplugin.optionalplugins.md create mode 100644 docs/development/core/server/kibana-plugin-server.discoveredplugin.requiredplugins.md create mode 100644 docs/development/core/server/kibana-plugin-server.pluginsservicesetup.contracts.md create mode 100644 docs/development/core/server/kibana-plugin-server.pluginsservicesetup.md create mode 100644 docs/development/core/server/kibana-plugin-server.pluginsservicesetup.uiplugins.md create mode 100644 docs/development/core/server/kibana-plugin-server.pluginsservicestart.contracts.md create mode 100644 docs/development/core/server/kibana-plugin-server.pluginsservicestart.md diff --git a/docs/development/core/server/kibana-plugin-server.configservice.atpath.md b/docs/development/core/server/kibana-plugin-server.configservice.atpath.md deleted file mode 100644 index 5ae66deb74856..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.atpath.md +++ /dev/null @@ -1,25 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [atPath](./kibana-plugin-server.configservice.atpath.md) - -## ConfigService.atPath() method - -Reads the subset of the config at the specified `path` and validates it against the static `schema` on the given `ConfigClass`. - -Signature: - -```typescript -atPath, TConfig>(path: ConfigPath, ConfigClass: ConfigWithSchema): Observable; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| path | ConfigPath | The path to the desired subset of the config. | -| ConfigClass | ConfigWithSchema<TSchema, TConfig> | A class (not an instance of a class) that contains a static schema that we validate the config at the given path against. | - -Returns: - -`Observable` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.getconfig$.md b/docs/development/core/server/kibana-plugin-server.configservice.getconfig$.md deleted file mode 100644 index 6a9e288a8160e..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.getconfig$.md +++ /dev/null @@ -1,17 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [getConfig$](./kibana-plugin-server.configservice.getconfig$.md) - -## ConfigService.getConfig$() method - -Returns the full config object observable. This is not intended for "normal use", but for features that \_need\_ access to the full object. - -Signature: - -```typescript -getConfig$(): Observable; -``` -Returns: - -`Observable` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.getunusedpaths.md b/docs/development/core/server/kibana-plugin-server.configservice.getunusedpaths.md deleted file mode 100644 index 9026672abb78e..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.getunusedpaths.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [getUnusedPaths](./kibana-plugin-server.configservice.getunusedpaths.md) - -## ConfigService.getUnusedPaths() method - -Signature: - -```typescript -getUnusedPaths(): Promise; -``` -Returns: - -`Promise` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.getusedpaths.md b/docs/development/core/server/kibana-plugin-server.configservice.getusedpaths.md deleted file mode 100644 index a29b075a8b3e4..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.getusedpaths.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [getUsedPaths](./kibana-plugin-server.configservice.getusedpaths.md) - -## ConfigService.getUsedPaths() method - -Signature: - -```typescript -getUsedPaths(): Promise; -``` -Returns: - -`Promise` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.isenabledatpath.md b/docs/development/core/server/kibana-plugin-server.configservice.isenabledatpath.md deleted file mode 100644 index 08c9985145f35..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.isenabledatpath.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [isEnabledAtPath](./kibana-plugin-server.configservice.isenabledatpath.md) - -## ConfigService.isEnabledAtPath() method - -Signature: - -```typescript -isEnabledAtPath(path: ConfigPath): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| path | ConfigPath | | - -Returns: - -`Promise` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.md b/docs/development/core/server/kibana-plugin-server.configservice.md deleted file mode 100644 index 34a2bd9cecaab..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) - -## ConfigService class - - -Signature: - -```typescript -export declare class ConfigService -``` - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [atPath(path, ConfigClass)](./kibana-plugin-server.configservice.atpath.md) | | Reads the subset of the config at the specified path and validates it against the static schema on the given ConfigClass. | -| [getConfig$()](./kibana-plugin-server.configservice.getconfig$.md) | | Returns the full config object observable. This is not intended for "normal use", but for features that \_need\_ access to the full object. | -| [getUnusedPaths()](./kibana-plugin-server.configservice.getunusedpaths.md) | | | -| [getUsedPaths()](./kibana-plugin-server.configservice.getusedpaths.md) | | | -| [isEnabledAtPath(path)](./kibana-plugin-server.configservice.isenabledatpath.md) | | | -| [optionalAtPath(path, ConfigClass)](./kibana-plugin-server.configservice.optionalatpath.md) | | Same as atPath, but returns undefined if there is no config at the specified path.[ConfigService.atPath()](./kibana-plugin-server.configservice.atpath.md) | - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.optionalatpath.md b/docs/development/core/server/kibana-plugin-server.configservice.optionalatpath.md deleted file mode 100644 index 8efc64568f830..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.optionalatpath.md +++ /dev/null @@ -1,27 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [optionalAtPath](./kibana-plugin-server.configservice.optionalatpath.md) - -## ConfigService.optionalAtPath() method - -Same as `atPath`, but returns `undefined` if there is no config at the specified path. - -[ConfigService.atPath()](./kibana-plugin-server.configservice.atpath.md) - -Signature: - -```typescript -optionalAtPath, TConfig>(path: ConfigPath, ConfigClass: ConfigWithSchema): Observable; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| path | ConfigPath | | -| ConfigClass | ConfigWithSchema<TSchema, TConfig> | | - -Returns: - -`Observable` - diff --git a/docs/development/core/server/kibana-plugin-server.configservice.setschema.md b/docs/development/core/server/kibana-plugin-server.configservice.setschema.md deleted file mode 100644 index 3db6b071dbdad..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.configservice.setschema.md +++ /dev/null @@ -1,25 +0,0 @@ - - -[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [ConfigService](./kibana-plugin-server.configservice.md) > [setSchema](./kibana-plugin-server.configservice.setschema.md) - -## ConfigService.setSchema() method - -Set config schema for a path and performs its validation - -Signature: - -```typescript -setSchema(path: ConfigPath, schema: Type): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| path | ConfigPath | | -| schema | Type<unknown> | | - -Returns: - -`Promise` - diff --git a/docs/development/core/server/kibana-plugin-server.corestart.md b/docs/development/core/server/kibana-plugin-server.corestart.md index 119036da61ee1..90cc4549eb3bf 100644 --- a/docs/development/core/server/kibana-plugin-server.corestart.md +++ b/docs/development/core/server/kibana-plugin-server.corestart.md @@ -4,6 +4,7 @@ ## CoreStart interface + Signature: ```typescript diff --git a/docs/development/core/server/kibana-plugin-server.discoveredplugin.configpath.md b/docs/development/core/server/kibana-plugin-server.discoveredplugin.configpath.md new file mode 100644 index 0000000000000..a870cd7d7a61e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.discoveredplugin.configpath.md @@ -0,0 +1,13 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) > [configPath](./kibana-plugin-server.discoveredplugin.configpath.md) + +## DiscoveredPlugin.configPath property + +Root configuration path used by the plugin, defaults to "id". + +Signature: + +```typescript +readonly configPath: ConfigPath; +``` diff --git a/docs/development/core/server/kibana-plugin-server.discoveredplugin.id.md b/docs/development/core/server/kibana-plugin-server.discoveredplugin.id.md new file mode 100644 index 0000000000000..6f75b399ace83 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.discoveredplugin.id.md @@ -0,0 +1,13 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) > [id](./kibana-plugin-server.discoveredplugin.id.md) + +## DiscoveredPlugin.id property + +Identifier of the plugin. + +Signature: + +```typescript +readonly id: PluginName; +``` diff --git a/docs/development/core/server/kibana-plugin-server.discoveredplugin.md b/docs/development/core/server/kibana-plugin-server.discoveredplugin.md new file mode 100644 index 0000000000000..d03d8a8f4a17a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.discoveredplugin.md @@ -0,0 +1,23 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) + +## DiscoveredPlugin interface + +Small container object used to expose information about discovered plugins that may or may not have been started. + +Signature: + +```typescript +export interface DiscoveredPlugin +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [configPath](./kibana-plugin-server.discoveredplugin.configpath.md) | ConfigPath | Root configuration path used by the plugin, defaults to "id". | +| [id](./kibana-plugin-server.discoveredplugin.id.md) | PluginName | Identifier of the plugin. | +| [optionalPlugins](./kibana-plugin-server.discoveredplugin.optionalplugins.md) | ReadonlyArray<PluginName> | An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. | +| [requiredPlugins](./kibana-plugin-server.discoveredplugin.requiredplugins.md) | ReadonlyArray<PluginName> | An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. | + diff --git a/docs/development/core/server/kibana-plugin-server.discoveredplugin.optionalplugins.md b/docs/development/core/server/kibana-plugin-server.discoveredplugin.optionalplugins.md new file mode 100644 index 0000000000000..1ebc425f44ce5 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.discoveredplugin.optionalplugins.md @@ -0,0 +1,13 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) > [optionalPlugins](./kibana-plugin-server.discoveredplugin.optionalplugins.md) + +## DiscoveredPlugin.optionalPlugins property + +An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. + +Signature: + +```typescript +readonly optionalPlugins: ReadonlyArray; +``` diff --git a/docs/development/core/server/kibana-plugin-server.discoveredplugin.requiredplugins.md b/docs/development/core/server/kibana-plugin-server.discoveredplugin.requiredplugins.md new file mode 100644 index 0000000000000..4ca74797289f7 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.discoveredplugin.requiredplugins.md @@ -0,0 +1,13 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) > [requiredPlugins](./kibana-plugin-server.discoveredplugin.requiredplugins.md) + +## DiscoveredPlugin.requiredPlugins property + +An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. + +Signature: + +```typescript +readonly requiredPlugins: ReadonlyArray; +``` diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index f3e11fca6b280..027aef60265a2 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -9,7 +9,6 @@ | Class | Description | | --- | --- | | [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)). | -| [ConfigService](./kibana-plugin-server.configservice.md) | | | [KibanaRequest](./kibana-plugin-server.kibanarequest.md) | | | [Router](./kibana-plugin-server.router.md) | | | [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API | @@ -22,6 +21,7 @@ | [CallAPIOptions](./kibana-plugin-server.callapioptions.md) | The set of options that defines how API call should be made and result be processed. | | [CoreSetup](./kibana-plugin-server.coresetup.md) | | | [CoreStart](./kibana-plugin-server.corestart.md) | | +| [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) | Small container object used to expose information about discovered plugins that may or may not have been started. | | [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) | | | [HttpServiceStart](./kibana-plugin-server.httpservicestart.md) | | | [Logger](./kibana-plugin-server.logger.md) | Logger exposes all the necessary methods to log any type of information and this is the interface used by the logging consumers including plugins. | @@ -31,6 +31,8 @@ | [Plugin](./kibana-plugin-server.plugin.md) | The interface that should be returned by a PluginInitializer. | | [PluginInitializerContext](./kibana-plugin-server.plugininitializercontext.md) | Context that's available to plugins during initialization stage. | | [PluginSetupContext](./kibana-plugin-server.pluginsetupcontext.md) | Context passed to the plugins setup method. | +| [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) | | +| [PluginsServiceStart](./kibana-plugin-server.pluginsservicestart.md) | | | [PluginStartContext](./kibana-plugin-server.pluginstartcontext.md) | Context passed to the plugins start method. | ## Type Aliases diff --git a/docs/development/core/server/kibana-plugin-server.plugininitializercontext.config.md b/docs/development/core/server/kibana-plugin-server.plugininitializercontext.config.md index fb4fddf584f43..9dea92155bcd8 100644 --- a/docs/development/core/server/kibana-plugin-server.plugininitializercontext.config.md +++ b/docs/development/core/server/kibana-plugin-server.plugininitializercontext.config.md @@ -8,7 +8,7 @@ ```typescript config: { - create: , Config>(ConfigClass: ConfigWithSchema) => Observable; - createIfExists: , Config>(ConfigClass: ConfigWithSchema) => Observable; + create: () => Observable; + createIfExists: () => Observable; }; ``` diff --git a/docs/development/core/server/kibana-plugin-server.plugininitializercontext.md b/docs/development/core/server/kibana-plugin-server.plugininitializercontext.md index 6e35d28e2ef8f..a266d20fbf0f2 100644 --- a/docs/development/core/server/kibana-plugin-server.plugininitializercontext.md +++ b/docs/development/core/server/kibana-plugin-server.plugininitializercontext.md @@ -16,7 +16,7 @@ export interface PluginInitializerContext | Property | Type | Description | | --- | --- | --- | -| [config](./kibana-plugin-server.plugininitializercontext.config.md) | {`

` create: <Schema extends Type<any>, Config>(ConfigClass: ConfigWithSchema<Schema, Config>) => Observable<Config>;`

` createIfExists: <Schema extends Type<any>, Config>(ConfigClass: ConfigWithSchema<Schema, Config>) => Observable<Config | undefined>;`

` } | | +| [config](./kibana-plugin-server.plugininitializercontext.config.md) | {`

` create: <Schema>() => Observable<Schema>;`

` createIfExists: <Schema>() => Observable<Schema | undefined>;`

` } | | | [env](./kibana-plugin-server.plugininitializercontext.env.md) | {`

` mode: EnvironmentMode;`

` } | | | [logger](./kibana-plugin-server.plugininitializercontext.logger.md) | LoggerFactory | | diff --git a/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.contracts.md b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.contracts.md new file mode 100644 index 0000000000000..090693a814c1d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.contracts.md @@ -0,0 +1,11 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) > [contracts](./kibana-plugin-server.pluginsservicesetup.contracts.md) + +## PluginsServiceSetup.contracts property + +Signature: + +```typescript +contracts: Map; +``` diff --git a/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.md b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.md new file mode 100644 index 0000000000000..c1b3c739d80fe --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.md @@ -0,0 +1,20 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) + +## PluginsServiceSetup interface + + +Signature: + +```typescript +export interface PluginsServiceSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [contracts](./kibana-plugin-server.pluginsservicesetup.contracts.md) | Map<PluginName, unknown> | | +| [uiPlugins](./kibana-plugin-server.pluginsservicesetup.uiplugins.md) | {`

` public: Map<PluginName, DiscoveredPlugin>;`

` internal: Map<PluginName, DiscoveredPluginInternal>;`

` } | | + diff --git a/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.uiplugins.md b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.uiplugins.md new file mode 100644 index 0000000000000..ff63944fdf64d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.pluginsservicesetup.uiplugins.md @@ -0,0 +1,14 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) > [uiPlugins](./kibana-plugin-server.pluginsservicesetup.uiplugins.md) + +## PluginsServiceSetup.uiPlugins property + +Signature: + +```typescript +uiPlugins: { + public: Map; + internal: Map; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-server.pluginsservicestart.contracts.md b/docs/development/core/server/kibana-plugin-server.pluginsservicestart.contracts.md new file mode 100644 index 0000000000000..f6316e7772648 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.pluginsservicestart.contracts.md @@ -0,0 +1,11 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [PluginsServiceStart](./kibana-plugin-server.pluginsservicestart.md) > [contracts](./kibana-plugin-server.pluginsservicestart.contracts.md) + +## PluginsServiceStart.contracts property + +Signature: + +```typescript +contracts: Map; +``` diff --git a/docs/development/core/server/kibana-plugin-server.pluginsservicestart.md b/docs/development/core/server/kibana-plugin-server.pluginsservicestart.md new file mode 100644 index 0000000000000..6e7354d3ea409 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.pluginsservicestart.md @@ -0,0 +1,19 @@ + + +[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [PluginsServiceStart](./kibana-plugin-server.pluginsservicestart.md) + +## PluginsServiceStart interface + + +Signature: + +```typescript +export interface PluginsServiceStart +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [contracts](./kibana-plugin-server.pluginsservicestart.contracts.md) | Map<PluginName, unknown> | | + diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index ddee8e3eb07e3..ca7f63b01e5fb 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -61,8 +61,7 @@ export class ConfigService { // Warning: (ae-forgotten-export) The symbol "Config" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Env" needs to be exported by the entry point index.d.ts constructor(config$: Observable, env: Env, logger: LoggerFactory); - // Warning: (ae-forgotten-export) The symbol "ConfigWithSchema" needs to be exported by the entry point index.d.ts - atPath, TConfig>(path: ConfigPath, ConfigClass: ConfigWithSchema): Observable; + atPath(path: ConfigPath): Observable; getConfig$(): Observable; // (undocumented) getUnusedPaths(): Promise; @@ -70,7 +69,7 @@ export class ConfigService { getUsedPaths(): Promise; // (undocumented) isEnabledAtPath(path: ConfigPath): Promise; - optionalAtPath, TConfig>(path: ConfigPath, ConfigClass: ConfigWithSchema): Observable; + optionalAtPath(path: ConfigPath): Observable; // Warning: (ae-forgotten-export) The symbol "ConfigPath" needs to be exported by the entry point index.d.ts setSchema(path: ConfigPath, schema: Type): Promise; } @@ -260,8 +259,8 @@ export type PluginInitializer, Config>(ConfigClass: ConfigWithSchema) => Observable; - createIfExists: , Config>(ConfigClass: ConfigWithSchema) => Observable; + create: () => Observable; + createIfExists: () => Observable; }; // (undocumented) env: { @@ -339,7 +338,7 @@ export class ScopedClusterClient { // Warnings were encountered during analysis: // -// src/core/server/plugins/plugin_context.ts:36:10 - (ae-forgotten-export) The symbol "EnvironmentMode" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/plugin_context.ts:35:10 - (ae-forgotten-export) The symbol "EnvironmentMode" needs to be exported by the entry point index.d.ts // src/core/server/plugins/plugins_service.ts:37:5 - (ae-forgotten-export) The symbol "DiscoveredPluginInternal" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package)