From 26c47bdf5ec20b3de79cd96b9ef11267b54d7e04 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Thu, 15 Oct 2020 14:55:13 -0700 Subject: [PATCH 01/11] [Search] Add request context and asScoped pattern --- .../search_examples/server/my_strategy.ts | 10 +- .../server/routes/server_search_route.ts | 7 +- .../data/common/search/aggs/agg_config.ts | 3 +- .../data/common/search/es_search/types.ts | 11 -- .../search_source/search_source.test.ts | 4 +- .../search/search_source/search_source.ts | 21 ++-- src/plugins/data/common/search/types.ts | 28 +++-- src/plugins/data/public/index.ts | 1 - src/plugins/data/public/search/index.ts | 1 - .../data/public/search/search_interceptor.ts | 2 +- .../data/public/search/search_service.ts | 21 +--- src/plugins/data/server/index.ts | 1 + .../es_search/es_search_strategy.test.ts | 24 ++--- .../search/es_search/es_search_strategy.ts | 5 +- src/plugins/data/server/search/index.ts | 6 +- src/plugins/data/server/search/mocks.ts | 5 +- .../data/server/search/routes/search.test.ts | 53 ++++------ .../data/server/search/routes/search.ts | 21 +--- .../data/server/search/search_service.ts | 96 +++++++++-------- src/plugins/data/server/search/types.ts | 29 +++-- .../server/routes/validate_es.ts | 14 +-- .../abstract_search_strategy.test.js | 21 +--- .../strategies/abstract_search_strategy.ts | 8 +- .../server/search/eql_search_strategy.test.ts | 49 ++++----- .../server/search/eql_search_strategy.ts | 9 +- .../server/search/es_search_strategy.test.ts | 46 +++----- .../server/search/es_search_strategy.ts | 100 ++++++++---------- .../search_strategy/index_fields/index.ts | 7 +- .../security_solution/index.ts | 10 +- .../server/search_strategy/timeline/index.ts | 10 +- 30 files changed, 272 insertions(+), 351 deletions(-) diff --git a/examples/search_examples/server/my_strategy.ts b/examples/search_examples/server/my_strategy.ts index 26e7056cdd787..957216c7b9713 100644 --- a/examples/search_examples/server/my_strategy.ts +++ b/examples/search_examples/server/my_strategy.ts @@ -24,18 +24,18 @@ import { IMyStrategyResponse, IMyStrategyRequest } from '../common'; export const mySearchStrategyProvider = ( data: PluginStart ): ISearchStrategy => { - const es = data.search.getSearchStrategy('es'); + const es = data.search.getSearchStrategy(); return { - search: (request, options, context) => - es.search(request, options, context).pipe( + search: (deps, request, options) => + es.search(deps, request, options).pipe( map((esSearchRes) => ({ ...esSearchRes, cool: request.get_cool ? 'YES' : 'NOPE', })) ), - cancel: async (context, id) => { + cancel: async (deps, id) => { if (es.cancel) { - es.cancel(context, id); + es.cancel(deps, id); } }, }; diff --git a/examples/search_examples/server/routes/server_search_route.ts b/examples/search_examples/server/routes/server_search_route.ts index 21ae38b99f3d2..dae423aeecc8c 100644 --- a/examples/search_examples/server/routes/server_search_route.ts +++ b/examples/search_examples/server/routes/server_search_route.ts @@ -39,8 +39,8 @@ export function registerServerSearchRoute(router: IRouter, data: DataPluginStart // Run a synchronous search server side, by enforcing a high keepalive and waiting for completion. // If you wish to run the search with polling (in basic+), you'd have to poll on the search API. // Please reach out to the @app-arch-team if you need this to be implemented. - const res = await data.search - .search( + const res = await context + .search!.search( { params: { index, @@ -57,8 +57,7 @@ export function registerServerSearchRoute(router: IRouter, data: DataPluginStart keepAlive: '5m', }, } as IEsSearchRequest, - {}, - context + {} ) .toPromise(); diff --git a/src/plugins/data/common/search/aggs/agg_config.ts b/src/plugins/data/common/search/aggs/agg_config.ts index 910c79f5dd0d7..8ca27755e3dda 100644 --- a/src/plugins/data/common/search/aggs/agg_config.ts +++ b/src/plugins/data/common/search/aggs/agg_config.ts @@ -21,13 +21,12 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import { Assign, Ensure } from '@kbn/utility-types'; -import { ISearchSource } from 'src/plugins/data/public'; +import { ISearchOptions, ISearchSource } from 'src/plugins/data/public'; import { ExpressionAstFunction, ExpressionAstArgument, SerializedFieldFormat, } from 'src/plugins/expressions/common'; -import { ISearchOptions } from '../es_search'; import { IAggType } from './agg_type'; import { writeParams } from './agg_params'; diff --git a/src/plugins/data/common/search/es_search/types.ts b/src/plugins/data/common/search/es_search/types.ts index b1c3e5cdd3960..7dbbd01d2cdad 100644 --- a/src/plugins/data/common/search/es_search/types.ts +++ b/src/plugins/data/common/search/es_search/types.ts @@ -22,17 +22,6 @@ import { IKibanaSearchRequest, IKibanaSearchResponse } from '../types'; export const ES_SEARCH_STRATEGY = 'es'; -export interface ISearchOptions { - /** - * An `AbortSignal` that allows the caller of `search` to abort a search request. - */ - abortSignal?: AbortSignal; - /** - * Use this option to force using a specific server side search strategy. Leave empty to use the default strategy. - */ - strategy?: string; -} - export type ISearchRequestParams> = { trackTotalHits?: boolean; } & Search; diff --git a/src/plugins/data/common/search/search_source/search_source.test.ts b/src/plugins/data/common/search/search_source/search_source.test.ts index 00e06663e998e..98d66310c040e 100644 --- a/src/plugins/data/common/search/search_source/search_source.test.ts +++ b/src/plugins/data/common/search/search_source/search_source.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, of } from 'rxjs'; import { IndexPattern } from '../../index_patterns'; import { GetConfigFn } from '../../types'; import { fetchSoon } from './legacy'; @@ -53,7 +53,7 @@ describe('SearchSource', () => { let searchSourceDependencies: SearchSourceDependencies; beforeEach(() => { - mockSearchMethod = jest.fn().mockResolvedValue({ rawResponse: '' }); + mockSearchMethod = jest.fn().mockReturnValue(of({ rawResponse: '' })); searchSourceDependencies = { getConfig: jest.fn(), diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index 1a6b770cf2ca8..418e316860eb9 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -75,8 +75,7 @@ import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; import { fieldWildcardFilter } from '../../../../kibana_utils/common'; import { IIndexPattern } from '../../index_patterns'; -import { IEsSearchRequest, IEsSearchResponse, ISearchOptions } from '../..'; -import { IKibanaSearchRequest, IKibanaSearchResponse } from '../types'; +import { ISearchGeneric, ISearchOptions } from '../..'; import { ISearchSource, SearchSourceOptions, SearchSourceFields } from './types'; import { FetchHandlers, RequestFailure, getSearchParamsFromRequest, SearchRequest } from './fetch'; @@ -102,15 +101,7 @@ export const searchSourceRequiredUiSettings = [ ]; export interface SearchSourceDependencies extends FetchHandlers { - // Types are nearly identical to ISearchGeneric, except we are making - // search options required here and returning a promise instead of observable. - search: < - SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, - SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse - >( - request: SearchStrategyRequest, - options: ISearchOptions - ) => Promise; + search: ISearchGeneric; } /** @public **/ @@ -144,7 +135,7 @@ export class SearchSource { } /** - * sets value to a single search source feild + * sets value to a single search source field * @param field: field name * @param value: value for the field */ @@ -319,9 +310,9 @@ export class SearchSource { getConfig, }); - return search({ params, indexType: searchRequest.indexType }, options).then(({ rawResponse }) => - onResponse(searchRequest, rawResponse) - ); + return search({ params, indexType: searchRequest.indexType }, options) + .toPromise() + .then(({ rawResponse }) => onResponse(searchRequest, rawResponse)); } /** diff --git a/src/plugins/data/common/search/types.ts b/src/plugins/data/common/search/types.ts index c3943af5c6ff7..fa93f64da2699 100644 --- a/src/plugins/data/common/search/types.ts +++ b/src/plugins/data/common/search/types.ts @@ -18,12 +18,7 @@ */ import { Observable } from 'rxjs'; -import { IEsSearchRequest, IEsSearchResponse, ISearchOptions } from '../../common/search'; - -export type ISearch = ( - request: IKibanaSearchRequest, - options?: ISearchOptions -) => Observable; +import { IEsSearchRequest, IEsSearchResponse } from './es_search'; export type ISearchGeneric = < SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, @@ -33,6 +28,13 @@ export type ISearchGeneric = < options?: ISearchOptions ) => Observable; +export type ISearchCancelGeneric = (id: string, options?: ISearchOptions) => Promise; + +export interface ISearchClient { + search: ISearchGeneric; + cancel: ISearchCancelGeneric; +} + export interface IKibanaSearchResponse { /** * Some responses may contain a unique id to identify the request this response came from. @@ -61,6 +63,9 @@ export interface IKibanaSearchResponse { */ isPartial?: boolean; + /** + * The raw response returned by the internal search method (usually the raw ES response) + */ rawResponse: RawResponse; } @@ -72,3 +77,14 @@ export interface IKibanaSearchRequest { params?: Params; } + +export interface ISearchOptions { + /** + * An `AbortSignal` that allows the caller of `search` to abort a search request. + */ + abortSignal?: AbortSignal; + /** + * Use this option to force using a specific server side search strategy. Leave empty to use the default strategy. + */ + strategy?: string; +} diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index c041511745be2..7c5dabed8a0cc 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -358,7 +358,6 @@ export { IKibanaSearchRequest, IKibanaSearchResponse, injectSearchSourceReferences, - ISearch, ISearchSetup, ISearchStart, ISearchStartSearchSource, diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 86804a819cb0e..8ab92aed18b0a 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -31,7 +31,6 @@ export { IKibanaSearchRequest, IKibanaSearchResponse, injectReferences as injectSearchSourceReferences, - ISearch, ISearchGeneric, ISearchSource, parseSearchSourceJSON, diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index 2e42635a7f811..2ebf98ad0fdbe 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -191,7 +191,7 @@ export class SearchInterceptor { * * @param request * @options - * @returns `Observalbe` emitting the search response or an error. + * @returns `Observable` emitting the search response or an error. */ public search( request: IKibanaSearchRequest, diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 734e88e085661..c124527f3da2d 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -22,16 +22,7 @@ import { BehaviorSubject } from 'rxjs'; import { ISearchSetup, ISearchStart, SearchEnhancements } from './types'; import { handleResponse } from './fetch'; -import { - IEsSearchRequest, - IEsSearchResponse, - IKibanaSearchRequest, - IKibanaSearchResponse, - ISearchGeneric, - ISearchOptions, - SearchSourceService, - SearchSourceDependencies, -} from '../../common/search'; +import { ISearchGeneric, SearchSourceService, SearchSourceDependencies } from '../../common/search'; import { getCallMsearch } from './legacy'; import { AggsService, AggsStartDependencies } from './aggs'; import { IndexPatternsContract } from '../index_patterns/index_patterns'; @@ -120,15 +111,7 @@ export class SearchService implements Plugin { const searchSourceDependencies: SearchSourceDependencies = { getConfig: uiSettings.get.bind(uiSettings), - search: < - SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, - SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse - >( - request: SearchStrategyRequest, - options: ISearchOptions - ) => { - return search(request, options).toPromise(); - }, + search, onResponse: handleResponse, legacy: { callMsearch: getCallMsearch({ http }), diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 11dcbb01bf4a6..8c4fb6cb0a0bc 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -213,6 +213,7 @@ export { ISearchStrategy, ISearchSetup, ISearchStart, + SearchStrategyDependencies, toSnakeCase, getAsyncOptions, getDefaultSearchParams, diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts index 2dbcc3196aa75..ddac28d9d54f5 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts @@ -17,9 +17,9 @@ * under the License. */ -import { RequestHandlerContext } from '../../../../../core/server'; import { pluginInitializerContextConfigMock } from '../../../../../core/server/mocks'; import { esSearchStrategyProvider } from './es_search_strategy'; +import { SearchStrategyDependencies } from '../types'; describe('ES search strategy', () => { const mockLogger: any = { @@ -36,16 +36,12 @@ describe('ES search strategy', () => { }, }); - const mockContext = ({ - core: { - uiSettings: { - client: { - get: () => {}, - }, - }, - elasticsearch: { client: { asCurrentUser: { search: mockApiCaller } } }, + const mockDeps = ({ + uiSettingsClient: { + get: () => {}, }, - } as unknown) as RequestHandlerContext; + esClient: { asCurrentUser: { search: mockApiCaller } }, + } as unknown) as SearchStrategyDependencies; const mockConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; @@ -63,7 +59,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*' }; await esSearchStrategyProvider(mockConfig$, mockLogger) - .search({ params }, {}, mockContext) + .search(mockDeps, { params }, {}) .subscribe(() => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ @@ -79,7 +75,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; await esSearchStrategyProvider(mockConfig$, mockLogger) - .search({ params }, {}, mockContext) + .search(mockDeps, { params }, {}) .subscribe(() => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ @@ -93,11 +89,11 @@ describe('ES search strategy', () => { it('has all response parameters', async (done) => await esSearchStrategyProvider(mockConfig$, mockLogger) .search( + mockDeps, { params: { index: 'logstash-*' }, }, - {}, - mockContext + {} ) .subscribe((data) => { expect(data.isRunning).toBe(false); diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.ts b/src/plugins/data/server/search/es_search/es_search_strategy.ts index 92cc941e14853..cb66cafb66144 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.ts @@ -38,12 +38,11 @@ export const esSearchStrategyProvider = ( usage?: SearchUsage ): ISearchStrategy => { return { - search: (request, options, context) => + search: ({ esClient, uiSettingsClient }, request, options) => from( new Promise(async (resolve, reject) => { logger.debug(`search ${request.params?.index}`); const config = await config$.pipe(first()).toPromise(); - const uiSettingsClient = await context.core.uiSettings.client; // Only default index pattern type is supported here. // See data_enhanced for other type support. @@ -64,7 +63,7 @@ export const esSearchStrategyProvider = ( try { const promise = shimAbortSignal( - context.core.elasticsearch.client.asCurrentUser.search(params), + esClient.asCurrentUser.search(params), options?.abortSignal ); const { body: rawResponse } = (await promise) as ApiResponse>; diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index b671ed806510b..1be641401b29c 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -17,12 +17,8 @@ * under the License. */ -export { ISearchStrategy, ISearchSetup, ISearchStart, SearchEnhancements } from './types'; - +export * from './types'; export * from './es_search'; - export { usageProvider, SearchUsage } from './collectors'; - export * from './aggs'; - export { shimHitsTotal } from './routes'; diff --git a/src/plugins/data/server/search/mocks.ts b/src/plugins/data/server/search/mocks.ts index 0d4ba0cba24a3..4914726c85ef8 100644 --- a/src/plugins/data/server/search/mocks.ts +++ b/src/plugins/data/server/search/mocks.ts @@ -33,7 +33,10 @@ export function createSearchStartMock(): jest.Mocked { return { aggs: searchAggsStartMock(), getSearchStrategy: jest.fn(), - search: jest.fn(), + asScoped: jest.fn().mockReturnValue({ + search: jest.fn(), + cancel: jest.fn(), + }), searchSource: searchSourceMock.createStartContract(), }; } diff --git a/src/plugins/data/server/search/routes/search.test.ts b/src/plugins/data/server/search/routes/search.test.ts index 834e5de5c3121..1ad4a4d9dae29 100644 --- a/src/plugins/data/server/search/routes/search.test.ts +++ b/src/plugins/data/server/search/routes/search.test.ts @@ -17,34 +17,18 @@ * under the License. */ -import { Observable, from } from 'rxjs'; - -import { - CoreSetup, - RequestHandlerContext, - SharedGlobalConfig, - StartServicesAccessor, -} from 'src/core/server'; -import { - coreMock, - httpServerMock, - pluginInitializerContextConfigMock, -} from '../../../../../../src/core/server/mocks'; +import { from } from 'rxjs'; + +import { CoreSetup, RequestHandlerContext } from 'src/core/server'; +import { coreMock, httpServerMock } from '../../../../../../src/core/server/mocks'; import { registerSearchRoute } from './search'; import { DataPluginStart } from '../../plugin'; -import { dataPluginMock } from '../../mocks'; describe('Search service', () => { - let mockDataStart: MockedKeys; let mockCoreSetup: MockedKeys>; - let getStartServices: jest.Mocked>; - let globalConfig$: Observable; beforeEach(() => { - mockDataStart = dataPluginMock.createStartContract(); - mockCoreSetup = coreMock.createSetup({ pluginStartContract: mockDataStart }); - getStartServices = mockCoreSetup.getStartServices; - globalConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; + mockCoreSetup = coreMock.createSetup(); }); it('handler calls context.search.search with the given request and strategy', async () => { @@ -67,8 +51,12 @@ describe('Search service', () => { }, }; - mockDataStart.search.search.mockReturnValue(from(Promise.resolve(response))); - const mockContext = {}; + const mockContext = { + search: { + search: jest.fn().mockReturnValue(from(Promise.resolve(response))), + }, + }; + const mockBody = { id: undefined, params: {} }; const mockParams = { strategy: 'foo' }; const mockRequest = httpServerMock.createKibanaRequest({ @@ -77,14 +65,14 @@ describe('Search service', () => { }); const mockResponse = httpServerMock.createResponseFactory(); - registerSearchRoute(mockCoreSetup.http.createRouter(), { getStartServices, globalConfig$ }); + registerSearchRoute(mockCoreSetup.http.createRouter()); const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockDataStart.search.search).toBeCalled(); - expect(mockDataStart.search.search.mock.calls[0][0]).toStrictEqual(mockBody); + expect(mockContext.search.search).toBeCalled(); + expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody); expect(mockResponse.ok).toBeCalled(); expect(mockResponse.ok.mock.calls[0][0]).toEqual({ body: response, @@ -101,9 +89,12 @@ describe('Search service', () => { }) ); - mockDataStart.search.search.mockReturnValue(rejectedValue); + const mockContext = { + search: { + search: jest.fn().mockReturnValue(rejectedValue), + }, + }; - const mockContext = {}; const mockBody = { id: undefined, params: {} }; const mockParams = { strategy: 'foo' }; const mockRequest = httpServerMock.createKibanaRequest({ @@ -112,14 +103,14 @@ describe('Search service', () => { }); const mockResponse = httpServerMock.createResponseFactory(); - registerSearchRoute(mockCoreSetup.http.createRouter(), { getStartServices, globalConfig$ }); + registerSearchRoute(mockCoreSetup.http.createRouter()); const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockDataStart.search.search).toBeCalled(); - expect(mockDataStart.search.search.mock.calls[0][0]).toStrictEqual(mockBody); + expect(mockContext.search.search).toBeCalled(); + expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody); expect(mockResponse.customError).toBeCalled(); const error: any = mockResponse.customError.mock.calls[0][0]; expect(error.body.message).toBe('oh no'); diff --git a/src/plugins/data/server/search/routes/search.ts b/src/plugins/data/server/search/routes/search.ts index 1e8433d9685e3..9fb8b0d004f08 100644 --- a/src/plugins/data/server/search/routes/search.ts +++ b/src/plugins/data/server/search/routes/search.ts @@ -20,13 +20,9 @@ import { schema } from '@kbn/config-schema'; import { IRouter } from 'src/core/server'; import { getRequestAbortedSignal } from '../../lib'; -import { SearchRouteDependencies } from '../search_service'; import { shimHitsTotal } from './shim_hits_total'; -export function registerSearchRoute( - router: IRouter, - { getStartServices }: SearchRouteDependencies -): void { +export function registerSearchRoute(router: IRouter): void { router.post( { path: '/internal/search/{strategy}/{id?}', @@ -46,17 +42,14 @@ export function registerSearchRoute( const { strategy, id } = request.params; const abortSignal = getRequestAbortedSignal(request.events.aborted$); - const [, , selfStart] = await getStartServices(); - try { - const response = await selfStart.search - .search( + const response = await context + .search!.search( { ...searchRequest, id }, { abortSignal, strategy, - }, - context + } ) .toPromise(); @@ -97,12 +90,8 @@ export function registerSearchRoute( async (context, request, res) => { const { strategy, id } = request.params; - const [, , selfStart] = await getStartServices(); - const searchStrategy = selfStart.search.getSearchStrategy(strategy); - if (!searchStrategy.cancel) return res.ok(); - try { - await searchStrategy.cancel(context, id); + await context.search!.cancel(id, { strategy }); return res.ok(); } catch (err) { return res.customError({ diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 0130d3aacc91f..c7ef611e90cb2 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -26,12 +26,17 @@ import { Logger, Plugin, PluginInitializerContext, - RequestHandlerContext, SharedGlobalConfig, StartServicesAccessor, } from 'src/core/server'; import { first } from 'rxjs/operators'; -import { ISearchSetup, ISearchStart, ISearchStrategy, SearchEnhancements } from './types'; +import { + ISearchSetup, + ISearchStart, + ISearchStrategy, + SearchEnhancements, + SearchStrategyDependencies, +} from './types'; import { AggsService, AggsSetupDependencies } from './aggs'; @@ -53,6 +58,7 @@ import { SearchSourceService, searchSourceRequiredUiSettings, ISearchOptions, + ISearchClient, } from '../../common/search'; import { getShardDelayBucketAgg, @@ -61,6 +67,12 @@ import { import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn'; import { ConfigSchema } from '../../config'; +declare module 'src/core/server' { + interface RequestHandlerContext { + search?: ISearchClient; + } +} + type StrategyMap = Record>; /** @internal */ @@ -103,9 +115,17 @@ export class SearchService implements Plugin { getStartServices: core.getStartServices, globalConfig$: this.initializerContext.config.legacy.globalConfig$, }; - registerSearchRoute(router, routeDependencies); + registerSearchRoute(router); registerMsearchRoute(router, routeDependencies); + core.http.registerRouteHandlerContext('search', (context) => { + return this.getSearchClient({ + savedObjectsClient: context.core.savedObjects.client, + esClient: context.core.elasticsearch.client, + uiSettingsClient: context.core.uiSettings.client, + }); + }); + this.registerSearchStrategy( ES_SEARCH_STRATEGY, esSearchStrategyProvider( @@ -144,14 +164,25 @@ export class SearchService implements Plugin { usage, }; } + public start( { elasticsearch, savedObjects, uiSettings }: CoreStart, { fieldFormats, indexPatterns }: SearchServiceStartDependencies ): ISearchStart { + const getSearchClientAsScoped = (request: KibanaRequest) => { + const savedObjectsClient = savedObjects.getScopedClient(request); + const deps = { + savedObjectsClient, + esClient: elasticsearch.client.asScoped(request), + uiSettingsClient: uiSettings.asScopedToClient(savedObjectsClient), + }; + return this.getSearchClient(deps); + }; + return { aggs: this.aggsService.start({ fieldFormats, uiSettings }), getSearchStrategy: this.getSearchStrategy, - search: this.search.bind(this), + asScoped: getSearchClientAsScoped, searchSource: { asScoped: async (request: KibanaRequest) => { const esClient = elasticsearch.client.asScoped(request); @@ -169,39 +200,7 @@ export class SearchService implements Plugin { const searchSourceDependencies: SearchSourceDependencies = { getConfig: (key: string): T => uiSettingsCache[key], - search: < - SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, - SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse - >( - searchStrategyRequest: SearchStrategyRequest, - options: ISearchOptions - ) => { - /** - * Unless we want all SearchSource users to provide both a KibanaRequest - * (needed for index patterns) AND the RequestHandlerContext (needed for - * low-level search), we need to fake the context as it can be derived - * from the request object anyway. This will pose problems for folks who - * are registering custom search strategies as they are only getting a - * subset of the entire context. Ideally low-level search should be - * refactored to only require the needed dependencies: esClient & uiSettings. - */ - const fakeRequestHandlerContext = { - core: { - elasticsearch: { - client: esClient, - }, - uiSettings: { - client: uiSettingsClient, - }, - }, - } as RequestHandlerContext; - - return this.search( - searchStrategyRequest, - options, - fakeRequestHandlerContext - ).toPromise(); - }, + search: getSearchClientAsScoped(request).search, // onResponse isn't used on the server, so we just return the original value onResponse: (req, res) => res, legacy: { @@ -239,22 +238,35 @@ export class SearchService implements Plugin { SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse >( + deps: SearchStrategyDependencies, searchRequest: SearchStrategyRequest, - options: ISearchOptions, - context: RequestHandlerContext + options?: ISearchOptions ) => { const strategy = this.getSearchStrategy( - options.strategy || this.defaultSearchStrategyName + options?.strategy ); - return strategy.search(searchRequest, options, context); + return strategy.search(deps, searchRequest, options); + }; + + private cancel = (deps: SearchStrategyDependencies, id: string, options?: ISearchOptions) => { + const strategy = this.getSearchStrategy(options?.strategy); + + return strategy.cancel ? strategy.cancel(deps, id) : Promise.resolve(); + }; + + private getSearchClient = (deps: SearchStrategyDependencies): ISearchClient => { + return { + search: (searchRequest, options?) => this.search(deps, searchRequest, options), + cancel: (id: string, options?: ISearchOptions) => this.cancel(deps, id, options), + }; }; private getSearchStrategy = < SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse >( - name: string + name: string = this.defaultSearchStrategyName ): ISearchStrategy => { this.logger.debug(`Get strategy ${name}`); const strategy = this.searchStrategies[name]; diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index 9ba06d88dc4b3..622d6856b20f6 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -18,12 +18,18 @@ */ import { Observable } from 'rxjs'; -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; +import { + IScopedClusterClient, + IUiSettingsClient, + SavedObjectsClientContract, + KibanaRequest, +} from 'src/core/server'; import { ISearchOptions, ISearchStartSearchSource, IKibanaSearchRequest, IKibanaSearchResponse, + ISearchClient, } from '../../common/search'; import { AggsSetup, AggsStart } from './aggs'; import { SearchUsage } from './collectors'; @@ -33,6 +39,12 @@ export interface SearchEnhancements { defaultStrategy: string; } +export interface SearchStrategyDependencies { + savedObjectsClient: SavedObjectsClientContract; + esClient: IScopedClusterClient; + uiSettingsClient: IUiSettingsClient; +} + export interface ISearchSetup { aggs: AggsSetup; /** @@ -67,11 +79,11 @@ export interface ISearchStrategy< SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse > { search: ( + deps: SearchStrategyDependencies, request: SearchStrategyRequest, - options: ISearchOptions, - context: RequestHandlerContext + options?: ISearchOptions ) => Observable; - cancel?: (context: RequestHandlerContext, id: string) => Promise; + cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; } export interface ISearchStart< @@ -80,13 +92,14 @@ export interface ISearchStart< > { aggs: AggsStart; /** - * Get other registered search strategies. For example, if a new strategy needs to use the - * already-registered ES search strategy, it can use this function to accomplish that. + * Get other registered search strategies by name (or, by default, the Elasticsearch strategy). + * For example, if a new strategy needs to use the already-registered ES search strategy, it can + * use this function to accomplish that. */ getSearchStrategy: ( - name: string + name?: string // Name of the search strategy (defaults to the Elasticsearch strategy) ) => ISearchStrategy; - search: ISearchStrategy['search']; + asScoped: (request: KibanaRequest) => ISearchClient; searchSource: { asScoped: (request: KibanaRequest) => Promise; }; diff --git a/src/plugins/vis_type_timelion/server/routes/validate_es.ts b/src/plugins/vis_type_timelion/server/routes/validate_es.ts index 242be515e52bc..73f169e4bd859 100644 --- a/src/plugins/vis_type_timelion/server/routes/validate_es.ts +++ b/src/plugins/vis_type_timelion/server/routes/validate_es.ts @@ -20,7 +20,6 @@ import _ from 'lodash'; import { IRouter, CoreSetup } from 'kibana/server'; import { ES_SEARCH_STRATEGY } from '../../../data/server'; -import { TimelionPluginStartDeps } from '../plugin'; export function validateEsRoute(router: IRouter, core: CoreSetup) { router.get( @@ -30,7 +29,6 @@ export function validateEsRoute(router: IRouter, core: CoreSetup) { }, async function (context, request, response) { const uiSettings = await context.core.uiSettings.client.getAll(); - const deps = (await core.getStartServices())[1] as TimelionPluginStartDeps; const timefield = uiSettings['timelion:es.timefield']; @@ -58,14 +56,10 @@ export function validateEsRoute(router: IRouter, core: CoreSetup) { let resp; try { resp = ( - await deps.data.search - .search( - body, - { - strategy: ES_SEARCH_STRATEGY, - }, - context - ) + await context + .search!.search(body, { + strategy: ES_SEARCH_STRATEGY, + }) .toPromise() ).rawResponse; } catch (errResp) { 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 ceae784cf74a6..ece0ba4c2da2d 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 @@ -60,22 +60,8 @@ describe('AbstractSearchStrategy', () => { const responses = await abstractSearchStrategy.search( { - requestContext: {}, - framework: { - core: { - getStartServices: jest.fn().mockReturnValue( - Promise.resolve([ - {}, - { - data: { - search: { - search: searchFn, - }, - }, - }, - ]) - ), - }, + requestContext: { + search: { search: searchFn }, }, }, searches @@ -92,8 +78,7 @@ describe('AbstractSearchStrategy', () => { }, { 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 7b62ad310a354..c670825093608 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 @@ -56,12 +56,11 @@ export class AbstractSearchStrategy { } 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 + .search!.search( { params: { ...body, @@ -72,8 +71,7 @@ export class AbstractSearchStrategy { { ...options, strategy: this.searchStrategyName, - }, - req.requestContext + } ) .toPromise() ); diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts index 5b634fe4cf26c..72705f52b2937 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger, RequestHandlerContext } from 'src/core/server'; +import { Logger } from 'src/core/server'; import { EqlSearchStrategyRequest } from '../../common/search/types'; import { eqlSearchStrategyProvider } from './eql_search_strategy'; +import { SearchStrategyDependencies } from '../../../../../src/plugins/data/server'; const getMockEqlResponse = () => ({ body: { @@ -46,32 +47,26 @@ describe('EQL search strategy', () => { describe('search()', () => { let mockEqlSearch: jest.Mock; let mockEqlGet: jest.Mock; - let mockContext: RequestHandlerContext; + let mockDeps: SearchStrategyDependencies; let params: Required['params']; let options: Required['options']; beforeEach(() => { mockEqlSearch = jest.fn().mockResolvedValueOnce(getMockEqlResponse()); mockEqlGet = jest.fn().mockResolvedValueOnce(getMockEqlResponse()); - mockContext = ({ - core: { - uiSettings: { - client: { - get: jest.fn(), - }, - }, - elasticsearch: { - client: { - asCurrentUser: { - eql: { - get: mockEqlGet, - search: mockEqlSearch, - }, - }, + mockDeps = ({ + uiSettingsClient: { + get: jest.fn(), + }, + esClient: { + asCurrentUser: { + eql: { + get: mockEqlGet, + search: mockEqlSearch, }, }, }, - } as unknown) as RequestHandlerContext; + } as unknown) as SearchStrategyDependencies; params = { index: 'logstash-*', body: { query: 'process where 1 == 1' }, @@ -82,7 +77,7 @@ describe('EQL search strategy', () => { describe('async functionality', () => { it('performs an eql client search with params when no ID is provided', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search({ options, params }, {}, mockContext).toPromise(); + await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); const [[request, requestOptions]] = mockEqlSearch.mock.calls; expect(request.index).toEqual('logstash-*'); @@ -92,7 +87,7 @@ describe('EQL search strategy', () => { it('retrieves the current request if an id is provided', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search({ id: 'my-search-id' }, {}, mockContext).toPromise(); + await eqlSearch.search(mockDeps, { id: 'my-search-id' }, {}).toPromise(); const [[requestParams]] = mockEqlGet.mock.calls; expect(mockEqlSearch).not.toHaveBeenCalled(); @@ -103,7 +98,7 @@ describe('EQL search strategy', () => { describe('arguments', () => { it('sends along async search options', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search({ options, params }, {}, mockContext).toPromise(); + await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); const [[request]] = mockEqlSearch.mock.calls; expect(request).toEqual( @@ -116,7 +111,7 @@ describe('EQL search strategy', () => { it('sends along default search parameters', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search({ options, params }, {}, mockContext).toPromise(); + await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); const [[request]] = mockEqlSearch.mock.calls; expect(request).toEqual( @@ -131,6 +126,7 @@ describe('EQL search strategy', () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch .search( + mockDeps, { options, params: { @@ -139,8 +135,7 @@ describe('EQL search strategy', () => { keep_on_completion: false, }, }, - {}, - mockContext + {} ) .toPromise(); const [[request]] = mockEqlSearch.mock.calls; @@ -158,12 +153,12 @@ describe('EQL search strategy', () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch .search( + mockDeps, { options: { ...options, maxRetries: 2, ignore: [300] }, params, }, - {}, - mockContext + {} ) .toPromise(); const [[, requestOptions]] = mockEqlSearch.mock.calls; @@ -179,7 +174,7 @@ describe('EQL search strategy', () => { it('passes transport options for an existing request', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch - .search({ id: 'my-search-id', options: { ignore: [400] } }, {}, mockContext) + .search(mockDeps, { id: 'my-search-id', options: { ignore: [400] } }, {}) .toPromise(); const [[, requestOptions]] = mockEqlGet.mock.calls; diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts index a7ca999699e23..377b90c9cf7a9 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts @@ -21,19 +21,18 @@ export const eqlSearchStrategyProvider = ( logger: Logger ): ISearchStrategy => { return { - cancel: async (context, id) => { + cancel: async ({ esClient }, id) => { logger.debug(`_eql/delete ${id}`); - await context.core.elasticsearch.client.asCurrentUser.eql.delete({ + await esClient.asCurrentUser.eql.delete({ id, }); }, - search: (request, options, context) => + search: ({ esClient, uiSettingsClient }, request, options) => from( new Promise(async (resolve) => { logger.debug(`_eql/search ${JSON.stringify(request.params) || request.id}`); let promise: TransportRequestPromise; - const eqlClient = context.core.elasticsearch.client.asCurrentUser.eql; - const uiSettingsClient = await context.core.uiSettings.client; + const eqlClient = esClient.asCurrentUser.eql; const asyncOptions = getAsyncOptions(); const searchOptions = toSnakeCase({ ...request.options }); diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts index bab304b6afc9f..4f6b490972f06 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from '../../../../../src/core/server'; import { enhancedEsSearchStrategyProvider } from './es_search_strategy'; import { BehaviorSubject } from 'rxjs'; +import { SearchStrategyDependencies } from '../../../../../src/plugins/data/server/search'; const mockAsyncResponse = { body: { @@ -40,26 +40,20 @@ describe('ES search strategy', () => { const mockLogger: any = { debug: () => {}, }; - const mockContext = { - core: { - uiSettings: { - client: { - get: jest.fn(), - }, - }, - elasticsearch: { - client: { - asCurrentUser: { - asyncSearch: { - get: mockGetCaller, - submit: mockSubmitCaller, - }, - transport: { request: mockApiCaller }, - }, + const mockDeps = ({ + uiSettingsClient: { + get: jest.fn(), + }, + esClient: { + asCurrentUser: { + asyncSearch: { + get: mockGetCaller, + submit: mockSubmitCaller, }, + transport: { request: mockApiCaller }, }, }, - }; + } as unknown) as SearchStrategyDependencies; const mockConfig$ = new BehaviorSubject({ elasticsearch: { shardTimeout: { @@ -86,9 +80,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', body: { query: {} } }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch - .search({ params }, {}, (mockContext as unknown) as RequestHandlerContext) - .toPromise(); + await esSearch.search(mockDeps, { params }, {}).toPromise(); expect(mockSubmitCaller).toBeCalled(); const request = mockSubmitCaller.mock.calls[0][0]; @@ -102,9 +94,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', body: { query: {} } }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch - .search({ id: 'foo', params }, {}, (mockContext as unknown) as RequestHandlerContext) - .toPromise(); + await esSearch.search(mockDeps, { id: 'foo', params }, {}).toPromise(); expect(mockGetCaller).toBeCalled(); const request = mockGetCaller.mock.calls[0][0]; @@ -121,12 +111,12 @@ describe('ES search strategy', () => { await esSearch .search( + mockDeps, { indexType: 'rollup', params, }, - {}, - (mockContext as unknown) as RequestHandlerContext + {} ) .toPromise(); @@ -142,9 +132,7 @@ describe('ES search strategy', () => { const params = { index: 'foo-*', body: {} }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch - .search({ params }, {}, (mockContext as unknown) as RequestHandlerContext) - .toPromise(); + await esSearch.search(mockDeps, { params }, {}).toPromise(); expect(mockSubmitCaller).toBeCalled(); const request = mockSubmitCaller.mock.calls[0][0]; diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts index 9b89fb9fab3cb..58de427a14b07 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts @@ -9,7 +9,7 @@ import { first } from 'rxjs/operators'; import { SearchResponse } from 'elasticsearch'; import { Observable } from 'rxjs'; import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; -import { SharedGlobalConfig, RequestHandlerContext, Logger } from '../../../../../src/core/server'; +import { SharedGlobalConfig, Logger } from '../../../../../src/core/server'; import { getTotalLoaded, ISearchStrategy, @@ -20,13 +20,14 @@ import { shimHitsTotal, getAsyncOptions, shimAbortSignal, + SearchStrategyDependencies, } from '../../../../../src/plugins/data/server'; import { IEnhancedEsSearchRequest } from '../../common'; import { ISearchOptions, IEsSearchResponse, isCompleteResponse, -} from '../../../../../src/plugins/data/common/search'; +} from '../../../../../src/plugins/data/common'; function isEnhancedEsSearchResponse(response: any): response is IEsSearchResponse { return response.hasOwnProperty('isPartial') && response.hasOwnProperty('isRunning'); @@ -36,55 +37,48 @@ export const enhancedEsSearchStrategyProvider = ( config$: Observable, logger: Logger, usage?: SearchUsage -): ISearchStrategy => { - const search = ( - request: IEnhancedEsSearchRequest, - options: ISearchOptions, - context: RequestHandlerContext - ) => - from( - new Promise(async (resolve, reject) => { - logger.debug(`search ${JSON.stringify(request.params) || request.id}`); - - const isAsync = request.indexType !== 'rollup'; - - try { - const response = isAsync - ? await asyncSearch(request, options, context) - : await rollupSearch(request, options, context); - - if ( - usage && - isAsync && - isEnhancedEsSearchResponse(response) && - isCompleteResponse(response) - ) { - usage.trackSuccess(response.rawResponse.took); +): ISearchStrategy => { + return { + search: (deps, request, options) => + from( + new Promise(async (resolve, reject) => { + logger.debug(`search ${JSON.stringify(request.params) || request.id}`); + + const isAsync = request.indexType !== 'rollup'; + + try { + const response = isAsync + ? await asyncSearch(deps, request, options) + : await rollupSearch(deps, request, options); + + if ( + usage && + isAsync && + isEnhancedEsSearchResponse(response) && + isCompleteResponse(response) + ) { + usage.trackSuccess(response.rawResponse.took); + } + + resolve(response); + } catch (e) { + if (usage) usage.trackError(); + reject(e); } - - resolve(response); - } catch (e) { - if (usage) usage.trackError(); - reject(e); - } - }) - ); - - const cancel = async (context: RequestHandlerContext, id: string) => { - logger.debug(`cancel ${id}`); - await context.core.elasticsearch.client.asCurrentUser.asyncSearch.delete({ - id, - }); + }) + ), + cancel: async ({ esClient }, id) => { + logger.debug(`cancel ${id}`); + await esClient.asCurrentUser.asyncSearch.delete({ id }); + }, }; async function asyncSearch( + { esClient, uiSettingsClient }: SearchStrategyDependencies, request: IEnhancedEsSearchRequest, - options: ISearchOptions, - context: RequestHandlerContext + options?: ISearchOptions ): Promise { let promise: TransportRequestPromise; - const esClient = context.core.elasticsearch.client.asCurrentUser; - const uiSettingsClient = await context.core.uiSettings.client; const asyncOptions = getAsyncOptions(); // If we have an ID, then just poll for that ID, otherwise send the entire request body @@ -96,9 +90,9 @@ export const enhancedEsSearchStrategyProvider = ( ...request.params, }); - promise = esClient.asyncSearch.submit(submitOptions); + promise = esClient.asCurrentUser.asyncSearch.submit(submitOptions); } else { - promise = esClient.asyncSearch.get({ + promise = esClient.asCurrentUser.asyncSearch.get({ id: request.id, ...toSnakeCase(asyncOptions), }); @@ -115,13 +109,11 @@ export const enhancedEsSearchStrategyProvider = ( }; } - const rollupSearch = async function ( + async function rollupSearch( + { esClient, uiSettingsClient }: SearchStrategyDependencies, request: IEnhancedEsSearchRequest, - options: ISearchOptions, - context: RequestHandlerContext + options?: ISearchOptions ): Promise { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const uiSettingsClient = await context.core.uiSettings.client; const config = await config$.pipe(first()).toPromise(); const { body, index, ...params } = request.params!; const method = 'POST'; @@ -132,7 +124,7 @@ export const enhancedEsSearchStrategyProvider = ( ...params, }); - const promise = esClient.transport.request({ + const promise = esClient.asCurrentUser.transport.request({ method, path, body, @@ -146,7 +138,5 @@ export const enhancedEsSearchStrategyProvider = ( rawResponse: response, ...getTotalLoaded(response._shards), }; - }; - - return { search, cancel }; + } }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts b/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts index bc461f3885a70..a0955f5d44f2a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts @@ -26,13 +26,10 @@ export const securitySolutionIndexFieldsProvider = (): ISearchStrategy< const beatFields: BeatFields = require('../../utils/beat_schema/fields').fieldsBeat; return { - search: (request, options, context) => + search: ({ esClient }, request, options) => from( new Promise(async (resolve) => { - const { elasticsearch } = context.core; - const indexPatternsFetcher = new IndexPatternsFetcher( - elasticsearch.legacy.client.callAsCurrentUser - ); + const indexPatternsFetcher = new IndexPatternsFetcher(esClient.asCurrentUser); const dedupeIndices = dedupeIndexName(request.indices); const responsesIndexFields = await Promise.all( diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts index 962865880df5f..2d6937f40b5d1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts @@ -17,10 +17,10 @@ import { SecuritySolutionFactory } from './factory/types'; export const securitySolutionSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy, StrategyResponseType> => { - const es = data.search.getSearchStrategy('es'); + const es = data.search.getSearchStrategy(); return { - search: (request, options, context) => { + search: (deps, request, options) => { if (request.factoryQueryType == null) { throw new Error('factoryQueryType is required'); } @@ -28,12 +28,12 @@ export const securitySolutionSearchStrategyProvider = queryFactory.parse(request, esSearchRes))); }, - cancel: async (context, id) => { + cancel: async (deps, id) => { if (es.cancel) { - es.cancel(context, id); + es.cancel(deps, id); } }, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts index 165f0f586ebdb..39f65054d4f71 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts @@ -17,10 +17,10 @@ import { SecuritySolutionTimelineFactory } from './factory/types'; export const securitySolutionTimelineSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy, TimelineStrategyResponseType> => { - const es = data.search.getSearchStrategy('es'); + const es = data.search.getSearchStrategy(); return { - search: (request, options, context) => { + search: (deps, request, options) => { if (request.factoryQueryType == null) { throw new Error('factoryQueryType is required'); } @@ -29,12 +29,12 @@ export const securitySolutionTimelineSearchStrategyProvider = queryFactory.parse(request, esSearchRes))); }, - cancel: async (context, id) => { + cancel: async (deps, id) => { if (es.cancel) { - es.cancel(context, id); + es.cancel(deps, id); } }, }; From 36b8fcbd1c49226ee099a899755a860a2d7ceb74 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Thu, 15 Oct 2020 15:11:48 -0700 Subject: [PATCH 02/11] Update docs --- ...ugins-data-public.ikibanasearchresponse.md | 2 +- ...ublic.ikibanasearchresponse.rawresponse.md | 2 + ...bana-plugin-plugins-data-public.isearch.md | 11 ---- .../kibana-plugin-plugins-data-public.md | 1 - ...ns-data-public.searchinterceptor.search.md | 2 +- ...plugin-plugins-data-public.searchsource.md | 2 +- ...gins-data-public.searchsource.serialize.md | 4 +- ...ugins-data-public.searchsource.setfield.md | 2 +- ...gins-data-server.isearchstart.asscoped.md} | 6 +- ...a-server.isearchstart.getsearchstrategy.md | 4 +- ...plugin-plugins-data-server.isearchstart.md | 4 +- ...gins-data-server.isearchstrategy.cancel.md | 2 +- ...gin-plugins-data-server.isearchstrategy.md | 4 +- ...gins-data-server.isearchstrategy.search.md | 2 +- .../kibana-plugin-plugins-data-server.md | 1 + ...plugin-plugins-data-server.plugin.start.md | 8 +-- ...ver.searchstrategydependencies.esclient.md | 11 ++++ ...-data-server.searchstrategydependencies.md | 20 +++++++ ...strategydependencies.savedobjectsclient.md | 11 ++++ ...chstrategydependencies.uisettingsclient.md | 11 ++++ src/plugins/data/public/public.api.md | 40 ++++++------- src/plugins/data/server/server.api.md | 59 ++++++++++++------- 22 files changed, 131 insertions(+), 78 deletions(-) delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearch.md rename docs/development/plugins/data/server/{kibana-plugin-plugins-data-server.isearchstart.search.md => kibana-plugin-plugins-data-server.isearchstart.asscoped.md} (54%) create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.md create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md index 159dc8f4ada18..1d3e0c08dfc18 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md @@ -18,6 +18,6 @@ export interface IKibanaSearchResponse | [isPartial](./kibana-plugin-plugins-data-public.ikibanasearchresponse.ispartial.md) | boolean | Indicates whether the results returned are complete or partial | | [isRunning](./kibana-plugin-plugins-data-public.ikibanasearchresponse.isrunning.md) | boolean | Indicates whether search is still in flight | | [loaded](./kibana-plugin-plugins-data-public.ikibanasearchresponse.loaded.md) | number | If relevant to the search strategy, return a loaded number that represents how progress is indicated. | -| [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | RawResponse | | +| [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | RawResponse | The raw response returned by the internal search method (usually the raw ES response) | | [total](./kibana-plugin-plugins-data-public.ikibanasearchresponse.total.md) | number | If relevant to the search strategy, return a total number that represents how progress is indicated. | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md index 865c7d795801b..5857911259e12 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md @@ -4,6 +4,8 @@ ## IKibanaSearchResponse.rawResponse property +The raw response returned by the internal search method (usually the raw ES response) + Signature: ```typescript diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearch.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearch.md deleted file mode 100644 index 79f667a70571a..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearch.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearch](./kibana-plugin-plugins-data-public.isearch.md) - -## ISearch type - -Signature: - -```typescript -export declare type ISearch = (request: IKibanaSearchRequest, options?: ISearchOptions) => Observable; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index 6a3c437305cc8..cb0008e426edf 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -158,7 +158,6 @@ | [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | | | [IndexPatternSelectProps](./kibana-plugin-plugins-data-public.indexpatternselectprops.md) | | | [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) | | -| [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | | | [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | | | [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | search source interface | | [MatchAllFilter](./kibana-plugin-plugins-data-public.matchallfilter.md) | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md index 672ff5065c456..61f8eeb973f4c 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md @@ -23,5 +23,5 @@ search(request: IKibanaSearchRequest, options?: ISearchOptions): Observable` -`Observalbe` emitting the search response or an error. +`Observable` emitting the search response or an error. diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.md index 87346f81b13e2..548fa66e6e518 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.md @@ -42,7 +42,7 @@ export declare class SearchSource | [getSerializedFields()](./kibana-plugin-plugins-data-public.searchsource.getserializedfields.md) | | serializes search source fields (which can later be passed to [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md)) | | [onRequestStart(handler)](./kibana-plugin-plugins-data-public.searchsource.onrequeststart.md) | | Add a handler that will be notified whenever requests start | | [serialize()](./kibana-plugin-plugins-data-public.searchsource.serialize.md) | | Serializes the instance to a JSON string and a set of referenced objects. Use this method to get a representation of the search source which can be stored in a saved object.The references returned by this function can be mixed with other references in the same object, however make sure there are no name-collisions. The references will be named kibanaSavedObjectMeta.searchSourceJSON.index and kibanaSavedObjectMeta.searchSourceJSON.filter[<number>].meta.index.Using createSearchSource, the instance can be re-created. | -| [setField(field, value)](./kibana-plugin-plugins-data-public.searchsource.setfield.md) | | sets value to a single search source feild | +| [setField(field, value)](./kibana-plugin-plugins-data-public.searchsource.setfield.md) | | sets value to a single search source field | | [setFields(newFields)](./kibana-plugin-plugins-data-public.searchsource.setfields.md) | | Internal, do not use. Overrides all search source fields with the new field array. | | [setParent(parent, options)](./kibana-plugin-plugins-data-public.searchsource.setparent.md) | | Set a searchSource that this source should inherit from | | [setPreferredSearchStrategyId(searchStrategyId)](./kibana-plugin-plugins-data-public.searchsource.setpreferredsearchstrategyid.md) | | internal, dont use | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.serialize.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.serialize.md index 496e1ae9677d8..3bc2a20541777 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.serialize.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.serialize.md @@ -15,13 +15,13 @@ Using `createSearchSource`, the instance can be re-created. ```typescript serialize(): { searchSourceJSON: string; - references: import("../../../../../core/types").SavedObjectReference[]; + references: import("src/core/server").SavedObjectReference[]; }; ``` Returns: `{ searchSourceJSON: string; - references: import("../../../../../core/types").SavedObjectReference[]; + references: import("src/core/server").SavedObjectReference[]; }` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.setfield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.setfield.md index 22619940f1589..e96a35d8deee9 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.setfield.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.setfield.md @@ -4,7 +4,7 @@ ## SearchSource.setField() method -sets value to a single search source feild +sets value to a single search source field Signature: diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.search.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md similarity index 54% rename from docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.search.md rename to docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md index 98ea175aaaea7..f97cc22a53001 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.search.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md @@ -1,11 +1,11 @@ -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [search](./kibana-plugin-plugins-data-server.isearchstart.search.md) +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md) -## ISearchStart.search property +## ISearchStart.asScoped property Signature: ```typescript -search: ISearchStrategy['search']; +asScoped: (request: KibanaRequest) => ISearchClient; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md index 398ea21641942..9820e281c3f93 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md @@ -4,10 +4,10 @@ ## ISearchStart.getSearchStrategy property -Get other registered search strategies. For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. +Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. Signature: ```typescript -getSearchStrategy: (name: string) => ISearchStrategy; +getSearchStrategy: (name?: string) => ISearchStrategy; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md index b99c5f0f10a9e..771b529f23824 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md @@ -15,7 +15,7 @@ export interface ISearchStartAggsStart | | -| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | (name: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> | Get other registered search strategies. For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. | -| [search](./kibana-plugin-plugins-data-server.isearchstart.search.md) | ISearchStrategy['search'] | | +| [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md) | (request: KibanaRequest) => ISearchClient | | +| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | (name?: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> | Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. | | [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) | {
asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;
} | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md index 34903697090ea..5267290b3b0ee 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md @@ -7,5 +7,5 @@ Signature: ```typescript -cancel?: (context: RequestHandlerContext, id: string) => Promise; +cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md index 6dd95da2be3c1..39cc51049175e 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md @@ -16,6 +16,6 @@ export interface ISearchStrategy(context: RequestHandlerContext, id: string) => Promise<void> | | -| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | (request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable<SearchStrategyResponse> | | +| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | (deps: SearchStrategyDependencies, id: string) => Promise<void> | | +| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable<SearchStrategyResponse> | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md index 84b90ae23f916..d7911cbfdcbac 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md @@ -7,5 +7,5 @@ Signature: ```typescript -search: (request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable; +search: (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index f1eecd6e49b02..fa3d35e8fe7e4 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -58,6 +58,7 @@ | [PluginSetup](./kibana-plugin-plugins-data-server.pluginsetup.md) | | | [PluginStart](./kibana-plugin-plugins-data-server.pluginstart.md) | | | [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) | | +| [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) | | | [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) | | | [TabbedAggColumn](./kibana-plugin-plugins-data-server.tabbedaggcolumn.md) | \* | | [TabbedTable](./kibana-plugin-plugins-data-server.tabbedtable.md) | \* | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md index 215eac9829451..a1e42c44fa861 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md @@ -9,10 +9,10 @@ ```typescript start(core: CoreStart): { fieldFormats: { - fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; + fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise; }; indexPatterns: { - indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; + indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; }; search: ISearchStart>; }; @@ -28,10 +28,10 @@ start(core: CoreStart): { `{ fieldFormats: { - fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; + fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise; }; indexPatterns: { - indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; + indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; }; search: ISearchStart>; }` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md new file mode 100644 index 0000000000000..d205021e10954 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [esClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md) + +## SearchStrategyDependencies.esClient property + +Signature: + +```typescript +esClient: IScopedClusterClient; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.md new file mode 100644 index 0000000000000..be95fb04a2c4f --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) + +## SearchStrategyDependencies interface + +Signature: + +```typescript +export interface SearchStrategyDependencies +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [esClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md) | IScopedClusterClient | | +| [savedObjectsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md) | SavedObjectsClientContract | | +| [uiSettingsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md) | IUiSettingsClient | | + diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md new file mode 100644 index 0000000000000..f159a863312a4 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [savedObjectsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md) + +## SearchStrategyDependencies.savedObjectsClient property + +Signature: + +```typescript +savedObjectsClient: SavedObjectsClientContract; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md new file mode 100644 index 0000000000000..38a33e41c396f --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [uiSettingsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md) + +## SearchStrategyDependencies.uiSettingsClient property + +Signature: + +```typescript +uiSettingsClient: IUiSettingsClient; +``` diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 2ed3e440040de..230b0f0bc0ed9 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -136,7 +136,7 @@ export class AggConfig { // (undocumented) makeLabel(percentageMode?: boolean): any; static nextId(list: IAggConfig[]): number; - onSearchRequestStart(searchSource: ISearchSource_2, options?: ISearchOptions): Promise | Promise; + onSearchRequestStart(searchSource: ISearchSource_2, options?: ISearchOptions_2): Promise | Promise; // (undocumented) params: any; // Warning: (ae-incompatible-release-tags) The symbol "parent" is marked as @public, but its signature references "IAggConfigs" which is marked as @internal @@ -1044,7 +1044,6 @@ export interface IKibanaSearchResponse { isPartial?: boolean; isRunning?: boolean; loaded?: number; - // (undocumented) rawResponse: RawResponse; total?: number; } @@ -1374,11 +1373,6 @@ export type InputTimeRange = TimeRange | { // @public (undocumented) export const isCompleteResponse: (response?: IKibanaSearchResponse | undefined) => boolean | undefined; -// Warning: (ae-missing-release-tag) "ISearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ISearch = (request: IKibanaSearchRequest, options?: ISearchOptions) => Observable; - // Warning: (ae-missing-release-tag) "ISearchGeneric" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -2066,7 +2060,7 @@ export class SearchSource { onRequestStart(handler: (searchSource: SearchSource, options?: ISearchOptions) => Promise): void; serialize(): { searchSourceJSON: string; - references: import("../../../../../core/types").SavedObjectReference[]; + references: import("src/core/server").SavedObjectReference[]; }; setField(field: K, value: SearchSourceFields[K]): this; setFields(newFields: SearchSourceFields): this; @@ -2300,21 +2294,21 @@ export const UI_SETTINGS: { // src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:415:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 0828460830f2c..942d4df96083a 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -21,8 +21,10 @@ import { ErrorToastOptions } from 'src/core/public/notifications'; import { ExpressionAstFunction } from 'src/plugins/expressions/common'; import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import { ISavedObjectsRepository } from 'kibana/server'; +import { IScopedClusterClient } from 'src/core/server'; import { ISearchOptions as ISearchOptions_2 } from 'src/plugins/data/public'; import { ISearchSource } from 'src/plugins/data/public'; +import { IUiSettingsClient } from 'src/core/server'; import { KibanaRequest } from 'src/core/server'; import { LegacyAPICaller } from 'kibana/server'; import { Logger } from 'kibana/server'; @@ -38,7 +40,6 @@ import { Plugin as Plugin_3 } from 'kibana/server'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/server'; import { RecursiveReadonly } from '@kbn/utility-types'; import { RequestAdapter } from 'src/plugins/inspector/common'; -import { RequestHandlerContext } from 'src/core/server'; import { RequestStatistics } from 'src/plugins/inspector/common'; import { SavedObject } from 'src/core/server'; import { SavedObjectsClientContract } from 'src/core/server'; @@ -366,7 +367,7 @@ export const getAsyncOptions: () => { // Warning: (ae-missing-release-tag) "getDefaultSearchParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise<{ +export function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient_2): Promise<{ maxConcurrentShardRequests: number | undefined; ignoreThrottled: boolean; ignoreUnavailable: boolean; @@ -712,9 +713,11 @@ export interface ISearchStart ISearchStrategy; + // Warning: (ae-forgotten-export) The symbol "ISearchClient" needs to be exported by the entry point index.d.ts + // // (undocumented) - search: ISearchStrategy['search']; + asScoped: (request: KibanaRequest) => ISearchClient; + getSearchStrategy: (name?: string) => ISearchStrategy; // (undocumented) searchSource: { asScoped: (request: KibanaRequest) => Promise; @@ -726,9 +729,9 @@ export interface ISearchStart { // (undocumented) - cancel?: (context: RequestHandlerContext, id: string) => Promise; + cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; // (undocumented) - search: (request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable; + search: (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable; } // @public (undocumented) @@ -877,10 +880,10 @@ export class Plugin implements Plugin_2 Promise; + fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise; }; indexPatterns: { - indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; + indexPatternsServiceFactory: (savedObjectsClient: Pick) => Promise; }; search: ISearchStart>; }; @@ -978,6 +981,18 @@ export const search: { tabifyGetColumns: typeof tabifyGetColumns; }; +// Warning: (ae-missing-release-tag) "SearchStrategyDependencies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SearchStrategyDependencies { + // (undocumented) + esClient: IScopedClusterClient; + // (undocumented) + savedObjectsClient: SavedObjectsClientContract; + // (undocumented) + uiSettingsClient: IUiSettingsClient; +} + // Warning: (ae-missing-release-tag) "SearchUsage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1126,22 +1141,22 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:228:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:228:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:228:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:228:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:230:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:231:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:240:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:241:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:242:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:246:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:247:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:251:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:254:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:229:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:229:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:229:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:229:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:231:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:232:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:241:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:242:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:243:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:247:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:248:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:252:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:255:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index_patterns/index_patterns_service.ts:50:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:88:66 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/search/types.ts:91:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/search/types.ts:104:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) From c7296f0b667f8d25ae961d2d255f1189ca011cf3 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Mon, 19 Oct 2020 14:27:20 -0700 Subject: [PATCH 03/11] Unify interface for getting search client --- .../data/server/search/search_service.ts | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index c7ef611e90cb2..2b4eee1db18e5 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -118,12 +118,9 @@ export class SearchService implements Plugin { registerSearchRoute(router); registerMsearchRoute(router, routeDependencies); - core.http.registerRouteHandlerContext('search', (context) => { - return this.getSearchClient({ - savedObjectsClient: context.core.savedObjects.client, - esClient: context.core.elasticsearch.client, - uiSettingsClient: context.core.uiSettings.client, - }); + core.http.registerRouteHandlerContext('search', async (context, request) => { + const [coreStart] = await core.getStartServices(); + return this.asScopedProvider(coreStart)(request); }); this.registerSearchStrategy( @@ -166,23 +163,15 @@ export class SearchService implements Plugin { } public start( - { elasticsearch, savedObjects, uiSettings }: CoreStart, + core: CoreStart, { fieldFormats, indexPatterns }: SearchServiceStartDependencies ): ISearchStart { - const getSearchClientAsScoped = (request: KibanaRequest) => { - const savedObjectsClient = savedObjects.getScopedClient(request); - const deps = { - savedObjectsClient, - esClient: elasticsearch.client.asScoped(request), - uiSettingsClient: uiSettings.asScopedToClient(savedObjectsClient), - }; - return this.getSearchClient(deps); - }; - + const { elasticsearch, savedObjects, uiSettings } = core; + const asScoped = this.asScopedProvider(core); return { aggs: this.aggsService.start({ fieldFormats, uiSettings }), getSearchStrategy: this.getSearchStrategy, - asScoped: getSearchClientAsScoped, + asScoped, searchSource: { asScoped: async (request: KibanaRequest) => { const esClient = elasticsearch.client.asScoped(request); @@ -200,7 +189,7 @@ export class SearchService implements Plugin { const searchSourceDependencies: SearchSourceDependencies = { getConfig: (key: string): T => uiSettingsCache[key], - search: getSearchClientAsScoped(request).search, + search: asScoped(request).search, // onResponse isn't used on the server, so we just return the original value onResponse: (req, res) => res, legacy: { @@ -255,13 +244,6 @@ export class SearchService implements Plugin { return strategy.cancel ? strategy.cancel(deps, id) : Promise.resolve(); }; - private getSearchClient = (deps: SearchStrategyDependencies): ISearchClient => { - return { - search: (searchRequest, options?) => this.search(deps, searchRequest, options), - cancel: (id: string, options?: ISearchOptions) => this.cancel(deps, id, options), - }; - }; - private getSearchStrategy = < SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse @@ -275,4 +257,19 @@ export class SearchService implements Plugin { } return strategy; }; + + private asScopedProvider = ({ elasticsearch, savedObjects, uiSettings }: CoreStart) => { + return (request: KibanaRequest): ISearchClient => { + const savedObjectsClient = savedObjects.getScopedClient(request); + const deps = { + savedObjectsClient, + esClient: elasticsearch.client.asScoped(request), + uiSettingsClient: uiSettings.asScopedToClient(savedObjectsClient), + }; + return { + search: (searchRequest, options) => this.search(deps, searchRequest, options), + cancel: (id, options) => this.cancel(deps, id, options), + }; + }; + }; } From 9dadfb22c0ffea82372933d5f5ef48c2335c3d05 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 20 Oct 2020 10:08:33 -0700 Subject: [PATCH 04/11] Update examples/search_examples/server/my_strategy.ts Co-authored-by: Anton Dosov --- examples/search_examples/server/my_strategy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/search_examples/server/my_strategy.ts b/examples/search_examples/server/my_strategy.ts index 957216c7b9713..b537e5b579833 100644 --- a/examples/search_examples/server/my_strategy.ts +++ b/examples/search_examples/server/my_strategy.ts @@ -35,7 +35,7 @@ export const mySearchStrategyProvider = ( ), cancel: async (deps, id) => { if (es.cancel) { - es.cancel(deps, id); + await es.cancel(deps, id); } }, }; From 2b3d2a0415930ecbad9f996bddc08a1d94ffb60c Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Mon, 26 Oct 2020 12:38:52 -0700 Subject: [PATCH 05/11] Review feedback --- .../search_examples/server/my_strategy.ts | 8 ++++---- .../search/search_source/search_source.ts | 5 +++-- .../es_search/es_search_strategy.test.ts | 8 ++++---- .../search/es_search/es_search_strategy.ts | 4 ++-- .../data/server/search/search_service.ts | 18 ++++++++--------- src/plugins/data/server/search/types.ts | 6 +++--- .../public/search/search_interceptor.ts | 2 +- .../server/search/eql_search_strategy.test.ts | 20 +++++++++---------- .../server/search/eql_search_strategy.ts | 6 +++--- .../server/search/es_search_strategy.test.ts | 10 +++++----- .../server/search/es_search_strategy.ts | 20 +++++++++---------- .../search_strategy/index_fields/index.ts | 2 +- .../security_solution/index.ts | 8 ++++---- .../server/search_strategy/timeline/index.ts | 8 ++++---- 14 files changed, 63 insertions(+), 62 deletions(-) diff --git a/examples/search_examples/server/my_strategy.ts b/examples/search_examples/server/my_strategy.ts index 957216c7b9713..cb06f931bd119 100644 --- a/examples/search_examples/server/my_strategy.ts +++ b/examples/search_examples/server/my_strategy.ts @@ -26,16 +26,16 @@ export const mySearchStrategyProvider = ( ): ISearchStrategy => { const es = data.search.getSearchStrategy(); return { - search: (deps, request, options) => - es.search(deps, request, options).pipe( + search: (request, options, deps) => + es.search(request, options, deps).pipe( map((esSearchRes) => ({ ...esSearchRes, cool: request.get_cool ? 'YES' : 'NOPE', })) ), - cancel: async (deps, id) => { + cancel: async (id, options, deps) => { if (es.cancel) { - es.cancel(deps, id); + return es.cancel(id, options, deps); } }, }; diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index 418e316860eb9..f52b8434f0c8f 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -71,6 +71,7 @@ import { setWith } from '@elastic/safer-lodash-set'; import { uniqueId, uniq, extend, pick, difference, omit, isObject, keys, isFunction } from 'lodash'; +import { map } from 'rxjs/operators'; import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; import { fieldWildcardFilter } from '../../../../kibana_utils/common'; @@ -311,8 +312,8 @@ export class SearchSource { }); return search({ params, indexType: searchRequest.indexType }, options) - .toPromise() - .then(({ rawResponse }) => onResponse(searchRequest, rawResponse)); + .pipe(map(({ rawResponse }) => onResponse(searchRequest, rawResponse))) + .toPromise(); } /** diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts index ddac28d9d54f5..4556bee94603f 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts @@ -59,7 +59,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*' }; await esSearchStrategyProvider(mockConfig$, mockLogger) - .search(mockDeps, { params }, {}) + .search({ params }, {}, mockDeps) .subscribe(() => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ @@ -75,7 +75,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; await esSearchStrategyProvider(mockConfig$, mockLogger) - .search(mockDeps, { params }, {}) + .search({ params }, {}, mockDeps) .subscribe(() => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ @@ -89,11 +89,11 @@ describe('ES search strategy', () => { it('has all response parameters', async (done) => await esSearchStrategyProvider(mockConfig$, mockLogger) .search( - mockDeps, { params: { index: 'logstash-*' }, }, - {} + {}, + mockDeps ) .subscribe((data) => { expect(data.isRunning).toBe(false); diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.ts b/src/plugins/data/server/search/es_search/es_search_strategy.ts index cb66cafb66144..d20f90ae1cb0b 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.ts @@ -38,7 +38,7 @@ export const esSearchStrategyProvider = ( usage?: SearchUsage ): ISearchStrategy => { return { - search: ({ esClient, uiSettingsClient }, request, options) => + search: (request, options, { esClient, uiSettingsClient }) => from( new Promise(async (resolve, reject) => { logger.debug(`search ${request.params?.index}`); @@ -64,7 +64,7 @@ export const esSearchStrategyProvider = ( try { const promise = shimAbortSignal( esClient.asCurrentUser.search(params), - options?.abortSignal + options.abortSignal ); const { body: rawResponse } = (await promise) as ApiResponse>; diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 2b4eee1db18e5..b6d9d7f3e4e6a 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -227,21 +227,21 @@ export class SearchService implements Plugin { SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse >( - deps: SearchStrategyDependencies, searchRequest: SearchStrategyRequest, - options?: ISearchOptions + options: ISearchOptions, + deps: SearchStrategyDependencies ) => { const strategy = this.getSearchStrategy( - options?.strategy + options.strategy ); - return strategy.search(deps, searchRequest, options); + return strategy.search(searchRequest, options, deps); }; - private cancel = (deps: SearchStrategyDependencies, id: string, options?: ISearchOptions) => { - const strategy = this.getSearchStrategy(options?.strategy); + private cancel = (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => { + const strategy = this.getSearchStrategy(options.strategy); - return strategy.cancel ? strategy.cancel(deps, id) : Promise.resolve(); + return strategy.cancel ? strategy.cancel(id, options, deps) : Promise.resolve(); }; private getSearchStrategy = < @@ -267,8 +267,8 @@ export class SearchService implements Plugin { uiSettingsClient: uiSettings.asScopedToClient(savedObjectsClient), }; return { - search: (searchRequest, options) => this.search(deps, searchRequest, options), - cancel: (id, options) => this.cancel(deps, id, options), + search: (searchRequest, options = {}) => this.search(searchRequest, options, deps), + cancel: (id, options = {}) => this.cancel(id, options, deps), }; }; }; diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index 622d6856b20f6..ebce02014c2a4 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -79,11 +79,11 @@ export interface ISearchStrategy< SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse > { search: ( - deps: SearchStrategyDependencies, request: SearchStrategyRequest, - options?: ISearchOptions + options: ISearchOptions, + deps: SearchStrategyDependencies ) => Observable; - cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; + cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise; } export interface ISearchStart< diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts index aee32a7c62759..91304e3191ae2 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts @@ -65,7 +65,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { timeout: this.searchTimeout, }); const aborted$ = from(toPromise(combinedSignal)); - const strategy = options?.strategy || ENHANCED_ES_SEARCH_STRATEGY; + const strategy = options?.strategy ?? ENHANCED_ES_SEARCH_STRATEGY; this.pendingCount$.next(this.pendingCount$.getValue() + 1); diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts index 91bc4ac524b9e..efa481ec15c40 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts @@ -77,7 +77,7 @@ describe('EQL search strategy', () => { describe('async functionality', () => { it('performs an eql client search with params when no ID is provided', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); + await eqlSearch.search({ options, params }, {}, mockDeps).toPromise(); const [[request, requestOptions]] = mockEqlSearch.mock.calls; expect(request.index).toEqual('logstash-*'); @@ -87,7 +87,7 @@ describe('EQL search strategy', () => { it('retrieves the current request if an id is provided', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search(mockDeps, { id: 'my-search-id' }, {}).toPromise(); + await eqlSearch.search({ id: 'my-search-id' }, {}, mockDeps).toPromise(); const [[requestParams]] = mockEqlGet.mock.calls; expect(mockEqlSearch).not.toHaveBeenCalled(); @@ -98,7 +98,7 @@ describe('EQL search strategy', () => { expect.assertions(1); mockEqlSearch.mockReset().mockRejectedValueOnce(new Error('client error')); const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - eqlSearch.search({ options, params }, {}, mockContext).subscribe( + eqlSearch.search({ options, params }, {}, mockDeps).subscribe( () => {}, (err) => { expect(err).toEqual(new Error('client error')); @@ -110,7 +110,7 @@ describe('EQL search strategy', () => { describe('arguments', () => { it('sends along async search options', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); + await eqlSearch.search({ options, params }, {}, mockDeps).toPromise(); const [[request]] = mockEqlSearch.mock.calls; expect(request).toEqual( @@ -123,7 +123,7 @@ describe('EQL search strategy', () => { it('sends along default search parameters', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); - await eqlSearch.search(mockDeps, { options, params }, {}).toPromise(); + await eqlSearch.search({ options, params }, {}, mockDeps).toPromise(); const [[request]] = mockEqlSearch.mock.calls; expect(request).toEqual( @@ -138,7 +138,6 @@ describe('EQL search strategy', () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch .search( - mockDeps, { options, params: { @@ -147,7 +146,8 @@ describe('EQL search strategy', () => { keep_on_completion: false, }, }, - {} + {}, + mockDeps ) .toPromise(); const [[request]] = mockEqlSearch.mock.calls; @@ -165,12 +165,12 @@ describe('EQL search strategy', () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch .search( - mockDeps, { options: { ...options, maxRetries: 2, ignore: [300] }, params, }, - {} + {}, + mockDeps ) .toPromise(); const [[, requestOptions]] = mockEqlSearch.mock.calls; @@ -186,7 +186,7 @@ describe('EQL search strategy', () => { it('passes transport options for an existing request', async () => { const eqlSearch = await eqlSearchStrategyProvider(mockLogger); await eqlSearch - .search(mockDeps, { id: 'my-search-id', options: { ignore: [400] } }, {}) + .search({ id: 'my-search-id', options: { ignore: [400] } }, {}, mockDeps) .toPromise(); const [[, requestOptions]] = mockEqlGet.mock.calls; diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts index d2c3c22dca383..ad154014866ea 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.ts @@ -21,13 +21,13 @@ export const eqlSearchStrategyProvider = ( logger: Logger ): ISearchStrategy => { return { - cancel: async ({ esClient }, id) => { + cancel: async (id, options, { esClient }) => { logger.debug(`_eql/delete ${id}`); await esClient.asCurrentUser.eql.delete({ id, }); }, - search: ({ esClient, uiSettingsClient }, request, options) => + search: (request, options, { esClient, uiSettingsClient }) => from( new Promise(async (resolve, reject) => { logger.debug(`_eql/search ${JSON.stringify(request.params) || request.id}`); @@ -62,7 +62,7 @@ export const eqlSearchStrategyProvider = ( ); } - const rawResponse = await shimAbortSignal(promise, options?.abortSignal); + const rawResponse = await shimAbortSignal(promise, options.abortSignal); const { id, is_partial: isPartial, is_running: isRunning } = rawResponse.body; resolve({ diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts index 4f6b490972f06..b9b6e25067f2f 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts @@ -80,7 +80,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', body: { query: {} } }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch.search(mockDeps, { params }, {}).toPromise(); + await esSearch.search({ params }, {}, mockDeps).toPromise(); expect(mockSubmitCaller).toBeCalled(); const request = mockSubmitCaller.mock.calls[0][0]; @@ -94,7 +94,7 @@ describe('ES search strategy', () => { const params = { index: 'logstash-*', body: { query: {} } }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch.search(mockDeps, { id: 'foo', params }, {}).toPromise(); + await esSearch.search({ id: 'foo', params }, {}, mockDeps).toPromise(); expect(mockGetCaller).toBeCalled(); const request = mockGetCaller.mock.calls[0][0]; @@ -111,12 +111,12 @@ describe('ES search strategy', () => { await esSearch .search( - mockDeps, { indexType: 'rollup', params, }, - {} + {}, + mockDeps ) .toPromise(); @@ -132,7 +132,7 @@ describe('ES search strategy', () => { const params = { index: 'foo-*', body: {} }; const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger); - await esSearch.search(mockDeps, { params }, {}).toPromise(); + await esSearch.search({ params }, {}, mockDeps).toPromise(); expect(mockSubmitCaller).toBeCalled(); const request = mockSubmitCaller.mock.calls[0][0]; diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts index 58de427a14b07..144a063148953 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts @@ -39,7 +39,7 @@ export const enhancedEsSearchStrategyProvider = ( usage?: SearchUsage ): ISearchStrategy => { return { - search: (deps, request, options) => + search: (request, options, deps) => from( new Promise(async (resolve, reject) => { logger.debug(`search ${JSON.stringify(request.params) || request.id}`); @@ -48,8 +48,8 @@ export const enhancedEsSearchStrategyProvider = ( try { const response = isAsync - ? await asyncSearch(deps, request, options) - : await rollupSearch(deps, request, options); + ? await asyncSearch(request, options, deps) + : await rollupSearch(request, options, deps); if ( usage && @@ -67,16 +67,16 @@ export const enhancedEsSearchStrategyProvider = ( } }) ), - cancel: async ({ esClient }, id) => { + cancel: async (id, options, { esClient }) => { logger.debug(`cancel ${id}`); await esClient.asCurrentUser.asyncSearch.delete({ id }); }, }; async function asyncSearch( - { esClient, uiSettingsClient }: SearchStrategyDependencies, request: IEnhancedEsSearchRequest, - options?: ISearchOptions + options: ISearchOptions, + { esClient, uiSettingsClient }: SearchStrategyDependencies ): Promise { let promise: TransportRequestPromise; const asyncOptions = getAsyncOptions(); @@ -98,7 +98,7 @@ export const enhancedEsSearchStrategyProvider = ( }); } - const esResponse = await shimAbortSignal(promise, options?.abortSignal); + const esResponse = await shimAbortSignal(promise, options.abortSignal); const { id, response, is_partial: isPartial, is_running: isRunning } = esResponse.body; return { id, @@ -110,9 +110,9 @@ export const enhancedEsSearchStrategyProvider = ( } async function rollupSearch( - { esClient, uiSettingsClient }: SearchStrategyDependencies, request: IEnhancedEsSearchRequest, - options?: ISearchOptions + options: ISearchOptions, + { esClient, uiSettingsClient }: SearchStrategyDependencies ): Promise { const config = await config$.pipe(first()).toPromise(); const { body, index, ...params } = request.params!; @@ -131,7 +131,7 @@ export const enhancedEsSearchStrategyProvider = ( querystring, }); - const esResponse = await shimAbortSignal(promise, options?.abortSignal); + const esResponse = await shimAbortSignal(promise, options.abortSignal); const response = esResponse.body as SearchResponse; return { diff --git a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts b/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts index a0955f5d44f2a..81ee4dc7c9ad2 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts @@ -26,7 +26,7 @@ export const securitySolutionIndexFieldsProvider = (): ISearchStrategy< const beatFields: BeatFields = require('../../utils/beat_schema/fields').fieldsBeat; return { - search: ({ esClient }, request, options) => + search: (request, options, { esClient }) => from( new Promise(async (resolve) => { const indexPatternsFetcher = new IndexPatternsFetcher(esClient.asCurrentUser); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts index 2d6937f40b5d1..9128238631208 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts @@ -20,7 +20,7 @@ export const securitySolutionSearchStrategyProvider = { + search: (request, options, deps) => { if (request.factoryQueryType == null) { throw new Error('factoryQueryType is required'); } @@ -28,12 +28,12 @@ export const securitySolutionSearchStrategyProvider = queryFactory.parse(request, esSearchRes))); }, - cancel: async (deps, id) => { + cancel: async (id, options, deps) => { if (es.cancel) { - es.cancel(deps, id); + return es.cancel(id, options, deps); } }, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts index 39f65054d4f71..6967db17813a8 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts @@ -20,7 +20,7 @@ export const securitySolutionTimelineSearchStrategyProvider = { + search: (request, options, deps) => { if (request.factoryQueryType == null) { throw new Error('factoryQueryType is required'); } @@ -29,12 +29,12 @@ export const securitySolutionTimelineSearchStrategyProvider = queryFactory.parse(request, esSearchRes))); }, - cancel: async (deps, id) => { + cancel: async (id, options, deps) => { if (es.cancel) { - es.cancel(deps, id); + return es.cancel(id, options, deps); } }, }; From 6c9aec5ef110aff5115fa32ec9e9e79d34b6bf00 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Wed, 28 Oct 2020 12:27:42 -0700 Subject: [PATCH 06/11] Fix checks --- examples/search_examples/server/my_strategy.ts | 4 ++-- .../server/series_functions/es/index.js | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/examples/search_examples/server/my_strategy.ts b/examples/search_examples/server/my_strategy.ts index f210fa9a32329..d5b19f0619bbc 100644 --- a/examples/search_examples/server/my_strategy.ts +++ b/examples/search_examples/server/my_strategy.ts @@ -33,9 +33,9 @@ export const mySearchStrategyProvider = ( cool: request.get_cool ? 'YES' : 'NOPE', })) ), - cancel: (id, options, deps) => { + cancel: async (id, options, deps) => { if (es.cancel) { - return es.cancel(id, options, deps); + await es.cancel(id, options, deps); } }, }; diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/index.js b/src/plugins/vis_type_timelion/server/series_functions/es/index.js index fc3250f0d4726..c04f044b79717 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/index.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/index.js @@ -130,16 +130,10 @@ export default new Datasource('es', { const body = buildRequest(config, tlConfig, scriptedFields, esShardTimeout); - const deps = (await tlConfig.getStartServices())[1]; - - const resp = await deps.data.search - .search( - body, - { - strategy: ES_SEARCH_STRATEGY, - }, - tlConfig.context - ) + const resp = await tlConfig.context.search + .search(body, { + strategy: ES_SEARCH_STRATEGY, + }) .toPromise(); if (!resp.rawResponse._shards.total) { From 1ae55efa63b53e7cf18239ab509bda3e1c79423d Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Thu, 29 Oct 2020 09:32:05 -0700 Subject: [PATCH 07/11] Fix CI --- ...n-plugins-data-server.isearchstrategy.cancel.md | 2 +- ...a-plugin-plugins-data-server.isearchstrategy.md | 4 ++-- ...n-plugins-data-server.isearchstrategy.search.md | 2 +- src/plugins/data/server/server.api.md | 4 ++-- .../server/series_functions/es/es.test.js | 9 +-------- .../server/series_functions/fixtures/tl_config.js | 14 +++++--------- 6 files changed, 12 insertions(+), 23 deletions(-) diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md index 5267290b3b0ee..709d9bb7be9e5 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.cancel.md @@ -7,5 +7,5 @@ Signature: ```typescript -cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; +cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md index 39cc51049175e..c9f4c886735a7 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.md @@ -16,6 +16,6 @@ export interface ISearchStrategy(deps: SearchStrategyDependencies, id: string) => Promise<void> | | -| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable<SearchStrategyResponse> | | +| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise<void> | | +| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | (request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable<SearchStrategyResponse> | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md index d7911cbfdcbac..266995f2ec82c 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstrategy.search.md @@ -7,5 +7,5 @@ Signature: ```typescript -search: (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable; +search: (request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable; ``` diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 952bdf28235c5..b10f2d2891067 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -741,9 +741,9 @@ export interface ISearchStart { // (undocumented) - cancel?: (deps: SearchStrategyDependencies, id: string) => Promise; + cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise; // (undocumented) - search: (deps: SearchStrategyDependencies, request: SearchStrategyRequest, options?: ISearchOptions) => Observable; + search: (request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable; } // @public (undocumented) diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js index 8be3cf5171c65..95cc9388574a0 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js @@ -33,14 +33,7 @@ import { UI_SETTINGS } from '../../../../data/server'; function stubRequestAndServer(response, indexPatternSavedObjects = []) { return { - getStartServices: sinon - .stub() - .returns( - Promise.resolve([ - {}, - { data: { search: { search: () => from(Promise.resolve(response)) } } }, - ]) - ), + context: { search: { search: () => from(Promise.resolve(response)) } }, savedObjectsClient: { find: function () { return Promise.resolve({ diff --git a/src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js b/src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js index 38d70278fbf00..2f51cf38c0180 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js +++ b/src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js @@ -18,7 +18,7 @@ */ import moment from 'moment'; -import sinon from 'sinon'; +import { of } from 'rxjs'; import timelionDefaults from '../../lib/get_namespaced_settings'; import esResponse from './es_response'; @@ -30,14 +30,6 @@ export default function () { if (!functions[name]) throw new Error('No such function: ' + name); return functions[name]; }, - getStartServices: sinon - .stub() - .returns( - Promise.resolve([ - {}, - { data: { search: { search: () => Promise.resolve({ rawResponse: esResponse }) } } }, - ]) - ), esShardTimeout: moment.duration(30000), allowedGraphiteUrls: ['https://www.hostedgraphite.com/UID/ACCESS_KEY/graphite'], @@ -54,5 +46,9 @@ export default function () { tlConfig.setTargetSeries(); + tlConfig.context = { + search: { search: () => of({ rawResponse: esResponse }) }, + }; + return tlConfig; } From 4634fb47d486c24487477769d6d3198081505997 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Thu, 29 Oct 2020 15:36:23 -0700 Subject: [PATCH 08/11] Fix security search --- .../server/search_strategy/security_solution/index.ts | 2 +- .../security_solution/server/search_strategy/timeline/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts index 9128238631208..4abec07b3b493 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts @@ -17,7 +17,7 @@ import { SecuritySolutionFactory } from './factory/types'; export const securitySolutionSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy, StrategyResponseType> => { - const es = data.search.getSearchStrategy(); + const es = data.search.getSearchStrategy('es'); return { search: (request, options, deps) => { diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts index 6967db17813a8..0b73eed61765f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts @@ -17,7 +17,7 @@ import { SecuritySolutionTimelineFactory } from './factory/types'; export const securitySolutionTimelineSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy, TimelineStrategyResponseType> => { - const es = data.search.getSearchStrategy(); + const es = data.search.getSearchStrategy('es'); return { search: (request, options, deps) => { From 5f7c9abdbdea13345d60b9b327702885b64aa9e0 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Mon, 2 Nov 2020 10:08:48 -0700 Subject: [PATCH 09/11] Fix test --- .../vis_type_timelion/server/series_functions/es/es.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js index e1ce94d0694fe..2fa18b259de52 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js @@ -32,7 +32,6 @@ import { UI_SETTINGS } from '../../../../data/server'; describe('es', () => { let tlConfig; - let dataSearchStub; function stubRequestAndServer(response, indexPatternSavedObjects = []) { return { @@ -73,7 +72,7 @@ describe('es', () => { await invoke(es, [5], tlConfig); - expect(dataSearchStub.data.search.search.mock.calls[0][1]).toHaveProperty('sessionId', 1); + expect(tlConfig.context.search.search.mock.calls[0][1]).toHaveProperty('sessionId', 1); }); test('returns a seriesList', () => { From f1b515d57fc62ee478eccee3662e6baae7f4c0c2 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Mon, 2 Nov 2020 10:32:03 -0700 Subject: [PATCH 10/11] Fix test for reals --- .../vis_type_timelion/server/series_functions/es/es.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js index 2fa18b259de52..f4ba36e4fdd67 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { from } from 'rxjs'; +import { of } from 'rxjs'; import es from './index'; import tlConfigFn from '../fixtures/tl_config'; import * as aggResponse from './lib/agg_response_to_series_list'; @@ -35,7 +35,7 @@ describe('es', () => { function stubRequestAndServer(response, indexPatternSavedObjects = []) { return { - context: { search: { search: () => from(Promise.resolve(response)) } }, + context: { search: { search: jest.fn().mockReturnValue(of(response)) } }, savedObjectsClient: { find: function () { return Promise.resolve({ From 11517ee82a35b21c292f5f031c074ee39ac3ea08 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 3 Nov 2020 08:50:29 -0700 Subject: [PATCH 11/11] Fix types --- .../data_enhanced/server/search/eql_search_strategy.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts index d33b629a90756..88aaee8eb7da2 100644 --- a/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/eql_search_strategy.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import type { RequestHandlerContext, Logger } from 'kibana/server'; +import type { Logger } from 'kibana/server'; import { EqlSearchStrategyRequest } from '../../common/search/types'; import { eqlSearchStrategyProvider } from './eql_search_strategy'; import { SearchStrategyDependencies } from '../../../../../src/plugins/data/server';