Skip to content

Commit

Permalink
[Vega] Shim new platform (#40032)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexwizp authored Jul 19, 2019
1 parent 8b5aa21 commit 206266d
Show file tree
Hide file tree
Showing 19 changed files with 521 additions and 259 deletions.
47 changes: 47 additions & 0 deletions src/legacy/core_plugins/vega/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 { resolve } from 'path';
import { Legacy } from 'kibana';

import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';

const vegaPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
new Plugin({
id: 'vega',
require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'],
publicDir: resolve(__dirname, 'public'),
uiExports: {
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
hacks: [resolve(__dirname, 'public/legacy')],
injectDefaultVars: server => ({
enableExternalUrls: server.config().get('vega.enableExternalUrls'),
}),
},
init: (server: Legacy.Server) => ({}),
config(Joi: any) {
return Joi.object({
enabled: Joi.boolean().default(true),
enableExternalUrls: Joi.boolean().default(false),
}).default();
},
} as Legacy.PluginSpecOptions);

// eslint-disable-next-line import/no-default-export
export default vegaPluginInitializer;
32 changes: 21 additions & 11 deletions src/legacy/core_plugins/vega/public/__tests__/vega_visualization.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Promise from 'bluebird';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import $ from 'jquery';
import { VegaVisualizationProvider } from '../vega_visualization';
import { createVegaVisualization } from '../vega_visualization';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
import * as visModule from 'ui/vis';
import { ImageComparator } from 'test_utils/image_comparator';
Expand All @@ -41,33 +41,44 @@ import vegaMapImage256 from './vega_map_image_256.png';
import { VegaParser } from '../data_model/vega_parser';
import { SearchCache } from '../data_model/search_cache';

import { visualizations } from '../../../visualizations/public';
import { createVegaTypeDefinition } from '../vega_type';

const THRESHOLD = 0.10;
const PIXEL_DIFF = 10;
const PIXEL_DIFF = 30;

describe('VegaVisualizations', () => {

let domNode;
let VegaVisualization;
let Vis;
let indexPattern;
let vis;
let imageComparator;
let vegaVisualizationDependencies;

beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject((Private) => {
beforeEach(ngMock.inject((Private, $injector) => {
vegaVisualizationDependencies = {
es: $injector.get('es'),
serviceSettings: $injector.get('serviceSettings'),
uiSettings: $injector.get('config'),
};

visualizations.types.VisTypesRegistryProvider.register(() =>
createVegaTypeDefinition(vegaVisualizationDependencies)
);

Vis = Private(visModule.VisProvider);
VegaVisualization = Private(VegaVisualizationProvider);
indexPattern = Private(LogstashIndexPatternStubProvider);

VegaVisualization = createVegaVisualization(vegaVisualizationDependencies);
indexPattern = Private(LogstashIndexPatternStubProvider);
}));


describe('VegaVisualization - basics', () => {

beforeEach(async function () {
setupDOM('512px', '512px');
imageComparator = new ImageComparator();

vis = new Vis(indexPattern, { type: 'vega' });
});

Expand All @@ -77,10 +88,10 @@ describe('VegaVisualizations', () => {
});

it('should show vegalite graph and update on resize', async function () {

let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, vis);

const vegaParser = new VegaParser(vegaliteGraph, new SearchCache());
await vegaParser.parseAsync();

Expand All @@ -105,15 +116,14 @@ describe('VegaVisualizations', () => {

let vegaVis;
try {

vegaVis = new VegaVisualization(domNode, vis);
const vegaParser = new VegaParser(vegaGraph, new SearchCache());
await vegaParser.parseAsync();

await vegaVis.render(vegaParser, vis.params, { data: true });
const mismatchedPixels = await compareImage(vegaImage512);
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);

expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
} finally {
vegaVis.destroy();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,18 @@ describe('EsQueryParser.populateData', () => {

beforeEach(() => {
searchStub = sinon.stub();
parser = new EsQueryParser({}, { search: searchStub }, undefined, undefined, 1234);
parser = new EsQueryParser({}, { search: searchStub }, undefined, undefined);

searchStub.returns(Promise.resolve([{}, {}]));
});
it('should set the timeout for each request', async () => {
await parser.populateData([{ url: { body: { } }, dataObject: {} }, { url: { body: {} }, dataObject: {} }]);
expect(searchStub.firstCall.args[0][0].body.timeout).to.eql('1234ms');
expect(searchStub.firstCall.args[0][1].body.timeout).to.eql('1234ms');
expect(searchStub.firstCall.args[0][0].body.timeout).to.be.defined;
});

it('should remove possible timeout parameters on a request', async () => {
await parser.populateData([{ url: { timeout: '500h', body: { timeout: '500h' } }, dataObject: {} }]);
expect(searchStub.firstCall.args[0][0].body.timeout).to.eql('1234ms');
expect(searchStub.firstCall.args[0][0].body.timeout).to.be.defined;
expect(searchStub.firstCall.args[0][0].timeout).to.be(undefined);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import _ from 'lodash';
import moment from 'moment';
import { i18n } from '@kbn/i18n';

import { getEsShardTimeout } from '../helpers';

const TIMEFILTER = '%timefilter%';
const AUTOINTERVAL = '%autointerval%';
const MUST_CLAUSE = '%dashboard_context-must_clause%';
Expand All @@ -36,12 +38,12 @@ const TIMEFIELD = '%timefield%';
*/
export class EsQueryParser {

constructor(timeCache, searchCache, filters, onWarning, esShardTimeout) {
constructor(timeCache, searchCache, filters, onWarning) {
this._timeCache = timeCache;
this._searchCache = searchCache;
this._filters = filters;
this._onWarning = onWarning;
this._esShardTimeout = esShardTimeout;
this._esShardTimeout = getEsShardTimeout();
}

// noinspection JSMethodCanBeStatic
Expand Down
4 changes: 2 additions & 2 deletions src/legacy/core_plugins/vega/public/data_model/vega_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ const DEFAULT_PARSER = 'elasticsearch';

export class VegaParser {

constructor(spec, searchCache, timeCache, filters, serviceSettings, esShardTimeout) {
constructor(spec, searchCache, timeCache, filters, serviceSettings) {
this.spec = spec;
this.hideWarnings = false;
this.error = undefined;
this.warnings = [];

const onWarn = this._onWarning.bind(this);
this._urlParsers = {
elasticsearch: new EsQueryParser(timeCache, searchCache, filters, onWarn, esShardTimeout),
elasticsearch: new EsQueryParser(timeCache, searchCache, filters, onWarn),
emsfile: new EmsFileParser(serviceSettings),
url: new UrlParser(onWarn),
};
Expand Down
20 changes: 20 additions & 0 deletions src/legacy/core_plugins/vega/public/helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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.
*/

export * from './vega_config_provider';
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,7 @@
* under the License.
*/

import { resolve } from 'path';
import chrome from 'ui/chrome';

export default kibana => new kibana.Plugin({
id: 'vega',
require: ['elasticsearch'],

uiExports: {
visTypes: ['plugins/vega/vega_type'],
interpreter: ['plugins/vega/vega_fn'],
injectDefaultVars: server => ({ vegaConfig: server.config().get('vega') }),
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
},

config: (Joi) => Joi.object({
enabled: Joi.boolean().default(true),
enableExternalUrls: Joi.boolean().default(false)
}).default(),

});
export const getEsShardTimeout = () => chrome.getInjected('esShardTimeout');
export const getEnableExternalUrls = () => chrome.getInjected('enableExternalUrls');
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,9 @@
* under the License.
*/

import { PluginInitializerContext } from '../../../../core/public';
import { VegaPlugin as Plugin } from './plugin';

import 'ngreact';

import { wrapInI18nContext } from 'ui/i18n';
import { uiModules } from 'ui/modules';
const module = uiModules.get('kibana/vega', ['react']);

import { VegaHelpMenu } from './vega_help_menu';
import { VegaActionsMenu } from './vega_action_menu';

module.directive('vegaActionsMenu', function (reactDirective) {
return reactDirective(wrapInI18nContext(VegaActionsMenu));
});

module.directive('vegaHelpMenu', function (reactDirective) {
return reactDirective(wrapInI18nContext(VegaHelpMenu));
});
export function plugin(initializerContext: PluginInitializerContext) {
return new Plugin(initializerContext);
}
40 changes: 40 additions & 0 deletions src/legacy/core_plugins/vega/public/legacy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 { PluginInitializerContext } from 'kibana/public';
import { npSetup, npStart } from 'ui/new_platform';

import { visualizations } from '../../visualizations/public';
import { VegaPluginSetupDependencies } from './plugin';
import { LegacyDependenciesPlugin } from './shim';
import { plugin } from '.';

const plugins: Readonly<VegaPluginSetupDependencies> = {
visualizations,
data: npSetup.plugins.data,

// Temporary solution
// It will be removed when all dependent services are migrated to the new platform.
__LEGACY: new LegacyDependenciesPlugin(),
};

const pluginInstance = plugin({} as PluginInitializerContext);

export const setup = pluginInstance.setup(npSetup.core, plugins);
export const start = pluginInstance.start(npStart.core);
75 changes: 75 additions & 0 deletions src/legacy/core_plugins/vega/public/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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 {
PluginInitializerContext,
CoreSetup,
CoreStart,
Plugin,
UiSettingsClientContract,
} from '../../../../core/public';
import { LegacyDependenciesPlugin, LegacyDependenciesPluginSetup } from './shim';

// @ts-ignore
import { createVegaFn } from './vega_fn';
// @ts-ignore
import { createVegaTypeDefinition } from './vega_type';
import { DataSetup } from '../../data/public';
import { VisualizationsSetup } from '../../visualizations/public';

/** @private */
interface VegaVisualizationDependencies extends LegacyDependenciesPluginSetup {
uiSettings: UiSettingsClientContract;
}

/** @internal */
export interface VegaPluginSetupDependencies {
// TODO: Remove `any` as functionsRegistry will be added to the DataSetup.
data: DataSetup | any;
visualizations: VisualizationsSetup;
__LEGACY: LegacyDependenciesPlugin;
}

/** @internal */
export class VegaPlugin implements Plugin<Promise<void>, void> {
initializerContext: PluginInitializerContext;

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

public async setup(
core: CoreSetup,
{ data, visualizations, __LEGACY }: VegaPluginSetupDependencies
) {
const visualizationDependencies: Readonly<VegaVisualizationDependencies> = {
uiSettings: core.uiSettings,
...(await __LEGACY.setup()),
};

data.expressions.registerFunction(() => createVegaFn(visualizationDependencies));

visualizations.types.VisTypesRegistryProvider.register(() =>
createVegaTypeDefinition(visualizationDependencies)
);
}

public start(core: CoreStart) {
// nothing to do here yet
}
}
Loading

0 comments on commit 206266d

Please sign in to comment.