From 5242103e4a3d835803ad9039f5dfcbe5665cfbf3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 18 Sep 2020 08:58:35 +0300 Subject: [PATCH] Use Search API in TSVB (#76274) (#77767) * Use Search API for TSVB * Fixed ci * Fixed ci * Use constants * Fixed tests * Fixed ci * Fixed ci * Back old rollup search * Fixed test * Fixed tests * Fixed issue with series data * Fixed comments * Fixed comments * Fixed unit test * Deleted unused import * Fixed comments Co-authored-by: Elastic Machine Co-authored-by: Uladzislau Lasitsa Co-authored-by: Elastic Machine --- .../vis_type_timeseries/server/index.ts | 10 +-- .../server/lib/get_fields.ts | 17 +---- .../server/lib/get_vis_data.ts | 19 +---- .../search_requests/abstract_request.js | 28 ------- .../search_requests/abstract_request.test.js | 46 ----------- .../search_requests/multi_search_request.js | 49 ------------ .../multi_search_request.test.js | 67 ---------------- .../search_requests/search_request.js | 37 --------- .../search_requests/search_request.test.js | 76 ------------------- .../search_requests/single_search_request.js | 37 --------- .../single_search_request.test.js | 59 -------------- .../search_strategies_registry.test.ts | 4 +- .../abstract_search_strategy.test.js | 69 ++++++++++------- .../strategies/abstract_search_strategy.ts | 55 ++++++++------ .../strategies/default_search_strategy.js | 13 +--- .../default_search_strategy.test.js | 28 +------ .../server/lib/vis_data/get_annotations.js | 6 +- .../server/lib/vis_data/get_series_data.js | 10 ++- .../server/lib/vis_data/get_table_data.js | 10 ++- .../vis_type_timeseries/server/plugin.ts | 12 ++- .../vis_type_timeseries/server/routes/vis.ts | 3 +- x-pack/plugins/data_enhanced/server/index.ts | 2 + .../register_rollup_search_strategy.test.js | 11 +-- .../register_rollup_search_strategy.ts | 13 ++-- .../rollup_search_request.test.js | 53 ------------- .../rollup_search_request.ts | 28 ------- .../rollup_search_strategy.test.js | 44 +++++++---- .../rollup_search_strategy.ts | 46 ++++++----- x-pack/plugins/rollup/server/plugin.ts | 20 ++--- x-pack/plugins/rollup/server/types.ts | 8 +- 30 files changed, 193 insertions(+), 687 deletions(-) delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.test.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.test.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js delete mode 100644 src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js delete mode 100644 x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.test.js delete mode 100644 x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.ts diff --git a/src/plugins/vis_type_timeseries/server/index.ts b/src/plugins/vis_type_timeseries/server/index.ts index f460257caf5e3..333ed0ff64fdb 100644 --- a/src/plugins/vis_type_timeseries/server/index.ts +++ b/src/plugins/vis_type_timeseries/server/index.ts @@ -21,7 +21,7 @@ import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/serve import { VisTypeTimeseriesConfig, config as configSchema } from './config'; import { VisTypeTimeseriesPlugin } from './plugin'; -export { VisTypeTimeseriesSetup, Framework } from './plugin'; +export { VisTypeTimeseriesSetup } from './plugin'; export const config: PluginConfigDescriptor = { deprecations: ({ unused, renameFromRoot }) => [ @@ -39,10 +39,10 @@ export const config: PluginConfigDescriptor = { export { ValidationTelemetryServiceSetup } from './validation_telemetry'; -// @ts-ignore -export { AbstractSearchStrategy } from './lib/search_strategies/strategies/abstract_search_strategy'; -// @ts-ignore -export { AbstractSearchRequest } from './lib/search_strategies/search_requests/abstract_request'; +export { + AbstractSearchStrategy, + ReqFacade, +} from './lib/search_strategies/strategies/abstract_search_strategy'; // @ts-ignore export { DefaultSearchCapabilities } from './lib/search_strategies/default_search_capabilities'; diff --git a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts index 0f0d99bff6f1c..777de89672bbe 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts @@ -38,6 +38,7 @@ export async function getFields( // 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: ReqFacade = { + requestContext, ...request, framework, payload: {}, @@ -48,22 +49,6 @@ export async function getFields( }, 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.legacy.client.callAsCurrentUser( - endpoint, - params - ); - }, - }; - }, - }, - }, - }, getEsShardTimeout: async () => { return await framework.globalConfig$ .pipe( diff --git a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts index f697e754a2e00..5eef2b53e2431 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts @@ -21,7 +21,7 @@ import { FakeRequest, RequestHandlerContext } from 'kibana/server'; import _ from 'lodash'; import { first, map } from 'rxjs/operators'; import { getPanelData } from './vis_data/get_panel_data'; -import { Framework } from '../index'; +import { Framework } from '../plugin'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; interface GetVisDataResponse { @@ -65,28 +65,13 @@ export function getVisData( // 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: ReqFacade = { + requestContext, ...request, framework, pre: {}, payload: request.body, 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.legacy.client.callAsCurrentUser( - endpoint, - params - ); - }, - }; - }, - }, - }, - }, getEsShardTimeout: async () => { return await framework.globalConfig$ .pipe( diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.js deleted file mode 100644 index abd2a4c65d35c..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 class AbstractSearchRequest { - constructor(req, callWithRequest) { - this.req = req; - this.callWithRequest = callWithRequest; - } - - search() { - throw new Error('AbstractSearchRequest: search method should be defined'); - } -} diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.test.js deleted file mode 100644 index 6f71aa63728d5..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/abstract_request.test.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 { AbstractSearchRequest } from './abstract_request'; - -describe('AbstractSearchRequest', () => { - let searchRequest; - let req; - let callWithRequest; - - beforeEach(() => { - req = {}; - callWithRequest = jest.fn(); - searchRequest = new AbstractSearchRequest(req, callWithRequest); - }); - - test('should init an AbstractSearchRequest instance', () => { - expect(searchRequest.req).toBe(req); - expect(searchRequest.callWithRequest).toBe(callWithRequest); - expect(searchRequest.search).toBeDefined(); - }); - - test('should throw an error trying to search', () => { - try { - searchRequest.search(); - } catch (error) { - expect(error instanceof Error).toBe(true); - expect(error.message).toEqual('AbstractSearchRequest: search method should be defined'); - } - }); -}); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js deleted file mode 100644 index 9ada39e359589..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 { AbstractSearchRequest } from './abstract_request'; -import { UI_SETTINGS } from '../../../../../data/server'; - -const SEARCH_METHOD = 'msearch'; - -export class MultiSearchRequest extends AbstractSearchRequest { - async search(searches) { - const includeFrozen = await this.req - .getUiSettingsService() - .get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - const multiSearchBody = searches.reduce( - (acc, { body, index }) => [ - ...acc, - { - index, - ignoreUnavailable: true, - }, - body, - ], - [] - ); - - const { responses } = await this.callWithRequest(this.req, SEARCH_METHOD, { - body: multiSearchBody, - rest_total_hits_as_int: true, - ignore_throttled: !includeFrozen, - }); - - return responses; - } -} diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js deleted file mode 100644 index c113db76332b7..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 { MultiSearchRequest } from './multi_search_request'; -import { UI_SETTINGS } from '../../../../../data/server'; - -describe('MultiSearchRequest', () => { - let searchRequest; - let req; - let callWithRequest; - let getServiceMock; - let includeFrozen; - - beforeEach(() => { - includeFrozen = false; - getServiceMock = jest.fn().mockResolvedValue(includeFrozen); - req = { - getUiSettingsService: jest.fn().mockReturnValue({ get: getServiceMock }), - }; - callWithRequest = jest.fn().mockReturnValue({ responses: [] }); - searchRequest = new MultiSearchRequest(req, callWithRequest); - }); - - test('should init an MultiSearchRequest instance', () => { - expect(searchRequest.req).toBe(req); - expect(searchRequest.callWithRequest).toBe(callWithRequest); - expect(searchRequest.search).toBeDefined(); - }); - - test('should get the response from elastic msearch', async () => { - const searches = [ - { body: 'body1', index: 'index' }, - { body: 'body2', index: 'index' }, - ]; - - const responses = await searchRequest.search(searches); - - expect(responses).toEqual([]); - expect(req.getUiSettingsService).toHaveBeenCalled(); - expect(getServiceMock).toHaveBeenCalledWith(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - expect(callWithRequest).toHaveBeenCalledWith(req, 'msearch', { - body: [ - { ignoreUnavailable: true, index: 'index' }, - 'body1', - { ignoreUnavailable: true, index: 'index' }, - 'body2', - ], - rest_total_hits_as_int: true, - ignore_throttled: !includeFrozen, - }); - }); -}); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.js deleted file mode 100644 index e6e3bcb527286..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 { AbstractSearchRequest } from './abstract_request'; - -import { MultiSearchRequest } from './multi_search_request'; -import { SingleSearchRequest } from './single_search_request'; - -export class SearchRequest extends AbstractSearchRequest { - getSearchRequestType(searches) { - const isMultiSearch = Array.isArray(searches) && searches.length > 1; - const SearchRequest = isMultiSearch ? MultiSearchRequest : SingleSearchRequest; - - return new SearchRequest(this.req, this.callWithRequest); - } - - async search(options) { - const concreteSearchRequest = this.getSearchRequestType(options); - - return concreteSearchRequest.search(options); - } -} diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.test.js deleted file mode 100644 index 3d35a4aa37c5a..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/search_request.test.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 { SearchRequest } from './search_request'; -import { MultiSearchRequest } from './multi_search_request'; -import { SingleSearchRequest } from './single_search_request'; - -describe('SearchRequest', () => { - let searchRequest; - let req; - let callWithRequest; - let getServiceMock; - let includeFrozen; - - beforeEach(() => { - includeFrozen = false; - getServiceMock = jest.fn().mockResolvedValue(includeFrozen); - req = { - getUiSettingsService: jest.fn().mockReturnValue({ get: getServiceMock }), - }; - callWithRequest = jest.fn().mockReturnValue({ responses: [] }); - searchRequest = new SearchRequest(req, callWithRequest); - }); - - test('should init an AbstractSearchRequest instance', () => { - expect(searchRequest.req).toBe(req); - expect(searchRequest.callWithRequest).toBe(callWithRequest); - expect(searchRequest.search).toBeDefined(); - }); - - test('should return search value', async () => { - const concreteSearchRequest = { - search: jest.fn().mockReturnValue('concreteSearchRequest'), - }; - const options = {}; - searchRequest.getSearchRequestType = jest.fn().mockReturnValue(concreteSearchRequest); - - const result = await searchRequest.search(options); - - expect(result).toBe('concreteSearchRequest'); - }); - - test('should return a MultiSearchRequest for multi searches', () => { - const searches = [ - { index: 'index', body: 'body' }, - { index: 'index', body: 'body' }, - ]; - - const result = searchRequest.getSearchRequestType(searches); - - expect(result instanceof MultiSearchRequest).toBe(true); - }); - - test('should return a SingleSearchRequest for single search', () => { - const searches = [{ index: 'index', body: 'body' }]; - - const result = searchRequest.getSearchRequestType(searches); - - expect(result instanceof SingleSearchRequest).toBe(true); - }); -}); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js deleted file mode 100644 index 7d8b60a7e4595..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 { AbstractSearchRequest } from './abstract_request'; -import { UI_SETTINGS } from '../../../../../data/server'; - -const SEARCH_METHOD = 'search'; - -export class SingleSearchRequest extends AbstractSearchRequest { - async search([{ body, index }]) { - const includeFrozen = await this.req - .getUiSettingsService() - .get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - const resp = await this.callWithRequest(this.req, SEARCH_METHOD, { - ignore_throttled: !includeFrozen, - body, - index, - }); - - return [resp]; - } -} diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js deleted file mode 100644 index b899814f2fe13..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 { SingleSearchRequest } from './single_search_request'; -import { UI_SETTINGS } from '../../../../../data/server'; - -describe('SingleSearchRequest', () => { - let searchRequest; - let req; - let callWithRequest; - let getServiceMock; - let includeFrozen; - - beforeEach(() => { - includeFrozen = false; - getServiceMock = jest.fn().mockResolvedValue(includeFrozen); - req = { - getUiSettingsService: jest.fn().mockReturnValue({ get: getServiceMock }), - }; - callWithRequest = jest.fn().mockReturnValue({}); - searchRequest = new SingleSearchRequest(req, callWithRequest); - }); - - test('should init an SingleSearchRequest instance', () => { - expect(searchRequest.req).toBe(req); - expect(searchRequest.callWithRequest).toBe(callWithRequest); - expect(searchRequest.search).toBeDefined(); - }); - - test('should get the response from elastic search', async () => { - const searches = [{ body: 'body', index: 'index' }]; - - const responses = await searchRequest.search(searches); - - expect(responses).toEqual([{}]); - expect(req.getUiSettingsService).toHaveBeenCalled(); - expect(getServiceMock).toHaveBeenCalledWith(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - expect(callWithRequest).toHaveBeenCalledWith(req, 'search', { - body: 'body', - index: 'index', - ignore_throttled: !includeFrozen, - }); - }); -}); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategies_registry.test.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategies_registry.test.ts index ecd09653b3b48..66ea4f017dd90 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategies_registry.test.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_strategies_registry.test.ts @@ -65,7 +65,7 @@ describe('SearchStrategyRegister', () => { }); test('should add a strategy if it is an instance of AbstractSearchStrategy', () => { - const anotherSearchStrategy = new MockSearchStrategy({}, {} as any, {}); + const anotherSearchStrategy = new MockSearchStrategy('es'); const addedStrategies = registry.addStrategy(anotherSearchStrategy); expect(addedStrategies.length).toEqual(2); @@ -75,7 +75,7 @@ describe('SearchStrategyRegister', () => { test('should return a MockSearchStrategy instance', async () => { const req = {}; const indexPattern = '*'; - const anotherSearchStrategy = new MockSearchStrategy({}, {} as any, {}); + const anotherSearchStrategy = new MockSearchStrategy('es'); registry.addStrategy(anotherSearchStrategy); const { searchStrategy, capabilities } = (await registry.getViableStrategy(req, indexPattern))!; diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js index 1fbaffd794c89..6773ee482b098 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js @@ -18,24 +18,13 @@ */ import { AbstractSearchStrategy } from './abstract_search_strategy'; -class SearchRequest { - constructor(req, callWithRequest) { - this.req = req; - this.callWithRequest = callWithRequest; - } -} - describe('AbstractSearchStrategy', () => { let abstractSearchStrategy; - let server; - let callWithRequestFactory; let req; let mockedFields; let indexPattern; beforeEach(() => { - server = {}; - callWithRequestFactory = jest.fn().mockReturnValue('callWithRequest'); mockedFields = {}; req = { pre: { @@ -45,16 +34,11 @@ describe('AbstractSearchStrategy', () => { }, }; - abstractSearchStrategy = new AbstractSearchStrategy( - server, - callWithRequestFactory, - SearchRequest - ); + abstractSearchStrategy = new AbstractSearchStrategy('es'); }); test('should init an AbstractSearchStrategy instance', () => { - expect(abstractSearchStrategy.getCallWithRequestInstance).toBeDefined(); - expect(abstractSearchStrategy.getSearchRequest).toBeDefined(); + expect(abstractSearchStrategy.search).toBeDefined(); expect(abstractSearchStrategy.getFieldsForWildcard).toBeDefined(); expect(abstractSearchStrategy.checkForViability).toBeDefined(); }); @@ -68,17 +52,46 @@ describe('AbstractSearchStrategy', () => { }); }); - test('should invoke callWithRequestFactory with req param passed', () => { - abstractSearchStrategy.getCallWithRequestInstance(req); + test('should return response', async () => { + const searches = [{ body: 'body', index: 'index' }]; + const searchFn = jest.fn().mockReturnValue(Promise.resolve({})); - expect(callWithRequestFactory).toHaveBeenCalledWith(server, req); - }); - - test('should return a search request', () => { - const searchRequest = abstractSearchStrategy.getSearchRequest(req); + const responses = await abstractSearchStrategy.search( + { + requestContext: {}, + framework: { + core: { + getStartServices: jest.fn().mockReturnValue( + Promise.resolve([ + {}, + { + data: { + search: { + search: searchFn, + }, + }, + }, + ]) + ), + }, + }, + }, + searches + ); - expect(searchRequest instanceof SearchRequest).toBe(true); - expect(searchRequest.callWithRequest).toBe('callWithRequest'); - expect(searchRequest.req).toBe(req); + expect(responses).toEqual([{}]); + expect(searchFn).toHaveBeenCalledWith( + {}, + { + params: { + body: 'body', + index: 'index', + }, + indexType: undefined, + }, + { + strategy: 'es', + } + ); }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts index 0b1c6e6e20414..92b7e6976962e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts @@ -18,7 +18,7 @@ */ import { - LegacyAPICaller, + RequestHandlerContext, FakeRequest, IUiSettingsClient, SavedObjectsClientContract, @@ -33,6 +33,7 @@ import { IndexPatternsFetcher } from '../../../../../data/server'; * This will be replaced by standard KibanaRequest and RequestContext objects in a later version. */ export type ReqFacade = FakeRequest & { + requestContext: RequestHandlerContext; framework: Framework; payload: unknown; pre: { @@ -40,34 +41,42 @@ export type ReqFacade = FakeRequest & { }; getUiSettingsService: () => IUiSettingsClient; getSavedObjectsClient: () => SavedObjectsClientContract; - server: { - plugins: { - elasticsearch: { - getCluster: () => { - callWithRequest: (req: ReqFacade, endpoint: string, params: any) => Promise; - }; - }; - }; - }; getEsShardTimeout: () => Promise; }; export class AbstractSearchStrategy { - public getCallWithRequestInstance: (req: ReqFacade) => LegacyAPICaller; - public getSearchRequest: (req: ReqFacade) => any; - - constructor( - server: any, - callWithRequestFactory: (server: any, req: ReqFacade) => LegacyAPICaller, - SearchRequest: any - ) { - this.getCallWithRequestInstance = (req) => callWithRequestFactory(server, req); + public searchStrategyName!: string; + public indexType?: string; + public additionalParams: any; - this.getSearchRequest = (req) => { - const callWithRequest = this.getCallWithRequestInstance(req); + constructor(name: string, type?: string, additionalParams: any = {}) { + this.searchStrategyName = name; + this.indexType = type; + this.additionalParams = additionalParams; + } - return new SearchRequest(req, callWithRequest); - }; + async search(req: ReqFacade, bodies: any[], options = {}) { + const [, deps] = await req.framework.core.getStartServices(); + const requests: any[] = []; + bodies.forEach((body) => { + requests.push( + deps.data.search.search( + req.requestContext, + { + params: { + ...body, + ...this.additionalParams, + }, + indexType: this.indexType, + }, + { + ...options, + strategy: this.searchStrategyName, + } + ) + ); + }); + return Promise.all(requests); } async getFieldsForWildcard(req: ReqFacade, indexPattern: string, capabilities: any) { diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.js index 63f2911ce1118..7c3609ae3c405 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.js @@ -16,21 +16,16 @@ * specific language governing permissions and limitations * under the License. */ + +import { ES_SEARCH_STRATEGY } from '../../../../../data/server'; import { AbstractSearchStrategy } from './abstract_search_strategy'; -import { SearchRequest } from '../search_requests/search_request'; import { DefaultSearchCapabilities } from '../default_search_capabilities'; -const callWithRequestFactory = (server, request) => { - const { callWithRequest } = request.server.plugins.elasticsearch.getCluster('data'); - - return callWithRequest; -}; - export class DefaultSearchStrategy extends AbstractSearchStrategy { name = 'default'; - constructor(server) { - super(server, callWithRequestFactory, SearchRequest); + constructor() { + super(ES_SEARCH_STRATEGY); } checkForViability(req) { diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.test.js index 2e3a459bf06fd..a9994ba3e1f75 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/default_search_strategy.test.js @@ -20,42 +20,20 @@ import { DefaultSearchStrategy } from './default_search_strategy'; describe('DefaultSearchStrategy', () => { let defaultSearchStrategy; - let server; - let callWithRequest; let req; beforeEach(() => { - server = {}; - callWithRequest = jest.fn(); - req = { - server: { - plugins: { - elasticsearch: { - getCluster: jest.fn().mockReturnValue({ - callWithRequest, - }), - }, - }, - }, - }; - defaultSearchStrategy = new DefaultSearchStrategy(server); + req = {}; + defaultSearchStrategy = new DefaultSearchStrategy(); }); test('should init an DefaultSearchStrategy instance', () => { expect(defaultSearchStrategy.name).toBe('default'); expect(defaultSearchStrategy.checkForViability).toBeDefined(); - expect(defaultSearchStrategy.getCallWithRequestInstance).toBeDefined(); - expect(defaultSearchStrategy.getSearchRequest).toBeDefined(); + expect(defaultSearchStrategy.search).toBeDefined(); expect(defaultSearchStrategy.getFieldsForWildcard).toBeDefined(); }); - test('should invoke callWithRequestFactory with passed params', () => { - const value = defaultSearchStrategy.getCallWithRequestInstance(req); - - expect(value).toBe(callWithRequest); - expect(req.server.plugins.elasticsearch.getCluster).toHaveBeenCalledWith('data'); - }); - test('should check a strategy for viability', () => { const value = defaultSearchStrategy.checkForViability(req); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js index b015aaf0ef8db..d8a230dfeef4e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js @@ -39,7 +39,6 @@ export async function getAnnotations({ capabilities, series, }) { - const searchRequest = searchStrategy.getSearchRequest(req); const annotations = panel.annotations.filter(validAnnotation); const lastSeriesTimestamp = getLastSeriesTimestamp(series); const handleAnnotationResponseBy = handleAnnotationResponse(lastSeriesTimestamp); @@ -47,6 +46,7 @@ export async function getAnnotations({ const bodiesPromises = annotations.map((annotation) => getAnnotationRequestParams(req, panel, annotation, esQueryConfig, capabilities) ); + const searches = (await Promise.all(bodiesPromises)).reduce( (acc, items) => acc.concat(items), [] @@ -55,10 +55,10 @@ export async function getAnnotations({ if (!searches.length) return { responses: [] }; try { - const data = await searchRequest.search(searches); + const data = await searchStrategy.search(req.framework.core, req.requestContext, searches); return annotations.reduce((acc, annotation, index) => { - acc[annotation.id] = handleAnnotationResponseBy(data[index], annotation); + acc[annotation.id] = handleAnnotationResponseBy(data[index].rawResponse, annotation); return acc; }, {}); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js index ee48816c6a8af..1eace13c2e336 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_series_data.js @@ -28,7 +28,6 @@ export async function getSeriesData(req, panel) { searchStrategy, capabilities, } = await req.framework.searchStrategyRegistry.getViableStrategyForPanel(req, panel); - const searchRequest = searchStrategy.getSearchRequest(req); const esQueryConfig = await getEsQueryConfig(req); const meta = { type: panel.type, @@ -45,8 +44,13 @@ export async function getSeriesData(req, panel) { [] ); - const data = await searchRequest.search(searches); - const series = data.map(handleResponseBody(panel)); + const data = await searchStrategy.search(req, searches); + + const handleResponseBodyFn = handleResponseBody(panel); + + const series = data.map((resp) => + handleResponseBodyFn(resp.rawResponse ? resp.rawResponse : resp) + ); let annotations = null; if (panel.annotations && panel.annotations.length) { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js index 1d1c245907959..3791eb229db5b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_table_data.js @@ -30,7 +30,6 @@ export async function getTableData(req, panel) { searchStrategy, capabilities, } = await req.framework.searchStrategyRegistry.getViableStrategy(req, panelIndexPattern); - const searchRequest = searchStrategy.getSearchRequest(req); const esQueryConfig = await getEsQueryConfig(req); const { indexPatternObject } = await getIndexPatternObject(req, panelIndexPattern); @@ -41,13 +40,18 @@ export async function getTableData(req, panel) { try { const body = buildRequestBody(req, panel, esQueryConfig, indexPatternObject, capabilities); - const [resp] = await searchRequest.search([ + const [resp] = await searchStrategy.search(req, [ { body, index: panelIndexPattern, }, ]); - const buckets = get(resp, 'aggregations.pivot.buckets', []); + + const buckets = get( + resp.rawResponse ? resp.rawResponse : resp, + 'aggregations.pivot.buckets', + [] + ); return { ...meta, diff --git a/src/plugins/vis_type_timeseries/server/plugin.ts b/src/plugins/vis_type_timeseries/server/plugin.ts index d863937a4e3dc..678ba2b371978 100644 --- a/src/plugins/vis_type_timeseries/server/plugin.ts +++ b/src/plugins/vis_type_timeseries/server/plugin.ts @@ -33,6 +33,7 @@ import { VisTypeTimeseriesConfig } from './config'; import { getVisData, GetVisData, GetVisDataOptions } from './lib/get_vis_data'; import { ValidationTelemetryService } from './validation_telemetry'; import { UsageCollectionSetup } from '../../usage_collection/server'; +import { PluginStart } from '../../data/server'; import { visDataRoutes } from './routes/vis'; // @ts-ignore import { fieldsRoutes } from './routes/fields'; @@ -47,6 +48,10 @@ interface VisTypeTimeseriesPluginSetupDependencies { usageCollection?: UsageCollectionSetup; } +interface VisTypeTimeseriesPluginStartDependencies { + data: PluginStart; +} + export interface VisTypeTimeseriesSetup { getVisData: ( requestContext: RequestHandlerContext, @@ -57,7 +62,7 @@ export interface VisTypeTimeseriesSetup { } export interface Framework { - core: CoreSetup; + core: CoreSetup; plugins: any; config$: Observable; globalConfig$: PluginInitializerContext['config']['legacy']['globalConfig$']; @@ -74,7 +79,10 @@ export class VisTypeTimeseriesPlugin implements Plugin { this.validationTelementryService = new ValidationTelemetryService(); } - public setup(core: CoreSetup, plugins: VisTypeTimeseriesPluginSetupDependencies) { + public setup( + core: CoreSetup, + plugins: VisTypeTimeseriesPluginSetupDependencies + ) { const logger = this.initializerContext.logger.get('visTypeTimeseries'); core.uiSettings.register(uiSettings); const config$ = this.initializerContext.config.create(); diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts index 48efd4398e4d4..1ca8b57ab230f 100644 --- a/src/plugins/vis_type_timeseries/server/routes/vis.ts +++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts @@ -21,7 +21,8 @@ import { IRouter, KibanaRequest } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { getVisData, GetVisDataOptions } from '../lib/get_vis_data'; import { visPayloadSchema } from '../../common/vis_schema'; -import { Framework, ValidationTelemetryServiceSetup } from '../index'; +import { ValidationTelemetryServiceSetup } from '../index'; +import { Framework } from '../plugin'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); diff --git a/x-pack/plugins/data_enhanced/server/index.ts b/x-pack/plugins/data_enhanced/server/index.ts index fbe1ecc10d632..3c5d5d1e99d13 100644 --- a/x-pack/plugins/data_enhanced/server/index.ts +++ b/x-pack/plugins/data_enhanced/server/index.ts @@ -11,4 +11,6 @@ export function plugin(initializerContext: PluginInitializerContext) { return new EnhancedDataServerPlugin(initializerContext); } +export { ENHANCED_ES_SEARCH_STRATEGY } from '../common'; + export { EnhancedDataServerPlugin as Plugin }; diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.test.js b/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.test.js index d466ebd69737e..8672a8b8f6849 100644 --- a/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.test.js +++ b/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.test.js @@ -6,21 +6,16 @@ import { registerRollupSearchStrategy } from './register_rollup_search_strategy'; describe('Register Rollup Search Strategy', () => { - let routeDependencies; let addSearchStrategy; + let getRollupService; beforeEach(() => { - routeDependencies = { - router: jest.fn().mockName('router'), - elasticsearchService: jest.fn().mockName('elasticsearchService'), - elasticsearch: jest.fn().mockName('elasticsearch'), - }; - addSearchStrategy = jest.fn().mockName('addSearchStrategy'); + getRollupService = jest.fn().mockName('getRollupService'); }); test('should run initialization', () => { - registerRollupSearchStrategy(routeDependencies, addSearchStrategy); + registerRollupSearchStrategy(addSearchStrategy, getRollupService); expect(addSearchStrategy).toHaveBeenCalled(); }); diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.ts b/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.ts index 333863979ba95..22dafbb71d802 100644 --- a/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.ts +++ b/x-pack/plugins/rollup/server/lib/search_strategies/register_rollup_search_strategy.ts @@ -4,27 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ILegacyScopedClusterClient } from 'src/core/server'; import { - AbstractSearchRequest, DefaultSearchCapabilities, AbstractSearchStrategy, + ReqFacade, } from '../../../../../../src/plugins/vis_type_timeseries/server'; -import { CallWithRequestFactoryShim } from '../../types'; import { getRollupSearchStrategy } from './rollup_search_strategy'; -import { getRollupSearchRequest } from './rollup_search_request'; import { getRollupSearchCapabilities } from './rollup_search_capabilities'; export const registerRollupSearchStrategy = ( - callWithRequestFactory: CallWithRequestFactoryShim, - addSearchStrategy: (searchStrategy: any) => void + addSearchStrategy: (searchStrategy: any) => void, + getRollupService: (reg: ReqFacade) => Promise ) => { - const RollupSearchRequest = getRollupSearchRequest(AbstractSearchRequest); const RollupSearchCapabilities = getRollupSearchCapabilities(DefaultSearchCapabilities); const RollupSearchStrategy = getRollupSearchStrategy( AbstractSearchStrategy, - RollupSearchRequest, RollupSearchCapabilities, - callWithRequestFactory + getRollupService ); addSearchStrategy(new RollupSearchStrategy()); diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.test.js b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.test.js deleted file mode 100644 index 2ea0612140946..0000000000000 --- a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.test.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { getRollupSearchRequest } from './rollup_search_request'; - -class AbstractSearchRequest { - indexPattern = 'indexPattern'; - callWithRequest = jest.fn(({ body }) => Promise.resolve(body)); -} - -describe('Rollup search request', () => { - let RollupSearchRequest; - - beforeEach(() => { - RollupSearchRequest = getRollupSearchRequest(AbstractSearchRequest); - }); - - test('should create instance of RollupSearchRequest', () => { - const rollupSearchRequest = new RollupSearchRequest(); - - expect(rollupSearchRequest).toBeInstanceOf(AbstractSearchRequest); - expect(rollupSearchRequest.search).toBeDefined(); - expect(rollupSearchRequest.callWithRequest).toBeDefined(); - }); - - test('should send one request for single search', async () => { - const rollupSearchRequest = new RollupSearchRequest(); - const searches = [{ body: 'body', index: 'index' }]; - - await rollupSearchRequest.search(searches); - - expect(rollupSearchRequest.callWithRequest).toHaveBeenCalledTimes(1); - expect(rollupSearchRequest.callWithRequest).toHaveBeenCalledWith('rollup.search', { - body: 'body', - index: 'index', - rest_total_hits_as_int: true, - }); - }); - - test('should send multiple request for multi search', async () => { - const rollupSearchRequest = new RollupSearchRequest(); - const searches = [ - { body: 'body', index: 'index' }, - { body: 'body1', index: 'index' }, - ]; - - await rollupSearchRequest.search(searches); - - expect(rollupSearchRequest.callWithRequest).toHaveBeenCalledTimes(2); - }); -}); diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.ts b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.ts deleted file mode 100644 index 7e12d5286f34c..0000000000000 --- a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_request.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -const SEARCH_METHOD = 'rollup.search'; - -interface Search { - index: string; - body: { - [key: string]: any; - }; -} - -export const getRollupSearchRequest = (AbstractSearchRequest: any) => - class RollupSearchRequest extends AbstractSearchRequest { - async search(searches: Search[]) { - const requests = searches.map(({ body, index }) => - this.callWithRequest(SEARCH_METHOD, { - body, - index, - rest_total_hits_as_int: true, - }) - ); - - return await Promise.all(requests); - } - }; diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.test.js b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.test.js index 63f4628e36bfe..f3da7ed3fdd17 100644 --- a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.test.js +++ b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.test.js @@ -7,13 +7,32 @@ import { getRollupSearchStrategy } from './rollup_search_strategy'; describe('Rollup Search Strategy', () => { let RollupSearchStrategy; - let RollupSearchRequest; let RollupSearchCapabilities; let callWithRequest; let rollupResolvedData; - const server = 'server'; - const request = 'request'; + const request = { + requestContext: { + core: { + elasticsearch: { + client: { + asCurrentUser: { + rollup: { + getRollupIndexCaps: jest.fn().mockImplementation(() => rollupResolvedData), + }, + }, + }, + }, + }, + }, + }; + const getRollupService = jest.fn().mockImplementation(() => { + return { + callAsCurrentUser: async () => { + return rollupResolvedData; + }, + }; + }); const indexPattern = 'indexPattern'; beforeEach(() => { @@ -33,19 +52,17 @@ describe('Rollup Search Strategy', () => { } } - RollupSearchRequest = jest.fn(); RollupSearchCapabilities = jest.fn(() => 'capabilities'); - callWithRequest = jest.fn().mockImplementation(() => rollupResolvedData); RollupSearchStrategy = getRollupSearchStrategy( AbstractSearchStrategy, - RollupSearchRequest, - RollupSearchCapabilities + RollupSearchCapabilities, + getRollupService ); }); test('should create instance of RollupSearchRequest', () => { - const rollupSearchStrategy = new RollupSearchStrategy(server); + const rollupSearchStrategy = new RollupSearchStrategy(); expect(rollupSearchStrategy.name).toBe('rollup'); }); @@ -55,7 +72,7 @@ describe('Rollup Search Strategy', () => { const rollupIndex = 'rollupIndex'; beforeEach(() => { - rollupSearchStrategy = new RollupSearchStrategy(server); + rollupSearchStrategy = new RollupSearchStrategy(); rollupSearchStrategy.getRollupData = jest.fn(() => ({ [rollupIndex]: { rollup_jobs: [ @@ -104,7 +121,7 @@ describe('Rollup Search Strategy', () => { let rollupSearchStrategy; beforeEach(() => { - rollupSearchStrategy = new RollupSearchStrategy(server); + rollupSearchStrategy = new RollupSearchStrategy(); }); test('should return rollup data', async () => { @@ -112,10 +129,7 @@ describe('Rollup Search Strategy', () => { const rollupData = await rollupSearchStrategy.getRollupData(request, indexPattern); - expect(callWithRequest).toHaveBeenCalledWith('rollup.rollupIndexCapabilities', { - indexPattern, - }); - expect(rollupSearchStrategy.getCallWithRequestInstance).toHaveBeenCalledWith(request); + expect(getRollupService).toHaveBeenCalled(); expect(rollupData).toBe('data'); }); @@ -135,7 +149,7 @@ describe('Rollup Search Strategy', () => { const rollupIndex = 'rollupIndex'; beforeEach(() => { - rollupSearchStrategy = new RollupSearchStrategy(server); + rollupSearchStrategy = new RollupSearchStrategy(); fieldsCapabilities = { [rollupIndex]: { aggs: { diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts index 885836780f1a9..e7794caf8697b 100644 --- a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts +++ b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts @@ -4,15 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ import { keyBy, isString } from 'lodash'; -import { KibanaRequest } from 'src/core/server'; - -import { CallWithRequestFactoryShim } from '../../types'; +import { ILegacyScopedClusterClient } from 'src/core/server'; +import { ReqFacade } from '../../../../../../src/plugins/vis_type_timeseries/server'; +import { ENHANCED_ES_SEARCH_STRATEGY } from '../../../../data_enhanced/server'; import { mergeCapabilitiesWithFields } from '../merge_capabilities_with_fields'; import { getCapabilitiesForRollupIndices } from '../map_capabilities'; -const ROLLUP_INDEX_CAPABILITIES_METHOD = 'rollup.rollupIndexCapabilities'; - -const getRollupIndices = (rollupData: { [key: string]: any[] }) => Object.keys(rollupData); +const getRollupIndices = (rollupData: { [key: string]: any }) => Object.keys(rollupData); const isIndexPatternContainsWildcard = (indexPattern: string) => indexPattern.includes('*'); const isIndexPatternValid = (indexPattern: string) => @@ -20,28 +18,40 @@ const isIndexPatternValid = (indexPattern: string) => export const getRollupSearchStrategy = ( AbstractSearchStrategy: any, - RollupSearchRequest: any, RollupSearchCapabilities: any, - callWithRequestFactory: CallWithRequestFactoryShim + getRollupService: (reg: ReqFacade) => Promise ) => class RollupSearchStrategy extends AbstractSearchStrategy { name = 'rollup'; constructor() { - // TODO: When vis_type_timeseries and AbstractSearchStrategy are migrated to the NP, it - // shouldn't require elasticsearchService to be injected, and we can remove this null argument. - super(null, callWithRequestFactory, RollupSearchRequest); + super(ENHANCED_ES_SEARCH_STRATEGY, 'rollup', { rest_total_hits_as_int: true }); } - getRollupData(req: KibanaRequest, indexPattern: string) { - const callWithRequest = this.getCallWithRequestInstance(req); + async search(req: ReqFacade, bodies: any[], options = {}) { + const rollupService = await getRollupService(req); + const requests: any[] = []; + bodies.forEach((body) => { + requests.push( + rollupService.callAsCurrentUser('rollup.search', { + ...body, + rest_total_hits_as_int: true, + }) + ); + }); + return Promise.all(requests); + } - return callWithRequest(ROLLUP_INDEX_CAPABILITIES_METHOD, { - indexPattern, - }).catch(() => Promise.resolve({})); + async getRollupData(req: ReqFacade, indexPattern: string) { + const rollupService = await getRollupService(req); + return rollupService + .callAsCurrentUser('rollup.rollupIndexCapabilities', { + indexPattern, + }) + .catch(() => Promise.resolve({})); } - async checkForViability(req: KibanaRequest, indexPattern: string) { + async checkForViability(req: ReqFacade, indexPattern: string) { let isViable = false; let capabilities = null; @@ -66,7 +76,7 @@ export const getRollupSearchStrategy = ( } async getFieldsForWildcard( - req: KibanaRequest, + req: ReqFacade, indexPattern: string, { fieldsCapabilities, diff --git a/x-pack/plugins/rollup/server/plugin.ts b/x-pack/plugins/rollup/server/plugin.ts index 8b3a6355f950d..fe193150fc1ca 100644 --- a/x-pack/plugins/rollup/server/plugin.ts +++ b/x-pack/plugins/rollup/server/plugin.ts @@ -17,17 +17,16 @@ import { ILegacyCustomClusterClient, Plugin, Logger, - KibanaRequest, PluginInitializerContext, ILegacyScopedClusterClient, - LegacyAPICaller, SharedGlobalConfig, } from 'src/core/server'; import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; +import { ReqFacade } from '../../../../src/plugins/vis_type_timeseries/server'; import { PLUGIN, CONFIG_ROLLUPS } from '../common'; -import { Dependencies, CallWithRequestFactoryShim } from './types'; +import { Dependencies } from './types'; import { registerApiRoutes } from './routes'; import { License } from './services'; import { registerRollupUsageCollector } from './collectors'; @@ -132,19 +131,12 @@ export class RollupPlugin implements Plugin { }); if (visTypeTimeseries) { - // TODO: When vis_type_timeseries is fully migrated to the NP, it shouldn't require this shim. - const callWithRequestFactoryShim = ( - elasticsearchServiceShim: CallWithRequestFactoryShim, - request: KibanaRequest - ): LegacyAPICaller => { - return async (...args: Parameters) => { - this.rollupEsClient = this.rollupEsClient ?? (await getCustomEsClient(getStartServices)); - return await this.rollupEsClient.asScoped(request).callAsCurrentUser(...args); - }; + const getRollupService = async (request: ReqFacade) => { + this.rollupEsClient = this.rollupEsClient ?? (await getCustomEsClient(getStartServices)); + return this.rollupEsClient.asScoped(request); }; - const { addSearchStrategy } = visTypeTimeseries; - registerRollupSearchStrategy(callWithRequestFactoryShim, addSearchStrategy); + registerRollupSearchStrategy(addSearchStrategy, getRollupService); } if (usageCollection) { diff --git a/x-pack/plugins/rollup/server/types.ts b/x-pack/plugins/rollup/server/types.ts index 290d2df050099..b167806cf8d5d 100644 --- a/x-pack/plugins/rollup/server/types.ts +++ b/x-pack/plugins/rollup/server/types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IRouter, LegacyAPICaller, KibanaRequest } from 'src/core/server'; +import { IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { VisTypeTimeseriesSetup } from 'src/plugins/vis_type_timeseries/server'; @@ -39,9 +39,3 @@ export interface RouteDependencies { IndexPatternsFetcher: typeof IndexPatternsFetcher; }; } - -// TODO: When vis_type_timeseries is fully migrated to the NP, it shouldn't require this shim. -export type CallWithRequestFactoryShim = ( - elasticsearchServiceShim: CallWithRequestFactoryShim, - request: KibanaRequest -) => LegacyAPICaller;