diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 9eae7fd717eda09..c5c7d82e223b0d0 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -40,6 +40,23 @@ import { getByAlias } from '../util/get_by_alias'; import { ExecutionContract } from './execution_contract'; import { ExpressionExecutionParams } from '../service'; +/** + * AbortController is not available in Node until v15, so we + * need to temporarily mock it for plugins using expressions + * on the server. + * + * TODO: Remove this once Kibana is upgraded to Node 15. + */ +const getNewAbortController = (): AbortController => { + try { + return new AbortController(); + } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const polyfill = require('abortcontroller-polyfill/dist/cjs-ponyfill'); + return new polyfill.AbortController(); + } +}; + const createAbortErrorValue = () => createError({ message: 'The expression was aborted.', @@ -87,7 +104,7 @@ export class Execution< /** * AbortController to cancel this Execution. */ - private readonly abortController = new AbortController(); + private readonly abortController = getNewAbortController(); /** * Promise that rejects if/when abort controller sends "abort" signal. diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json index 7eafb185617c421..084cee2fddf0845 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json @@ -8,7 +8,7 @@ "kibanaUtils", "expressions" ], - "server": false, + "server": true, "ui": true, "requiredBundles": [ "inspector" diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/index.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/index.ts new file mode 100644 index 000000000000000..2e55966785909a1 --- /dev/null +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/index.ts @@ -0,0 +1,23 @@ +/* + * 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 { PluginInitializer } from '../../../../../src/core/server'; +import { TestPlugin, TestPluginSetup, TestPluginStart } from './plugin'; + +export const plugin: PluginInitializer = () => new TestPlugin(); diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/plugin.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/plugin.ts new file mode 100644 index 000000000000000..260d12cd3d2c35d --- /dev/null +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/server/plugin.ts @@ -0,0 +1,59 @@ +/* + * 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 } from '@kbn/config-schema'; +import { CoreSetup, Plugin } from '../../../../../src/core/server'; +import { PluginStart as DataPluginStart } from '../../../../../src/plugins/data/server'; +import { ExpressionsServerStart } from '../../../../../src/plugins/expressions/server'; + +export interface TestStartDeps { + data: DataPluginStart; + expressions: ExpressionsServerStart; +} + +export class TestPlugin implements Plugin { + public setup(core: CoreSetup) { + const router = core.http.createRouter(); + + router.post( + { + path: '/api/interpreter_functional/run_expression', + validate: { + body: schema.object({ + input: schema.maybe(schema.object({}, { unknowns: 'allow' })), + expression: schema.string(), + }), + }, + }, + async (context, req, res) => { + const [, { expressions }] = await core.getStartServices(); + const output = await expressions.run(req.body.expression, req.body.input, { + kibanaRequest: req, + }); + return res.ok({ body: output }); + } + ); + } + + public start() {} + public stop() {} +} + +export type TestPluginSetup = ReturnType; +export type TestPluginStart = ReturnType; diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json index f77a5eaffc3018b..3d9d8ca9451d41e 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json @@ -8,6 +8,7 @@ "index.ts", "public/**/*.ts", "public/**/*.tsx", + "server/**/*.ts", "../../../../typings/**/*", ], "exclude": [], diff --git a/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts b/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts index a7a7118da5222f2..acf72000d162bc2 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts @@ -33,13 +33,15 @@ export default function ({ getService, updateBaselines, }: FtrProviderContext & { updateBaselines: boolean }) { + const supertest = getService('supertest'); let expectExpression: ExpectExpression; + describe('esaggs pipeline expression tests', () => { before(() => { expectExpression = expectExpressionProvider({ getService, updateBaselines }); }); - describe('correctly renders tagcloud', () => { + describe('correctly filters based on context', () => { it('filters on index pattern primary date field by default', async () => { const timeRange = { from: '2006-09-21T00:00:00Z', @@ -88,5 +90,25 @@ export default function ({ expect(getCell(result, 0, 0)).to.be(7452); }); }); + + describe('correctly runs on the server', () => { + it('runs the provided agg on the server', async () => { + const expression = ` + esaggs index={indexPatternLoad id='logstash-*'} + aggs={aggAvg id="1" enabled=true schema="metric" field="bytes"} + `; + await supertest + .post('/api/interpreter_functional/run_expression') + .set('kbn-xsrf', 'anything') + .send({ expression, input: undefined }) + .expect(200) + .expect(({ body }) => { + expect(body.columns[0].meta.index).to.be('logstash-*'); + expect(body.columns[0].meta.source).to.be('esaggs'); + expect(body.columns[0].meta.sourceParams.type).to.be('avg'); + expect(getCell(body, 0, 0)).to.be(5727.3136246786635); + }); + }); + }); }); }