Skip to content

Commit

Permalink
vis_type_timeseries server side new platform migration (elastic#52501)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerry350 committed Dec 19, 2019
1 parent d20a6bc commit 10cfd9e
Show file tree
Hide file tree
Showing 17 changed files with 292 additions and 143 deletions.
13 changes: 4 additions & 9 deletions src/legacy/core_plugins/vis_type_timeseries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@

import { resolve } from 'path';
import { Legacy } from 'kibana';
import { PluginInitializerContext } from 'src/core/server';
import { CoreSetup } from 'src/core/server';

import { plugin } from './server/';
import { CustomCoreSetup } from './server/plugin';

import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';
import { VisTypeTimeseriesSetup } from '../../../plugins/vis_type_timeseries/server';

const metricsPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
new Plugin({
Expand All @@ -38,10 +34,9 @@ const metricsPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPlu
injectDefaultVars: server => ({}),
},
init: (server: Legacy.Server) => {
const initializerContext = {} as PluginInitializerContext;
const core = { http: { server } } as CoreSetup & CustomCoreSetup;

plugin(initializerContext).setup(core);
const visTypeTimeSeriesPlugin = server.newPlatform.setup.plugins
.metrics as VisTypeTimeseriesSetup;
visTypeTimeSeriesPlugin.__legacy.registerLegacyAPI({ server });
},
config(Joi: any) {
return Joi.object({
Expand Down
8 changes: 2 additions & 6 deletions src/legacy/core_plugins/vis_type_timeseries/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,5 @@
* under the License.
*/

import { PluginInitializerContext } from 'kibana/server';
import { MetricsServerPlugin as Plugin } from './plugin';

export function plugin(initializerContext: PluginInitializerContext) {
return new Plugin(initializerContext);
}
export { init } from './init';
export { getVisData, GetVisData, GetVisDataOptions } from './lib/get_vis_data';
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
* under the License.
*/

import { Legacy } from 'kibana';
import { PluginInitializerContext, CoreSetup } from 'kibana/server';

// @ts-ignore
import { fieldsRoutes } from './routes/fields';
// @ts-ignore
Expand All @@ -28,30 +25,15 @@ import { visDataRoutes } from './routes/vis';
import { SearchStrategiesRegister } from './lib/search_strategies/search_strategies_register';
// @ts-ignore
import { getVisData } from './lib/get_vis_data';
import { Framework } from '../../../../plugins/vis_type_timeseries/server';

// TODO: Remove as CoreSetup is completed.
export interface CustomCoreSetup {
http: {
server: Legacy.Server;
};
}

export class MetricsServerPlugin {
public initializerContext: PluginInitializerContext;

constructor(initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
}

public setup(core: CoreSetup & CustomCoreSetup) {
const { http } = core;

fieldsRoutes(http.server);
visDataRoutes(http.server);
export const init = async (framework: Framework, __LEGACY: any) => {
const { core } = framework;
const router = core.http.createRouter();

// Expose getVisData to allow plugins to use TSVB's backend for metrics
http.server.expose('getVisData', getVisData);
visDataRoutes(router, framework);

SearchStrategiesRegister.init(http.server);
}
}
// [LEGACY_TODO]
fieldsRoutes(__LEGACY.server);
SearchStrategiesRegister.init(__LEGACY.server);
};
101 changes: 101 additions & 0 deletions src/legacy/core_plugins/vis_type_timeseries/server/lib/get_vis_data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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 { RequestHandlerContext } from 'src/core/server';
import _ from 'lodash';
import { first, map } from 'rxjs/operators';
import { getPanelData } from './vis_data/get_panel_data';
import { Framework } from '../../../../../plugins/vis_type_timeseries/server';

interface GetVisDataResponse {
[key: string]: GetVisDataPanel;
}

interface GetVisDataPanel {
id: string;
series: GetVisDataSeries[];
}

interface GetVisDataSeries {
id: string;
label: string;
data: GetVisDataDataPoint[];
}

type GetVisDataDataPoint = [number, number];

export interface GetVisDataOptions {
timerange?: any;
panels?: any;
filters?: any;
state?: any;
query?: any;
}

export type GetVisData = (
requestContext: RequestHandlerContext,
options: GetVisDataOptions,
framework: Framework
) => Promise<GetVisDataResponse>;

export function getVisData(
requestContext: RequestHandlerContext,
options: GetVisDataOptions,
framework: Framework
): Promise<GetVisDataResponse> {
// NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It
// removes the need to refactor many layers of dependencies on "req", and instead just augments the top
// level object passed from here. The layers should be refactored fully at some point, but for now
// this works and we are still using the New Platform services for these vis data portions.
const reqFacade: any = {
payload: options,
getUiSettingsService: () => requestContext.core.uiSettings.client,
getSavedObjectsClient: () => requestContext.core.savedObjects.client,
server: {
plugins: {
elasticsearch: {
getCluster: () => {
return {
callWithRequest: async (req: any, endpoint: string, params: any) => {
return await requestContext.core.elasticsearch.dataClient.callAsCurrentUser(
endpoint,
params
);
},
};
},
},
},
},
getEsShardTimeout: async () => {
return await framework.globalConfig$
.pipe(
first(),
map(config => config.elasticsearch.shardTimeout.asMilliseconds())
)
.toPromise();
},
};
const promises = reqFacade.payload.panels.map(getPanelData(reqFacade));
return Promise.all(promises).then(res => {
return res.reduce((acc, data) => {
return _.assign(acc as any, data);
}, {});
}) as Promise<GetVisDataResponse>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,14 @@
* under the License.
*/

import moment from 'moment';
import { of } from 'rxjs';
import { expect } from 'chai';
import { getEsShardTimeout } from '../../helpers/get_es_shard_timeout';

describe('getEsShardTimeout', () => {
it('should return the elasticsearch.shardTimeout', async () => {
const req = {
server: {
newPlatform: {
__internals: {
elasticsearch: { legacy: { config$: of({ shardTimeout: moment.duration(12345) }) } },
},
},
getEsShardTimeout: async () => {
return 12345;
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,4 @@
* under the License.
*/

import _ from 'lodash';
import { getPanelData } from './vis_data/get_panel_data';

export function getVisData(req) {
const promises = req.payload.panels.map(getPanelData(req));
return Promise.all(promises).then(res => {
return res.reduce((acc, data) => {
return _.assign(acc, data);
}, {});
});
}
export function getPanelData(req: any): any;
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export async function getSeriesData(req, panel) {

const data = await searchRequest.search(searches);
const series = data.map(handleResponseBody(panel));

let annotations = null;

if (panel.annotations && panel.annotations.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { first, map } from 'rxjs/operators';

export async function getEsShardTimeout(req) {
return await req.server.newPlatform.__internals.elasticsearch.legacy.config$
.pipe(
first(),
map(config => config.shardTimeout.asMilliseconds())
)
.toPromise();
return await req.getEsShardTimeout();
}
35 changes: 20 additions & 15 deletions src/legacy/core_plugins/vis_type_timeseries/server/routes/vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,28 @@
* under the License.
*/

import { schema } from '@kbn/config-schema';
import { getVisData } from '../lib/get_vis_data';
import Boom from 'boom';

export const visDataRoutes = server => {
server.route({
path: '/api/metrics/vis/data',
method: 'POST',
handler: async req => {
try {
return await getVisData(req);
} catch (err) {
if (err.isBoom && err.status === 401) {
return err;
}
const escapeHatch = schema.object({}, { allowUnknowns: true });

throw Boom.boomify(err, { statusCode: 500 });
}
export const visDataRoutes = (router, framework) => {
router.post(
{
path: '/api/metrics/vis/data',
validate: {
body: escapeHatch,
},
},
});
async (requestContext, request, response) => {
try {
const results = await getVisData(requestContext, request.body, framework);
return response.ok({ body: results });
} catch (error) {
return response.internalError({
body: error.message,
});
}
}
);
};
6 changes: 6 additions & 0 deletions src/plugins/vis_type_timeseries/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "metrics",
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true
}
35 changes: 35 additions & 0 deletions src/plugins/vis_type_timeseries/server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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';
import { PluginInitializerContext } from 'src/core/server';
import { VisTypeTimeseriesPlugin } from './plugin';
export { VisTypeTimeseriesSetup, Framework } from './plugin';

export const config = {
schema: schema.object({
enabled: schema.boolean({ defaultValue: true }),
}),
};

export type VisTypeTimeseriesConfig = TypeOf<typeof config.schema>;

export function plugin(initializerContext: PluginInitializerContext) {
return new VisTypeTimeseriesPlugin(initializerContext);
}
Loading

0 comments on commit 10cfd9e

Please sign in to comment.