Skip to content

Commit

Permalink
[Search] Expose data.search.asyncSearch.* in kibana.yml (#142976)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dosant authored Oct 11, 2022
1 parent 87e5713 commit 782e5de
Show file tree
Hide file tree
Showing 19 changed files with 528 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ kibana_vars=(
csp.report_to
data.autocomplete.valueSuggestions.terminateAfter
data.autocomplete.valueSuggestions.timeout
data.search.asyncSearch.waitForCompletion
data.search.asyncSearch.keepAlive
data.search.asyncSearch.batchedReduceSize
data.search.sessions.defaultExpiration
data.search.sessions.enabled
data.search.sessions.maxUpdateRetries
Expand Down
40 changes: 40 additions & 0 deletions src/plugins/data/config.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import moment from 'moment/moment';
import { SearchConfigSchema, SearchSessionsConfigSchema } from './config';

export const getMockSearchConfig = ({
sessions: { enabled = true, defaultExpiration = moment.duration(7, 'd') } = {
enabled: true,
defaultExpiration: moment.duration(7, 'd'),
},
asyncSearch: {
waitForCompletion = moment.duration(100, 'ms'),
keepAlive = moment.duration(1, 'm'),
batchedReduceSize = 64,
} = {
waitForCompletion: moment.duration(100, 'ms'),
keepAlive: moment.duration(1, 'm'),
batchedReduceSize: 64,
},
}: Partial<{
sessions: Partial<SearchSessionsConfigSchema>;
asyncSearch: Partial<SearchConfigSchema['asyncSearch']>;
}>): SearchConfigSchema =>
({
asyncSearch: {
waitForCompletion,
keepAlive,
batchedReduceSize,
} as SearchConfigSchema['asyncSearch'],
sessions: {
enabled,
defaultExpiration,
} as SearchSessionsConfigSchema,
} as SearchConfigSchema);
29 changes: 19 additions & 10 deletions src/plugins/data/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,29 @@ export const searchSessionsConfigSchema = schema.object({
}),
});

export const configSchema = schema.object({
search: schema.object({
aggs: schema.object({
shardDelay: schema.object({
// Whether or not to register the shard_delay (which is only available in snapshot versions
// of Elasticsearch) agg type/expression function to make it available in the UI for either
// functional or manual testing
enabled: schema.boolean({ defaultValue: false }),
}),
export const searchConfigSchema = schema.object({
asyncSearch: schema.object({
waitForCompletion: schema.duration({ defaultValue: '100ms' }),
keepAlive: schema.duration({ defaultValue: '1m' }),
batchedReduceSize: schema.number({ defaultValue: 64 }),
}),
aggs: schema.object({
shardDelay: schema.object({
// Whether or not to register the shard_delay (which is only available in snapshot versions
// of Elasticsearch) agg type/expression function to make it available in the UI for either
// functional or manual testing
enabled: schema.boolean({ defaultValue: false }),
}),
sessions: searchSessionsConfigSchema,
}),
sessions: searchSessionsConfigSchema,
});

export const configSchema = schema.object({
search: searchConfigSchema,
});

export type ConfigSchema = TypeOf<typeof configSchema>;

export type SearchConfigSchema = TypeOf<typeof searchConfigSchema>;

export type SearchSessionsConfigSchema = TypeOf<typeof searchSessionsConfigSchema>;
12 changes: 10 additions & 2 deletions src/plugins/data/server/search/search_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
ENHANCED_ES_SEARCH_STRATEGY,
enhancedEsSearchStrategyProvider(
this.initializerContext.config.legacy.globalConfig$,
this.initializerContext.config.get().search,
this.logger,
usage
)
Expand All @@ -189,13 +190,20 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
// for example use case
this.searchAsInternalUser = enhancedEsSearchStrategyProvider(
this.initializerContext.config.legacy.globalConfig$,
this.initializerContext.config.get().search,
this.logger,
usage,
true
);

this.registerSearchStrategy(EQL_SEARCH_STRATEGY, eqlSearchStrategyProvider(this.logger));
this.registerSearchStrategy(SQL_SEARCH_STRATEGY, sqlSearchStrategyProvider(this.logger));
this.registerSearchStrategy(
EQL_SEARCH_STRATEGY,
eqlSearchStrategyProvider(this.initializerContext.config.get().search, this.logger)
);
this.registerSearchStrategy(
SQL_SEARCH_STRATEGY,
sqlSearchStrategyProvider(this.initializerContext.config.get().search, this.logger)
);

registerBsearchRoute(
bfetch,
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/data/server/search/session/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export interface IScopedSearchSessionsClient {
expires: Date
) => Promise<SavedObjectsUpdateResponse<SearchSessionSavedObjectAttributes>>;
status: (sessionId: string) => Promise<SearchSessionStatusResponse>;
getConfig: () => SearchSessionsConfigSchema | null;
getConfig: () => SearchSessionsConfigSchema;
}

export interface ISearchSessionService {
Expand Down
181 changes: 125 additions & 56 deletions src/plugins/data/server/search/strategies/common/async_utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,39 @@
* Side Public License, v 1.
*/

import { getCommonDefaultAsyncSubmitParams, getCommonDefaultAsyncGetParams } from './async_utils';
import { getCommonDefaultAsyncGetParams, getCommonDefaultAsyncSubmitParams } from './async_utils';
import moment from 'moment';
import { SearchSessionsConfigSchema } from '../../../../config';

const getMockSearchSessionsConfig = ({
enabled = true,
defaultExpiration = moment.duration(7, 'd'),
} = {}) =>
({
enabled,
defaultExpiration,
} as SearchSessionsConfigSchema);
import { getMockSearchConfig } from '../../../../config.mock';

describe('request utils', () => {
describe('getCommonDefaultAsyncSubmitParams', () => {
test('Uses short `keep_alive` if no `sessionId` is provided', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
test('Uses `keep_alive` from asyncSearch config if no `sessionId` is provided', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
},
});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {});
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Uses short `keep_alive` if sessions enabled but no yet saved', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
},
});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {
sessionId: 'foo',
});
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Uses `keep_alive` from config if sessions enabled and session is saved', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
},
});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {
sessionId: 'foo',
Expand All @@ -50,29 +47,33 @@ describe('request utils', () => {
expect(params).toHaveProperty('keep_alive', '259200000ms');
});

test('Uses `keepAlive` of `1m` if disabled', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
test('Uses `keepAlive` from asyncSearch config if sessions disabled', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
},
});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {
sessionId: 'foo',
});
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Uses `keep_on_completion` if enabled', async () => {
const mockConfig = getMockSearchSessionsConfig({});
test('Uses `keep_on_completion` if sessions enabled', async () => {
const mockConfig = getMockSearchConfig({});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {
sessionId: 'foo',
});
expect(params).toHaveProperty('keep_on_completion', true);
});

