Skip to content

Commit

Permalink
Migrate kibana.autocomplete config to data plugin (#100586)
Browse files Browse the repository at this point in the history
* Migrate kibana.autocomplete config to data plugin

* Fix CI

* Fix tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
lukasolson and kibanamachine authored Jun 1, 2021
1 parent f58ddc4 commit 8edb316
Show file tree
Hide file tree
Showing 20 changed files with 134 additions and 100 deletions.
4 changes: 2 additions & 2 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ on the {kib} index at startup. {kib} users still need to authenticate with
{es} {ref}/indices-create-index.html[index name limitations].
*Default: `".kibana"`*

| `kibana.autocompleteTimeout:` {ess-icon}
| `data.autocomplete.valueSuggestions.timeout:` {ess-icon}
| Time in milliseconds to wait for autocomplete suggestions from {es}.
This value must be a whole number greater than zero. *Default: `"1000"`*

| `kibana.autocompleteTerminateAfter:` {ess-icon}
| `data.autocomplete.valueSuggestions.terminateAfter:` {ess-icon}
| Maximum number of documents loaded by each shard to generate autocomplete
suggestions. This value must be a whole number greater than zero.
*Default: `"100000"`*
Expand Down
2 changes: 0 additions & 2 deletions src/core/server/kibana_config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ it('set correct defaults ', () => {
const configValue = config.schema.validate({});
expect(configValue).toMatchInlineSnapshot(`
Object {
"autocompleteTerminateAfter": "PT1M40S",
"autocompleteTimeout": "PT1S",
"enabled": true,
"index": ".kibana",
}
Expand Down
6 changes: 0 additions & 6 deletions src/core/server/kibana_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ export const config = {
schema: schema.object({
enabled: schema.boolean({ defaultValue: true }),
index: schema.string({ defaultValue: '.kibana' }),
autocompleteTerminateAfter: schema.duration({ defaultValue: 100000 }),
autocompleteTimeout: schema.duration({ defaultValue: 1000 }),
}),
deprecations,
exposeToUsage: {
autocompleteTerminateAfter: true,
autocompleteTimeout: true,
},
};
2 changes: 0 additions & 2 deletions src/core/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ export function pluginInitializerContextConfigMock<T>(config: T) {
const globalConfig: SharedGlobalConfig = {
kibana: {
index: '.kibana-tests',
autocompleteTerminateAfter: duration(100000),
autocompleteTimeout: duration(1000),
},
elasticsearch: {
shardTimeout: duration('30s'),
Expand Down
4 changes: 0 additions & 4 deletions src/core/server/plugins/legacy_config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ describe('Legacy config', () => {
expect(legacyConfig).toStrictEqual({
kibana: {
index: '.kibana',
autocompleteTerminateAfter: duration(100000),
autocompleteTimeout: duration(1000),
},
elasticsearch: {
shardTimeout: duration(30, 's'),
Expand All @@ -66,8 +64,6 @@ describe('Legacy config', () => {
expect(legacyConfig).toStrictEqual({
kibana: {
index: '.kibana',
autocompleteTerminateAfter: duration(100000),
autocompleteTimeout: duration(1000),
},
elasticsearch: {
shardTimeout: duration(30, 's'),
Expand Down
2 changes: 0 additions & 2 deletions src/core/server/plugins/plugin_context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ describe('createPluginInitializerContext', () => {
expect(configObject).toStrictEqual({
kibana: {
index: '.kibana',
autocompleteTerminateAfter: duration(100000),
autocompleteTimeout: duration(1000),
},
elasticsearch: {
shardTimeout: duration(30, 's'),
Expand Down
2 changes: 1 addition & 1 deletion src/core/server/plugins/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ export interface AsyncPlugin<

export const SharedGlobalConfigKeys = {
// We can add more if really needed
kibana: ['index', 'autocompleteTerminateAfter', 'autocompleteTimeout'] as const,
kibana: ['index'] as const,
elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout'] as const,
path: ['data'] as const,
savedObjects: ['maxImportPayloadBytes'] as const,
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const configSchema = schema.object({
}),
valueSuggestions: schema.object({
enabled: schema.boolean({ defaultValue: true }),
terminateAfter: schema.duration({ defaultValue: 100000 }),
timeout: schema.duration({ defaultValue: 1000 }),
}),
}),
search: schema.object({
Expand Down
9 changes: 8 additions & 1 deletion src/plugins/data/public/autocomplete/autocomplete_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { CoreSetup, PluginInitializerContext } from 'src/core/public';
import moment from 'moment';
import { TimefilterSetup } from '../query';
import { QuerySuggestionGetFn } from './providers/query_suggestion_provider';
import {
Expand All @@ -27,7 +28,7 @@ import { DataPublicPluginStart, DataStartDependencies } from '../types';
export class AutocompleteService {
autocompleteConfig: ConfigSchema['autocomplete'];

constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
constructor(private initializerContext: PluginInitializerContext<ConfigSchema>) {
const { autocomplete } = initializerContext.config.get<ConfigSchema>();

this.autocompleteConfig = autocomplete;
Expand Down Expand Up @@ -55,6 +56,8 @@ export class AutocompleteService {
usageCollection,
}: { timefilter: TimefilterSetup; usageCollection?: UsageCollectionSetup }
) {
const { autocomplete } = this.initializerContext.config.get<ConfigSchema>();
const { terminateAfter, timeout } = autocomplete.valueSuggestions;
const usageCollector = createUsageCollector(core.getStartServices, usageCollection);

this.getValueSuggestions = this.autocompleteConfig.valueSuggestions.enabled
Expand All @@ -71,6 +74,10 @@ export class AutocompleteService {
* please use "getQuerySuggestions" from the start contract
*/
getQuerySuggestions: this.getQuerySuggestions,
getAutocompleteSettings: () => ({
terminateAfter: moment.duration(terminateAfter).asMilliseconds(),
timeout: moment.duration(timeout).asMilliseconds(),
}),
};
}

Expand Down
5 changes: 3 additions & 2 deletions src/plugins/data/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import { createNowProviderMock } from './now_provider/mocks';
export type Setup = jest.Mocked<ReturnType<Plugin['setup']>>;
export type Start = jest.Mocked<ReturnType<Plugin['start']>>;

const automcompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
const autocompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
getQuerySuggestions: jest.fn(),
getAutocompleteSettings: jest.fn(),
};

const autocompleteStartMock: jest.Mocked<AutocompleteStart> = {
Expand All @@ -29,7 +30,7 @@ const autocompleteStartMock: jest.Mocked<AutocompleteStart> = {
const createSetupContract = (): Setup => {
const querySetupMock = queryServiceMock.createSetupContract();
return {
autocomplete: automcompleteSetupMock,
autocomplete: autocompleteSetupMock,
search: searchServiceMock.createSetupContract(),
fieldFormats: fieldFormatsServiceMock.createSetupContract(),
query: querySetupMock,
Expand Down
8 changes: 3 additions & 5 deletions src/plugins/data/server/autocomplete/autocomplete_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@
* Side Public License, v 1.
*/

import { TypeOf } from '@kbn/config-schema';
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server';
import { registerRoutes } from './routes';
import { ConfigSchema, configSchema } from '../../config';
import { ConfigSchema } from '../../config';

export class AutocompleteService implements Plugin<void> {
private valueSuggestionsEnabled: boolean = true;

constructor(private initializerContext: PluginInitializerContext<ConfigSchema>) {
initializerContext.config.create<TypeOf<typeof configSchema>>().subscribe((configUpdate) => {
initializerContext.config.create().subscribe((configUpdate) => {
this.valueSuggestionsEnabled = configUpdate.autocomplete.valueSuggestions.enabled;
});
}

public setup(core: CoreSetup) {
if (this.valueSuggestionsEnabled)
registerRoutes(core, this.initializerContext.config.legacy.globalConfig$);
if (this.valueSuggestionsEnabled) registerRoutes(core, this.initializerContext.config.create());
}

public start() {}
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/data/server/autocomplete/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
*/

import { Observable } from 'rxjs';
import { CoreSetup, SharedGlobalConfig } from 'kibana/server';
import { CoreSetup } from 'kibana/server';
import { registerValueSuggestionsRoute } from './value_suggestions_route';
import { ConfigSchema } from '../../config';

export function registerRoutes({ http }: CoreSetup, config$: Observable<SharedGlobalConfig>): void {
export function registerRoutes({ http }: CoreSetup, config$: Observable<ConfigSchema>): void {
const router = http.createRouter();

registerValueSuggestionsRoute(router, config$);
Expand Down
12 changes: 5 additions & 7 deletions src/plugins/data/server/autocomplete/value_suggestions_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@

import { get, map } from 'lodash';
import { schema } from '@kbn/config-schema';
import { IRouter, SharedGlobalConfig } from 'kibana/server';
import { IRouter } from 'kibana/server';

import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import type { estypes } from '@elastic/elasticsearch';
import type { IFieldType } from '../index';
import { findIndexPatternById, getFieldByName } from '../index_patterns';
import { getRequestAbortedSignal } from '../lib';
import { ConfigSchema } from '../../config';

export function registerValueSuggestionsRoute(
router: IRouter,
config$: Observable<SharedGlobalConfig>
) {
export function registerValueSuggestionsRoute(router: IRouter, config$: Observable<ConfigSchema>) {
router.post(
{
path: '/api/kibana/suggestions/values/{index}',
Expand Down Expand Up @@ -50,8 +48,8 @@ export function registerValueSuggestionsRoute(
const signal = getRequestAbortedSignal(request.events.aborted$);

const autocompleteSearchOptions = {
timeout: `${config.kibana.autocompleteTimeout.asMilliseconds()}ms`,
terminate_after: config.kibana.autocompleteTerminateAfter.asMilliseconds(),
timeout: `${config.autocomplete.valueSuggestions.timeout.asMilliseconds()}ms`,
terminate_after: config.autocomplete.valueSuggestions.terminateAfter.asMilliseconds(),
};

let field: IFieldType | undefined = fieldMeta;
Expand Down
71 changes: 71 additions & 0 deletions src/plugins/data/server/config_deprecations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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 { cloneDeep } from 'lodash';

import { applyDeprecations, configDeprecationFactory } from '@kbn/config';

import { autocompleteConfigDeprecationProvider } from './config_deprecations';

const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = autocompleteConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
const migrated = applyDeprecations(
settings,
deprecations.map((deprecation) => ({
deprecation,
path: '',
})),
() => ({ message }) => deprecationMessages.push(message)
);
return {
messages: deprecationMessages,
migrated: migrated.config,
};
};

describe('Config Deprecations', () => {
it('does not report deprecations for default configuration', () => {
const defaultConfig = { data: { autocomplete: { valueSuggestions: {} } } };
const { messages, migrated } = applyConfigDeprecations(cloneDeep(defaultConfig));
expect(migrated).toEqual(defaultConfig);
expect(messages).toHaveLength(0);
});

it('renames kibana.autocompleteTerminateAfter to data.autocomplete.valueSuggestions.terminateAfter', () => {
const config = {
kibana: {
autocompleteTerminateAfter: 123,
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.kibana.autocompleteTerminateAfter).not.toBeDefined();
expect(migrated.data.autocomplete.valueSuggestions.terminateAfter).toEqual(123);
expect(messages).toMatchInlineSnapshot(`
Array [
"\\"kibana.autocompleteTerminateAfter\\" is deprecated and has been replaced by \\"data.autocomplete.valueSuggestions.terminateAfter\\"",
]
`);
});

it('renames kibana.autocompleteTimeout to data.autocomplete.valueSuggestions.timeout', () => {
const config = {
kibana: {
autocompleteTimeout: 123,
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.kibana.autocompleteTimeout).not.toBeDefined();
expect(migrated.data.autocomplete.valueSuggestions.timeout).toEqual(123);
expect(messages).toMatchInlineSnapshot(`
Array [
"\\"kibana.autocompleteTimeout\\" is deprecated and has been replaced by \\"data.autocomplete.valueSuggestions.timeout\\"",
]
`);
});
});
19 changes: 19 additions & 0 deletions src/plugins/data/server/config_deprecations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 type { ConfigDeprecationProvider } from 'src/core/server';

export const autocompleteConfigDeprecationProvider: ConfigDeprecationProvider = ({
renameFromRoot,
}) => [
renameFromRoot(
'kibana.autocompleteTerminateAfter',
'data.autocomplete.valueSuggestions.terminateAfter'
),
renameFromRoot('kibana.autocompleteTimeout', 'data.autocomplete.valueSuggestions.timeout'),
];
2 changes: 2 additions & 0 deletions src/plugins/data/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ import {
tabifyGetColumns,
calcAutoIntervalLessThan,
} from '../common';
import { autocompleteConfigDeprecationProvider } from './config_deprecations';

export {
// aggs
Expand Down Expand Up @@ -301,6 +302,7 @@ export {
};

export const config: PluginConfigDescriptor<ConfigSchema> = {
deprecations: autocompleteConfigDeprecationProvider,
exposeToBrowser: {
autocomplete: true,
search: true,
Expand Down
24 changes: 12 additions & 12 deletions src/plugins/data/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1543,18 +1543,18 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
// src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "HistogramFormat" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:128:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:128:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:243:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:243:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:245:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:246:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:255:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:256:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:257:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:261:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:262:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:269:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:270:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:244:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:244:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:246:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:247:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:256:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:257:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:258:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:262:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:263:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:267:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:270:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/plugin.ts:81:74 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/search/types.ts:115:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/input_control_vis/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "inputControlVis",
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,
"server": false,
"ui": true,
"requiredPlugins": [
"data",
Expand Down
11 changes: 2 additions & 9 deletions src/plugins/input_control_vis/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ export interface InputControlVisPluginStartDependencies {

/** @internal */
export class InputControlVisPlugin implements Plugin<void, void> {
private cachedSettings: InputControlSettings | undefined = undefined;

constructor(public initializerContext: PluginInitializerContext) {}

public setup(
Expand All @@ -56,13 +54,8 @@ export class InputControlVisPlugin implements Plugin<void, void> {
core,
data,
getSettings: async () => {
if (!this.cachedSettings) {
this.cachedSettings = await core.http.get<InputControlSettings>(
'/api/input_control_vis/settings'
);
}

return this.cachedSettings;
const { timeout, terminateAfter } = data.autocomplete.getAutocompleteSettings();
return { autocompleteTimeout: timeout, autocompleteTerminateAfter: terminateAfter };
},
};

Expand Down
Loading

0 comments on commit 8edb316

Please sign in to comment.