diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md index 4baf98038f89a7..f81d03a28ec124 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `IndexPattern` class Signature: ```typescript -constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); +constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| { spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | +| { spec, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md index 325b97383e328d..c07041470d102e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md @@ -14,7 +14,7 @@ export declare class IndexPattern implements IIndexPattern | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | +| [(constructor)({ spec, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | ## Properties @@ -53,7 +53,6 @@ export declare class IndexPattern implements IIndexPattern | [getTimeField()](./kibana-plugin-plugins-data-public.indexpattern.gettimefield.md) | | | | [isTimeBased()](./kibana-plugin-plugins-data-public.indexpattern.istimebased.md) | | | | [isTimeNanosBased()](./kibana-plugin-plugins-data-public.indexpattern.istimenanosbased.md) | | | -| [popularizeField(fieldName, unit)](./kibana-plugin-plugins-data-public.indexpattern.popularizefield.md) | | | | [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | Remove scripted field from field list | | [toSpec()](./kibana-plugin-plugins-data-public.indexpattern.tospec.md) | | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md deleted file mode 100644 index eba53821585204..00000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [popularizeField](./kibana-plugin-plugins-data-public.indexpattern.popularizefield.md) - -## IndexPattern.popularizeField() method - -Signature: - -```typescript -popularizeField(fieldName: string, unit?: number): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| fieldName | string | | -| unit | number | | - -Returns: - -`Promise` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md index af087344268d73..34df8656e91759 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md @@ -43,5 +43,5 @@ export declare class IndexPatternsService | [createAndSave(spec, override, skipFetchFields)](./kibana-plugin-plugins-data-public.indexpatternsservice.createandsave.md) | | Create a new index pattern and save it right away | | [createSavedObject(indexPattern, override)](./kibana-plugin-plugins-data-public.indexpatternsservice.createsavedobject.md) | | Save a new index pattern | | [delete(indexPatternId)](./kibana-plugin-plugins-data-public.indexpatternsservice.delete.md) | | Deletes an index pattern from .kibana index | -| [updateSavedObject(indexPattern, saveAttempts)](./kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md) | | Save existing index pattern. Will attempt to merge differences if there are conflicts | +| [updateSavedObject(indexPattern, saveAttempts, ignoreErrors)](./kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md) | | Save existing index pattern. Will attempt to merge differences if there are conflicts | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md index 3973f5d4c3e7b4..5fc16c70de7edb 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md @@ -9,7 +9,7 @@ Save existing index pattern. Will attempt to merge differences if there are conf Signature: ```typescript -updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): Promise; +updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number, ignoreErrors?: boolean): Promise; ``` ## Parameters @@ -18,6 +18,7 @@ updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): PromiseIndexPattern | | | saveAttempts | number | | +| ignoreErrors | boolean | | Returns: diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md index f7f8e51c4b632a..22ee6f15933ea1 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `IndexPattern` class Signature: ```typescript -constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); +constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| { spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | +| { spec, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md index e5a9e7d8f9f933..603864234d34bb 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md @@ -14,7 +14,7 @@ export declare class IndexPattern implements IIndexPattern | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-server.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | +| [(constructor)({ spec, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-server.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | ## Properties @@ -53,7 +53,6 @@ export declare class IndexPattern implements IIndexPattern | [getTimeField()](./kibana-plugin-plugins-data-server.indexpattern.gettimefield.md) | | | | [isTimeBased()](./kibana-plugin-plugins-data-server.indexpattern.istimebased.md) | | | | [isTimeNanosBased()](./kibana-plugin-plugins-data-server.indexpattern.istimenanosbased.md) | | | -| [popularizeField(fieldName, unit)](./kibana-plugin-plugins-data-server.indexpattern.popularizefield.md) | | | | [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-server.indexpattern.removescriptedfield.md) | | Remove scripted field from field list | | [toSpec()](./kibana-plugin-plugins-data-server.indexpattern.tospec.md) | | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md deleted file mode 100644 index 8b2c9242a62568..00000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [popularizeField](./kibana-plugin-plugins-data-server.indexpattern.popularizefield.md) - -## IndexPattern.popularizeField() method - -Signature: - -```typescript -popularizeField(fieldName: string, unit?: number): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| fieldName | string | | -| unit | number | | - -Returns: - -`Promise` - diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts index bfb5fd9da56e6c..a8d53223c06d11 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts @@ -89,7 +89,6 @@ describe('IndexPattern', () => { describe('api', () => { test('should have expected properties', () => { - expect(indexPattern).toHaveProperty('popularizeField'); expect(indexPattern).toHaveProperty('getScriptedFields'); expect(indexPattern).toHaveProperty('getNonScriptedFields'); expect(indexPattern).toHaveProperty('addScriptedField'); @@ -241,50 +240,4 @@ describe('IndexPattern', () => { expect(restoredPattern.fieldFormatMap.bytes instanceof MockFieldFormatter).toEqual(true); }); }); - - describe('popularizeField', () => { - test('should increment the popularity count by default', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - - await indexPattern.popularizeField(field.name); - - expect(field.count).toEqual(oldCount + 1); - }); - }); - - test('should increment the popularity count', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - const incrementAmount = 4; - - await indexPattern.popularizeField(field.name, incrementAmount); - - expect(field.count).toEqual(oldCount + incrementAmount); - }); - }); - - test('should decrement the popularity count', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - const incrementAmount = 4; - const decrementAmount = -2; - - await indexPattern.popularizeField(field.name, incrementAmount); - await indexPattern.popularizeField(field.name, decrementAmount); - - expect(field.count).toEqual(oldCount + incrementAmount + decrementAmount); - }); - }); - - test('should not go below 0', () => { - indexPattern.fields.forEach(async (field) => { - const decrementAmount = -Number.MAX_VALUE; - - await indexPattern.popularizeField(field.name, decrementAmount); - - expect(field.count).toEqual(0); - }); - }); - }); }); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index e880c3a9ff825a..5fc6344c935d5b 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -74,7 +74,6 @@ export class IndexPattern implements IIndexPattern { public metaFields: string[]; // savedObject version public version: string | undefined; - private savedObjectsClient: SavedObjectsClientCommon; public sourceFilters?: SourceFilter[]; private originalSavedObjectBody: SavedObjectBody = {}; private shortDotsEnable: boolean = false; @@ -82,13 +81,11 @@ export class IndexPattern implements IIndexPattern { constructor({ spec = {}, - savedObjectsClient, fieldFormats, shortDotsEnable = false, metaFields = [], }: IndexPatternDeps) { // set dependencies - this.savedObjectsClient = savedObjectsClient; this.fieldFormats = fieldFormats; // set config this.shortDotsEnable = shortDotsEnable; @@ -267,39 +264,6 @@ export class IndexPattern implements IIndexPattern { } } - async popularizeField(fieldName: string, unit = 1) { - /** - * This function is just used by Discover and it's high likely to be removed in the near future - * It doesn't use the save function to skip the error message that's displayed when - * a user adds several columns in a higher frequency that the changes can be persisted to ES - * resulting in 409 errors - */ - if (!this.id) return; - const field = this.fields.getByName(fieldName); - if (!field) { - return; - } - const count = Math.max((field.count || 0) + unit, 0); - if (field.count === count) { - return; - } - field.count = count; - - try { - const res = await this.savedObjectsClient.update( - 'index-pattern', - this.id, - this.getAsSavedObjectBody(), - { - version: this.version, - } - ); - this.version = res.version; - } catch (e) { - // no need for an error message here - } - } - getNonScriptedFields() { return [...this.fields.getAll().filter((field) => !field.scripted)]; } diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index eef8ef10ea7546..9a86541376cd80 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -516,7 +516,8 @@ export class IndexPatternsService { async updateSavedObject( indexPattern: IndexPattern, - saveAttempts: number = 0 + saveAttempts: number = 0, + ignoreErrors: boolean = false ): Promise { if (!indexPattern.id) return; @@ -567,6 +568,9 @@ export class IndexPatternsService { } if (unresolvedCollision) { + if (ignoreErrors) { + return; + } const title = i18n.translate('data.indexPatterns.unableWriteLabel', { defaultMessage: 'Unable to write index pattern! Refresh the page to get the most up to date changes for this index pattern.', @@ -586,7 +590,7 @@ export class IndexPatternsService { indexPatternCache.clear(indexPattern.id!); // Try the save again - return this.updateSavedObject(indexPattern, saveAttempts); + return this.updateSavedObject(indexPattern, saveAttempts, ignoreErrors); } throw err; }); diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 947ba8224625f7..b8eb7a556ac445 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1086,7 +1086,7 @@ export type IMetricAggType = MetricAggType; // @public (undocumented) export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts - constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); + constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); addScriptedField(name: string, script: string, fieldType?: string): Promise; // (undocumented) fieldFormatMap: Record; @@ -1163,8 +1163,6 @@ export class IndexPattern implements IIndexPattern { isTimeNanosBased(): boolean; // (undocumented) metaFields: string[]; - // (undocumented) - popularizeField(fieldName: string, unit?: number): Promise; removeScriptedField(fieldName: string): void; resetOriginalSavedObjectBody: () => void; // Warning: (ae-forgotten-export) The symbol "SourceFilter" needs to be exported by the entry point index.d.ts @@ -1386,7 +1384,7 @@ export class IndexPatternsService { refreshFields: (indexPattern: IndexPattern) => Promise; savedObjectToSpec: (savedObject: SavedObject) => IndexPatternSpec; setDefault: (id: string, force?: boolean) => Promise; - updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): Promise; + updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number, ignoreErrors?: boolean): Promise; } // Warning: (ae-missing-release-tag) "TypeMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index ae5159e7882d5a..fed0c1a02297e6 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -502,7 +502,7 @@ export type IMetricAggType = MetricAggType; // @public (undocumented) export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts - constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); + constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); addScriptedField(name: string, script: string, fieldType?: string): Promise; // (undocumented) fieldFormatMap: Record; @@ -583,8 +583,6 @@ export class IndexPattern implements IIndexPattern { isTimeNanosBased(): boolean; // (undocumented) metaFields: string[]; - // (undocumented) - popularizeField(fieldName: string, unit?: number): Promise; removeScriptedField(fieldName: string): void; resetOriginalSavedObjectBody: () => void; // Warning: (ae-forgotten-export) The symbol "SourceFilter" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/discover/public/application/angular/context/query_parameters/actions.js b/src/plugins/discover/public/application/angular/context/query_parameters/actions.js index fcd4b8ac02cfb4..cdf92837372261 100644 --- a/src/plugins/discover/public/application/angular/context/query_parameters/actions.js +++ b/src/plugins/discover/public/application/angular/context/query_parameters/actions.js @@ -19,6 +19,7 @@ import _ from 'lodash'; import { esFilters } from '../../../../../../data/public'; +import { popularizeField } from '../../../helpers/popularize_field'; import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE, QUERY_PARAMETER_KEYS } from './constants'; @@ -56,7 +57,7 @@ export function getQueryParameterActions(filterManager, indexPatterns) { filterManager.addFilters(newFilters); if (indexPatterns) { const indexPattern = await indexPatterns.get(indexPatternId); - indexPattern.popularizeField(field.name, 1); + await popularizeField(indexPattern, field.name, indexPatterns); } }; diff --git a/src/plugins/discover/public/application/angular/context_app.js b/src/plugins/discover/public/application/angular/context_app.js index f698ed84a8948f..145d3afe232243 100644 --- a/src/plugins/discover/public/application/angular/context_app.js +++ b/src/plugins/discover/public/application/angular/context_app.js @@ -56,8 +56,8 @@ getAngularModule().directive('contextApp', function ContextApp() { }); function ContextAppController($scope, Private) { - const { filterManager, indexpatterns, uiSettings } = getServices(); - const queryParameterActions = getQueryParameterActions(filterManager, indexpatterns); + const { filterManager, indexPatterns, uiSettings } = getServices(); + const queryParameterActions = getQueryParameterActions(filterManager, indexPatterns); const queryActions = Private(QueryActionsProvider); this.state = createInitialState( parseInt(uiSettings.get(CONTEXT_STEP_SETTING), 10), diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index a396033e5dedb3..92b96d11723e09 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -70,6 +70,7 @@ const { import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../helpers/breadcrumbs'; import { validateTimeRange } from '../helpers/validate_time_range'; +import { popularizeField } from '../helpers/popularize_field'; import { getIndexPatternId } from '../helpers/get_index_pattern_id'; import { addFatalError } from '../../../../kibana_legacy/public'; @@ -952,7 +953,9 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise // TODO: On array fields, negating does not negate the combination, rather all terms $scope.filterQuery = function (field, values, operation) { - $scope.indexPattern.popularizeField(field, 1); + const { indexPattern } = $scope; + + popularizeField(indexPattern, field.name, indexPatterns); const newFilters = esFilters.generateFilters( filterManager, field, @@ -965,7 +968,8 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise $scope.addColumn = function addColumn(columnName) { if (uiCapabilities.discover.save) { - $scope.indexPattern.popularizeField(columnName, 1); + const { indexPattern } = $scope; + popularizeField(indexPattern, columnName, indexPatterns); } const columns = columnActions.addColumn($scope.state.columns, columnName); setAppState({ columns }); @@ -973,7 +977,8 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise $scope.removeColumn = function removeColumn(columnName) { if (uiCapabilities.discover.save) { - $scope.indexPattern.popularizeField(columnName, 1); + const { indexPattern } = $scope; + popularizeField(indexPattern, columnName, indexPatterns); } const columns = columnActions.removeColumn($scope.state.columns, columnName); // The state's sort property is an array of [sortByColumn,sortDirection] diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts index 1de62fe5a0348f..af88cacfcf9923 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts @@ -221,7 +221,6 @@ export class SearchEmbeddable if (!searchScope.columns) { return; } - indexPattern.popularizeField(columnName, 1); const columns = columnActions.addColumn(searchScope.columns, columnName); this.updateInput({ columns }); }; diff --git a/src/plugins/discover/public/application/helpers/popularize_field.test.ts b/src/plugins/discover/public/application/helpers/popularize_field.test.ts new file mode 100644 index 00000000000000..f1ff67c23b92bb --- /dev/null +++ b/src/plugins/discover/public/application/helpers/popularize_field.test.ts @@ -0,0 +1,82 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IndexPattern, IndexPatternsService } from '../../../../data/public'; +import { popularizeField } from './popularize_field'; + +describe('Popularize field', () => { + test('returns undefined if index pattern lacks id', async () => { + const indexPattern = ({} as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({} as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); + + test('returns undefined if field not found', async () => { + const indexPattern = ({ + fields: { + getByName: () => {}, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({} as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); + + test('returns undefined if successful', async () => { + const field = { + count: 0, + }; + const indexPattern = ({ + id: 'id', + fields: { + getByName: () => field, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({ + updateSavedObject: async () => {}, + } as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + expect(field.count).toEqual(1); + }); + + test('hides errors', async () => { + const field = { + count: 0, + }; + const indexPattern = ({ + id: 'id', + fields: { + getByName: () => field, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({ + updateSavedObject: async () => { + throw new Error('unknown error'); + }, + } as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/plugins/discover/public/application/helpers/popularize_field.ts b/src/plugins/discover/public/application/helpers/popularize_field.ts new file mode 100644 index 00000000000000..0aea86e47c9542 --- /dev/null +++ b/src/plugins/discover/public/application/helpers/popularize_field.ts @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IndexPattern, IndexPatternsService } from '../../../../data/public'; + +async function popularizeField( + indexPattern: IndexPattern, + fieldName: string, + indexPatternsService: IndexPatternsService +) { + if (!indexPattern.id) return; + const field = indexPattern.fields.getByName(fieldName); + if (!field) { + return; + } + + field.count++; + // Catch 409 errors caused by user adding columns in a higher frequency that the changes can be persisted to Elasticsearch + try { + await indexPatternsService.updateSavedObject(indexPattern, 0, true); + // eslint-disable-next-line no-empty + } catch {} +} + +export { popularizeField };