diff --git a/platform/README.md b/platform/README.md index 354231fffba82..2008a6aa93e12 100644 --- a/platform/README.md +++ b/platform/README.md @@ -11,15 +11,26 @@ folder and re-run `npm install`. Make sure to build the code first, e.g. `npm run ts:build` or `npm run ts:start`. -This builds the code into `./ts-tmp/` for now. If you get into a weird state you -might clean the `ts-tmp` directory. +This builds the code into `./target/` for now. If you get into a weird state you +might clean the `target` directory. -When this completes you can start the server and plugins: +When this completes you can start the server and plugins as a standalone Node application: -``` +```bash node scripts/platform.js ``` +Or load it as a part of the legacy platform: + +```bash +npm start +``` + +In the latter case, all Kibana requests will hit the new platform first and it will decide whether request can be +solely handled by the new platform or request should be forwarded to the legacy platform. In this mode new platform does +not read config file directly, but rather transforms config provided by the legacy platform. In addition to that all log +records are forwarded to the legacy platform so that it can layout and output them properly. + ## Running tests Run Jest: diff --git a/platform/config/Env.ts b/platform/config/Env.ts index 2c28f169abdae..cea8dc049f39b 100644 --- a/platform/config/Env.ts +++ b/platform/config/Env.ts @@ -1,7 +1,7 @@ import * as process from 'process'; import { resolve } from 'path'; -import { LegacyPlatformProxifier } from '../legacy'; +import { LegacyKbnServer } from '../legacy'; interface EnvOptions { config?: string; @@ -48,10 +48,8 @@ export class Env { /** * @internal */ - getNewPlatformProxyListener(): LegacyPlatformProxifier | undefined { - if (this.options.kbnServer !== undefined) { - return this.options.kbnServer.newPlatformProxyListener; - } + getLegacyKbnServer(): LegacyKbnServer | undefined { + return this.options.kbnServer; } private getDefaultConfigFile() { diff --git a/platform/config/__tests__/Env.test.ts b/platform/config/__tests__/Env.test.ts index 95b00e4d35943..efe1afa329f5d 100644 --- a/platform/config/__tests__/Env.test.ts +++ b/platform/config/__tests__/Env.test.ts @@ -26,14 +26,14 @@ test('correctly creates default environment with empty options.', () => { expect(defaultEnv.getPluginDir('some-plugin')).toEqual( '/test/cwd/core_plugins/some-plugin/target/dist' ); - expect(defaultEnv.getNewPlatformProxyListener()).toBeUndefined(); + expect(defaultEnv.getLegacyKbnServer()).toBeUndefined(); }); test('correctly creates default environment with options overrides.', () => { - const proxyListenerMock = {}; + const kbnServerMock = {}; const defaultEnv = Env.createDefault({ config: '/some/other/path/some-kibana.yml', - kbnServer: { newPlatformProxyListener: proxyListenerMock } + kbnServer: kbnServerMock }); expect(defaultEnv.homeDir).toEqual('/test/cwd'); @@ -49,7 +49,7 @@ test('correctly creates default environment with options overrides.', () => { expect(defaultEnv.getPluginDir('some-plugin')).toEqual( '/test/cwd/core_plugins/some-plugin/target/dist' ); - expect(defaultEnv.getNewPlatformProxyListener()).toBe(proxyListenerMock); + expect(defaultEnv.getLegacyKbnServer()).toBe(kbnServerMock); }); test('correctly creates environment with constructor.', () => { @@ -70,5 +70,5 @@ test('correctly creates environment with constructor.', () => { expect(defaultEnv.getPluginDir('some-plugin')).toEqual( '/some/home/dir/core_plugins/some-plugin/target/dist' ); - expect(defaultEnv.getNewPlatformProxyListener()).toBeUndefined(); + expect(defaultEnv.getLegacyKbnServer()).toBeUndefined(); }); diff --git a/platform/legacy/LegacyKbnServer.ts b/platform/legacy/LegacyKbnServer.ts index db5a9959e55ff..4a7c98365831b 100644 --- a/platform/legacy/LegacyKbnServer.ts +++ b/platform/legacy/LegacyKbnServer.ts @@ -1,21 +1,25 @@ -import { LegacyConfig } from './LegacyPlatformConfig'; -import { LegacyPlatformProxifier } from './LegacyPlatformProxifier'; - /** - * Represents legacy kbnServer instance, provided by the legacy platform. + * Represents a wrapper around legacy `kbnServer` instance that exposes only + * a subset of `kbnServer` APIs used by the new platform. * @internal */ -export interface LegacyKbnServer { - readonly config: LegacyConfig; +export class LegacyKbnServer { + constructor(private readonly rawKbnServer: any) {} /** - * Custom HTTP Listener provided by the new platform and that will be used - * within legacy platform by HapiJS server. + * Custom HTTP Listener used by HapiJS server in the legacy platform. */ - newPlatformProxyListener: LegacyPlatformProxifier; + get newPlatformProxyListener() { + return this.rawKbnServer.newPlatform.proxyListener; + } /** - * Propagates legacy config updates to the new platform. + * Forwards log request to the legacy platform. + * @param tags A string or array of strings used to briefly identify the event. + * @param [data] Optional string or object to log with the event. + * @param [timestamp] Timestamp value associated with the log record. */ - updateNewPlatformConfig: (legacyConfig: LegacyConfig) => void; + log(tags: string | string[], data?: string | Error, timestamp?: Date) { + this.rawKbnServer.server.log(tags, data, timestamp); + } } diff --git a/platform/legacy/LegacyPlatformConfig.ts b/platform/legacy/LegacyPlatformConfig.ts index f15805a68d1b0..eca32ce4c098c 100644 --- a/platform/legacy/LegacyPlatformConfig.ts +++ b/platform/legacy/LegacyPlatformConfig.ts @@ -69,7 +69,7 @@ export class LegacyConfigToRawConfigAdapter implements RawConfig { private static transformLogging(configValue: LegacyLoggingConfig) { const loggingConfig = { root: { level: 'info' }, - appenders: { default: {} } + appenders: { default: { kind: 'legacy-appender' } } }; if (configValue.silent) { @@ -80,23 +80,6 @@ export class LegacyConfigToRawConfigAdapter implements RawConfig { loggingConfig.root.level = 'all'; } - const layout = configValue.json - ? { kind: 'json' } - : { kind: 'pattern', highlight: true }; - - if (configValue.dest && configValue.dest !== 'stdout') { - loggingConfig.appenders.default = { - kind: 'file', - path: configValue.dest, - layout - }; - } else { - loggingConfig.appenders.default = { - kind: 'console', - layout - }; - } - return loggingConfig; } diff --git a/platform/legacy/__tests__/LegacyKbnServer.test.ts b/platform/legacy/__tests__/LegacyKbnServer.test.ts new file mode 100644 index 0000000000000..bc788a4170595 --- /dev/null +++ b/platform/legacy/__tests__/LegacyKbnServer.test.ts @@ -0,0 +1,28 @@ +import { LegacyKbnServer } from '..'; + +test('correctly returns `newPlatformProxyListener`.', () => { + const rawKbnServer = { + newPlatform: { + proxyListener: {} + } + }; + + const legacyKbnServer = new LegacyKbnServer(rawKbnServer); + expect(legacyKbnServer.newPlatformProxyListener).toBe( + rawKbnServer.newPlatform.proxyListener + ); +}); + +test('correctly forwards log record.', () => { + const rawKbnServer = { + server: { log: jest.fn() } + }; + + const legacyKbnServer = new LegacyKbnServer(rawKbnServer); + + const timestamp = new Date(Date.UTC(2012, 1, 1, 11, 22, 33, 44)); + legacyKbnServer.log(['one', 'two'], 'message', timestamp); + legacyKbnServer.log('three', new Error('log error'), timestamp); + + expect(rawKbnServer.server.log.mock.calls).toMatchSnapshot(); +}); diff --git a/platform/legacy/__tests__/LegacyPlatformConfig.test.ts b/platform/legacy/__tests__/LegacyPlatformConfig.test.ts index b75dc5298f040..567a09844d2ec 100644 --- a/platform/legacy/__tests__/LegacyPlatformConfig.test.ts +++ b/platform/legacy/__tests__/LegacyPlatformConfig.test.ts @@ -38,10 +38,7 @@ describe('Retrieving values', () => { expect(configAdapter.get('logging')).toEqual({ root: { level: 'off' }, appenders: { - default: { - kind: 'console', - layout: { kind: 'pattern', highlight: true } - } + default: { kind: 'legacy-appender' } } }); }); @@ -54,11 +51,7 @@ describe('Retrieving values', () => { expect(configAdapter.get('logging')).toEqual({ root: { level: 'all' }, appenders: { - default: { - kind: 'file', - path: '/some/path.log', - layout: { kind: 'json' } - } + default: { kind: 'legacy-appender' } } }); }); diff --git a/platform/legacy/__tests__/LegacyPlatformProxifier.test.ts b/platform/legacy/__tests__/LegacyPlatformProxifier.test.ts index 239c118cb931e..7075bfac10a5c 100644 --- a/platform/legacy/__tests__/LegacyPlatformProxifier.test.ts +++ b/platform/legacy/__tests__/LegacyPlatformProxifier.test.ts @@ -6,7 +6,7 @@ class mockNetServer extends EventEmitter { return { port: 1234, family: 'test-family', address: 'test-address' }; } - getConnections(callback: (error: Error, count: number) => void) { + getConnections(callback: (error: Error | undefined, count: number) => void) { callback(undefined, 100500); } } @@ -57,7 +57,7 @@ test('correctly binds to the server and redirects its events.', () => { const listener = jest.fn(); proxifier.addListener(eventName, listener); - return [eventName, listener]; + return [eventName, listener] as [string, () => void]; }) ); @@ -86,7 +86,7 @@ test('correctly unbinds from the previous server.', () => { const listener = jest.fn(); proxifier.addListener(eventName, listener); - return [eventName, listener]; + return [eventName, listener] as [string, () => void]; }) ); diff --git a/platform/legacy/__tests__/__snapshots__/LegacyKbnServer.test.ts.snap b/platform/legacy/__tests__/__snapshots__/LegacyKbnServer.test.ts.snap new file mode 100644 index 0000000000000..af1b7cf4c6e76 --- /dev/null +++ b/platform/legacy/__tests__/__snapshots__/LegacyKbnServer.test.ts.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`correctly forwards log record. 1`] = ` +Array [ + Array [ + Array [ + "one", + "two", + ], + "message", + 2012-02-01T11:22:33.044Z, + ], + Array [ + "three", + [Error: log error], + 2012-02-01T11:22:33.044Z, + ], +] +`; diff --git a/platform/legacy/index.ts b/platform/legacy/index.ts index 7f384edc6ab11..b4a38ad94fb67 100644 --- a/platform/legacy/index.ts +++ b/platform/legacy/index.ts @@ -21,17 +21,24 @@ import { /** * @internal */ -export const injectIntoKbnServer = (kbnServer: LegacyKbnServer) => { - const legacyConfig$ = new BehaviorSubject(kbnServer.config); +export const injectIntoKbnServer = (rawKbnServer: any) => { + const legacyConfig$ = new BehaviorSubject(rawKbnServer.config); const config$ = legacyConfig$.map( legacyConfig => new LegacyConfigToRawConfigAdapter(legacyConfig) ); - kbnServer.updateNewPlatformConfig = (legacyConfig: LegacyConfig) => { - legacyConfig$.next(legacyConfig); - }; + rawKbnServer.newPlatform = { + // Custom HTTP Listener that will be used within legacy platform by HapiJS server. + proxyListener: new LegacyPlatformProxifier( + new Root( + config$, + Env.createDefault({ kbnServer: new LegacyKbnServer(rawKbnServer) }) + ) + ), - kbnServer.newPlatformProxyListener = new LegacyPlatformProxifier( - new Root(config$, Env.createDefault({ kbnServer })) - ); + // Propagates legacy config updates to the new platform. + updateConfig(legacyConfig: LegacyConfig) { + legacyConfig$.next(legacyConfig); + } + }; }; diff --git a/platform/legacy/logging/appenders/LegacyAppender.ts b/platform/legacy/logging/appenders/LegacyAppender.ts new file mode 100644 index 0000000000000..646c8a1c3ce0d --- /dev/null +++ b/platform/legacy/logging/appenders/LegacyAppender.ts @@ -0,0 +1,39 @@ +import { Schema, typeOfSchema } from '../../../types/schema'; +import { LogRecord } from '../../../logging/LogRecord'; +import { DisposableAppender } from '../../../logging/appenders/Appenders'; +import { LegacyKbnServer } from '../../LegacyKbnServer'; + +const createSchema = (schema: Schema) => { + const { literal, object } = schema; + + return object({ kind: literal('legacy-appender') }); +}; + +const schemaType = typeOfSchema(createSchema); +/** @internal */ +export type LegacyAppenderConfigType = typeof schemaType; + +/** + * Simple appender that just forwards `LogRecord` to the legacy KbnServer log. + * @internal + */ +export class LegacyAppender implements DisposableAppender { + static createConfigSchema = createSchema; + + constructor(private readonly kbnServer: LegacyKbnServer) {} + + /** + * Forwards `LogRecord` to the legacy platform that will layout and + * write record to the configured destination. + * @param record `LogRecord` instance to forward to. + */ + append(record: LogRecord) { + this.kbnServer.log( + [record.level.id.toLowerCase(), ...record.context.split('.')], + record.error || record.message, + record.timestamp + ); + } + + async dispose() {} +} diff --git a/platform/legacy/logging/appenders/__tests__/LegacyAppender.test.ts b/platform/legacy/logging/appenders/__tests__/LegacyAppender.test.ts new file mode 100644 index 0000000000000..413cde2abfc83 --- /dev/null +++ b/platform/legacy/logging/appenders/__tests__/LegacyAppender.test.ts @@ -0,0 +1,83 @@ +import * as mockSchema from '../../../../lib/schema'; +import { LogLevel } from '../../../../logging/LogLevel'; +import { LogRecord } from '../../../../logging/LogRecord'; +import { LegacyKbnServer } from '../../../LegacyKbnServer'; +import { LegacyAppender } from '../LegacyAppender'; + +test('`createConfigSchema()` creates correct schema.', () => { + const appenderSchema = LegacyAppender.createConfigSchema(mockSchema); + const validConfig = { kind: 'legacy-appender' }; + expect(appenderSchema.validate(validConfig)).toEqual({ + kind: 'legacy-appender' + }); + + const wrongConfig = { kind: 'not-legacy-appender' }; + expect(() => appenderSchema.validate(wrongConfig)).toThrow(); +}); + +test('`append()` correctly pushes records to legacy platform.', () => { + const timestamp = new Date(Date.UTC(2012, 1, 1, 11, 22, 33, 44)); + const records: LogRecord[] = [ + { + timestamp, + message: 'message-1', + context: 'context-1', + level: LogLevel.Trace + }, + { + timestamp, + message: 'message-2', + context: 'context-2', + level: LogLevel.Debug + }, + { + timestamp, + message: 'message-3', + context: 'context-3.sub-context-3', + level: LogLevel.Info + }, + { + timestamp, + message: 'message-4', + context: 'context-4.sub-context-4', + level: LogLevel.Warn + }, + { + timestamp, + message: 'message-5-with-error', + context: 'context-5', + error: new Error('Some Error'), + level: LogLevel.Error + }, + { + timestamp, + message: 'message-6-with-message', + context: 'context-6', + level: LogLevel.Error + }, + { + timestamp, + message: 'message-7-with-error', + context: 'context-7.sub-context-7.sub-sub-context-7', + error: new Error('Some Fatal Error'), + level: LogLevel.Fatal + }, + { + timestamp, + message: 'message-8-with-message', + context: 'context-8.sub-context-8.sub-sub-context-8', + level: LogLevel.Fatal + } + ]; + + const rawKbnServerMock = { + server: { log: jest.fn() } + }; + const appender = new LegacyAppender(new LegacyKbnServer(rawKbnServerMock)); + + for (const record of records) { + appender.append(record); + } + + expect(rawKbnServerMock.server.log.mock.calls).toMatchSnapshot(); +}); diff --git a/platform/legacy/logging/appenders/__tests__/__snapshots__/LegacyAppender.test.ts.snap b/platform/legacy/logging/appenders/__tests__/__snapshots__/LegacyAppender.test.ts.snap new file mode 100644 index 0000000000000..4a024fc806a13 --- /dev/null +++ b/platform/legacy/logging/appenders/__tests__/__snapshots__/LegacyAppender.test.ts.snap @@ -0,0 +1,76 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`\`append()\` correctly pushes records to legacy platform. 1`] = ` +Array [ + Array [ + Array [ + "trace", + "context-1", + ], + "message-1", + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "debug", + "context-2", + ], + "message-2", + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "info", + "context-3", + "sub-context-3", + ], + "message-3", + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "warn", + "context-4", + "sub-context-4", + ], + "message-4", + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "error", + "context-5", + ], + [Error: Some Error], + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "error", + "context-6", + ], + "message-6-with-message", + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "fatal", + "context-7", + "sub-context-7", + "sub-sub-context-7", + ], + [Error: Some Fatal Error], + 2012-02-01T11:22:33.044Z, + ], + Array [ + Array [ + "fatal", + "context-8", + "sub-context-8", + "sub-sub-context-8", + ], + "message-8-with-message", + 2012-02-01T11:22:33.044Z, + ], +] +`; diff --git a/platform/logging/LoggerFactory.ts b/platform/logging/LoggerFactory.ts index ed06100016ccd..0737a214bfc32 100644 --- a/platform/logging/LoggerFactory.ts +++ b/platform/logging/LoggerFactory.ts @@ -1,3 +1,4 @@ +import { Env } from '../config/Env'; import { LoggingConfig, LoggerConfigType } from './LoggingConfig'; import { LogLevel } from './LogLevel'; import { Logger, BaseLogger, LoggerAdapter } from './Logger'; @@ -24,6 +25,8 @@ export class MutableLoggerFactory implements LoggerFactory { private readonly bufferAppender = new BufferAppender(); private readonly loggers: Map = new Map(); + constructor(private readonly env: Env) {} + get(...contextParts: string[]): Logger { const context = LoggingConfig.getLoggerContext(contextParts); if (this.loggers.has(context)) { @@ -53,7 +56,10 @@ export class MutableLoggerFactory implements LoggerFactory { this.appenders.clear(); for (const [appenderKey, appenderConfig] of config.appenders.entries()) { - this.appenders.set(appenderKey, Appenders.create(appenderConfig)); + this.appenders.set( + appenderKey, + Appenders.create(appenderConfig, this.env) + ); } for (const [loggerKey, loggerAdapter] of this.loggers.entries()) { diff --git a/platform/logging/__tests__/LoggerFactory.test.ts b/platform/logging/__tests__/LoggerFactory.test.ts index 302baf85a69ef..efef0075c7a0a 100644 --- a/platform/logging/__tests__/LoggerFactory.test.ts +++ b/platform/logging/__tests__/LoggerFactory.test.ts @@ -32,7 +32,7 @@ beforeEach(() => { }); test('`get()` returns Logger that appends records to buffer if config is not ready.', () => { - const factory = new MutableLoggerFactory(); + const factory = new MutableLoggerFactory({} as any); const loggerWithoutConfig = factory.get('some-context'); const testsLogger = factory.get('tests'); const testsChildLogger = factory.get('tests', 'child'); @@ -92,7 +92,7 @@ test('`get()` returns Logger that appends records to buffer if config is not rea test('`get()` returns `root` logger if context is not specified.', () => { const loggingConfigSchema = LoggingConfig.createSchema(mockSchema); - const factory = new MutableLoggerFactory(); + const factory = new MutableLoggerFactory({} as any); const config = loggingConfigSchema.validate({ appenders: { default: { @@ -114,7 +114,7 @@ test('`get()` returns `root` logger if context is not specified.', () => { }); test('`close()` disposes all resources used by appenders.', async () => { - const factory = new MutableLoggerFactory(); + const factory = new MutableLoggerFactory({} as any); const loggingConfigSchema = LoggingConfig.createSchema(mockSchema); const config = new LoggingConfig( diff --git a/platform/logging/__tests__/LoggingService.test.ts b/platform/logging/__tests__/LoggingService.test.ts index d318898298601..ffbfac432ec5e 100644 --- a/platform/logging/__tests__/LoggingService.test.ts +++ b/platform/logging/__tests__/LoggingService.test.ts @@ -24,7 +24,7 @@ let service: LoggingService; let updateConfigMock: jest.Mock; let closeMock: jest.Mock; beforeEach(() => { - factory = new MutableLoggerFactory(); + factory = new MutableLoggerFactory({} as any); updateConfigMock = jest .spyOn(factory, 'updateConfig') .mockImplementation(() => {}); diff --git a/platform/logging/appenders/Appenders.ts b/platform/logging/appenders/Appenders.ts index e01dd454a2402..8ee47558cae2f 100644 --- a/platform/logging/appenders/Appenders.ts +++ b/platform/logging/appenders/Appenders.ts @@ -1,17 +1,23 @@ import { assertNever } from '../../lib/utils'; import { Schema } from '../../types/schema'; +import { Env } from '../../config/Env'; import { ConsoleAppender, ConsoleAppenderConfigType } from './console/ConsoleAppender'; import { FileAppender, FileAppenderConfigType } from './file/FileAppender'; +import { + LegacyAppender, + LegacyAppenderConfigType +} from '../../legacy/logging/appenders/LegacyAppender'; import { LogRecord } from '../LogRecord'; import { Layouts } from '../layouts/Layouts'; /** @internal */ export type AppenderConfigType = | ConsoleAppenderConfigType - | FileAppenderConfigType; + | FileAppenderConfigType + | LegacyAppenderConfigType; /** * Entity that can append `LogRecord` instances to file, stdout, memory or whatever @@ -39,23 +45,29 @@ export class Appenders { return oneOf([ ConsoleAppender.createConfigSchema(schema), - FileAppender.createConfigSchema(schema) + FileAppender.createConfigSchema(schema), + LegacyAppender.createConfigSchema(schema) ]); } /** * Factory method that creates specific `Appender` instances based on the passed `config` parameter. * @param config Configuration specific to a particular `Appender` implementation. + * @param env Current environment that is required by some appenders. * @returns Fully constructed `Appender` instance. */ - static create(config: AppenderConfigType): DisposableAppender { - const layout = Layouts.create(config.layout); - + static create(config: AppenderConfigType, env: Env): DisposableAppender { switch (config.kind) { case 'console': - return new ConsoleAppender(layout); + return new ConsoleAppender(Layouts.create(config.layout)); case 'file': - return new FileAppender(layout, config.path); + return new FileAppender(Layouts.create(config.layout), config.path); + case 'legacy-appender': + const legacyKbnServer = env.getLegacyKbnServer(); + if (legacyKbnServer === undefined) { + throw new Error('Legacy appender requires kbnServer.'); + } + return new LegacyAppender(legacyKbnServer); default: return assertNever(config); } diff --git a/platform/logging/appenders/__tests__/Appenders.test.ts b/platform/logging/appenders/__tests__/Appenders.test.ts index 38f21695dbff9..b29528f7ae4b5 100644 --- a/platform/logging/appenders/__tests__/Appenders.test.ts +++ b/platform/logging/appenders/__tests__/Appenders.test.ts @@ -11,6 +11,7 @@ jest.mock('../../layouts/Layouts', () => ({ import { ConsoleAppender } from '../console/ConsoleAppender'; import { FileAppender } from '../file/FileAppender'; +import { LegacyAppender } from '../../../legacy/logging/appenders/LegacyAppender'; import { Appenders } from '../Appenders'; beforeEach(() => { @@ -60,24 +61,46 @@ test('`createConfigSchema()` creates correct schema.', () => { test('`create()` creates correct appender.', () => { mockCreateLayout.mockReturnValue({ format: () => '' }); - const consoleAppender = Appenders.create({ - kind: 'console', - layout: { - kind: 'pattern', - pattern: '', - highlight: true - } - }); + const consoleAppender = Appenders.create( + { + kind: 'console', + layout: { + kind: 'pattern', + pattern: '', + highlight: true + } + }, + {} as any + ); expect(consoleAppender).toBeInstanceOf(ConsoleAppender); - const fileAppender = Appenders.create({ - kind: 'file', - path: 'path', - layout: { - kind: 'pattern', - pattern: '', - highlight: true - } - }); + const fileAppender = Appenders.create( + { + kind: 'file', + path: 'path', + layout: { + kind: 'pattern', + pattern: '', + highlight: true + } + }, + {} as any + ); expect(fileAppender).toBeInstanceOf(FileAppender); }); + +test('`create()` fails to create legacy appender if kbnServer is not provided.', () => { + expect(() => { + Appenders.create({ kind: 'legacy-appender' }, { + getLegacyKbnServer() {} + } as any); + }).toThrowErrorMatchingSnapshot(); +}); + +test('`create()` creates legacy appender if kbnServer is provided.', () => { + const legacyAppender = Appenders.create({ kind: 'legacy-appender' }, { + getLegacyKbnServer: () => ({}) + } as any); + + expect(legacyAppender).toBeInstanceOf(LegacyAppender); +}); diff --git a/platform/logging/appenders/__tests__/__snapshots__/Appenders.test.ts.snap b/platform/logging/appenders/__tests__/__snapshots__/Appenders.test.ts.snap new file mode 100644 index 0000000000000..e7e8f70b345c7 --- /dev/null +++ b/platform/logging/appenders/__tests__/__snapshots__/Appenders.test.ts.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`\`create()\` fails to create legacy appender if kbnServer is not provided. 1`] = `"Legacy appender requires kbnServer."`; diff --git a/platform/root/__tests__/index.test.ts b/platform/root/__tests__/index.test.ts index fdf4ba7f6745f..7c243f8f7dc95 100644 --- a/platform/root/__tests__/index.test.ts +++ b/platform/root/__tests__/index.test.ts @@ -41,9 +41,10 @@ jest.mock('../../logging/LoggerFactory', () => ({ import { Root } from '../'; import { Env } from '../../config/Env'; +import { RawConfig } from '../../config/RawConfigService'; const env = new Env('.', {}); -const config$ = new BehaviorSubject({}); +const config$ = new BehaviorSubject({} as RawConfig); let mockProcessExit = jest .spyOn(global.process, 'exit') diff --git a/platform/root/index.ts b/platform/root/index.ts index 0d4c9fbfb369f..f3cc037d30587 100644 --- a/platform/root/index.ts +++ b/platform/root/index.ts @@ -25,7 +25,7 @@ export class Root { private readonly env: Env, private readonly onShutdown: OnShutdown = () => {} ) { - const loggerFactory = new MutableLoggerFactory(); + const loggerFactory = new MutableLoggerFactory(env); this.loggingService = new LoggingService(loggerFactory); this.logger = loggerFactory; diff --git a/platform/server/http/HttpServer.ts b/platform/server/http/HttpServer.ts index 153085064a361..7944f439244c3 100644 --- a/platform/server/http/HttpServer.ts +++ b/platform/server/http/HttpServer.ts @@ -29,14 +29,16 @@ export class HttpServer { async start(config: HttpConfig) { this.server = this.initializeServer(config); - const proxyListener = this.env.getNewPlatformProxyListener(); - if (proxyListener !== undefined) { - proxyListener.bind(this.server); + const legacyKbnServer = this.env.getLegacyKbnServer(); + if (legacyKbnServer !== undefined) { + legacyKbnServer.newPlatformProxyListener.bind(this.server); // We register Kibana proxy middleware right before we start server to allow // all new platform plugins register their endpoints, so that kbnServer // handles only requests that aren't handled by the new platform. - this.app.use((req, res) => proxyListener.proxy(req, res)); + this.app.use((req, res) => + legacyKbnServer.newPlatformProxyListener.proxy(req, res) + ); } this.log.info(`starting http server [${config.host}:${config.port}]`); diff --git a/platform/server/http/__tests__/HttpServer.test.ts b/platform/server/http/__tests__/HttpServer.test.ts index 7fcd8f166e32c..bf3d568fb3e79 100644 --- a/platform/server/http/__tests__/HttpServer.test.ts +++ b/platform/server/http/__tests__/HttpServer.test.ts @@ -412,7 +412,7 @@ describe('when run within legacy platform', () => { ); }); - it('binds proxy listener to server.', async () => { + test('binds proxy listener to server.', async () => { expect(newPlatformProxyListenerMock.bind).not.toHaveBeenCalled(); await server.start(config); @@ -426,7 +426,7 @@ describe('when run within legacy platform', () => { ); }); - it('forwards request to legacy platform if new one can not handle it', async () => { + test('forwards request to legacy platform if new one can not handle it', async () => { await server.start(config); await supertest((server as any).server) @@ -442,7 +442,7 @@ describe('when run within legacy platform', () => { }); }); - it('do not forward request to legacy platform if new one can handle it', async () => { + test('do not forward request to legacy platform if new one can handle it', async () => { await server.start(config); await supertest((server as any).server) diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 5f8ad90892068..cf5e64105ec2e 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -181,8 +181,8 @@ export default function (program) { kbnServer.server.log(['info', 'config'], 'Reloaded logging configuration due to SIGHUP.'); // If new platform config subscription is active, let's notify it with the updated config. - if (kbnServer.updateNewPlatformConfig) { - kbnServer.updateNewPlatformConfig(config); + if (kbnServer.newPlatform) { + kbnServer.newPlatform.updateConfig(config); } }); diff --git a/src/server/http/setup_connection.js b/src/server/http/setup_connection.js index a7338a75b73fc..293aa480e1072 100644 --- a/src/server/http/setup_connection.js +++ b/src/server/http/setup_connection.js @@ -3,7 +3,8 @@ import { map } from 'lodash'; import secureOptions from './secure_options'; export default function (kbnServer, server, config) { - const newPlatformProxyListener = kbnServer && kbnServer.newPlatformProxyListener; + const newPlatformProxyListener = kbnServer && kbnServer.newPlatform + && kbnServer.newPlatform.proxyListener; // this mixin is used outside of the kbn server, so it MUST work without a full kbnServer object. kbnServer = null;