Skip to content

Commit

Permalink
Register legacy proxy route in LegacyService instead of HttpServer.
Browse files Browse the repository at this point in the history
  • Loading branch information
azasypkin committed Jul 30, 2018
1 parent 57f4b2c commit 9821d83
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 58 deletions.
48 changes: 12 additions & 36 deletions src/core/server/http/http_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { Server } from 'hapi-latest';

import { modifyUrl } from '../../utils';
import { Env } from '../config';
import { LegacyPlatformProxifier } from '../legacy_compat';
import { Logger } from '../logging';
import { HttpConfig } from './http_config';
import { createServer, getServerOptions } from './http_tools';
Expand Down Expand Up @@ -61,36 +60,12 @@ export class HttpServer {
}
}

const legacyProxifier = new LegacyPlatformProxifier(this.log, this.server.listener);
this.env.legacy.emit('kbn:connection', {
...serverOptions,
port: undefined,
autoListen: false,
listener: legacyProxifier,
});

// We register Kibana proxy middleware right before we start server to allow
// all new platform plugins register their routes, so that `legacyProxifier`
// handles only requests that aren't handled by the new platform.
this.server.route({
handler: ({ raw: { req, res } }, responseToolkit) => {
this.log.debug(`Request will be handled by proxy ${req.method}:${req.url}.`);

// Forward request and response objects to the legacy platform. This method
// is used whenever new platform doesn't know how to handle the request.
legacyProxifier.emit('request', req, res);

return responseToolkit.abandon;
},
method: '*',
options: {
payload: {
output: 'stream',
parse: false,
timeout: false,
},
},
path: '/{p*}',
// Notify legacy compatibility layer about HTTP(S) connection providing server
// instance with connection options so that we can properly bridge core and
// the "legacy" Kibana internally.
this.env.legacy.emit('connection', {
options: serverOptions,
server: this.server,
});

await this.server.start();
Expand All @@ -103,12 +78,13 @@ export class HttpServer {
}

public async stop() {
this.log.info('stopping http server');

if (this.server !== undefined) {
await this.server.stop();
this.server = undefined;
if (this.server === undefined) {
return;
}

this.log.info('stopping http server');
await this.server.stop();
this.server = undefined;
}

private setupBasePathRewrite(server: Server, config: HttpConfig) {
Expand Down
11 changes: 6 additions & 5 deletions src/core/server/http/https_redirect_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ export class HttpsRedirectServer {
}

public async stop() {
this.log.info('stopping HTTPS redirect server');

if (this.server !== undefined) {
await this.server.stop();
this.server = undefined;
if (this.server === undefined) {
return;
}

this.log.info('stopping HTTP --> HTTPS redirect server');
await this.server.stop();
this.server = undefined;
}
}
65 changes: 48 additions & 17 deletions src/core/server/legacy_compat/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@
* under the License.
*/

import { EventEmitter } from 'events';
import { ServerOptions } from 'hapi-latest';
import { Server, ServerOptions } from 'hapi-latest';
import { CLUSTER_MANAGER_PATH, REPL_PATH } from '../../cli/installation_features';
import { $combineLatest, first, k$, map, Subscription, toPromise } from '../../lib/kbn_observable';
import {
$combineLatest,
BehaviorSubject,
filter,
first,
k$,
map,
Subscription,
toPromise,
} from '../../lib/kbn_observable';
import { CoreService } from '../../types/core_service';
import { ConfigService, Env, RawConfig } from '../config';
import { DevConfig } from '../dev';
import { BasePathProxyServer, HttpConfig } from '../http';
import { Logger, LoggerFactory } from '../logging';
import { LegacyPlatformProxifier } from './index';

interface LegacyKbnServer {
applyLoggingConfiguration: (settings: Readonly<Record<string, any>>) => void;
Expand All @@ -51,14 +60,15 @@ export class LegacyService implements CoreService {
private readonly log: Logger;
private kbnServer?: LegacyKbnServer;
private kbnServerSubscription?: Subscription;
private readonly connection$: BehaviorSubject<ServerOptions | null> = new BehaviorSubject(null);

constructor(
private readonly env: Env,
private readonly logger: LoggerFactory,
private readonly configService: ConfigService,
private readonly options: LegacyServiceOptions
) {
this.log = logger.get('legacy.service');
this.log = logger.get('legacy', 'service');

this.setupConnectionListener();
}
Expand Down Expand Up @@ -104,19 +114,40 @@ export class LegacyService implements CoreService {
}

private setupConnectionListener() {
let serverOptions: ServerOptions;
this.env.legacy.once('kbn:connection', options => {
serverOptions = options;
});

this.env.legacy.on('newListener', function onNewListener(this: EventEmitter, event, listener) {
if (event === 'kbn:connection' && serverOptions !== undefined) {
listener(serverOptions);

// Node enforces that `this` points to the `env.legacy`.
this.removeListener('newListener', onNewListener);
this.env.legacy.once(
'connection',
({ server, options }: { server: Server; options: ServerOptions }) => {
const legacyProxifier = new LegacyPlatformProxifier(
this.logger.get('legacy', 'proxy'),
server.listener
);

// We register Kibana proxy middleware right before we start server to allow
// all new platform plugins register their routes, so that `legacyProxifier`
// handles only requests that aren't handled by the new platform.
server.route({
path: '/{p*}',
method: '*',
options: { payload: { output: 'stream', parse: false, timeout: false } },
handler: ({ raw: { req, res } }, responseToolkit) => {
this.log.debug(`Request will be handled by proxy ${req.method}:${req.url}.`);

// Forward request and response objects to the legacy platform. This method
// is used whenever new platform doesn't know how to handle the request.
legacyProxifier.emit('request', req, res);

return responseToolkit.abandon;
},
});

this.connection$.next({
...options,
port: undefined,
autoListen: false,
listener: legacyProxifier as any,
});
}
});
);
}

private async createClusterManager(rawConfig: RawConfig) {
Expand Down Expand Up @@ -158,7 +189,7 @@ export class LegacyService implements CoreService {
// let it continue initialization without waiting for connection options.
const connection = !httpConfig.autoListen
? { autoListen: false }
: await new Promise(resolve => this.env.legacy.once('kbn:connection', resolve));
: await k$(this.connection$)(filter(conn => conn !== null), first(), toPromise());

const KbnServer = require('../../../server/kbn_server');
const kbnServer: LegacyKbnServer = new KbnServer(rawConfig.getRaw(), { connection });
Expand Down

0 comments on commit 9821d83

Please sign in to comment.