From dc55b2077785dc42c00fb44b1e48779b133f346e Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Tue, 14 Jul 2020 15:18:59 +0300 Subject: [PATCH] [Search] Server side search API (#70446) * [search] Refactor the way search strategies are registered/retrieved on the server * Fix types and tests and update docs * Fix failing test * Move strategy name into options * Remove FE strategies * TypeScript of hell delete search explorer * Fix search interceptor OSS tests * test cleanup * fix * return search wrapper * initial api * Shiny happy cleanup * docs * fix jest test * simplify strategy registration * fix rebase * fix rebase * fix backport * types * TS for strategy * docs Co-authored-by: Lukas Olson Co-authored-by: Elastic Machine --- ...plugins-data-server.irequesttypesmap.es.md | 11 --- ...in-plugins-data-server.irequesttypesmap.md | 20 ---- ...lugins-data-server.iresponsetypesmap.es.md | 11 --- ...n-plugins-data-server.iresponsetypesmap.md | 20 ---- ...bana-plugin-plugins-data-server.isearch.md | 11 --- ...lugin-plugins-data-server.isearchcancel.md | 11 --- ...ugin-plugins-data-server.isearchoptions.md | 1 + ...ins-data-server.isearchoptions.strategy.md | 11 +++ ...plugin-plugins-data-server.isearchsetup.md | 2 +- ...ver.isearchsetup.registersearchstrategy.md | 2 +- ...a-server.isearchstart.getsearchstrategy.md | 2 +- ...plugin-plugins-data-server.isearchstart.md | 3 +- ...plugins-data-server.isearchstart.search.md | 11 +++ ...gins-data-server.isearchstrategy.cancel.md | 2 +- ...gin-plugins-data-server.isearchstrategy.md | 6 +- ...gins-data-server.isearchstrategy.search.md | 2 +- .../kibana-plugin-plugins-data-server.md | 5 - ...ugin-plugins-data-server.tstrategytypes.md | 19 ---- src/plugins/data/server/index.ts | 7 +- .../search/es_search/es_search_strategy.ts | 7 +- src/plugins/data/server/search/index.ts | 12 +-- src/plugins/data/server/search/mocks.ts | 1 + src/plugins/data/server/search/routes.test.ts | 22 ++--- src/plugins/data/server/search/routes.ts | 6 +- .../data/server/search/search_service.ts | 37 +++++--- src/plugins/data/server/search/types.ts | 93 +++++-------------- src/plugins/data/server/server.api.md | 82 +++++----------- .../server/search/es_search_strategy.ts | 19 ++-- 28 files changed, 135 insertions(+), 301 deletions(-) delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.es.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.es.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearch.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.strategy.md create mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.search.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tstrategytypes.md diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.es.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.es.md deleted file mode 100644 index 9cebff05dc9db..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.es.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IRequestTypesMap](./kibana-plugin-plugins-data-server.irequesttypesmap.md) > [es](./kibana-plugin-plugins-data-server.irequesttypesmap.es.md) - -## IRequestTypesMap.es property - -Signature: - -```typescript -[ES_SEARCH_STRATEGY]: IEsSearchRequest; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.md deleted file mode 100644 index 3f5e4ba0f7799..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.irequesttypesmap.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IRequestTypesMap](./kibana-plugin-plugins-data-server.irequesttypesmap.md) - -## IRequestTypesMap interface - -The map of search strategy IDs to the corresponding request type definitions. - -Signature: - -```typescript -export interface IRequestTypesMap -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [es](./kibana-plugin-plugins-data-server.irequesttypesmap.es.md) | IEsSearchRequest | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.es.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.es.md deleted file mode 100644 index 1154fc141d6c7..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.es.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IResponseTypesMap](./kibana-plugin-plugins-data-server.iresponsetypesmap.md) > [es](./kibana-plugin-plugins-data-server.iresponsetypesmap.es.md) - -## IResponseTypesMap.es property - -Signature: - -```typescript -[ES_SEARCH_STRATEGY]: IEsSearchResponse; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.md deleted file mode 100644 index 629ab4347eda8..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iresponsetypesmap.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IResponseTypesMap](./kibana-plugin-plugins-data-server.iresponsetypesmap.md) - -## IResponseTypesMap interface - -The map of search strategy IDs to the corresponding response type definitions. - -Signature: - -```typescript -export interface IResponseTypesMap -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [es](./kibana-plugin-plugins-data-server.iresponsetypesmap.es.md) | IEsSearchResponse | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearch.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearch.md deleted file mode 100644 index 96991579c1716..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearch.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearch](./kibana-plugin-plugins-data-server.isearch.md) - -## ISearch type - -Signature: - -```typescript -export declare type ISearch = (context: RequestHandlerContext, request: IRequestTypesMap[T], options?: ISearchOptions) => Promise; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md deleted file mode 100644 index b5a687d1b19d8..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) - -## ISearchCancel type - -Signature: - -```typescript -export declare type ISearchCancel = (context: RequestHandlerContext, id: string) => Promise; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md index 49412fc42d3b5..002ce864a1aa4 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.md @@ -15,4 +15,5 @@ export interface ISearchOptions | Property | Type | Description | | --- | --- | --- | | [signal](./kibana-plugin-plugins-data-server.isearchoptions.signal.md) | AbortSignal | An AbortSignal that allows the caller of search to abort a search request. | +| [strategy](./kibana-plugin-plugins-data-server.isearchoptions.strategy.md) | string | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.strategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.strategy.md new file mode 100644 index 0000000000000..6df72d023e2c0 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchoptions.strategy.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchOptions](./kibana-plugin-plugins-data-server.isearchoptions.md) > [strategy](./kibana-plugin-plugins-data-server.isearchoptions.strategy.md) + +## ISearchOptions.strategy property + +Signature: + +```typescript +strategy?: string; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md index 93e253b2e98a3..ca8ad8fdc06ea 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md @@ -14,5 +14,5 @@ export interface ISearchSetup | Property | Type | Description | | --- | --- | --- | -| [registerSearchStrategy](./kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md) | TRegisterSearchStrategy | Extension point exposed for other plugins to register their own search strategies. | +| [registerSearchStrategy](./kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md) | (name: string, strategy: ISearchStrategy) => void | Extension point exposed for other plugins to register their own search strategies. | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md index c06b8b00806bf..73c575e7095ed 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md @@ -9,5 +9,5 @@ Extension point exposed for other plugins to register their own search strategie Signature: ```typescript -registerSearchStrategy: TRegisterSearchStrategy; +registerSearchStrategy: (name: string, strategy: ISearchStrategy) => void; ``` 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 0ba4bf578d6cc..970b2811a574b 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 @@ -9,5 +9,5 @@ Get other registered search strategies. For example, if a new strategy needs to Signature: ```typescript -getSearchStrategy: TGetSearchStrategy; +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 abe72396f61e1..308ce3cb568bc 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 @@ -14,5 +14,6 @@ export interface ISearchStart | Property | Type | Description | | --- | --- | --- | -| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | TGetSearchStrategy | 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. | +| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | (name: string) => ISearchStrategy | 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) | (context: RequestHandlerContext, request: IKibanaSearchRequest, options: ISearchOptions) => Promise<IKibanaSearchResponse> | | 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.search.md new file mode 100644 index 0000000000000..1c2ae91699559 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.search.md @@ -0,0 +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) + +## ISearchStart.search property + +Signature: + +```typescript +search: (context: RequestHandlerContext, request: IKibanaSearchRequest, options: ISearchOptions) => Promise; +``` 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 c1e0c3d9f2330..34903697090ea 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?: ISearchCancel; +cancel?: (context: RequestHandlerContext, 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 167c6ab6e5a16..d54e027c4b847 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 @@ -9,13 +9,13 @@ Search strategy interface contains a search method that takes in a request and r Signature: ```typescript -export interface ISearchStrategy +export interface ISearchStrategy ``` ## Properties | Property | Type | Description | | --- | --- | --- | -| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | ISearchCancel<T> | | -| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | ISearch<T> | | +| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | (context: RequestHandlerContext, id: string) => Promise<void> | | +| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | (context: RequestHandlerContext, request: IEsSearchRequest, options?: ISearchOptions) => Promise<IEsSearchResponse> | | 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 34a17ca87807a..1a225d0c9aeab 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: ISearch; +search: (context: RequestHandlerContext, request: IEsSearchRequest, options?: ISearchOptions) => Promise; ``` 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 c80112fb17dde..9adefda718338 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 @@ -40,8 +40,6 @@ | [IIndexPattern](./kibana-plugin-plugins-data-server.iindexpattern.md) | | | [IndexPatternAttributes](./kibana-plugin-plugins-data-server.indexpatternattributes.md) | Use data plugin interface instead | | [IndexPatternFieldDescriptor](./kibana-plugin-plugins-data-server.indexpatternfielddescriptor.md) | | -| [IRequestTypesMap](./kibana-plugin-plugins-data-server.irequesttypesmap.md) | The map of search strategy IDs to the corresponding request type definitions. | -| [IResponseTypesMap](./kibana-plugin-plugins-data-server.iresponsetypesmap.md) | The map of search strategy IDs to the corresponding response type definitions. | | [ISearchOptions](./kibana-plugin-plugins-data-server.isearchoptions.md) | | | [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) | | | [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) | | @@ -73,8 +71,5 @@ | --- | --- | | [FieldFormatsGetConfigFn](./kibana-plugin-plugins-data-server.fieldformatsgetconfigfn.md) | | | [IFieldFormatsRegistry](./kibana-plugin-plugins-data-server.ifieldformatsregistry.md) | | -| [ISearch](./kibana-plugin-plugins-data-server.isearch.md) | | -| [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) | | | [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.md) | | -| [TStrategyTypes](./kibana-plugin-plugins-data-server.tstrategytypes.md) | Contains all known strategy type identifiers that will be used to map to request and response shapes. Plugins that wish to add their own custom search strategies should extend this type via:const MY\_STRATEGY = 'MY\_STRATEGY';declare module 'src/plugins/search/server' { export interface IRequestTypesMap { \[MY\_STRATEGY\]: IMySearchRequest; }export interface IResponseTypesMap { \[MY\_STRATEGY\]: IMySearchResponse } } | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tstrategytypes.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tstrategytypes.md deleted file mode 100644 index 443d8d1b424d0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tstrategytypes.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [TStrategyTypes](./kibana-plugin-plugins-data-server.tstrategytypes.md) - -## TStrategyTypes type - -Contains all known strategy type identifiers that will be used to map to request and response shapes. Plugins that wish to add their own custom search strategies should extend this type via: - -const MY\_STRATEGY = 'MY\_STRATEGY'; - -declare module 'src/plugins/search/server' { export interface IRequestTypesMap { \[MY\_STRATEGY\]: IMySearchRequest; } - -export interface IResponseTypesMap { \[MY\_STRATEGY\]: IMySearchResponse } } - -Signature: - -```typescript -export declare type TStrategyTypes = typeof ES_SEARCH_STRATEGY | string; -``` diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index b94238dcf96a4..321bd913ce760 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -164,15 +164,10 @@ import { export { ParsedInterval } from '../common'; export { - ISearch, - ISearchCancel, + ISearchStrategy, ISearchOptions, - IRequestTypesMap, - IResponseTypesMap, ISearchSetup, ISearchStart, - TStrategyTypes, - ISearchStrategy, getDefaultSearchParams, getTotalLoaded, } from './search'; 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 db08ddf920818..82f8ef21ebb38 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 @@ -17,17 +17,16 @@ * under the License. */ import { first } from 'rxjs/operators'; -import { RequestHandlerContext, SharedGlobalConfig } from 'kibana/server'; +import { SharedGlobalConfig } from 'kibana/server'; import { SearchResponse } from 'elasticsearch'; import { Observable } from 'rxjs'; -import { ES_SEARCH_STRATEGY } from '../../../common/search'; import { ISearchStrategy, getDefaultSearchParams, getTotalLoaded } from '..'; export const esSearchStrategyProvider = ( config$: Observable -): ISearchStrategy => { +): ISearchStrategy => { return { - search: async (context: RequestHandlerContext, request, options) => { + search: async (context, request, options) => { const config = await config$.pipe(first()).toPromise(); const defaultParams = getDefaultSearchParams(config); diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index 882f56e83d4ca..67789fcbf56b4 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -17,16 +17,6 @@ * under the License. */ -export { - ISearch, - ISearchCancel, - ISearchOptions, - IRequestTypesMap, - IResponseTypesMap, - ISearchSetup, - ISearchStart, - TStrategyTypes, - ISearchStrategy, -} from './types'; +export { ISearchStrategy, ISearchOptions, ISearchSetup, ISearchStart } from './types'; export { getDefaultSearchParams, getTotalLoaded } from './es_search'; diff --git a/src/plugins/data/server/search/mocks.ts b/src/plugins/data/server/search/mocks.ts index 0aab466a9a0d9..b210df3c55db9 100644 --- a/src/plugins/data/server/search/mocks.ts +++ b/src/plugins/data/server/search/mocks.ts @@ -26,5 +26,6 @@ export function createSearchSetupMock() { export function createSearchStartMock() { return { getSearchStrategy: jest.fn(), + search: jest.fn(), }; } diff --git a/src/plugins/data/server/search/routes.test.ts b/src/plugins/data/server/search/routes.test.ts index 4ef67de93e454..167bd5af5d51d 100644 --- a/src/plugins/data/server/search/routes.test.ts +++ b/src/plugins/data/server/search/routes.test.ts @@ -33,9 +33,8 @@ describe('Search service', () => { }); it('handler calls context.search.search with the given request and strategy', async () => { - const mockSearch = jest.fn().mockResolvedValue('yay'); - mockDataStart.search.getSearchStrategy.mockReturnValueOnce({ search: mockSearch }); - + const response = { id: 'yay' }; + mockDataStart.search.search.mockResolvedValue(response); const mockContext = {}; const mockBody = { params: {} }; const mockParams = { strategy: 'foo' }; @@ -51,21 +50,21 @@ describe('Search service', () => { const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockDataStart.search.getSearchStrategy.mock.calls[0][0]).toBe(mockParams.strategy); - expect(mockSearch).toBeCalled(); - expect(mockSearch.mock.calls[0][1]).toStrictEqual(mockBody); + expect(mockDataStart.search.search).toBeCalled(); + expect(mockDataStart.search.search.mock.calls[0][1]).toStrictEqual(mockBody); expect(mockResponse.ok).toBeCalled(); - expect(mockResponse.ok.mock.calls[0][0]).toEqual({ body: 'yay' }); + expect(mockResponse.ok.mock.calls[0][0]).toEqual({ + body: response, + }); }); it('handler throws an error if the search throws an error', async () => { - const mockSearch = jest.fn().mockRejectedValue({ + mockDataStart.search.search.mockRejectedValue({ message: 'oh no', body: { error: 'oops', }, }); - mockDataStart.search.getSearchStrategy.mockReturnValueOnce({ search: mockSearch }); const mockContext = {}; const mockBody = { params: {} }; @@ -82,9 +81,8 @@ describe('Search service', () => { const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockDataStart.search.getSearchStrategy.mock.calls[0][0]).toBe(mockParams.strategy); - expect(mockSearch).toBeCalled(); - expect(mockSearch.mock.calls[0][1]).toStrictEqual(mockBody); + expect(mockDataStart.search.search).toBeCalled(); + expect(mockDataStart.search.search.mock.calls[0][1]).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.ts b/src/plugins/data/server/search/routes.ts index 7b6c045b0908c..bf1982a1f7fb2 100644 --- a/src/plugins/data/server/search/routes.ts +++ b/src/plugins/data/server/search/routes.ts @@ -42,10 +42,12 @@ export function registerSearchRoute(core: CoreSetup): v const signal = getRequestAbortedSignal(request.events.aborted$); const [, , selfStart] = await core.getStartServices(); - const searchStrategy = selfStart.search.getSearchStrategy(strategy); try { - const response = await searchStrategy.search(context, searchRequest, { signal }); + const response = await selfStart.search.search(context, searchRequest, { + signal, + strategy, + }); return res.ok({ body: response }); } 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 34ed8c6c6f401..20f9a7488893f 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -17,20 +17,24 @@ * under the License. */ -import { Plugin, PluginInitializerContext, CoreSetup } from '../../../../core/server'; import { - ISearchSetup, - ISearchStart, - TSearchStrategiesMap, - TRegisterSearchStrategy, - TGetSearchStrategy, -} from './types'; + Plugin, + PluginInitializerContext, + CoreSetup, + RequestHandlerContext, +} from '../../../../core/server'; +import { ISearchSetup, ISearchStart, ISearchStrategy } from './types'; import { registerSearchRoute } from './routes'; import { ES_SEARCH_STRATEGY, esSearchStrategyProvider } from './es_search'; import { DataPluginStart } from '../plugin'; +import { IEsSearchRequest } from '../../common'; + +interface StrategyMap { + [name: string]: ISearchStrategy; +} export class SearchService implements Plugin { - private searchStrategies: TSearchStrategiesMap = {}; + private searchStrategies: StrategyMap = {}; constructor(private initializerContext: PluginInitializerContext) {} @@ -45,17 +49,28 @@ export class SearchService implements Plugin { return { registerSearchStrategy: this.registerSearchStrategy }; } + private search(context: RequestHandlerContext, searchRequest: IEsSearchRequest, options: any) { + return this.getSearchStrategy(options.strategy || ES_SEARCH_STRATEGY).search( + context, + searchRequest, + { signal: options.signal } + ); + } + public start(): ISearchStart { - return { getSearchStrategy: this.getSearchStrategy }; + return { + getSearchStrategy: this.getSearchStrategy, + search: this.search, + }; } public stop() {} - private registerSearchStrategy: TRegisterSearchStrategy = (name, strategy) => { + private registerSearchStrategy = (name: string, strategy: ISearchStrategy) => { this.searchStrategies[name] = strategy; }; - private getSearchStrategy: TGetSearchStrategy = (name) => { + private getSearchStrategy = (name: string): ISearchStrategy => { const strategy = this.searchStrategies[name]; if (!strategy) { throw new Error(`Search strategy ${name} not found`); diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index dea325cc063bb..12f1a1a508bd2 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -19,14 +19,22 @@ import { RequestHandlerContext } from '../../../../core/server'; import { IKibanaSearchResponse, IKibanaSearchRequest } from '../../common/search'; -import { ES_SEARCH_STRATEGY, IEsSearchRequest, IEsSearchResponse } from './es_search'; +import { IEsSearchRequest, IEsSearchResponse } from './es_search'; + +export interface ISearchOptions { + /** + * An `AbortSignal` that allows the caller of `search` to abort a search request. + */ + signal?: AbortSignal; + strategy?: string; +} export interface ISearchSetup { /** * Extension point exposed for other plugins to register their own search * strategies. */ - registerSearchStrategy: TRegisterSearchStrategy; + registerSearchStrategy: (name: string, strategy: ISearchStrategy) => void; } export interface ISearchStart { @@ -34,78 +42,23 @@ export interface ISearchStart { * 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. */ - getSearchStrategy: TGetSearchStrategy; -} - -export interface ISearchOptions { - /** - * An `AbortSignal` that allows the caller of `search` to abort a search request. - */ - signal?: AbortSignal; + getSearchStrategy: (name: string) => ISearchStrategy; + search: ( + context: RequestHandlerContext, + request: IKibanaSearchRequest, + options: ISearchOptions + ) => Promise; } -/** - * Contains all known strategy type identifiers that will be used to map to - * request and response shapes. Plugins that wish to add their own custom search - * strategies should extend this type via: - * - * const MY_STRATEGY = 'MY_STRATEGY'; - * - * declare module 'src/plugins/search/server' { - * export interface IRequestTypesMap { - * [MY_STRATEGY]: IMySearchRequest; - * } - * - * export interface IResponseTypesMap { - * [MY_STRATEGY]: IMySearchResponse - * } - * } - */ -export type TStrategyTypes = typeof ES_SEARCH_STRATEGY | string; - -/** - * The map of search strategy IDs to the corresponding request type definitions. - */ -export interface IRequestTypesMap { - [ES_SEARCH_STRATEGY]: IEsSearchRequest; - [key: string]: IKibanaSearchRequest; -} - -/** - * The map of search strategy IDs to the corresponding response type definitions. - */ -export interface IResponseTypesMap { - [ES_SEARCH_STRATEGY]: IEsSearchResponse; - [key: string]: IKibanaSearchResponse; -} - -export type ISearch = ( - context: RequestHandlerContext, - request: IRequestTypesMap[T], - options?: ISearchOptions -) => Promise; - -export type ISearchCancel = ( - context: RequestHandlerContext, - id: string -) => Promise; - /** * Search strategy interface contains a search method that takes in a request and returns a promise * that resolves to a response. */ -export interface ISearchStrategy { - search: ISearch; - cancel?: ISearchCancel; +export interface ISearchStrategy { + search: ( + context: RequestHandlerContext, + request: IEsSearchRequest, + options?: ISearchOptions + ) => Promise; + cancel?: (context: RequestHandlerContext, id: string) => Promise; } - -export type TRegisterSearchStrategy = ( - name: T, - searchStrategy: ISearchStrategy -) => void; - -export type TGetSearchStrategy = (name: T) => ISearchStrategy; - -export type TSearchStrategiesMap = { - [K in TStrategyTypes]?: ISearchStrategy; -}; diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 1fe03119c789d..88f2cc3264c6e 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -507,77 +507,46 @@ export class IndexPatternsFetcher { }): Promise; } -// Warning: (ae-missing-release-tag) "IRequestTypesMap" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export interface IRequestTypesMap { - // Warning: (ae-forgotten-export) The symbol "IKibanaSearchRequest" needs to be exported by the entry point index.d.ts - // - // (undocumented) - [key: string]: IKibanaSearchRequest; - // Warning: (ae-forgotten-export) The symbol "ES_SEARCH_STRATEGY" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "IEsSearchRequest" needs to be exported by the entry point index.d.ts - // - // (undocumented) - [ES_SEARCH_STRATEGY]: IEsSearchRequest; -} - -// Warning: (ae-missing-release-tag) "IResponseTypesMap" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export interface IResponseTypesMap { - // Warning: (ae-forgotten-export) The symbol "IKibanaSearchResponse" needs to be exported by the entry point index.d.ts - // - // (undocumented) - [key: string]: IKibanaSearchResponse; - // Warning: (ae-forgotten-export) The symbol "IEsSearchResponse" needs to be exported by the entry point index.d.ts - // - // (undocumented) - [ES_SEARCH_STRATEGY]: IEsSearchResponse; -} - -// Warning: (ae-forgotten-export) The symbol "RequestHandlerContext" needs to be exported by the entry point index.d.ts -// 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 = (context: RequestHandlerContext, request: IRequestTypesMap[T], options?: ISearchOptions) => Promise; - -// Warning: (ae-missing-release-tag) "ISearchCancel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ISearchCancel = (context: RequestHandlerContext, id: string) => Promise; - // Warning: (ae-missing-release-tag) "ISearchOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface ISearchOptions { signal?: AbortSignal; + // (undocumented) + strategy?: string; } // Warning: (ae-missing-release-tag) "ISearchSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface ISearchSetup { - // Warning: (ae-forgotten-export) The symbol "TRegisterSearchStrategy" needs to be exported by the entry point index.d.ts - registerSearchStrategy: TRegisterSearchStrategy; + registerSearchStrategy: (name: string, strategy: ISearchStrategy) => void; } // Warning: (ae-missing-release-tag) "ISearchStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface ISearchStart { - // Warning: (ae-forgotten-export) The symbol "TGetSearchStrategy" needs to be exported by the entry point index.d.ts - getSearchStrategy: TGetSearchStrategy; + getSearchStrategy: (name: string) => ISearchStrategy; + // Warning: (ae-forgotten-export) The symbol "RequestHandlerContext" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "IKibanaSearchRequest" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "IKibanaSearchResponse" needs to be exported by the entry point index.d.ts + // + // (undocumented) + search: (context: RequestHandlerContext, request: IKibanaSearchRequest, options: ISearchOptions) => Promise; } // Warning: (ae-missing-release-tag) "ISearchStrategy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export interface ISearchStrategy { +export interface ISearchStrategy { // (undocumented) - cancel?: ISearchCancel; + cancel?: (context: RequestHandlerContext, id: string) => Promise; + // Warning: (ae-forgotten-export) The symbol "IEsSearchRequest" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "IEsSearchResponse" needs to be exported by the entry point index.d.ts + // // (undocumented) - search: ISearch; + search: (context: RequestHandlerContext, request: IEsSearchRequest, options?: ISearchOptions) => Promise; } // @public (undocumented) @@ -757,11 +726,6 @@ export interface TimeRange { to: string; } -// Warning: (ae-missing-release-tag) "TStrategyTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export type TStrategyTypes = typeof ES_SEARCH_STRATEGY | string; - // Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -820,13 +784,13 @@ export const UI_SETTINGS: { // 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:183:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:184:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:185:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:186:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:187:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:188:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:191:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:178:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:179:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:180:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:181:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:182:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:183:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:186:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) 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 7c1001697421f..7b29117495a67 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 @@ -8,12 +8,13 @@ import { first } from 'rxjs/operators'; import { mapKeys, snakeCase } from 'lodash'; import { SearchResponse } from 'elasticsearch'; import { Observable } from 'rxjs'; -import { LegacyAPICaller, SharedGlobalConfig } from '../../../../../src/core/server'; -import { ES_SEARCH_STRATEGY } from '../../../../../src/plugins/data/common'; import { - ISearch, + LegacyAPICaller, + SharedGlobalConfig, + RequestHandlerContext, +} from '../../../../../src/core/server'; +import { ISearchOptions, - ISearchCancel, getDefaultSearchParams, getTotalLoaded, ISearchStrategy, @@ -30,11 +31,11 @@ export interface AsyncSearchResponse { export const enhancedEsSearchStrategyProvider = ( config$: Observable -): ISearchStrategy => { - const search: ISearch = async ( - context, +): ISearchStrategy => { + const search = async ( + context: RequestHandlerContext, request: IEnhancedEsSearchRequest, - options + options?: ISearchOptions ) => { const config = await config$.pipe(first()).toPromise(); const caller = context.core.elasticsearch.legacy.client.callAsCurrentUser; @@ -46,7 +47,7 @@ export const enhancedEsSearchStrategyProvider = ( : asyncSearch(caller, { ...request, params }, options); }; - const cancel: ISearchCancel = async (context, id) => { + const cancel = async (context: RequestHandlerContext, id: string) => { const method = 'DELETE'; const path = encodeURI(`/_async_search/${id}`); await context.core.elasticsearch.legacy.client.callAsCurrentUser('transport.request', {