test('Does not use `keep_on_completion` if disabled', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
test('Does not use `keep_on_completion` if sessions disabled', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
},
});
const params = getCommonDefaultAsyncSubmitParams(mockConfig, {
sessionId: 'foo',
Expand All @@ -83,36 +84,44 @@ describe('request utils', () => {

describe('getCommonDefaultAsyncGetParams', () => {
test('Uses `wait_for_completion_timeout`', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, {});
expect(params).toHaveProperty('wait_for_completion_timeout');
});

test('Uses `keep_alive` if `sessionId` is not provided', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, {});
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Has short `keep_alive` if `sessionId` is provided', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
test('Has `keep_alive` from asyncSearch config if `sessionId` is provided', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, { sessionId: 'foo' });
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Has `keep_alive` from config if `sessionId` is provided and session is stored', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, {
sessionId: 'foo',
Expand All @@ -122,9 +131,11 @@ describe('request utils', () => {
});

test("Don't extend keepAlive if search has already been extended", async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, {
sessionId: 'foo',
Expand All @@ -135,9 +146,11 @@ describe('request utils', () => {
});

test("Don't extend keepAlive if search is being restored", async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, {
sessionId: 'foo',
Expand All @@ -149,12 +162,68 @@ describe('request utils', () => {
});

test('Uses `keep_alive` if `sessionId` is provided but sessions disabled', async () => {
const mockConfig = getMockSearchSessionsConfig({
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: false,
},
});
const params = getCommonDefaultAsyncGetParams(mockConfig, { sessionId: 'foo' });
expect(params).toHaveProperty('keep_alive', '1m');
expect(params).toHaveProperty('keep_alive', '60000ms');
});
});

describe('overrides: force disable sessions', () => {
test('Does not use `keep_on_completion` if sessions disabled through overrides', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncSubmitParams(
mockConfig,
{
sessionId: 'foo',
},
{ disableSearchSessions: true }
);
expect(params).toHaveProperty('keep_on_completion', false);
});

test('Uses `keepAlive` from asyncSearch config if sessions disabled through overrides', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncSubmitParams(
mockConfig,
{
sessionId: 'foo',
},
{ disableSearchSessions: true }
);
expect(params).toHaveProperty('keep_alive', '60000ms');
});

test('Uses `keep_alive` from asyncSearch config if sessions disabled through overrides and session is saved', async () => {
const mockConfig = getMockSearchConfig({
sessions: {
defaultExpiration: moment.duration(3, 'd'),
enabled: true,
},
});
const params = getCommonDefaultAsyncSubmitParams(
mockConfig,
{
sessionId: 'foo',
isStored: true,
},
{ disableSearchSessions: true }
);
expect(params).toHaveProperty('keep_alive', '60000ms');
});
});
});
Loading

0 comments on commit 782e5de

Please sign in to comment.