mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[data.search] Add request handler context and asScoped pattern (#80775)
* [Search] Add request context and asScoped pattern * Update docs * Unify interface for getting search client * Update examples/search_examples/server/my_strategy.ts Co-authored-by: Anton Dosov <dosantappdev@gmail.com> * Review feedback * Fix checks * Fix CI * Fix security search * Fix test * Fix test for reals * Fix types Co-authored-by: Anton Dosov <dosantappdev@gmail.com>
This commit is contained in:
parent
4b9570f209
commit
44368b0b66
57 changed files with 386 additions and 417 deletions
|
@ -18,6 +18,6 @@ export interface IKibanaSearchResponse<RawResponse = any>
|
|||
| [isPartial](./kibana-plugin-plugins-data-public.ikibanasearchresponse.ispartial.md) | <code>boolean</code> | Indicates whether the results returned are complete or partial |
|
||||
| [isRunning](./kibana-plugin-plugins-data-public.ikibanasearchresponse.isrunning.md) | <code>boolean</code> | Indicates whether search is still in flight |
|
||||
| [loaded](./kibana-plugin-plugins-data-public.ikibanasearchresponse.loaded.md) | <code>number</code> | If relevant to the search strategy, return a loaded number that represents how progress is indicated. |
|
||||
| [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | <code>RawResponse</code> | |
|
||||
| [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | <code>RawResponse</code> | The raw response returned by the internal search method (usually the raw ES response) |
|
||||
| [total](./kibana-plugin-plugins-data-public.ikibanasearchresponse.total.md) | <code>number</code> | If relevant to the search strategy, return a total number that represents how progress is indicated. |
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
## IKibanaSearchResponse.rawResponse property
|
||||
|
||||
The raw response returned by the internal search method (usually the raw ES response)
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearch](./kibana-plugin-plugins-data-public.isearch.md)
|
||||
|
||||
## ISearch type
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type ISearch = (request: IKibanaSearchRequest, options?: ISearchOptions) => Observable<IKibanaSearchResponse>;
|
||||
```
|
|
@ -159,7 +159,6 @@
|
|||
| [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | |
|
||||
| [IndexPatternSelectProps](./kibana-plugin-plugins-data-public.indexpatternselectprops.md) | |
|
||||
| [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) | |
|
||||
| [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | |
|
||||
| [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | |
|
||||
| [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | search source interface |
|
||||
| [MatchAllFilter](./kibana-plugin-plugins-data-public.matchallfilter.md) | |
|
||||
|
|
|
@ -23,5 +23,5 @@ search(request: IKibanaSearchRequest, options?: ISearchOptions): Observable<IKib
|
|||
|
||||
`Observable<IKibanaSearchResponse>`
|
||||
|
||||
`Observalbe` emitting the search response or an error.
|
||||
`Observable` emitting the search response or an error.
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ export declare class SearchSource
|
|||
| [getSerializedFields()](./kibana-plugin-plugins-data-public.searchsource.getserializedfields.md) | | serializes search source fields (which can later be passed to [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md)<!-- -->) |
|
||||
| [onRequestStart(handler)](./kibana-plugin-plugins-data-public.searchsource.onrequeststart.md) | | Add a handler that will be notified whenever requests start |
|
||||
| [serialize()](./kibana-plugin-plugins-data-public.searchsource.serialize.md) | | Serializes the instance to a JSON string and a set of referenced objects. Use this method to get a representation of the search source which can be stored in a saved object.<!-- -->The references returned by this function can be mixed with other references in the same object, however make sure there are no name-collisions. The references will be named <code>kibanaSavedObjectMeta.searchSourceJSON.index</code> and <code>kibanaSavedObjectMeta.searchSourceJSON.filter[<number>].meta.index</code>.<!-- -->Using <code>createSearchSource</code>, the instance can be re-created. |
|
||||
| [setField(field, value)](./kibana-plugin-plugins-data-public.searchsource.setfield.md) | | sets value to a single search source feild |
|
||||
| [setField(field, value)](./kibana-plugin-plugins-data-public.searchsource.setfield.md) | | sets value to a single search source field |
|
||||
| [setFields(newFields)](./kibana-plugin-plugins-data-public.searchsource.setfields.md) | | Internal, do not use. Overrides all search source fields with the new field array. |
|
||||
| [setParent(parent, options)](./kibana-plugin-plugins-data-public.searchsource.setparent.md) | | Set a searchSource that this source should inherit from |
|
||||
| [setPreferredSearchStrategyId(searchStrategyId)](./kibana-plugin-plugins-data-public.searchsource.setpreferredsearchstrategyid.md) | | internal, dont use |
|
||||
|
|
|
@ -15,13 +15,13 @@ Using `createSearchSource`<!-- -->, the instance can be re-created.
|
|||
```typescript
|
||||
serialize(): {
|
||||
searchSourceJSON: string;
|
||||
references: import("../../../../../core/types").SavedObjectReference[];
|
||||
references: import("src/core/server").SavedObjectReference[];
|
||||
};
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`{
|
||||
searchSourceJSON: string;
|
||||
references: import("../../../../../core/types").SavedObjectReference[];
|
||||
references: import("src/core/server").SavedObjectReference[];
|
||||
}`
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## SearchSource.setField() method
|
||||
|
||||
sets value to a single search source feild
|
||||
sets value to a single search source field
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [search](./kibana-plugin-plugins-data-server.isearchstart.search.md)
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md)
|
||||
|
||||
## ISearchStart.search property
|
||||
## ISearchStart.asScoped property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
search: ISearchStrategy['search'];
|
||||
asScoped: (request: KibanaRequest) => ISearchClient;
|
||||
```
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
## ISearchStart.getSearchStrategy property
|
||||
|
||||
Get other registered search strategies. For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that.
|
||||
Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getSearchStrategy: (name: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>;
|
||||
getSearchStrategy: (name?: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>;
|
||||
```
|
||||
|
|
|
@ -15,7 +15,7 @@ export interface ISearchStart<SearchStrategyRequest extends IKibanaSearchRequest
|
|||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [aggs](./kibana-plugin-plugins-data-server.isearchstart.aggs.md) | <code>AggsStart</code> | |
|
||||
| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | <code>(name: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse></code> | 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) | <code>ISearchStrategy['search']</code> | |
|
||||
| [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md) | <code>(request: KibanaRequest) => ISearchClient</code> | |
|
||||
| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | <code>(name?: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse></code> | Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. |
|
||||
| [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) | <code>{</code><br/><code> asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;</code><br/><code> }</code> | |
|
||||
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
cancel?: (context: RequestHandlerContext, id: string) => Promise<void>;
|
||||
cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise<void>;
|
||||
```
|
||||
|
|
|
@ -16,6 +16,6 @@ export interface ISearchStrategy<SearchStrategyRequest extends IKibanaSearchRequ
|
|||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | <code>(context: RequestHandlerContext, id: string) => Promise<void></code> | |
|
||||
| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | <code>(request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable<SearchStrategyResponse></code> | |
|
||||
| [cancel](./kibana-plugin-plugins-data-server.isearchstrategy.cancel.md) | <code>(id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise<void></code> | |
|
||||
| [search](./kibana-plugin-plugins-data-server.isearchstrategy.search.md) | <code>(request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable<SearchStrategyResponse></code> | |
|
||||
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
search: (request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable<SearchStrategyResponse>;
|
||||
search: (request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable<SearchStrategyResponse>;
|
||||
```
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
| [PluginSetup](./kibana-plugin-plugins-data-server.pluginsetup.md) | |
|
||||
| [PluginStart](./kibana-plugin-plugins-data-server.pluginstart.md) | |
|
||||
| [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) | |
|
||||
| [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) | |
|
||||
| [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) | |
|
||||
| [TabbedAggColumn](./kibana-plugin-plugins-data-server.tabbedaggcolumn.md) | \* |
|
||||
| [TabbedTable](./kibana-plugin-plugins-data-server.tabbedtable.md) | \* |
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
```typescript
|
||||
start(core: CoreStart): {
|
||||
fieldFormats: {
|
||||
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
};
|
||||
|
@ -28,10 +28,10 @@ start(core: CoreStart): {
|
|||
|
||||
`{
|
||||
fieldFormats: {
|
||||
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
}`
|
||||
|
|
|
@ -12,7 +12,7 @@ search: {
|
|||
utils: {
|
||||
doSearch: <SearchResponse = any>(searchMethod: () => Promise<SearchResponse>, abortSignal?: AbortSignal | undefined) => import("rxjs").Observable<SearchResponse>;
|
||||
shimAbortSignal: <T extends import("../common").TransportRequestPromise<unknown>>(promise: T, signal: AbortSignal | undefined) => T;
|
||||
trackSearchStatus: <KibanaResponse extends import("../common").IKibanaSearchResponse<any> = import("./search").IEsSearchResponse<import("../../../core/server").SearchResponse<unknown>>>(logger: import("@kbn/logging/target/logger").Logger, usage?: import("./search").SearchUsage | undefined) => import("rxjs").UnaryFunction<import("rxjs").Observable<KibanaResponse>, import("rxjs").Observable<KibanaResponse>>;
|
||||
trackSearchStatus: <KibanaResponse extends import("../common").IKibanaSearchResponse<any> = import("./search").IEsSearchResponse<import("src/core/server").SearchResponse<unknown>>>(logger: import("src/core/server").Logger, usage?: import("./search").SearchUsage | undefined) => import("rxjs").UnaryFunction<import("rxjs").Observable<KibanaResponse>, import("rxjs").Observable<KibanaResponse>>;
|
||||
includeTotalLoaded: () => import("rxjs").OperatorFunction<import("../common").IKibanaSearchResponse<import("elasticsearch").SearchResponse<unknown>>, {
|
||||
total: number;
|
||||
loaded: number;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [esClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md)
|
||||
|
||||
## SearchStrategyDependencies.esClient property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
esClient: IScopedClusterClient;
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md)
|
||||
|
||||
## SearchStrategyDependencies interface
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface SearchStrategyDependencies
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [esClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.esclient.md) | <code>IScopedClusterClient</code> | |
|
||||
| [savedObjectsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md) | <code>SavedObjectsClientContract</code> | |
|
||||
| [uiSettingsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md) | <code>IUiSettingsClient</code> | |
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [savedObjectsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.savedobjectsclient.md)
|
||||
|
||||
## SearchStrategyDependencies.savedObjectsClient property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) > [uiSettingsClient](./kibana-plugin-plugins-data-server.searchstrategydependencies.uisettingsclient.md)
|
||||
|
||||
## SearchStrategyDependencies.uiSettingsClient property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
uiSettingsClient: IUiSettingsClient;
|
||||
```
|
|
@ -24,18 +24,18 @@ import { IMyStrategyResponse, IMyStrategyRequest } from '../common';
|
|||
export const mySearchStrategyProvider = (
|
||||
data: PluginStart
|
||||
): ISearchStrategy<IMyStrategyRequest, IMyStrategyResponse> => {
|
||||
const es = data.search.getSearchStrategy('es');
|
||||
const es = data.search.getSearchStrategy();
|
||||
return {
|
||||
search: (request, options, context) =>
|
||||
es.search(request, options, context).pipe(
|
||||
search: (request, options, deps) =>
|
||||
es.search(request, options, deps).pipe(
|
||||
map((esSearchRes) => ({
|
||||
...esSearchRes,
|
||||
cool: request.get_cool ? 'YES' : 'NOPE',
|
||||
}))
|
||||
),
|
||||
cancel: async (context, id) => {
|
||||
cancel: async (id, options, deps) => {
|
||||
if (es.cancel) {
|
||||
es.cancel(context, id);
|
||||
await es.cancel(id, options, deps);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,8 +39,8 @@ export function registerServerSearchRoute(router: IRouter, data: DataPluginStart
|
|||
// Run a synchronous search server side, by enforcing a high keepalive and waiting for completion.
|
||||
// If you wish to run the search with polling (in basic+), you'd have to poll on the search API.
|
||||
// Please reach out to the @app-arch-team if you need this to be implemented.
|
||||
const res = await data.search
|
||||
.search(
|
||||
const res = await context
|
||||
.search!.search(
|
||||
{
|
||||
params: {
|
||||
index,
|
||||
|
@ -57,8 +57,7 @@ export function registerServerSearchRoute(router: IRouter, data: DataPluginStart
|
|||
keepAlive: '5m',
|
||||
},
|
||||
} as IEsSearchRequest,
|
||||
{},
|
||||
context
|
||||
{}
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
|
|
|
@ -21,13 +21,12 @@ import _ from 'lodash';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { Assign, Ensure } from '@kbn/utility-types';
|
||||
|
||||
import { ISearchSource } from 'src/plugins/data/public';
|
||||
import { ISearchOptions, ISearchSource } from 'src/plugins/data/public';
|
||||
import {
|
||||
ExpressionAstFunction,
|
||||
ExpressionAstArgument,
|
||||
SerializedFieldFormat,
|
||||
} from 'src/plugins/expressions/common';
|
||||
import { ISearchOptions } from '../es_search';
|
||||
|
||||
import { IAggType } from './agg_type';
|
||||
import { writeParams } from './agg_params';
|
||||
|
|
|
@ -22,22 +22,6 @@ import { IKibanaSearchRequest, IKibanaSearchResponse } from '../types';
|
|||
|
||||
export const ES_SEARCH_STRATEGY = 'es';
|
||||
|
||||
export interface ISearchOptions {
|
||||
/**
|
||||
* An `AbortSignal` that allows the caller of `search` to abort a search request.
|
||||
*/
|
||||
abortSignal?: AbortSignal;
|
||||
/**
|
||||
* Use this option to force using a specific server side search strategy. Leave empty to use the default strategy.
|
||||
*/
|
||||
strategy?: string;
|
||||
|
||||
/**
|
||||
* A session ID, grouping multiple search requests into a single session.
|
||||
*/
|
||||
sessionId?: string;
|
||||
}
|
||||
|
||||
export type ISearchRequestParams<T = Record<string, any>> = {
|
||||
trackTotalHits?: boolean;
|
||||
} & Search<T>;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { BehaviorSubject, of } from 'rxjs';
|
||||
import { IndexPattern } from '../../index_patterns';
|
||||
import { GetConfigFn } from '../../types';
|
||||
import { fetchSoon } from './legacy';
|
||||
|
@ -53,7 +53,7 @@ describe('SearchSource', () => {
|
|||
let searchSourceDependencies: SearchSourceDependencies;
|
||||
|
||||
beforeEach(() => {
|
||||
mockSearchMethod = jest.fn().mockResolvedValue({ rawResponse: '' });
|
||||
mockSearchMethod = jest.fn().mockReturnValue(of({ rawResponse: '' }));
|
||||
|
||||
searchSourceDependencies = {
|
||||
getConfig: jest.fn(),
|
||||
|
|
|
@ -71,12 +71,12 @@
|
|||
|
||||
import { setWith } from '@elastic/safer-lodash-set';
|
||||
import { uniqueId, uniq, extend, pick, difference, omit, isObject, keys, isFunction } from 'lodash';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { normalizeSortRequest } from './normalize_sort_request';
|
||||
import { filterDocvalueFields } from './filter_docvalue_fields';
|
||||
import { fieldWildcardFilter } from '../../../../kibana_utils/common';
|
||||
import { IIndexPattern } from '../../index_patterns';
|
||||
import { IEsSearchRequest, IEsSearchResponse, ISearchOptions } from '../../search';
|
||||
import type { IKibanaSearchRequest, IKibanaSearchResponse } from '../types';
|
||||
import { ISearchGeneric, ISearchOptions } from '../..';
|
||||
import type { ISearchSource, SearchSourceOptions, SearchSourceFields } from './types';
|
||||
import { FetchHandlers, RequestFailure, getSearchParamsFromRequest, SearchRequest } from './fetch';
|
||||
|
||||
|
@ -102,15 +102,7 @@ export const searchSourceRequiredUiSettings = [
|
|||
];
|
||||
|
||||
export interface SearchSourceDependencies extends FetchHandlers {
|
||||
// Types are nearly identical to ISearchGeneric, except we are making
|
||||
// search options required here and returning a promise instead of observable.
|
||||
search: <
|
||||
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
|
||||
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse
|
||||
>(
|
||||
request: SearchStrategyRequest,
|
||||
options: ISearchOptions
|
||||
) => Promise<SearchStrategyResponse>;
|
||||
search: ISearchGeneric;
|
||||
}
|
||||
|
||||
/** @public **/
|
||||
|
@ -144,7 +136,7 @@ export class SearchSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* sets value to a single search source feild
|
||||
* sets value to a single search source field
|
||||
* @param field: field name
|
||||
* @param value: value for the field
|
||||
*/
|
||||
|
@ -319,9 +311,9 @@ export class SearchSource {
|
|||
getConfig,
|
||||
});
|
||||
|
||||
return search({ params, indexType: searchRequest.indexType }, options).then(({ rawResponse }) =>
|
||||
onResponse(searchRequest, rawResponse)
|
||||
);
|
||||
return search({ params, indexType: searchRequest.indexType }, options)
|
||||
.pipe(map(({ rawResponse }) => onResponse(searchRequest, rawResponse)))
|
||||
.toPromise();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,12 +18,7 @@
|
|||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { IEsSearchRequest, IEsSearchResponse, ISearchOptions } from '../../common/search';
|
||||
|
||||
export type ISearch = (
|
||||
request: IKibanaSearchRequest,
|
||||
options?: ISearchOptions
|
||||
) => Observable<IKibanaSearchResponse>;
|
||||
import { IEsSearchRequest, IEsSearchResponse } from './es_search';
|
||||
|
||||
export type ISearchGeneric = <
|
||||
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
|
||||
|
@ -33,6 +28,13 @@ export type ISearchGeneric = <
|
|||
options?: ISearchOptions
|
||||
) => Observable<SearchStrategyResponse>;
|
||||
|
||||
export type ISearchCancelGeneric = (id: string, options?: ISearchOptions) => Promise<void>;
|
||||
|
||||
export interface ISearchClient {
|
||||
search: ISearchGeneric;
|
||||
cancel: ISearchCancelGeneric;
|
||||
}
|
||||
|
||||
export interface IKibanaSearchResponse<RawResponse = any> {
|
||||
/**
|
||||
* Some responses may contain a unique id to identify the request this response came from.
|
||||
|
@ -61,6 +63,9 @@ export interface IKibanaSearchResponse<RawResponse = any> {
|
|||
*/
|
||||
isPartial?: boolean;
|
||||
|
||||
/**
|
||||
* The raw response returned by the internal search method (usually the raw ES response)
|
||||
*/
|
||||
rawResponse: RawResponse;
|
||||
}
|
||||
|
||||
|
@ -72,3 +77,19 @@ export interface IKibanaSearchRequest<Params = any> {
|
|||
|
||||
params?: Params;
|
||||
}
|
||||
|
||||
export interface ISearchOptions {
|
||||
/**
|
||||
* An `AbortSignal` that allows the caller of `search` to abort a search request.
|
||||
*/
|
||||
abortSignal?: AbortSignal;
|
||||
/**
|
||||
* Use this option to force using a specific server side search strategy. Leave empty to use the default strategy.
|
||||
*/
|
||||
strategy?: string;
|
||||
|
||||
/**
|
||||
* A session ID, grouping multiple search requests into a single session.
|
||||
*/
|
||||
sessionId?: string;
|
||||
}
|
||||
|
|
|
@ -358,7 +358,6 @@ export {
|
|||
IKibanaSearchRequest,
|
||||
IKibanaSearchResponse,
|
||||
injectSearchSourceReferences,
|
||||
ISearch,
|
||||
ISearchSetup,
|
||||
ISearchStart,
|
||||
ISearchStartSearchSource,
|
||||
|
|
|
@ -137,7 +137,7 @@ export class AggConfig {
|
|||
// (undocumented)
|
||||
makeLabel(percentageMode?: boolean): any;
|
||||
static nextId(list: IAggConfig[]): number;
|
||||
onSearchRequestStart(searchSource: ISearchSource_2, options?: ISearchOptions): Promise<void> | Promise<any[]>;
|
||||
onSearchRequestStart(searchSource: ISearchSource_2, options?: ISearchOptions_2): Promise<void> | Promise<any[]>;
|
||||
// (undocumented)
|
||||
params: any;
|
||||
// Warning: (ae-incompatible-release-tags) The symbol "parent" is marked as @public, but its signature references "IAggConfigs" which is marked as @internal
|
||||
|
@ -1047,7 +1047,6 @@ export interface IKibanaSearchResponse<RawResponse = any> {
|
|||
isPartial?: boolean;
|
||||
isRunning?: boolean;
|
||||
loaded?: number;
|
||||
// (undocumented)
|
||||
rawResponse: RawResponse;
|
||||
total?: number;
|
||||
}
|
||||
|
@ -1384,11 +1383,6 @@ export type InputTimeRange = TimeRange | {
|
|||
// @public (undocumented)
|
||||
export const isCompleteResponse: (response?: IKibanaSearchResponse<any> | undefined) => boolean;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "ISearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type ISearch = (request: IKibanaSearchRequest, options?: ISearchOptions) => Observable<IKibanaSearchResponse>;
|
||||
|
||||
// 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)
|
||||
|
@ -2092,7 +2086,7 @@ export class SearchSource {
|
|||
onRequestStart(handler: (searchSource: SearchSource, options?: ISearchOptions) => Promise<unknown>): void;
|
||||
serialize(): {
|
||||
searchSourceJSON: string;
|
||||
references: import("../../../../../core/types").SavedObjectReference[];
|
||||
references: import("src/core/server").SavedObjectReference[];
|
||||
};
|
||||
setField<K extends keyof SearchSourceFields>(field: K, value: SearchSourceFields[K]): this;
|
||||
setFields(newFields: SearchSourceFields): this;
|
||||
|
@ -2327,21 +2321,21 @@ export const UI_SETTINGS: {
|
|||
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:388:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:415:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:387:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
|
|
@ -31,7 +31,6 @@ export {
|
|||
IKibanaSearchRequest,
|
||||
IKibanaSearchResponse,
|
||||
injectReferences as injectSearchSourceReferences,
|
||||
ISearch,
|
||||
ISearchGeneric,
|
||||
ISearchSource,
|
||||
parseSearchSourceJSON,
|
||||
|
|
|
@ -218,7 +218,7 @@ export class SearchInterceptor {
|
|||
*
|
||||
* @param request
|
||||
* @options
|
||||
* @returns `Observalbe` emitting the search response or an error.
|
||||
* @returns `Observable` emitting the search response or an error.
|
||||
*/
|
||||
public search(
|
||||
request: IKibanaSearchRequest,
|
||||
|
|
|
@ -23,12 +23,7 @@ import { ISearchSetup, ISearchStart, SearchEnhancements } from './types';
|
|||
|
||||
import { handleResponse } from './fetch';
|
||||
import {
|
||||
IEsSearchRequest,
|
||||
IEsSearchResponse,
|
||||
IKibanaSearchRequest,
|
||||
IKibanaSearchResponse,
|
||||
ISearchGeneric,
|
||||
ISearchOptions,
|
||||
SearchSourceService,
|
||||
SearchSourceDependencies,
|
||||
ISessionService,
|
||||
|
@ -126,15 +121,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
|
||||
const searchSourceDependencies: SearchSourceDependencies = {
|
||||
getConfig: uiSettings.get.bind(uiSettings),
|
||||
search: <
|
||||
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
|
||||
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse
|
||||
>(
|
||||
request: SearchStrategyRequest,
|
||||
options: ISearchOptions
|
||||
) => {
|
||||
return search<SearchStrategyRequest, SearchStrategyResponse>(request, options).toPromise();
|
||||
},
|
||||
search,
|
||||
onResponse: handleResponse,
|
||||
legacy: {
|
||||
callMsearch: getCallMsearch({ http }),
|
||||
|
|
|
@ -221,6 +221,7 @@ export {
|
|||
ISearchStrategy,
|
||||
ISearchSetup,
|
||||
ISearchStart,
|
||||
SearchStrategyDependencies,
|
||||
getDefaultSearchParams,
|
||||
getShardTimeout,
|
||||
shimHitsTotal,
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { RequestHandlerContext } from '../../../../../core/server';
|
||||
import { pluginInitializerContextConfigMock } from '../../../../../core/server/mocks';
|
||||
import { esSearchStrategyProvider } from './es_search_strategy';
|
||||
import { SearchStrategyDependencies } from '../types';
|
||||
|
||||
describe('ES search strategy', () => {
|
||||
const mockLogger: any = {
|
||||
|
@ -36,16 +36,12 @@ describe('ES search strategy', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const mockContext = ({
|
||||
core: {
|
||||
uiSettings: {
|
||||
client: {
|
||||
get: () => {},
|
||||
},
|
||||
},
|
||||
elasticsearch: { client: { asCurrentUser: { search: mockApiCaller } } },
|
||||
const mockDeps = ({
|
||||
uiSettingsClient: {
|
||||
get: () => {},
|
||||
},
|
||||
} as unknown) as RequestHandlerContext;
|
||||
esClient: { asCurrentUser: { search: mockApiCaller } },
|
||||
} as unknown) as SearchStrategyDependencies;
|
||||
|
||||
const mockConfig$ = pluginInitializerContextConfigMock<any>({}).legacy.globalConfig$;
|
||||
|
||||
|
@ -63,7 +59,7 @@ describe('ES search strategy', () => {
|
|||
const params = { index: 'logstash-*' };
|
||||
|
||||
await esSearchStrategyProvider(mockConfig$, mockLogger)
|
||||
.search({ params }, {}, mockContext)
|
||||
.search({ params }, {}, mockDeps)
|
||||
.subscribe(() => {
|
||||
expect(mockApiCaller).toBeCalled();
|
||||
expect(mockApiCaller.mock.calls[0][0]).toEqual({
|
||||
|
@ -79,7 +75,7 @@ describe('ES search strategy', () => {
|
|||
const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' };
|
||||
|
||||
await esSearchStrategyProvider(mockConfig$, mockLogger)
|
||||
.search({ params }, {}, mockContext)
|
||||
.search({ params }, {}, mockDeps)
|
||||
.subscribe(() => {
|
||||
expect(mockApiCaller).toBeCalled();
|
||||
expect(mockApiCaller.mock.calls[0][0]).toEqual({
|
||||
|
@ -97,7 +93,7 @@ describe('ES search strategy', () => {
|
|||
params: { index: 'logstash-*' },
|
||||
},
|
||||
{},
|
||||
mockContext
|
||||
mockDeps
|
||||
)
|
||||
.subscribe((data) => {
|
||||
expect(data.isRunning).toBe(false);
|
||||
|
|
|
@ -36,7 +36,7 @@ export const esSearchStrategyProvider = (
|
|||
logger: Logger,
|
||||
usage?: SearchUsage
|
||||
): ISearchStrategy => ({
|
||||
search: (request, { abortSignal }, context) => {
|
||||
search: (request, { abortSignal }, { esClient, uiSettingsClient }) => {
|
||||
// Only default index pattern type is supported here.
|
||||
// See data_enhanced for other type support.
|
||||
if (request.indexType) {
|
||||
|
@ -46,12 +46,12 @@ export const esSearchStrategyProvider = (
|
|||
return doSearch<ApiResponse<IEsRawSearchResponse>>(async () => {
|
||||
const config = await config$.pipe(first()).toPromise();
|
||||
const params = toSnakeCase({
|
||||
...(await getDefaultSearchParams(context.core.uiSettings.client)),
|
||||
...(await getDefaultSearchParams(uiSettingsClient)),
|
||||
...getShardTimeout(config),
|
||||
...request.params,
|
||||
});
|
||||
|
||||
return context.core.elasticsearch.client.asCurrentUser.search(params);
|
||||
return esClient.asCurrentUser.search(params);
|
||||
}, abortSignal).pipe(
|
||||
toKibanaSearchResponse(),
|
||||
trackSearchStatus(logger, usage),
|
||||
|
|
|
@ -17,12 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { ISearchStrategy, ISearchSetup, ISearchStart, SearchEnhancements } from './types';
|
||||
|
||||
export * from './types';
|
||||
export * from './es_search';
|
||||
|
||||
export { usageProvider, SearchUsage } from './collectors';
|
||||
|
||||
export * from './aggs';
|
||||
|
||||
export { shimHitsTotal } from './routes';
|
||||
|
|
|
@ -33,7 +33,10 @@ export function createSearchStartMock(): jest.Mocked<ISearchStart> {
|
|||
return {
|
||||
aggs: searchAggsStartMock(),
|
||||
getSearchStrategy: jest.fn(),
|
||||
search: jest.fn(),
|
||||
asScoped: jest.fn().mockReturnValue({
|
||||
search: jest.fn(),
|
||||
cancel: jest.fn(),
|
||||
}),
|
||||
searchSource: searchSourceMock.createStartContract(),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,35 +16,19 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { MockedKeys } from '@kbn/utility-types/jest';
|
||||
import { Observable, from } from 'rxjs';
|
||||
|
||||
import {
|
||||
CoreSetup,
|
||||
RequestHandlerContext,
|
||||
SharedGlobalConfig,
|
||||
StartServicesAccessor,
|
||||
} from 'src/core/server';
|
||||
import {
|
||||
coreMock,
|
||||
httpServerMock,
|
||||
pluginInitializerContextConfigMock,
|
||||
} from '../../../../../../src/core/server/mocks';
|
||||
import type { MockedKeys } from '@kbn/utility-types/jest';
|
||||
import { from } from 'rxjs';
|
||||
import { CoreSetup, RequestHandlerContext } from 'src/core/server';
|
||||
import { coreMock, httpServerMock } from '../../../../../../src/core/server/mocks';
|
||||
import { registerSearchRoute } from './search';
|
||||
import { DataPluginStart } from '../../plugin';
|
||||
import { dataPluginMock } from '../../mocks';
|
||||
|
||||
describe('Search service', () => {
|
||||
let mockDataStart: MockedKeys<DataPluginStart>;
|
||||
let mockCoreSetup: MockedKeys<CoreSetup<{}, DataPluginStart>>;
|
||||
let getStartServices: jest.Mocked<StartServicesAccessor<{}, DataPluginStart>>;
|
||||
let globalConfig$: Observable<SharedGlobalConfig>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockDataStart = dataPluginMock.createStartContract();
|
||||
mockCoreSetup = coreMock.createSetup({ pluginStartContract: mockDataStart });
|
||||
getStartServices = mockCoreSetup.getStartServices;
|
||||
globalConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$;
|
||||
mockCoreSetup = coreMock.createSetup();
|
||||
});
|
||||
|
||||
it('handler calls context.search.search with the given request and strategy', async () => {
|
||||
|
@ -67,8 +51,12 @@ describe('Search service', () => {
|
|||
},
|
||||
};
|
||||
|
||||
mockDataStart.search.search.mockReturnValue(from(Promise.resolve(response)));
|
||||
const mockContext = {};
|
||||
const mockContext = {
|
||||
search: {
|
||||
search: jest.fn().mockReturnValue(from(Promise.resolve(response))),
|
||||
},
|
||||
};
|
||||
|
||||
const mockBody = { id: undefined, params: {} };
|
||||
const mockParams = { strategy: 'foo' };
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
|
@ -77,14 +65,14 @@ describe('Search service', () => {
|
|||
});
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter(), { getStartServices, globalConfig$ });
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter());
|
||||
|
||||
const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value;
|
||||
const handler = mockRouter.post.mock.calls[0][1];
|
||||
await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse);
|
||||
|
||||
expect(mockDataStart.search.search).toBeCalled();
|
||||
expect(mockDataStart.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockContext.search.search).toBeCalled();
|
||||
expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockResponse.ok).toBeCalled();
|
||||
expect(mockResponse.ok.mock.calls[0][0]).toEqual({
|
||||
body: response,
|
||||
|
@ -101,9 +89,12 @@ describe('Search service', () => {
|
|||
})
|
||||
);
|
||||
|
||||
mockDataStart.search.search.mockReturnValue(rejectedValue);
|
||||
const mockContext = {
|
||||
search: {
|
||||
search: jest.fn().mockReturnValue(rejectedValue),
|
||||
},
|
||||
};
|
||||
|
||||
const mockContext = {};
|
||||
const mockBody = { id: undefined, params: {} };
|
||||
const mockParams = { strategy: 'foo' };
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
|
@ -112,14 +103,14 @@ describe('Search service', () => {
|
|||
});
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter(), { getStartServices, globalConfig$ });
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter());
|
||||
|
||||
const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value;
|
||||
const handler = mockRouter.post.mock.calls[0][1];
|
||||
await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse);
|
||||
|
||||
expect(mockDataStart.search.search).toBeCalled();
|
||||
expect(mockDataStart.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockContext.search.search).toBeCalled();
|
||||
expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockResponse.customError).toBeCalled();
|
||||
const error: any = mockResponse.customError.mock.calls[0][0];
|
||||
expect(error.body.message).toBe('oh no');
|
||||
|
|
|
@ -21,13 +21,9 @@ import { first } from 'rxjs/operators';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import type { IRouter } from 'src/core/server';
|
||||
import { getRequestAbortedSignal } from '../../lib';
|
||||
import type { SearchRouteDependencies } from '../search_service';
|
||||
import { shimHitsTotal } from './shim_hits_total';
|
||||
|
||||
export function registerSearchRoute(
|
||||
router: IRouter,
|
||||
{ getStartServices }: SearchRouteDependencies
|
||||
): void {
|
||||
export function registerSearchRoute(router: IRouter): void {
|
||||
router.post(
|
||||
{
|
||||
path: '/internal/search/{strategy}/{id?}',
|
||||
|
@ -47,17 +43,14 @@ export function registerSearchRoute(
|
|||
const { strategy, id } = request.params;
|
||||
const abortSignal = getRequestAbortedSignal(request.events.aborted$);
|
||||
|
||||
const [, , selfStart] = await getStartServices();
|
||||
|
||||
try {
|
||||
const response = await selfStart.search
|
||||
.search(
|
||||
const response = await context
|
||||
.search!.search(
|
||||
{ ...searchRequest, id },
|
||||
{
|
||||
abortSignal,
|
||||
strategy,
|
||||
},
|
||||
context
|
||||
}
|
||||
)
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
@ -99,12 +92,8 @@ export function registerSearchRoute(
|
|||
async (context, request, res) => {
|
||||
const { strategy, id } = request.params;
|
||||
|
||||
const [, , selfStart] = await getStartServices();
|
||||
const searchStrategy = selfStart.search.getSearchStrategy(strategy);
|
||||
if (!searchStrategy.cancel) return res.ok();
|
||||
|
||||
try {
|
||||
await searchStrategy.cancel(context, id);
|
||||
await context.search!.cancel(id, { strategy });
|
||||
return res.ok();
|
||||
} catch (err) {
|
||||
return res.customError({
|
||||
|
|
|
@ -26,12 +26,17 @@ import {
|
|||
Logger,
|
||||
Plugin,
|
||||
PluginInitializerContext,
|
||||
RequestHandlerContext,
|
||||
SharedGlobalConfig,
|
||||
StartServicesAccessor,
|
||||
} from 'src/core/server';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ISearchSetup, ISearchStart, ISearchStrategy, SearchEnhancements } from './types';
|
||||
import {
|
||||
ISearchSetup,
|
||||
ISearchStart,
|
||||
ISearchStrategy,
|
||||
SearchEnhancements,
|
||||
SearchStrategyDependencies,
|
||||
} from './types';
|
||||
|
||||
import { AggsService, AggsSetupDependencies } from './aggs';
|
||||
|
||||
|
@ -53,6 +58,7 @@ import {
|
|||
SearchSourceService,
|
||||
searchSourceRequiredUiSettings,
|
||||
ISearchOptions,
|
||||
ISearchClient,
|
||||
} from '../../common/search';
|
||||
import {
|
||||
getShardDelayBucketAgg,
|
||||
|
@ -61,6 +67,12 @@ import {
|
|||
import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn';
|
||||
import { ConfigSchema } from '../../config';
|
||||
|
||||
declare module 'src/core/server' {
|
||||
interface RequestHandlerContext {
|
||||
search?: ISearchClient;
|
||||
}
|
||||
}
|
||||
|
||||
type StrategyMap = Record<string, ISearchStrategy<any, any>>;
|
||||
|
||||
/** @internal */
|
||||
|
@ -103,9 +115,14 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
getStartServices: core.getStartServices,
|
||||
globalConfig$: this.initializerContext.config.legacy.globalConfig$,
|
||||
};
|
||||
registerSearchRoute(router, routeDependencies);
|
||||
registerSearchRoute(router);
|
||||
registerMsearchRoute(router, routeDependencies);
|
||||
|
||||
core.http.registerRouteHandlerContext('search', async (context, request) => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
return this.asScopedProvider(coreStart)(request);
|
||||
});
|
||||
|
||||
this.registerSearchStrategy(
|
||||
ES_SEARCH_STRATEGY,
|
||||
esSearchStrategyProvider(
|
||||
|
@ -144,14 +161,17 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
usage,
|
||||
};
|
||||
}
|
||||
|
||||
public start(
|
||||
{ elasticsearch, savedObjects, uiSettings }: CoreStart,
|
||||
core: CoreStart,
|
||||
{ fieldFormats, indexPatterns }: SearchServiceStartDependencies
|
||||
): ISearchStart {
|
||||
const { elasticsearch, savedObjects, uiSettings } = core;
|
||||
const asScoped = this.asScopedProvider(core);
|
||||
return {
|
||||
aggs: this.aggsService.start({ fieldFormats, uiSettings, indexPatterns }),
|
||||
getSearchStrategy: this.getSearchStrategy,
|
||||
search: this.search.bind(this),
|
||||
asScoped,
|
||||
searchSource: {
|
||||
asScoped: async (request: KibanaRequest) => {
|
||||
const esClient = elasticsearch.client.asScoped(request);
|
||||
|
@ -169,39 +189,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
|
||||
const searchSourceDependencies: SearchSourceDependencies = {
|
||||
getConfig: <T = any>(key: string): T => uiSettingsCache[key],
|
||||
search: <
|
||||
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
|
||||
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse
|
||||
>(
|
||||
searchStrategyRequest: SearchStrategyRequest,
|
||||
options: ISearchOptions
|
||||
) => {
|
||||
/**
|
||||
* Unless we want all SearchSource users to provide both a KibanaRequest
|
||||
* (needed for index patterns) AND the RequestHandlerContext (needed for
|
||||
* low-level search), we need to fake the context as it can be derived
|
||||
* from the request object anyway. This will pose problems for folks who
|
||||
* are registering custom search strategies as they are only getting a
|
||||
* subset of the entire context. Ideally low-level search should be
|
||||
* refactored to only require the needed dependencies: esClient & uiSettings.
|
||||
*/
|
||||
const fakeRequestHandlerContext = {
|
||||
core: {
|
||||
elasticsearch: {
|
||||
client: esClient,
|
||||
},
|
||||
uiSettings: {
|
||||
client: uiSettingsClient,
|
||||
},
|
||||
},
|
||||
} as RequestHandlerContext;
|
||||
|
||||
return this.search<SearchStrategyRequest, SearchStrategyResponse>(
|
||||
searchStrategyRequest,
|
||||
options,
|
||||
fakeRequestHandlerContext
|
||||
).toPromise();
|
||||
},
|
||||
search: asScoped(request).search,
|
||||
// onResponse isn't used on the server, so we just return the original value
|
||||
onResponse: (req, res) => res,
|
||||
legacy: {
|
||||
|
@ -241,20 +229,26 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
>(
|
||||
searchRequest: SearchStrategyRequest,
|
||||
options: ISearchOptions,
|
||||
context: RequestHandlerContext
|
||||
deps: SearchStrategyDependencies
|
||||
) => {
|
||||
const strategy = this.getSearchStrategy<SearchStrategyRequest, SearchStrategyResponse>(
|
||||
options.strategy || this.defaultSearchStrategyName
|
||||
options.strategy
|
||||
);
|
||||
|
||||
return strategy.search(searchRequest, options, context);
|
||||
return strategy.search(searchRequest, options, deps);
|
||||
};
|
||||
|
||||
private cancel = (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => {
|
||||
const strategy = this.getSearchStrategy(options.strategy);
|
||||
|
||||
return strategy.cancel ? strategy.cancel(id, options, deps) : Promise.resolve();
|
||||
};
|
||||
|
||||
private getSearchStrategy = <
|
||||
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
|
||||
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse
|
||||
>(
|
||||
name: string
|
||||
name: string = this.defaultSearchStrategyName
|
||||
): ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> => {
|
||||
this.logger.debug(`Get strategy ${name}`);
|
||||
const strategy = this.searchStrategies[name];
|
||||
|
@ -263,4 +257,19 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
}
|
||||
return strategy;
|
||||
};
|
||||
|
||||
private asScopedProvider = ({ elasticsearch, savedObjects, uiSettings }: CoreStart) => {
|
||||
return (request: KibanaRequest): ISearchClient => {
|
||||
const savedObjectsClient = savedObjects.getScopedClient(request);
|
||||
const deps = {
|
||||
savedObjectsClient,
|
||||
esClient: elasticsearch.client.asScoped(request),
|
||||
uiSettingsClient: uiSettings.asScopedToClient(savedObjectsClient),
|
||||
};
|
||||
return {
|
||||
search: (searchRequest, options = {}) => this.search(searchRequest, options, deps),
|
||||
cancel: (id, options = {}) => this.cancel(id, options, deps),
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,12 +18,18 @@
|
|||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { KibanaRequest, RequestHandlerContext } from 'src/core/server';
|
||||
import {
|
||||
IScopedClusterClient,
|
||||
IUiSettingsClient,
|
||||
SavedObjectsClientContract,
|
||||
KibanaRequest,
|
||||
} from 'src/core/server';
|
||||
import {
|
||||
ISearchOptions,
|
||||
ISearchStartSearchSource,
|
||||
IKibanaSearchRequest,
|
||||
IKibanaSearchResponse,
|
||||
ISearchClient,
|
||||
} from '../../common/search';
|
||||
import { AggsSetup, AggsStart } from './aggs';
|
||||
import { SearchUsage } from './collectors';
|
||||
|
@ -33,6 +39,12 @@ export interface SearchEnhancements {
|
|||
defaultStrategy: string;
|
||||
}
|
||||
|
||||
export interface SearchStrategyDependencies {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
esClient: IScopedClusterClient;
|
||||
uiSettingsClient: IUiSettingsClient;
|
||||
}
|
||||
|
||||
export interface ISearchSetup {
|
||||
aggs: AggsSetup;
|
||||
/**
|
||||
|
@ -69,9 +81,9 @@ export interface ISearchStrategy<
|
|||
search: (
|
||||
request: SearchStrategyRequest,
|
||||
options: ISearchOptions,
|
||||
context: RequestHandlerContext
|
||||
deps: SearchStrategyDependencies
|
||||
) => Observable<SearchStrategyResponse>;
|
||||
cancel?: (context: RequestHandlerContext, id: string) => Promise<void>;
|
||||
cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface ISearchStart<
|
||||
|
@ -80,13 +92,14 @@ export interface ISearchStart<
|
|||
> {
|
||||
aggs: AggsStart;
|
||||
/**
|
||||
* Get other registered search strategies. For example, if a new strategy needs to use the
|
||||
* already-registered ES search strategy, it can use this function to accomplish that.
|
||||
* Get other registered search strategies by name (or, by default, the Elasticsearch strategy).
|
||||
* For example, if a new strategy needs to use the already-registered ES search strategy, it can
|
||||
* use this function to accomplish that.
|
||||
*/
|
||||
getSearchStrategy: (
|
||||
name: string
|
||||
name?: string // Name of the search strategy (defaults to the Elasticsearch strategy)
|
||||
) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>;
|
||||
search: ISearchStrategy['search'];
|
||||
asScoped: (request: KibanaRequest) => ISearchClient;
|
||||
searchSource: {
|
||||
asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;
|
||||
};
|
||||
|
|
|
@ -22,8 +22,10 @@ import { ErrorToastOptions } from 'src/core/public/notifications';
|
|||
import { ExpressionAstFunction } from 'src/plugins/expressions/common';
|
||||
import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
|
||||
import { ISavedObjectsRepository } from 'kibana/server';
|
||||
import { IScopedClusterClient } from 'src/core/server';
|
||||
import { ISearchOptions as ISearchOptions_2 } from 'src/plugins/data/public';
|
||||
import { ISearchSource } from 'src/plugins/data/public';
|
||||
import { IUiSettingsClient } from 'src/core/server';
|
||||
import { KibanaRequest } from 'src/core/server';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { Logger } from 'kibana/server';
|
||||
|
@ -41,7 +43,6 @@ import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core
|
|||
import { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import { RecursiveReadonly } from '@kbn/utility-types';
|
||||
import { RequestAdapter } from 'src/plugins/inspector/common';
|
||||
import { RequestHandlerContext } from 'src/core/server';
|
||||
import { RequestStatistics } from 'src/plugins/inspector/common';
|
||||
import { SavedObject } from 'src/core/server';
|
||||
import { SavedObjectsClientContract } from 'src/core/server';
|
||||
|
@ -364,7 +365,7 @@ export type Filter = {
|
|||
// Warning: (ae-missing-release-tag) "getDefaultSearchParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise<{
|
||||
export function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient_2): Promise<{
|
||||
maxConcurrentShardRequests: number | undefined;
|
||||
ignoreUnavailable: boolean;
|
||||
trackTotalHits: boolean;
|
||||
|
@ -723,9 +724,11 @@ export interface ISearchStart<SearchStrategyRequest extends IKibanaSearchRequest
|
|||
//
|
||||
// (undocumented)
|
||||
aggs: AggsStart;
|
||||
getSearchStrategy: (name: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>;
|
||||
// Warning: (ae-forgotten-export) The symbol "ISearchClient" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
search: ISearchStrategy['search'];
|
||||
asScoped: (request: KibanaRequest) => ISearchClient;
|
||||
getSearchStrategy: (name?: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>;
|
||||
// (undocumented)
|
||||
searchSource: {
|
||||
asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;
|
||||
|
@ -737,9 +740,9 @@ export interface ISearchStart<SearchStrategyRequest extends IKibanaSearchRequest
|
|||
// @public
|
||||
export interface ISearchStrategy<SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse> {
|
||||
// (undocumented)
|
||||
cancel?: (context: RequestHandlerContext, id: string) => Promise<void>;
|
||||
cancel?: (id: string, options: ISearchOptions, deps: SearchStrategyDependencies) => Promise<void>;
|
||||
// (undocumented)
|
||||
search: (request: SearchStrategyRequest, options: ISearchOptions, context: RequestHandlerContext) => Observable<SearchStrategyResponse>;
|
||||
search: (request: SearchStrategyRequest, options: ISearchOptions, deps: SearchStrategyDependencies) => Observable<SearchStrategyResponse>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
|
@ -888,10 +891,10 @@ export class Plugin implements Plugin_2<PluginSetup, PluginStart, DataPluginSetu
|
|||
// (undocumented)
|
||||
start(core: CoreStart): {
|
||||
fieldFormats: {
|
||||
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
};
|
||||
|
@ -960,7 +963,7 @@ export const search: {
|
|||
utils: {
|
||||
doSearch: <SearchResponse = any>(searchMethod: () => Promise<SearchResponse>, abortSignal?: AbortSignal | undefined) => import("rxjs").Observable<SearchResponse>;
|
||||
shimAbortSignal: <T extends import("../common").TransportRequestPromise<unknown>>(promise: T, signal: AbortSignal | undefined) => T;
|
||||
trackSearchStatus: <KibanaResponse extends import("../common").IKibanaSearchResponse<any> = import("./search").IEsSearchResponse<import("../../../core/server").SearchResponse<unknown>>>(logger: import("@kbn/logging/target/logger").Logger, usage?: import("./search").SearchUsage | undefined) => import("rxjs").UnaryFunction<import("rxjs").Observable<KibanaResponse>, import("rxjs").Observable<KibanaResponse>>;
|
||||
trackSearchStatus: <KibanaResponse extends import("../common").IKibanaSearchResponse<any> = import("./search").IEsSearchResponse<import("src/core/server").SearchResponse<unknown>>>(logger: import("src/core/server").Logger, usage?: import("./search").SearchUsage | undefined) => import("rxjs").UnaryFunction<import("rxjs").Observable<KibanaResponse>, import("rxjs").Observable<KibanaResponse>>;
|
||||
includeTotalLoaded: () => import("rxjs").OperatorFunction<import("../common").IKibanaSearchResponse<import("elasticsearch").SearchResponse<unknown>>, {
|
||||
total: number;
|
||||
loaded: number;
|
||||
|
@ -1007,6 +1010,18 @@ export const search: {
|
|||
tabifyGetColumns: typeof tabifyGetColumns;
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "SearchStrategyDependencies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export interface SearchStrategyDependencies {
|
||||
// (undocumented)
|
||||
esClient: IScopedClusterClient;
|
||||
// (undocumented)
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
// (undocumented)
|
||||
uiSettingsClient: IUiSettingsClient;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "SearchUsage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
@ -1147,24 +1162,24 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
|
|||
// src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:249:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:250:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:254:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:255:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:264:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:265:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:270:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:275:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:278:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:235:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:235:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:235:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:235:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:250:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:251:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:255:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:256:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:265:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:267:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:272:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:276:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:279:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index_patterns/index_patterns_service.ts:50:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/plugin.ts:88:66 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/search/types.ts:91:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/search/types.ts:104:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import { IRouter, CoreSetup } from 'kibana/server';
|
||||
import { TimelionPluginStartDeps } from '../plugin';
|
||||
|
||||
export function validateEsRoute(router: IRouter, core: CoreSetup) {
|
||||
router.get(
|
||||
|
@ -29,7 +28,6 @@ export function validateEsRoute(router: IRouter, core: CoreSetup) {
|
|||
},
|
||||
async function (context, request, response) {
|
||||
const uiSettings = await context.core.uiSettings.client.getAll();
|
||||
const deps = (await core.getStartServices())[1] as TimelionPluginStartDeps;
|
||||
|
||||
const timefield = uiSettings['timelion:es.timefield'];
|
||||
|
||||
|
@ -56,7 +54,7 @@ export function validateEsRoute(router: IRouter, core: CoreSetup) {
|
|||
|
||||
let resp;
|
||||
try {
|
||||
resp = (await deps.data.search.search(body, {}, context).toPromise()).rawResponse;
|
||||
resp = (await context.search!.search(body, {}).toPromise()).rawResponse;
|
||||
} catch (errResp) {
|
||||
resp = errResp;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { from } from 'rxjs';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import es from './index';
|
||||
import tlConfigFn from '../fixtures/tl_config';
|
||||
import * as aggResponse from './lib/agg_response_to_series_list';
|
||||
|
@ -32,21 +32,10 @@ import { UI_SETTINGS } from '../../../../data/server';
|
|||
|
||||
describe('es', () => {
|
||||
let tlConfig;
|
||||
let dataSearchStub;
|
||||
let mockResponse;
|
||||
|
||||
beforeEach(() => {
|
||||
dataSearchStub = {
|
||||
data: {
|
||||
search: { search: jest.fn(() => from(Promise.resolve(mockResponse))) },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
function stubRequestAndServer(response, indexPatternSavedObjects = []) {
|
||||
mockResponse = response;
|
||||
return {
|
||||
getStartServices: sinon.stub().returns(Promise.resolve([{}, dataSearchStub])),
|
||||
context: { search: { search: jest.fn().mockReturnValue(of(response)) } },
|
||||
savedObjectsClient: {
|
||||
find: function () {
|
||||
return Promise.resolve({
|
||||
|
@ -83,7 +72,7 @@ describe('es', () => {
|
|||
|
||||
await invoke(es, [5], tlConfig);
|
||||
|
||||
expect(dataSearchStub.data.search.search.mock.calls[0][1]).toHaveProperty('sessionId', 1);
|
||||
expect(tlConfig.context.search.search.mock.calls[0][1]).toHaveProperty('sessionId', 1);
|
||||
});
|
||||
|
||||
test('returns a seriesList', () => {
|
||||
|
|
|
@ -128,9 +128,8 @@ export default new Datasource('es', {
|
|||
const esShardTimeout = tlConfig.esShardTimeout;
|
||||
|
||||
const body = buildRequest(config, tlConfig, scriptedFields, esShardTimeout);
|
||||
const deps = (await tlConfig.getStartServices())[1];
|
||||
|
||||
const resp = await deps.data.search
|
||||
const resp = await tlConfig.context.search
|
||||
.search(
|
||||
body,
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import sinon from 'sinon';
|
||||
import { of } from 'rxjs';
|
||||
import timelionDefaults from '../../lib/get_namespaced_settings';
|
||||
import esResponse from './es_response';
|
||||
|
||||
|
@ -30,14 +30,6 @@ export default function () {
|
|||
if (!functions[name]) throw new Error('No such function: ' + name);
|
||||
return functions[name];
|
||||
},
|
||||
getStartServices: sinon
|
||||
.stub()
|
||||
.returns(
|
||||
Promise.resolve([
|
||||
{},
|
||||
{ data: { search: { search: () => Promise.resolve({ rawResponse: esResponse }) } } },
|
||||
])
|
||||
),
|
||||
|
||||
esShardTimeout: moment.duration(30000),
|
||||
allowedGraphiteUrls: ['https://www.hostedgraphite.com/UID/ACCESS_KEY/graphite'],
|
||||
|
@ -54,5 +46,9 @@ export default function () {
|
|||
|
||||
tlConfig.setTargetSeries();
|
||||
|
||||
tlConfig.context = {
|
||||
search: { search: () => of({ rawResponse: esResponse }) },
|
||||
};
|
||||
|
||||
return tlConfig;
|
||||
}
|
||||
|
|
|
@ -60,22 +60,8 @@ describe('AbstractSearchStrategy', () => {
|
|||
|
||||
const responses = await abstractSearchStrategy.search(
|
||||
{
|
||||
requestContext: {},
|
||||
framework: {
|
||||
core: {
|
||||
getStartServices: jest.fn().mockReturnValue(
|
||||
Promise.resolve([
|
||||
{},
|
||||
{
|
||||
data: {
|
||||
search: {
|
||||
search: searchFn,
|
||||
},
|
||||
},
|
||||
},
|
||||
])
|
||||
),
|
||||
},
|
||||
requestContext: {
|
||||
search: { search: searchFn },
|
||||
},
|
||||
},
|
||||
searches
|
||||
|
@ -90,7 +76,6 @@ describe('AbstractSearchStrategy', () => {
|
|||
},
|
||||
indexType: undefined,
|
||||
},
|
||||
{},
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -54,12 +54,11 @@ export class AbstractSearchStrategy {
|
|||
}
|
||||
|
||||
async search(req: ReqFacade, bodies: any[], options = {}) {
|
||||
const [, deps] = await req.framework.core.getStartServices();
|
||||
const requests: any[] = [];
|
||||
bodies.forEach((body) => {
|
||||
requests.push(
|
||||
deps.data.search
|
||||
.search(
|
||||
req.requestContext
|
||||
.search!.search(
|
||||
{
|
||||
params: {
|
||||
...body,
|
||||
|
@ -69,8 +68,7 @@ export class AbstractSearchStrategy {
|
|||
},
|
||||
{
|
||||
...options,
|
||||
},
|
||||
req.requestContext
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
|
|
|
@ -71,7 +71,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor {
|
|||
timeout: this.searchTimeout,
|
||||
});
|
||||
const abortedPromise = toPromise(combinedSignal);
|
||||
const strategy = options?.strategy || ENHANCED_ES_SEARCH_STRATEGY;
|
||||
const strategy = options?.strategy ?? ENHANCED_ES_SEARCH_STRATEGY;
|
||||
|
||||
this.pendingCount$.next(this.pendingCount$.getValue() + 1);
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import type { RequestHandlerContext, Logger } from 'kibana/server';
|
||||
|
||||
import type { Logger } from 'kibana/server';
|
||||
import { EqlSearchStrategyRequest } from '../../common/search/types';
|
||||
import { eqlSearchStrategyProvider } from './eql_search_strategy';
|
||||
import { SearchStrategyDependencies } from '../../../../../src/plugins/data/server';
|
||||
|
||||
const getMockEqlResponse = () => ({
|
||||
body: {
|
||||
|
@ -46,32 +46,26 @@ describe('EQL search strategy', () => {
|
|||
describe('search()', () => {
|
||||
let mockEqlSearch: jest.Mock;
|
||||
let mockEqlGet: jest.Mock;
|
||||
let mockContext: RequestHandlerContext;
|
||||
let mockDeps: SearchStrategyDependencies;
|
||||
let params: Required<EqlSearchStrategyRequest>['params'];
|
||||
let options: Required<EqlSearchStrategyRequest>['options'];
|
||||
|
||||
beforeEach(() => {
|
||||
mockEqlSearch = jest.fn().mockResolvedValueOnce(getMockEqlResponse());
|
||||
mockEqlGet = jest.fn().mockResolvedValueOnce(getMockEqlResponse());
|
||||
mockContext = ({
|
||||
core: {
|
||||
uiSettings: {
|
||||
client: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
},
|
||||
elasticsearch: {
|
||||
client: {
|
||||
asCurrentUser: {
|
||||
eql: {
|
||||
get: mockEqlGet,
|
||||
search: mockEqlSearch,
|
||||
},
|
||||
},
|
||||
mockDeps = ({
|
||||
uiSettingsClient: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
esClient: {
|
||||
asCurrentUser: {
|
||||
eql: {
|
||||
get: mockEqlGet,
|
||||
search: mockEqlSearch,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown) as RequestHandlerContext;
|
||||
} as unknown) as SearchStrategyDependencies;
|
||||
params = {
|
||||
index: 'logstash-*',
|
||||
body: { query: 'process where 1 == 1' },
|
||||
|
@ -82,7 +76,7 @@ describe('EQL search strategy', () => {
|
|||
describe('async functionality', () => {
|
||||
it('performs an eql client search with params when no ID is provided', async () => {
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
await eqlSearch.search({ options, params }, {}, mockContext).toPromise();
|
||||
await eqlSearch.search({ options, params }, {}, mockDeps).toPromise();
|
||||
const [[request, requestOptions]] = mockEqlSearch.mock.calls;
|
||||
|
||||
expect(request.index).toEqual('logstash-*');
|
||||
|
@ -92,7 +86,7 @@ describe('EQL search strategy', () => {
|
|||
|
||||
it('retrieves the current request if an id is provided', async () => {
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
await eqlSearch.search({ id: 'my-search-id' }, {}, mockContext).toPromise();
|
||||
await eqlSearch.search({ id: 'my-search-id' }, {}, mockDeps).toPromise();
|
||||
const [[requestParams]] = mockEqlGet.mock.calls;
|
||||
|
||||
expect(mockEqlSearch).not.toHaveBeenCalled();
|
||||
|
@ -103,7 +97,7 @@ describe('EQL search strategy', () => {
|
|||
expect.assertions(1);
|
||||
mockEqlSearch.mockReset().mockRejectedValueOnce(new Error('client error'));
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
eqlSearch.search({ options, params }, {}, mockContext).subscribe(
|
||||
eqlSearch.search({ options, params }, {}, mockDeps).subscribe(
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err).toEqual(new Error('client error'));
|
||||
|
@ -115,7 +109,7 @@ describe('EQL search strategy', () => {
|
|||
describe('arguments', () => {
|
||||
it('sends along async search options', async () => {
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
await eqlSearch.search({ options, params }, {}, mockContext).toPromise();
|
||||
await eqlSearch.search({ options, params }, {}, mockDeps).toPromise();
|
||||
const [[request]] = mockEqlSearch.mock.calls;
|
||||
|
||||
expect(request).toEqual(
|
||||
|
@ -128,7 +122,7 @@ describe('EQL search strategy', () => {
|
|||
|
||||
it('sends along default search parameters', async () => {
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
await eqlSearch.search({ options, params }, {}, mockContext).toPromise();
|
||||
await eqlSearch.search({ options, params }, {}, mockDeps).toPromise();
|
||||
const [[request]] = mockEqlSearch.mock.calls;
|
||||
|
||||
expect(request).toEqual(
|
||||
|
@ -152,7 +146,7 @@ describe('EQL search strategy', () => {
|
|||
},
|
||||
},
|
||||
{},
|
||||
mockContext
|
||||
mockDeps
|
||||
)
|
||||
.toPromise();
|
||||
const [[request]] = mockEqlSearch.mock.calls;
|
||||
|
@ -175,7 +169,7 @@ describe('EQL search strategy', () => {
|
|||
params,
|
||||
},
|
||||
{},
|
||||
mockContext
|
||||
mockDeps
|
||||
)
|
||||
.toPromise();
|
||||
const [[, requestOptions]] = mockEqlSearch.mock.calls;
|
||||
|
@ -191,7 +185,7 @@ describe('EQL search strategy', () => {
|
|||
it('passes transport options for an existing request', async () => {
|
||||
const eqlSearch = await eqlSearchStrategyProvider(mockLogger);
|
||||
await eqlSearch
|
||||
.search({ id: 'my-search-id', options: { ignore: [400] } }, {}, mockContext)
|
||||
.search({ id: 'my-search-id', options: { ignore: [400] } }, {}, mockDeps)
|
||||
.toPromise();
|
||||
const [[, requestOptions]] = mockEqlGet.mock.calls;
|
||||
|
||||
|
|
|
@ -21,25 +21,25 @@ export const eqlSearchStrategyProvider = (
|
|||
logger: Logger
|
||||
): ISearchStrategy<EqlSearchStrategyRequest, EqlSearchStrategyResponse> => {
|
||||
return {
|
||||
cancel: async (context, id) => {
|
||||
cancel: async (id, options, { esClient }) => {
|
||||
logger.debug(`_eql/delete ${id}`);
|
||||
await context.core.elasticsearch.client.asCurrentUser.eql.delete({
|
||||
await esClient.asCurrentUser.eql.delete({
|
||||
id,
|
||||
});
|
||||
},
|
||||
|
||||
search: (request, options, context) => {
|
||||
search: (request, options, { esClient, uiSettingsClient }) => {
|
||||
logger.debug(`_eql/search ${JSON.stringify(request.params) || request.id}`);
|
||||
|
||||
const { utils } = search.esSearch;
|
||||
const asyncOptions = getAsyncOptions();
|
||||
const requestOptions = utils.toSnakeCase({ ...request.options });
|
||||
const client = context.core.elasticsearch.client.asCurrentUser.eql;
|
||||
const client = esClient.asCurrentUser.eql;
|
||||
|
||||
return doPartialSearch<ApiResponse<IEsRawSearchResponse>>(
|
||||
async () => {
|
||||
const { ignoreThrottled, ignoreUnavailable } = await getDefaultSearchParams(
|
||||
context.core.uiSettings.client
|
||||
uiSettingsClient
|
||||
);
|
||||
|
||||
return client.search(
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { RequestHandlerContext } from '../../../../../src/core/server';
|
||||
import { enhancedEsSearchStrategyProvider } from './es_search_strategy';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { SearchStrategyDependencies } from '../../../../../src/plugins/data/server/search';
|
||||
|
||||
const mockAsyncResponse = {
|
||||
body: {
|
||||
|
@ -40,26 +40,20 @@ describe('ES search strategy', () => {
|
|||
const mockLogger: any = {
|
||||
debug: () => {},
|
||||
};
|
||||
const mockContext = {
|
||||
core: {
|
||||
uiSettings: {
|
||||
client: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
},
|
||||
elasticsearch: {
|
||||
client: {
|
||||
asCurrentUser: {
|
||||
asyncSearch: {
|
||||
get: mockGetCaller,
|
||||
submit: mockSubmitCaller,
|
||||
},
|
||||
transport: { request: mockApiCaller },
|
||||
},
|
||||
const mockDeps = ({
|
||||
uiSettingsClient: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
esClient: {
|
||||
asCurrentUser: {
|
||||
asyncSearch: {
|
||||
get: mockGetCaller,
|
||||
submit: mockSubmitCaller,
|
||||
},
|
||||
transport: { request: mockApiCaller },
|
||||
},
|
||||
},
|
||||
};
|
||||
} as unknown) as SearchStrategyDependencies;
|
||||
const mockConfig$ = new BehaviorSubject<any>({
|
||||
elasticsearch: {
|
||||
shardTimeout: {
|
||||
|
@ -86,9 +80,7 @@ describe('ES search strategy', () => {
|
|||
const params = { index: 'logstash-*', body: { query: {} } };
|
||||
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
|
||||
|
||||
await esSearch
|
||||
.search({ params }, {}, (mockContext as unknown) as RequestHandlerContext)
|
||||
.toPromise();
|
||||
await esSearch.search({ params }, {}, mockDeps).toPromise();
|
||||
|
||||
expect(mockSubmitCaller).toBeCalled();
|
||||
const request = mockSubmitCaller.mock.calls[0][0];
|
||||
|
@ -102,9 +94,7 @@ describe('ES search strategy', () => {
|
|||
const params = { index: 'logstash-*', body: { query: {} } };
|
||||
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
|
||||
|
||||
await esSearch
|
||||
.search({ id: 'foo', params }, {}, (mockContext as unknown) as RequestHandlerContext)
|
||||
.toPromise();
|
||||
await esSearch.search({ id: 'foo', params }, {}, mockDeps).toPromise();
|
||||
|
||||
expect(mockGetCaller).toBeCalled();
|
||||
const request = mockGetCaller.mock.calls[0][0];
|
||||
|
@ -126,7 +116,7 @@ describe('ES search strategy', () => {
|
|||
params,
|
||||
},
|
||||
{},
|
||||
(mockContext as unknown) as RequestHandlerContext
|
||||
mockDeps
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
|
@ -142,9 +132,7 @@ describe('ES search strategy', () => {
|
|||
const params = { index: 'foo-*', body: {} };
|
||||
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
|
||||
|
||||
await esSearch
|
||||
.search({ params }, {}, (mockContext as unknown) as RequestHandlerContext)
|
||||
.toPromise();
|
||||
await esSearch.search({ params }, {}, mockDeps).toPromise();
|
||||
|
||||
expect(mockSubmitCaller).toBeCalled();
|
||||
const request = mockSubmitCaller.mock.calls[0][0];
|
||||
|
|
|
@ -11,15 +11,16 @@ import { Observable } from 'rxjs';
|
|||
import type { SearchResponse } from 'elasticsearch';
|
||||
import type { ApiResponse } from '@elastic/elasticsearch';
|
||||
|
||||
import { getShardTimeout, shimHitsTotal, search } from '../../../../../src/plugins/data/server';
|
||||
import {
|
||||
getShardTimeout,
|
||||
shimHitsTotal,
|
||||
search,
|
||||
SearchStrategyDependencies,
|
||||
} from '../../../../../src/plugins/data/server';
|
||||
import { doPartialSearch } from '../../common/search/es_search/es_search_rxjs_utils';
|
||||
import { getDefaultSearchParams, getAsyncOptions } from './get_default_search_params';
|
||||
|
||||
import type {
|
||||
SharedGlobalConfig,
|
||||
RequestHandlerContext,
|
||||
Logger,
|
||||
} from '../../../../../src/core/server';
|
||||
import type { SharedGlobalConfig, Logger } from '../../../../../src/core/server';
|
||||
|
||||
import type {
|
||||
ISearchStrategy,
|
||||
|
@ -41,20 +42,20 @@ export const enhancedEsSearchStrategyProvider = (
|
|||
config$: Observable<SharedGlobalConfig>,
|
||||
logger: Logger,
|
||||
usage?: SearchUsage
|
||||
): ISearchStrategy => {
|
||||
): ISearchStrategy<IEnhancedEsSearchRequest> => {
|
||||
function asyncSearch(
|
||||
request: IEnhancedEsSearchRequest,
|
||||
options: ISearchOptions,
|
||||
context: RequestHandlerContext
|
||||
{ esClient, uiSettingsClient }: SearchStrategyDependencies
|
||||
) {
|
||||
const asyncOptions = getAsyncOptions();
|
||||
const client = context.core.elasticsearch.client.asCurrentUser.asyncSearch;
|
||||
const client = esClient.asCurrentUser.asyncSearch;
|
||||
|
||||
return doPartialSearch<ApiResponse<IEsRawAsyncSearchResponse>>(
|
||||
async () =>
|
||||
client.submit(
|
||||
utils.toSnakeCase({
|
||||
...(await getDefaultSearchParams(context.core.uiSettings.client)),
|
||||
...(await getDefaultSearchParams(uiSettingsClient)),
|
||||
batchedReduceSize: 64,
|
||||
...asyncOptions,
|
||||
...request.params,
|
||||
|
@ -80,13 +81,11 @@ export const enhancedEsSearchStrategyProvider = (
|
|||
);
|
||||
}
|
||||
|
||||
const rollupSearch = async function (
|
||||
async function rollupSearch(
|
||||
request: IEnhancedEsSearchRequest,
|
||||
options: ISearchOptions,
|
||||
context: RequestHandlerContext
|
||||
{ esClient, uiSettingsClient }: SearchStrategyDependencies
|
||||
): Promise<IEsSearchResponse> {
|
||||
const esClient = context.core.elasticsearch.client.asCurrentUser;
|
||||
const uiSettingsClient = await context.core.uiSettings.client;
|
||||
const config = await config$.pipe(first()).toPromise();
|
||||
const { body, index, ...params } = request.params!;
|
||||
const method = 'POST';
|
||||
|
@ -97,7 +96,7 @@ export const enhancedEsSearchStrategyProvider = (
|
|||
...params,
|
||||
});
|
||||
|
||||
const promise = esClient.transport.request({
|
||||
const promise = esClient.asCurrentUser.transport.request({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
|
@ -111,26 +110,19 @@ export const enhancedEsSearchStrategyProvider = (
|
|||
rawResponse: response,
|
||||
...utils.getTotalLoaded(response._shards),
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
search: (
|
||||
request: IEnhancedEsSearchRequest,
|
||||
options: ISearchOptions,
|
||||
context: RequestHandlerContext
|
||||
) => {
|
||||
search: (request, options, deps) => {
|
||||
logger.debug(`search ${JSON.stringify(request.params) || request.id}`);
|
||||
|
||||
return request.indexType !== 'rollup'
|
||||
? asyncSearch(request, options, context)
|
||||
: from(rollupSearch(request, options, context));
|
||||
? asyncSearch(request, options, deps)
|
||||
: from(rollupSearch(request, options, deps));
|
||||
},
|
||||
cancel: async (context: RequestHandlerContext, id: string) => {
|
||||
cancel: async (id, options, { esClient }) => {
|
||||
logger.debug(`cancel ${id}`);
|
||||
|
||||
await context.core.elasticsearch.client.asCurrentUser.asyncSearch.delete({
|
||||
id,
|
||||
});
|
||||
await esClient.asCurrentUser.asyncSearch.delete({ id });
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -26,11 +26,10 @@ export const securitySolutionIndexFieldsProvider = (): ISearchStrategy<
|
|||
const beatFields: BeatFields = require('../../utils/beat_schema/fields').fieldsBeat;
|
||||
|
||||
return {
|
||||
search: (request, options, context) =>
|
||||
search: (request, options, { esClient }) =>
|
||||
from(
|
||||
new Promise<IndexFieldsStrategyResponse>(async (resolve) => {
|
||||
const { elasticsearch } = context.core;
|
||||
const indexPatternsFetcher = new IndexPatternsFetcher(elasticsearch.client.asCurrentUser);
|
||||
const indexPatternsFetcher = new IndexPatternsFetcher(esClient.asCurrentUser);
|
||||
const dedupeIndices = dedupeIndexName(request.indices);
|
||||
|
||||
const responsesIndexFields = await Promise.all(
|
||||
|
|
|
@ -20,7 +20,7 @@ export const securitySolutionSearchStrategyProvider = <T extends FactoryQueryTyp
|
|||
const es = data.search.getSearchStrategy('es');
|
||||
|
||||
return {
|
||||
search: (request, options, context) => {
|
||||
search: (request, options, deps) => {
|
||||
if (request.factoryQueryType == null) {
|
||||
throw new Error('factoryQueryType is required');
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ export const securitySolutionSearchStrategyProvider = <T extends FactoryQueryTyp
|
|||
securitySolutionFactory[request.factoryQueryType];
|
||||
const dsl = queryFactory.buildDsl(request);
|
||||
return es
|
||||
.search({ ...request, params: dsl }, options, context)
|
||||
.search({ ...request, params: dsl }, options, deps)
|
||||
.pipe(mergeMap((esSearchRes) => queryFactory.parse(request, esSearchRes)));
|
||||
},
|
||||
cancel: async (context, id) => {
|
||||
cancel: async (id, options, deps) => {
|
||||
if (es.cancel) {
|
||||
es.cancel(context, id);
|
||||
return es.cancel(id, options, deps);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ export const securitySolutionTimelineSearchStrategyProvider = <T extends Timelin
|
|||
const es = data.search.getSearchStrategy('es');
|
||||
|
||||
return {
|
||||
search: (request, options, context) => {
|
||||
search: (request, options, deps) => {
|
||||
if (request.factoryQueryType == null) {
|
||||
throw new Error('factoryQueryType is required');
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ export const securitySolutionTimelineSearchStrategyProvider = <T extends Timelin
|
|||
const dsl = queryFactory.buildDsl(request);
|
||||
|
||||
return es
|
||||
.search({ ...request, params: dsl }, options, context)
|
||||
.search({ ...request, params: dsl }, options, deps)
|
||||
.pipe(mergeMap((esSearchRes) => queryFactory.parse(request, esSearchRes)));
|
||||
},
|
||||
cancel: async (context, id) => {
|
||||
cancel: async (id, options, deps) => {
|
||||
if (es.cancel) {
|
||||
es.cancel(context, id);
|
||||
return es.cancel(id, options, deps);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue