diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md
deleted file mode 100644
index 7a7ea43bd3d40..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) > [core](./kibana-plugin-plugins-data-public.isearchcontext.core.md)
-
-## ISearchContext.core property
-
-Signature:
-
-```typescript
-core: CoreStart;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md
deleted file mode 100644
index 93ac88d200bb8..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) > [getSearchStrategy](./kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md)
-
-## ISearchContext.getSearchStrategy property
-
-Signature:
-
-```typescript
-getSearchStrategy: (name: T) => TSearchStrategyProvider;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md
deleted file mode 100644
index 9b89f71434119..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md)
-
-## ISearchContext interface
-
-Signature:
-
-```typescript
-export interface ISearchContext
-```
-
-## Properties
-
-| Property | Type | Description |
-| --- | --- | --- |
-| [core](./kibana-plugin-plugins-data-public.isearchcontext.core.md) | CoreStart
| |
-| [getSearchStrategy](./kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md) | <T extends TStrategyTypes>(name: T) => TSearchStrategyProvider<T>
| |
-
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 75d3abefc74b9..e818fb009fb19 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
@@ -67,7 +67,6 @@
| [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) | |
| [IRequestTypesMap](./kibana-plugin-plugins-data-public.irequesttypesmap.md) | |
| [IResponseTypesMap](./kibana-plugin-plugins-data-public.iresponsetypesmap.md) | |
-| [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) | |
| [ISearchOptions](./kibana-plugin-plugins-data-public.isearchoptions.md) | |
| [ISearchStrategy](./kibana-plugin-plugins-data-public.isearchstrategy.md) | Search strategy interface contains a search method that takes in a request and returns a promise that resolves to a response. |
| [ISyncSearchRequest](./kibana-plugin-plugins-data-public.isyncsearchrequest.md) | |
@@ -157,5 +156,4 @@
| [TabbedAggRow](./kibana-plugin-plugins-data-public.tabbedaggrow.md) | \* |
| [TimefilterContract](./kibana-plugin-plugins-data-public.timefiltercontract.md) | |
| [TimeHistoryContract](./kibana-plugin-plugins-data-public.timehistorycontract.md) | |
-| [TSearchStrategyProvider](./kibana-plugin-plugins-data-public.tsearchstrategyprovider.md) | Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md
deleted file mode 100644
index 3233bb48cea2c..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TSearchStrategyProvider](./kibana-plugin-plugins-data-public.tsearchstrategyprovider.md)
-
-## TSearchStrategyProvider type
-
-Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context.
-
-Signature:
-
-```typescript
-export declare type TSearchStrategyProvider = (context: ISearchContext) => ISearchStrategy;
-```
diff --git a/examples/demo_search/public/async_demo_search_strategy.ts b/examples/demo_search/public/async_demo_search_strategy.ts
index 7a3f33ce05a75..862324002840c 100644
--- a/examples/demo_search/public/async_demo_search_strategy.ts
+++ b/examples/demo_search/public/async_demo_search_strategy.ts
@@ -17,53 +17,27 @@
* under the License.
*/
-import { Observable } from 'rxjs';
-import {
- ISearchContext,
- TSearchStrategyProvider,
- ISearchStrategy,
-} from '../../../src/plugins/data/public';
-
-import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoResponse } from '../common';
+import { Observable, from } from 'rxjs';
+import { CoreSetup } from 'kibana/public';
+import { flatMap } from 'rxjs/operators';
+import { ISearch } from '../../../src/plugins/data/public';
import { ASYNC_SEARCH_STRATEGY } from '../../../x-pack/plugins/data_enhanced/public';
+import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoResponse } from '../common';
+import { DemoDataSearchStartDependencies } from './types';
-/**
- * This demo search strategy provider simply provides a shortcut for calling the DEMO_ASYNC_SEARCH_STRATEGY
- * on the server side, without users having to pass it in explicitly, and it takes advantage of the
- * already registered ASYNC_SEARCH_STRATEGY that exists on the client.
- *
- * so instead of callers having to do:
- *
- * ```
- * search(
- * { ...request, serverStrategy: DEMO_ASYNC_SEARCH_STRATEGY },
- * options,
- * ASYNC_SEARCH_STRATEGY
- * ) as Observable,
- *```
-
- * They can instead just do
- *
- * ```
- * search(request, options, DEMO_ASYNC_SEARCH_STRATEGY);
- * ```
- *
- * and are ensured type safety in regard to the request and response objects.
- *
- * @param context - context supplied by other plugins.
- * @param search - a search function to access other strategies that have already been registered.
- */
-export const asyncDemoClientSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-): ISearchStrategy => {
- const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY);
- const { search } = asyncStrategyProvider(context);
- return {
- search: (request, options) => {
- return search(
- { ...request, serverStrategy: ASYNC_DEMO_SEARCH_STRATEGY },
- options
- ) as Observable;
- },
+export function asyncDemoClientSearchStrategyProvider(core: CoreSetup) {
+ const search: ISearch = (request, options) => {
+ return from(core.getStartServices()).pipe(
+ flatMap((startServices) => {
+ const asyncStrategy = (startServices[1] as DemoDataSearchStartDependencies).data.search.getSearchStrategy(
+ ASYNC_SEARCH_STRATEGY
+ );
+ return asyncStrategy.search(
+ { ...request, serverStrategy: ASYNC_DEMO_SEARCH_STRATEGY },
+ options
+ ) as Observable;
+ })
+ );
};
-};
+ return { search };
+}
diff --git a/examples/demo_search/public/demo_search_strategy.ts b/examples/demo_search/public/demo_search_strategy.ts
index 8dc2779a8544c..d56d827a5c0f8 100644
--- a/examples/demo_search/public/demo_search_strategy.ts
+++ b/examples/demo_search/public/demo_search_strategy.ts
@@ -17,11 +17,12 @@
* under the License.
*/
-import { Observable } from 'rxjs';
-import { ISearchContext, SYNC_SEARCH_STRATEGY } from '../../../src/plugins/data/public';
-import { TSearchStrategyProvider, ISearchStrategy } from '../../../src/plugins/data/public';
-
+import { Observable, from } from 'rxjs';
+import { flatMap } from 'rxjs/operators';
+import { CoreSetup } from 'kibana/public';
+import { ISearch, SYNC_SEARCH_STRATEGY } from '../../../src/plugins/data/public';
import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common';
+import { DemoDataSearchStartDependencies } from './types';
/**
* This demo search strategy provider simply provides a shortcut for calling the DEMO_SEARCH_STRATEGY
@@ -31,7 +32,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common';
* so instead of callers having to do:
*
* ```
- * context.search(
+ * data.search.search(
* { ...request, serverStrategy: DEMO_SEARCH_STRATEGY },
* options,
* SYNC_SEARCH_STRATEGY
@@ -41,24 +42,24 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common';
* They can instead just do
*
* ```
- * context.search(request, options, DEMO_SEARCH_STRATEGY);
+ * data.search.search(request, options, DEMO_SEARCH_STRATEGY);
* ```
*
* and are ensured type safety in regard to the request and response objects.
- *
- * @param context - context supplied by other plugins.
- * @param search - a search function to access other strategies that have already been registered.
*/
-export const demoClientSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-): ISearchStrategy => {
- const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY);
- const { search } = syncStrategyProvider(context);
- return {
- search: (request, options) => {
- return search({ ...request, serverStrategy: DEMO_SEARCH_STRATEGY }, options) as Observable<
- IDemoResponse
- >;
- },
+export function demoClientSearchStrategyProvider(core: CoreSetup) {
+ const search: ISearch = (request, options) => {
+ return from(core.getStartServices()).pipe(
+ flatMap((startServices) => {
+ const syncStrategy = (startServices[1] as DemoDataSearchStartDependencies).data.search.getSearchStrategy(
+ SYNC_SEARCH_STRATEGY
+ );
+ return syncStrategy.search(
+ { ...request, serverStrategy: DEMO_SEARCH_STRATEGY },
+ options
+ ) as Observable;
+ })
+ );
};
-};
+ return { search };
+}
diff --git a/examples/demo_search/public/plugin.ts b/examples/demo_search/public/plugin.ts
index a2539cc7a21c5..5d074c19903e2 100644
--- a/examples/demo_search/public/plugin.ts
+++ b/examples/demo_search/public/plugin.ts
@@ -17,7 +17,6 @@
* under the License.
*/
-import { DataPublicPluginSetup } from '../../../src/plugins/data/public';
import { Plugin, CoreSetup } from '../../../src/core/public';
import {
DEMO_SEARCH_STRATEGY,
@@ -29,10 +28,7 @@ import {
} from '../common';
import { demoClientSearchStrategyProvider } from './demo_search_strategy';
import { asyncDemoClientSearchStrategyProvider } from './async_demo_search_strategy';
-
-interface DemoDataSearchSetupDependencies {
- data: DataPublicPluginSetup;
-}
+import { DemoDataSearchSetupDependencies, DemoDataSearchStartDependencies } from './types';
/**
* Add the typescript mappings for our search strategy to the request and
@@ -55,16 +51,13 @@ declare module '../../../src/plugins/data/public' {
}
}
-export class DemoDataPlugin implements Plugin {
- public setup(core: CoreSetup, deps: DemoDataSearchSetupDependencies) {
- deps.data.search.registerSearchStrategyProvider(
- DEMO_SEARCH_STRATEGY,
- demoClientSearchStrategyProvider
- );
- deps.data.search.registerSearchStrategyProvider(
- ASYNC_DEMO_SEARCH_STRATEGY,
- asyncDemoClientSearchStrategyProvider
- );
+export class DemoDataPlugin
+ implements Plugin {
+ public setup(core: CoreSetup, { data }: DemoDataSearchSetupDependencies) {
+ const demoClientSearchStrategy = demoClientSearchStrategyProvider(core);
+ const asyncDemoClientSearchStrategy = asyncDemoClientSearchStrategyProvider(core);
+ data.search.registerSearchStrategy(DEMO_SEARCH_STRATEGY, demoClientSearchStrategy);
+ data.search.registerSearchStrategy(ASYNC_DEMO_SEARCH_STRATEGY, asyncDemoClientSearchStrategy);
}
public start() {}
diff --git a/examples/demo_search/public/types.ts b/examples/demo_search/public/types.ts
new file mode 100644
index 0000000000000..64725da7df870
--- /dev/null
+++ b/examples/demo_search/public/types.ts
@@ -0,0 +1,28 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { DataPublicPluginStart, DataPublicPluginSetup } from '../../../src/plugins/data/public';
+
+export interface DemoDataSearchSetupDependencies {
+ data: DataPublicPluginSetup;
+}
+
+export interface DemoDataSearchStartDependencies {
+ data: DataPublicPluginStart;
+}
diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts
index 61b75892b65e0..ef99a8d1a9a1e 100644
--- a/src/plugins/data/public/index.ts
+++ b/src/plugins/data/public/index.ts
@@ -341,8 +341,6 @@ export {
SYNC_SEARCH_STRATEGY,
getEsPreference,
getSearchErrorType,
- ISearchContext,
- TSearchStrategyProvider,
ISearchStrategy,
ISearch,
ISearchOptions,
diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts
index 7307c93139d59..d544d3c800bbe 100644
--- a/src/plugins/data/public/mocks.ts
+++ b/src/plugins/data/public/mocks.ts
@@ -21,11 +21,17 @@ import { Plugin, IndexPatternsContract } from '.';
import { fieldFormatsServiceMock } from './field_formats/mocks';
import { searchSetupMock, searchStartMock } from './search/mocks';
import { queryServiceMock } from './query/mocks';
+import { AutocompleteStart, AutocompleteSetup } from './autocomplete';
export type Setup = jest.Mocked>;
export type Start = jest.Mocked>;
-const autocompleteMock: any = {
+const automcompleteSetupMock: jest.Mocked = {
+ addQuerySuggestionProvider: jest.fn(),
+ getQuerySuggestions: jest.fn(),
+};
+
+const autocompleteStartMock: jest.Mocked = {
getValueSuggestions: jest.fn(),
getQuerySuggestions: jest.fn(),
hasQuerySuggestions: jest.fn(),
@@ -34,7 +40,7 @@ const autocompleteMock: any = {
const createSetupContract = (): Setup => {
const querySetupMock = queryServiceMock.createSetupContract();
return {
- autocomplete: autocompleteMock,
+ autocomplete: automcompleteSetupMock,
search: searchSetupMock,
fieldFormats: fieldFormatsServiceMock.createSetupContract(),
query: querySetupMock,
@@ -48,7 +54,7 @@ const createStartContract = (): Start => {
createFiltersFromValueClickAction: jest.fn().mockResolvedValue(['yes']),
createFiltersFromRangeSelectAction: jest.fn(),
},
- autocomplete: autocompleteMock,
+ autocomplete: autocompleteStartMock,
search: searchStartMock,
fieldFormats: fieldFormatsServiceMock.createStartContract(),
query: queryStartMock,
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index 56505d5744988..516ca00c41f3c 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -1126,16 +1126,6 @@ export interface IResponseTypesMap {
// @public (undocumented)
export type ISearch = (request: IRequestTypesMap[T], options?: ISearchOptions) => Observable;
-// Warning: (ae-missing-release-tag) "ISearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export interface ISearchContext {
- // (undocumented)
- core: CoreStart;
- // (undocumented)
- getSearchStrategy: (name: T) => TSearchStrategyProvider;
-}
-
// 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)
@@ -1798,11 +1788,6 @@ export interface TimeRange {
to: string;
}
-// Warning: (ae-missing-release-tag) "TSearchStrategyProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
-export type TSearchStrategyProvider = (context: ISearchContext) => ISearchStrategy;
-
// 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)
@@ -1876,20 +1861,20 @@ 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:377:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:379:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:380:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:395:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:396:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:377:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:378:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:398:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:401: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:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts
diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.test.ts b/src/plugins/data/public/search/es_search/es_search_strategy.test.ts
index de1835f09f3bf..b580c5170aad7 100644
--- a/src/plugins/data/public/search/es_search/es_search_strategy.test.ts
+++ b/src/plugins/data/public/search/es_search/es_search_strategy.test.ts
@@ -17,40 +17,31 @@
* under the License.
*/
+import { CoreSetup } from '../../../../../core/public';
import { coreMock } from '../../../../../core/public/mocks';
import { esSearchStrategyProvider } from './es_search_strategy';
-import { CoreStart } from 'kibana/public';
import { ES_SEARCH_STRATEGY } from '../../../common/search/es_search';
describe('ES search strategy', () => {
- let mockCoreStart: MockedKeys;
- const mockSearch = jest.fn();
+ let mockCoreSetup: MockedKeys;
+ const mockSearch = { search: jest.fn() };
beforeEach(() => {
- mockCoreStart = coreMock.createStart();
- mockSearch.mockClear();
+ mockCoreSetup = coreMock.createSetup();
+ mockSearch.search.mockClear();
});
it('returns a strategy with `search` that calls the sync search `search`', () => {
const request = { params: {} };
const options = {};
- const esSearch = esSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
+ const esSearch = esSearchStrategyProvider(mockCoreSetup, mockSearch);
esSearch.search(request, options);
- expect(mockSearch.mock.calls[0][0]).toEqual({
+ expect(mockSearch.search.mock.calls[0][0]).toEqual({
...request,
serverStrategy: ES_SEARCH_STRATEGY,
});
- expect(mockSearch.mock.calls[0][1]).toBe(options);
+ expect(mockSearch.search.mock.calls[0][1]).toBe(options);
});
});
diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.ts b/src/plugins/data/public/search/es_search/es_search_strategy.ts
index a61428c998157..82f8bf21ee57b 100644
--- a/src/plugins/data/public/search/es_search/es_search_strategy.ts
+++ b/src/plugins/data/public/search/es_search/es_search_strategy.ts
@@ -18,25 +18,26 @@
*/
import { Observable } from 'rxjs';
+import { CoreSetup } from '../../../../../core/public';
import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../common/search';
+import { ISearch } from '../i_search';
+import { ISearchStrategy } from '../types';
import { SYNC_SEARCH_STRATEGY } from '../sync_search_strategy';
import { getEsPreference } from './get_es_preference';
-import { ISearchContext, TSearchStrategyProvider, ISearchStrategy } from '../types';
-export const esSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-): ISearchStrategy => {
- const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY);
- const { search } = syncStrategyProvider(context);
- return {
- search: (request, options) => {
- request.params = {
- preference: getEsPreference(context.core.uiSettings),
- ...request.params,
- };
- return search({ ...request, serverStrategy: ES_SEARCH_STRATEGY }, options) as Observable<
- IEsSearchResponse
- >;
- },
+export function esSearchStrategyProvider(
+ core: CoreSetup,
+ syncStrategy: ISearchStrategy
+) {
+ const search: ISearch = (request, options) => {
+ request.params = {
+ preference: getEsPreference(core.uiSettings),
+ ...request.params,
+ };
+ return syncStrategy.search(
+ { ...request, serverStrategy: ES_SEARCH_STRATEGY },
+ options
+ ) as Observable;
};
-};
+ return { search };
+}
diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts
index 26149432f6117..53686f9be9b4d 100644
--- a/src/plugins/data/public/search/index.ts
+++ b/src/plugins/data/public/search/index.ts
@@ -21,13 +21,7 @@ export * from './aggs';
export * from './expressions';
export * from './tabify';
-export {
- ISearchSetup,
- ISearchStart,
- ISearchContext,
- TSearchStrategyProvider,
- ISearchStrategy,
-} from './types';
+export { ISearchSetup, ISearchStart, ISearchStrategy } from './types';
export {
ISearch,
diff --git a/src/plugins/data/public/search/mocks.ts b/src/plugins/data/public/search/mocks.ts
index 44082040b5b0b..fcdbeb515423d 100644
--- a/src/plugins/data/public/search/mocks.ts
+++ b/src/plugins/data/public/search/mocks.ts
@@ -18,18 +18,20 @@
*/
import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks';
-import { ISearchStart } from './types';
+import { ISearchSetup, ISearchStart } from './types';
import { searchSourceMock, createSearchSourceMock } from './search_source/mocks';
-const searchSetupMock = {
+export * from './search_source/mocks';
+
+const searchSetupMock: jest.Mocked = {
aggs: searchAggsSetupMock(),
- registerSearchStrategyContext: jest.fn(),
- registerSearchStrategyProvider: jest.fn(),
+ registerSearchStrategy: jest.fn(),
};
const searchStartMock: jest.Mocked = {
aggs: searchAggsStartMock(),
setInterceptor: jest.fn(),
+ getSearchStrategy: jest.fn(),
search: jest.fn(),
searchSource: searchSourceMock,
__LEGACY: {
diff --git a/src/plugins/data/public/search/search_service.test.ts b/src/plugins/data/public/search/search_service.test.ts
index b1f7925bec4bb..fa138cef1a4a0 100644
--- a/src/plugins/data/public/search/search_service.test.ts
+++ b/src/plugins/data/public/search/search_service.test.ts
@@ -38,7 +38,7 @@ describe('Search service', () => {
packageInfo: { version: '8' },
expressions: expressionsPluginMock.createSetupContract(),
} as any);
- expect(setup).toHaveProperty('registerSearchStrategyProvider');
+ expect(setup).toHaveProperty('registerSearchStrategy');
});
});
});
diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts
index 1615aac9e7b7d..d5997c15817f6 100644
--- a/src/plugins/data/public/search/search_service.ts
+++ b/src/plugins/data/public/search/search_service.ts
@@ -18,11 +18,11 @@
*/
import { Plugin, CoreSetup, CoreStart, PackageInfo } from '../../../../core/public';
+import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy';
+import { ISearchSetup, ISearchStart, TSearchStrategiesMap, ISearchStrategy } from './types';
import { ExpressionsSetup } from '../../../../plugins/expressions/public';
-import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy';
import { createSearchSource, SearchSource, SearchSourceDependencies } from './search_source';
-import { ISearchSetup, ISearchStart, TSearchStrategyProvider, TSearchStrategiesMap } from './types';
import { TStrategyTypes } from './strategy_types';
import { getEsClient, LegacyApiCaller } from './legacy';
import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search';
@@ -54,11 +54,8 @@ interface SearchServiceStartDependencies {
}
/**
- * The search plugin exposes two registration methods for other plugins:
- * - registerSearchStrategyProvider for plugins to add their own custom
- * search strategies
- * - registerSearchStrategyContext for plugins to expose information
- * and/or functionality for other search strategies to use
+ * The search plugin exposes a method `registerSearchStrategy` for other plugins
+ * to add their own custom search strategies.
*
* It also comes with two search strategy implementations - SYNC_SEARCH_STRATEGY and ES_SEARCH_STRATEGY.
*/
@@ -73,17 +70,19 @@ export class SearchService implements Plugin {
private readonly aggTypesRegistry = new AggTypesRegistry();
private searchInterceptor!: SearchInterceptor;
- private registerSearchStrategyProvider = (
+ private registerSearchStrategy = (
name: T,
- strategyProvider: TSearchStrategyProvider
+ strategy: ISearchStrategy
) => {
- this.searchStrategies[name] = strategyProvider;
+ this.searchStrategies[name] = strategy;
};
- private getSearchStrategy = (name: T): TSearchStrategyProvider => {
- const strategyProvider = this.searchStrategies[name];
- if (!strategyProvider) throw new Error(`Search strategy ${name} not found`);
- return strategyProvider;
+ private getSearchStrategy = (name: T): ISearchStrategy => {
+ const strategy = this.searchStrategies[name];
+ if (!strategy) {
+ throw new Error(`Search strategy ${name} not found`);
+ }
+ return strategy;
};
public setup(
@@ -91,8 +90,11 @@ export class SearchService implements Plugin {
{ expressions, packageInfo, query, getInternalStartServices }: SearchServiceSetupDependencies
): ISearchSetup {
this.esClient = getEsClient(core.injectedMetadata, core.http, packageInfo);
- this.registerSearchStrategyProvider(SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider);
- this.registerSearchStrategyProvider(ES_SEARCH_STRATEGY, esSearchStrategyProvider);
+
+ const syncSearchStrategy = syncSearchStrategyProvider(core);
+ const esSearchStrategy = esSearchStrategyProvider(core, syncSearchStrategy);
+ this.registerSearchStrategy(SYNC_SEARCH_STRATEGY, syncSearchStrategy);
+ this.registerSearchStrategy(ES_SEARCH_STRATEGY, esSearchStrategy);
const aggTypesSetup = this.aggTypesRegistry.setup();
@@ -114,7 +116,7 @@ export class SearchService implements Plugin {
calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings),
types: aggTypesSetup,
},
- registerSearchStrategyProvider: this.registerSearchStrategyProvider,
+ registerSearchStrategy: this.registerSearchStrategy,
};
}
@@ -134,12 +136,10 @@ export class SearchService implements Plugin {
const aggTypesStart = this.aggTypesRegistry.start();
const search: ISearchGeneric = (request, options, strategyName) => {
- const strategyProvider = this.getSearchStrategy(strategyName || DEFAULT_SEARCH_STRATEGY);
- const searchStrategy = strategyProvider({
- core,
- getSearchStrategy: this.getSearchStrategy,
- });
- return this.searchInterceptor.search(searchStrategy.search as any, request, options);
+ const { search: defaultSearch } = this.getSearchStrategy(
+ strategyName || DEFAULT_SEARCH_STRATEGY
+ );
+ return this.searchInterceptor.search(defaultSearch as any, request, options);
};
const legacySearch = {
@@ -164,6 +164,7 @@ export class SearchService implements Plugin {
},
types: aggTypesStart,
},
+ getSearchStrategy: this.getSearchStrategy,
search,
searchSource: {
create: createSearchSource(dependencies.indexPatterns, searchSourceDependencies),
diff --git a/src/plugins/data/public/search/sync_search_strategy.test.ts b/src/plugins/data/public/search/sync_search_strategy.test.ts
index 6197980314b86..383a312fffad9 100644
--- a/src/plugins/data/public/search/sync_search_strategy.test.ts
+++ b/src/plugins/data/public/search/sync_search_strategy.test.ts
@@ -19,26 +19,23 @@
import { coreMock } from '../../../../core/public/mocks';
import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy';
-import { CoreStart } from 'kibana/public';
+import { CoreSetup } from 'kibana/public';
describe('Sync search strategy', () => {
- let mockCoreStart: MockedKeys;
+ let mockCoreSetup: MockedKeys;
beforeEach(() => {
- mockCoreStart = coreMock.createStart();
+ mockCoreSetup = coreMock.createSetup();
});
it('returns a strategy with `search` that calls the backend API', () => {
- mockCoreStart.http.fetch.mockImplementationOnce(() => Promise.resolve());
+ mockCoreSetup.http.fetch.mockImplementationOnce(() => Promise.resolve());
- const syncSearch = syncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn(),
- });
+ const syncSearch = syncSearchStrategyProvider(mockCoreSetup);
const request = { serverStrategy: SYNC_SEARCH_STRATEGY };
syncSearch.search(request, {});
- expect(mockCoreStart.http.fetch.mock.calls[0][0]).toEqual({
+ expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toEqual({
path: `/internal/search/${SYNC_SEARCH_STRATEGY}`,
body: JSON.stringify({
serverStrategy: 'SYNC_SEARCH_STRATEGY',
@@ -52,15 +49,12 @@ describe('Sync search strategy', () => {
const expectedLoadingCountValues = [0, 1, 0];
const receivedLoadingCountValues: number[] = [];
- mockCoreStart.http.fetch.mockResolvedValueOnce('response');
+ mockCoreSetup.http.fetch.mockResolvedValueOnce('response');
- const syncSearch = syncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn(),
- });
+ const syncSearch = syncSearchStrategyProvider(mockCoreSetup);
const request = { serverStrategy: SYNC_SEARCH_STRATEGY };
- const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0];
+ const loadingCount$ = mockCoreSetup.http.addLoadingCountSource.mock.calls[0][0];
loadingCount$.subscribe((value) => receivedLoadingCountValues.push(value));
await syncSearch.search(request, {}).toPromise();
@@ -73,15 +67,12 @@ describe('Sync search strategy', () => {
const expectedLoadingCountValues = [0, 1, 0];
const receivedLoadingCountValues: number[] = [];
- mockCoreStart.http.fetch.mockRejectedValueOnce('error');
+ mockCoreSetup.http.fetch.mockRejectedValueOnce('error');
- const syncSearch = syncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn(),
- });
+ const syncSearch = syncSearchStrategyProvider(mockCoreSetup);
const request = { serverStrategy: SYNC_SEARCH_STRATEGY };
- const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0];
+ const loadingCount$ = mockCoreSetup.http.addLoadingCountSource.mock.calls[0][0];
loadingCount$.subscribe((value) => receivedLoadingCountValues.push(value));
try {
diff --git a/src/plugins/data/public/search/sync_search_strategy.ts b/src/plugins/data/public/search/sync_search_strategy.ts
index 860ce593ae217..25d2731df7d5c 100644
--- a/src/plugins/data/public/search/sync_search_strategy.ts
+++ b/src/plugins/data/public/search/sync_search_strategy.ts
@@ -19,9 +19,9 @@
import { BehaviorSubject, from } from 'rxjs';
import { finalize } from 'rxjs/operators';
+import { CoreSetup } from '../../../../core/public';
import { IKibanaSearchRequest } from '../../common/search';
-import { ISearch, ISearchOptions } from './i_search';
-import { TSearchStrategyProvider, ISearchStrategy, ISearchContext } from './types';
+import { ISearch } from './i_search';
export const SYNC_SEARCH_STRATEGY = 'SYNC_SEARCH_STRATEGY';
@@ -29,27 +29,22 @@ export interface ISyncSearchRequest extends IKibanaSearchRequest {
serverStrategy: string;
}
-export const syncSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-): ISearchStrategy => {
+export function syncSearchStrategyProvider(core: CoreSetup) {
const loadingCount$ = new BehaviorSubject(0);
- context.core.http.addLoadingCountSource(loadingCount$);
+ core.http.addLoadingCountSource(loadingCount$);
- const search: ISearch = (
- request: ISyncSearchRequest,
- options: ISearchOptions = {}
- ) => {
+ const search: ISearch = (request, options) => {
loadingCount$.next(loadingCount$.getValue() + 1);
return from(
- context.core.http.fetch({
+ core.http.fetch({
path: `/internal/search/${request.serverStrategy}`,
method: 'POST',
body: JSON.stringify(request),
- signal: options.signal,
+ signal: options?.signal,
})
).pipe(finalize(() => loadingCount$.next(loadingCount$.getValue() - 1)));
};
return { search };
-};
+}
diff --git a/src/plugins/data/public/search/types.ts b/src/plugins/data/public/search/types.ts
index 64b4f1c5c2983..135974b697739 100644
--- a/src/plugins/data/public/search/types.ts
+++ b/src/plugins/data/public/search/types.ts
@@ -17,7 +17,6 @@
* under the License.
*/
-import { CoreStart } from 'kibana/public';
import { SearchAggsSetup, SearchAggsStart } from './aggs';
import { ISearch, ISearchGeneric } from './i_search';
import { TStrategyTypes } from './strategy_types';
@@ -25,11 +24,6 @@ import { LegacyApiCaller } from './legacy/es_client';
import { SearchInterceptor } from './search_interceptor';
import { ISearchSource, SearchSourceFields } from './search_source';
-export interface ISearchContext {
- core: CoreStart;
- getSearchStrategy: (name: T) => TSearchStrategyProvider;
-}
-
/**
* Search strategy interface contains a search method that takes in
* a request and returns a promise that resolves to a response.
@@ -39,27 +33,23 @@ export interface ISearchStrategy {
}
export type TSearchStrategiesMap = {
- [K in TStrategyTypes]?: TSearchStrategyProvider;
+ [K in TStrategyTypes]?: ISearchStrategy;
};
-/**
- * Search strategy provider creates an instance of a search strategy with the request
- * handler context bound to it. This way every search strategy can use
- * whatever information they require from the request context.
- */
-export type TSearchStrategyProvider = (
- context: ISearchContext
-) => ISearchStrategy;
-
/**
* Extension point exposed for other plugins to register their own search
* strategies.
*/
-export type TRegisterSearchStrategyProvider = (
+export type TRegisterSearchStrategy = (
name: T,
- searchStrategyProvider: TSearchStrategyProvider
+ searchStrategy: ISearchStrategy
) => void;
+/**
+ * Used if a plugin needs access to an already registered search strategy.
+ */
+export type TGetSearchStrategy = (name: T) => ISearchStrategy;
+
export interface ISearchStartLegacy {
esClient: LegacyApiCaller;
}
@@ -74,12 +64,18 @@ export interface ISearchSetup {
* Extension point exposed for other plugins to register their own search
* strategies.
*/
- registerSearchStrategyProvider: TRegisterSearchStrategyProvider;
+ registerSearchStrategy: TRegisterSearchStrategy;
}
export interface ISearchStart {
aggs: SearchAggsStart;
setInterceptor: (searchInterceptor: SearchInterceptor) => void;
+
+ /**
+ * Used if a plugin needs access to an already registered search strategy.
+ */
+ getSearchStrategy: TGetSearchStrategy;
+
search: ISearchGeneric;
searchSource: {
create: (fields?: SearchSourceFields) => Promise;
diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap
index 26ddb0809d24b..707e65d60870c 100644
--- a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap
+++ b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap
@@ -277,6 +277,7 @@ exports[`SavedObjectsTable import should show the flyout 1`] = `
"getMetrics": [Function],
},
},
+ "getSearchStrategy": [MockFunction],
"search": [MockFunction],
"searchSource": Object {
"create": [MockFunction],
diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts
index 72e0817eea8df..879c73587ed96 100644
--- a/x-pack/plugins/data_enhanced/public/plugin.ts
+++ b/x-pack/plugins/data_enhanced/public/plugin.ts
@@ -29,19 +29,20 @@ export interface DataEnhancedStartDependencies {
export type DataEnhancedSetup = ReturnType;
export type DataEnhancedStart = ReturnType;
-export class DataEnhancedPlugin implements Plugin {
- constructor() {}
-
- public setup(core: CoreSetup, { data }: DataEnhancedSetupDependencies) {
+export class DataEnhancedPlugin
+ implements Plugin {
+ public setup(
+ core: CoreSetup,
+ { data }: DataEnhancedSetupDependencies
+ ) {
data.autocomplete.addQuerySuggestionProvider(
KUERY_LANGUAGE_NAME,
setupKqlQuerySuggestionProvider(core)
);
- data.search.registerSearchStrategyProvider(ASYNC_SEARCH_STRATEGY, asyncSearchStrategyProvider);
- data.search.registerSearchStrategyProvider(
- ES_SEARCH_STRATEGY,
- enhancedEsSearchStrategyProvider
- );
+ const asyncSearchStrategy = asyncSearchStrategyProvider(core);
+ const esSearchStrategy = enhancedEsSearchStrategyProvider(core, asyncSearchStrategy);
+ data.search.registerSearchStrategy(ASYNC_SEARCH_STRATEGY, asyncSearchStrategy);
+ data.search.registerSearchStrategy(ES_SEARCH_STRATEGY, esSearchStrategy);
}
public start(core: CoreStart, plugins: DataEnhancedStartDependencies) {
diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts
index 6c635cc5b4489..3013f9966f068 100644
--- a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts
+++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts
@@ -6,35 +6,37 @@
import { of } from 'rxjs';
import { AbortController } from 'abort-controller';
+import { CoreSetup } from '../../../../../src/core/public';
import { coreMock } from '../../../../../src/core/public/mocks';
+import { DataPublicPluginStart } from '../../../../../src/plugins/data/public';
+import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks';
import { asyncSearchStrategyProvider } from './async_search_strategy';
-import { IAsyncSearchOptions } from './types';
-import { CoreStart } from 'kibana/public';
+import { IAsyncSearchOptions } from '.';
+import { DataEnhancedStartDependencies } from '../plugin';
describe('Async search strategy', () => {
- let mockCoreStart: MockedKeys;
+ let mockCoreSetup: jest.Mocked>;
+ let mockDataStart: jest.Mocked;
const mockSearch = jest.fn();
const mockRequest = { params: {}, serverStrategy: 'foo' };
const mockOptions: IAsyncSearchOptions = { pollInterval: 0 };
beforeEach(() => {
- mockCoreStart = coreMock.createStart();
+ mockCoreSetup = coreMock.createSetup();
+ mockDataStart = dataPluginMock.createStartContract();
+ (mockDataStart.search.getSearchStrategy as jest.Mock).mockReturnValue({ search: mockSearch });
+ mockCoreSetup.getStartServices.mockResolvedValue([
+ undefined as any,
+ { data: mockDataStart },
+ undefined,
+ ]);
mockSearch.mockReset();
});
it('only sends one request if the first response is complete', async () => {
mockSearch.mockReturnValueOnce(of({ id: 1, total: 1, loaded: 1 }));
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
await asyncSearch.search(mockRequest, mockOptions).toPromise();
@@ -51,17 +53,7 @@ describe('Async search strategy', () => {
of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false })
);
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
-
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
expect(mockSearch).toBeCalledTimes(0);
await asyncSearch.search(mockRequest, mockOptions).toPromise();
@@ -75,17 +67,7 @@ describe('Async search strategy', () => {
.mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: true }))
.mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: true }));
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
-
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
expect(mockSearch).toBeCalledTimes(0);
await asyncSearch
@@ -104,16 +86,7 @@ describe('Async search strategy', () => {
of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false })
);
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
expect(mockSearch).toBeCalledTimes(0);
@@ -131,16 +104,7 @@ describe('Async search strategy', () => {
of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false })
);
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
expect(mockSearch).toBeCalledTimes(0);
@@ -157,16 +121,7 @@ describe('Async search strategy', () => {
.mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 }))
.mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 }));
- const asyncSearch = asyncSearchStrategyProvider({
- core: mockCoreStart,
- getSearchStrategy: jest.fn().mockImplementation(() => {
- return () => {
- return {
- search: mockSearch,
- };
- };
- }),
- });
+ const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup);
const abortController = new AbortController();
const options = { ...mockOptions, signal: abortController.signal };
@@ -178,7 +133,7 @@ describe('Async search strategy', () => {
} catch (e) {
expect(e.name).toBe('AbortError');
expect(mockSearch).toBeCalledTimes(1);
- expect(mockCoreStart.http.delete).toBeCalled();
+ expect(mockCoreSetup.http.delete).toBeCalled();
}
});
});
diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts
index 18b5b976b3c1b..7de4dd28ad3d7 100644
--- a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts
+++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts
@@ -4,17 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EMPTY, fromEvent, NEVER, Observable, throwError, timer } from 'rxjs';
-import { mergeMap, expand, takeUntil } from 'rxjs/operators';
+import { EMPTY, fromEvent, NEVER, throwError, timer, Observable, from } from 'rxjs';
+import { mergeMap, expand, takeUntil, share, flatMap } from 'rxjs/operators';
+import { CoreSetup } from '../../../../../src/core/public';
import { AbortError } from '../../../../../src/plugins/data/common';
import {
- IKibanaSearchResponse,
- ISearchContext,
+ ISearch,
ISearchStrategy,
+ ISyncSearchRequest,
SYNC_SEARCH_STRATEGY,
- TSearchStrategyProvider,
} from '../../../../../src/plugins/data/public';
-import { IAsyncSearchRequest, IAsyncSearchOptions, IAsyncSearchResponse } from './types';
+import { IAsyncSearchOptions, IAsyncSearchResponse, IAsyncSearchRequest } from './types';
+import { DataEnhancedStartDependencies } from '../plugin';
export const ASYNC_SEARCH_STRATEGY = 'ASYNC_SEARCH_STRATEGY';
@@ -24,55 +25,59 @@ declare module '../../../../../src/plugins/data/public' {
}
}
-export const asyncSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-): ISearchStrategy => {
- const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY);
- const { search } = syncStrategyProvider(context);
- return {
- search: (
- request: IAsyncSearchRequest,
- { pollInterval = 1000, ...options }: IAsyncSearchOptions = {}
- ): Observable => {
- const { serverStrategy } = request;
- let id: string | undefined = request.id;
+export function asyncSearchStrategyProvider(
+ core: CoreSetup
+): ISearchStrategy {
+ const startServices$ = from(core.getStartServices()).pipe(share());
- const aborted$ = options.signal
- ? fromEvent(options.signal, 'abort').pipe(
- mergeMap(() => {
- // If we haven't received the response to the initial request, including the ID, then
- // we don't need to send a follow-up request to delete this search. Otherwise, we
- // send the follow-up request to delete this search, then throw an abort error.
- if (id !== undefined) {
- context.core.http.delete(`/internal/search/${request.serverStrategy}/${id}`);
- }
- return throwError(new AbortError());
- })
- )
- : NEVER;
+ const search: ISearch = (
+ request: ISyncSearchRequest,
+ { pollInterval = 1000, ...options }: IAsyncSearchOptions = {}
+ ) => {
+ const { serverStrategy } = request;
+ let { id } = request;
- return search(request, options).pipe(
- expand((response: IAsyncSearchResponse) => {
- // If the response indicates of an error, stop polling and complete the observable
- if (!response || (response.is_partial && !response.is_running)) {
+ const aborted$ = options.signal
+ ? fromEvent(options.signal, 'abort').pipe(
+ mergeMap(() => {
+ // If we haven't received the response to the initial request, including the ID, then
+ // we don't need to send a follow-up request to delete this search. Otherwise, we
+ // send the follow-up request to delete this search, then throw an abort error.
+ if (id !== undefined) {
+ core.http.delete(`/internal/search/${request.serverStrategy}/${id}`);
+ }
return throwError(new AbortError());
- }
+ })
+ )
+ : NEVER;
+
+ return startServices$.pipe(
+ flatMap((startServices) => {
+ const syncSearch = startServices[1].data.search.getSearchStrategy(SYNC_SEARCH_STRATEGY);
+ return (syncSearch.search(request, options) as Observable).pipe(
+ expand((response) => {
+ // If the response indicates of an error, stop polling and complete the observable
+ if (!response || (response.is_partial && !response.is_running)) {
+ return throwError(new AbortError());
+ }
- // If the response indicates it is complete, stop polling and complete the observable
- if (!response.is_running) return EMPTY;
+ // If the response indicates it is complete, stop polling and complete the observable
+ if (!response.is_running) return EMPTY;
- id = response.id;
+ id = response.id;
- // Delay by the given poll interval
- return timer(pollInterval).pipe(
- // Send future requests using just the ID from the response
- mergeMap(() => {
- return search({ id, serverStrategy }, options);
- })
- );
- }),
- takeUntil(aborted$)
- );
- },
+ // Delay by the given poll interval
+ return timer(pollInterval).pipe(
+ // Send future requests using just the ID from the response
+ mergeMap(() => {
+ return search({ id, serverStrategy }, options);
+ })
+ );
+ }),
+ takeUntil(aborted$)
+ );
+ })
+ );
};
-};
+ return { search };
+}
diff --git a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts
new file mode 100644
index 0000000000000..5d6bd53e2c945
--- /dev/null
+++ b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { CoreSetup } from '../../../../../src/core/public';
+import { coreMock } from '../../../../../src/core/public/mocks';
+import { ES_SEARCH_STRATEGY } from '../../../../../src/plugins/data/common';
+import { enhancedEsSearchStrategyProvider } from './es_search_strategy';
+import { IAsyncSearchOptions } from '.';
+
+describe('Enhanced ES search strategy', () => {
+ let mockCoreSetup: jest.Mocked;
+ const mockSearch = { search: jest.fn() };
+
+ beforeEach(() => {
+ mockCoreSetup = coreMock.createSetup();
+ mockSearch.search.mockClear();
+ });
+
+ it('returns a strategy with `search` that calls the async search `search`', () => {
+ const request = { params: {} };
+ const options: IAsyncSearchOptions = { pollInterval: 0 };
+
+ const esSearch = enhancedEsSearchStrategyProvider(mockCoreSetup, mockSearch);
+ esSearch.search(request, options);
+
+ expect(mockSearch.search.mock.calls[0][0]).toEqual({
+ ...request,
+ serverStrategy: ES_SEARCH_STRATEGY,
+ });
+ expect(mockSearch.search.mock.calls[0][1]).toEqual(options);
+ });
+});
diff --git a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts
index 3a511c7b5a176..c4b293a52a104 100644
--- a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts
+++ b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts
@@ -5,42 +5,40 @@
*/
import { Observable } from 'rxjs';
+import { CoreSetup } from '../../../../../src/core/public';
import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../../../src/plugins/data/common';
import {
- TSearchStrategyProvider,
- ISearchContext,
ISearch,
getEsPreference,
+ ISearchStrategy,
UI_SETTINGS,
} from '../../../../../src/plugins/data/public';
import { IEnhancedEsSearchRequest, EnhancedSearchParams } from '../../common';
import { ASYNC_SEARCH_STRATEGY } from './async_search_strategy';
import { IAsyncSearchOptions } from './types';
-export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider = (
- context: ISearchContext
-) => {
- const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY);
- const { search: asyncSearch } = asyncStrategyProvider(context);
-
+export function enhancedEsSearchStrategyProvider(
+ core: CoreSetup,
+ asyncStrategy: ISearchStrategy
+) {
const search: ISearch = (
request: IEnhancedEsSearchRequest,
options
) => {
const params: EnhancedSearchParams = {
- ignoreThrottled: !context.core.uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
- preference: getEsPreference(context.core.uiSettings),
+ ignoreThrottled: !core.uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
+ preference: getEsPreference(core.uiSettings),
...request.params,
};
request.params = params;
const asyncOptions: IAsyncSearchOptions = { pollInterval: 0, ...options };
- return asyncSearch(
+ return asyncStrategy.search(
{ ...request, serverStrategy: ES_SEARCH_STRATEGY },
asyncOptions
) as Observable;
};
return { search };
-};
+}