From 14cd01c8b3241500a1b9a918fd6179f6fbe72ee5 Mon Sep 17 00:00:00 2001 From: Diana Derevyankina Date: Mon, 14 Sep 2020 18:12:46 +0300 Subject: [PATCH 1/5] Fields dropdowns are not populated if one of the indices is missing --- .../index_patterns/fetcher/index_patterns_fetcher.ts | 5 +++-- .../data/server/index_patterns/fetcher/lib/es_api.ts | 9 +++++++-- .../lib/field_capabilities/field_capabilities.ts | 10 ++++++++-- .../public/application/components/visualization.js | 4 ++++ .../vis_type_timeseries/server/lib/get_fields.ts | 12 ++++++++---- .../strategies/abstract_search_strategy.ts | 1 + .../lib/vis_data/get_interval_and_timefield.js | 4 +--- 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/plugins/data/server/index_patterns/fetcher/index_patterns_fetcher.ts b/src/plugins/data/server/index_patterns/fetcher/index_patterns_fetcher.ts index ff9d67152e268..57c636a9e3c69 100644 --- a/src/plugins/data/server/index_patterns/fetcher/index_patterns_fetcher.ts +++ b/src/plugins/data/server/index_patterns/fetcher/index_patterns_fetcher.ts @@ -55,9 +55,10 @@ export class IndexPatternsFetcher { async getFieldsForWildcard(options: { pattern: string | string[]; metaFields?: string[]; + fieldCapsOptions?: { allowNoIndices: boolean }; }): Promise { - const { pattern, metaFields } = options; - return await getFieldCapabilities(this._callDataCluster, pattern, metaFields); + const { pattern, metaFields, fieldCapsOptions } = options; + return await getFieldCapabilities(this._callDataCluster, pattern, metaFields, fieldCapsOptions); } /** diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts b/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts index 0738a16034d46..27ce14f9a3597 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts +++ b/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts @@ -69,15 +69,20 @@ export async function callIndexAliasApi( * * @param {Function} callCluster bound function for accessing an es client * @param {Array|String} indices + * @param {Object} fieldCapsOptions * @return {Promise} */ -export async function callFieldCapsApi(callCluster: LegacyAPICaller, indices: string[] | string) { +export async function callFieldCapsApi( + callCluster: LegacyAPICaller, + indices: string[] | string, + fieldCapsOptions: { allowNoIndices: boolean } = { allowNoIndices: false } +) { try { return (await callCluster('fieldCaps', { index: indices, fields: '*', ignoreUnavailable: true, - allowNoIndices: false, + ...fieldCapsOptions, })) as FieldCapsResponse; } catch (error) { throw convertEsError(indices, error); diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts index 6b26c82dc95e7..62e77e0adad66 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts @@ -32,14 +32,20 @@ import { FieldDescriptor } from '../../index_patterns_fetcher'; * @param {Function} callCluster bound function for accessing an es client * @param {Array} [indices=[]] the list of indexes to check * @param {Array} [metaFields=[]] the list of internal fields to include + * @param {Object} fieldCapsOptions * @return {Promise>} */ export async function getFieldCapabilities( callCluster: LegacyAPICaller, indices: string | string[] = [], - metaFields: string[] = [] + metaFields: string[] = [], + fieldCapsOptions?: { allowNoIndices: boolean } ) { - const esFieldCaps: FieldCapsResponse = await callFieldCapsApi(callCluster, indices); + const esFieldCaps: FieldCapsResponse = await callFieldCapsApi( + callCluster, + indices, + fieldCapsOptions + ); const fieldsFromFieldCapsByName = keyBy(readFieldCapsResponse(esFieldCaps), 'name'); const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName) diff --git a/src/plugins/vis_type_timeseries/public/application/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js index 8b8218653f97c..2774c1c6f24df 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/visualization.js +++ b/src/plugins/vis_type_timeseries/public/application/components/visualization.js @@ -43,6 +43,10 @@ export function Visualization(props) { const { visData, model } = props; // Show the error panel const error = _.get(visData, `${model.id}.error`); + if (_.get(error, 'error.type') === 'index_not_found_exception') { + const index = _.get(error, 'error.index'); + error.message = `Index "${index}" is missing`; + } if (error) { return (
diff --git a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts index 0f0d99bff6f1c..18e10bbe4b2d2 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts @@ -16,12 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { uniqBy } from 'lodash'; +import { uniqBy, get } from 'lodash'; import { first, map } from 'rxjs/operators'; import { KibanaRequest, RequestHandlerContext } from 'kibana/server'; -// @ts-ignore -import { getIndexPatternObject } from './vis_data/helpers/get_index_pattern'; import { indexPatterns } from '../../../data/server'; import { Framework } from '../plugin'; import { IndexPatternFieldDescriptor, IndexPatternsFetcher } from '../../../data/server'; @@ -73,7 +71,13 @@ export async function getFields( .toPromise(); }, }; - const { indexPatternString } = await getIndexPatternObject(reqFacade, indexPattern); + let indexPatternString = indexPattern; + + if (!indexPatternString) { + const index = await reqFacade.getUiSettingsService().get('defaultIndex'); + indexPatternString = get(index, 'title', ''); + } + const { searchStrategy, capabilities, diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts index 0b1c6e6e20414..281d64c905c5e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts @@ -75,6 +75,7 @@ export class AbstractSearchStrategy { return await indexPatternsService!.getFieldsForWildcard({ pattern: indexPattern, + fieldCapsOptions: { allowNoIndices: true }, }); } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_interval_and_timefield.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_interval_and_timefield.js index e4bda194299df..82a2ef66cb1c0 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_interval_and_timefield.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_interval_and_timefield.js @@ -17,12 +17,10 @@ * under the License. */ -import { get } from 'lodash'; - const DEFAULT_TIME_FIELD = '@timestamp'; export function getIntervalAndTimefield(panel, series = {}, indexPatternObject) { - const getDefaultTimeField = () => get(indexPatternObject, 'timeFieldName', DEFAULT_TIME_FIELD); + const getDefaultTimeField = () => indexPatternObject?.timeFieldName ?? DEFAULT_TIME_FIELD; const timeField = (series.override_index_pattern && series.series_time_field) || From 031e90b8109b885b22713257b621138a7687cf51 Mon Sep 17 00:00:00 2001 From: Diana Derevyankina Date: Mon, 14 Sep 2020 23:59:31 +0300 Subject: [PATCH 2/5] Fix tests and accept api changes --- ...-data-server.indexpatternsfetcher.getfieldsforwildcard.md | 5 ++++- .../lib/field_capabilities/field_capabilities.test.js | 2 +- src/plugins/data/server/server.api.md | 3 +++ .../strategies/abstract_search_strategy.test.js | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsfetcher.getfieldsforwildcard.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsfetcher.getfieldsforwildcard.md index 6bd3bbf2433cd..52382372d6d96 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsfetcher.getfieldsforwildcard.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsfetcher.getfieldsforwildcard.md @@ -12,6 +12,9 @@ Get a list of field objects for an index pattern that may contain wildcards getFieldsForWildcard(options: { pattern: string | string[]; metaFields?: string[]; + fieldCapsOptions?: { + allowNoIndices: boolean; + }; }): Promise; ``` @@ -19,7 +22,7 @@ getFieldsForWildcard(options: { | Parameter | Type | Description | | --- | --- | --- | -| options | {
pattern: string | string[];
metaFields?: string[];
} | | +| options | {
pattern: string | string[];
metaFields?: string[];
fieldCapsOptions?: {
allowNoIndices: boolean;
};
} | | Returns: diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.test.js b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.test.js index a0af7582ac6f3..0e5757b7b782b 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.test.js +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.test.js @@ -61,7 +61,7 @@ describe('index_patterns/field_capabilities/field_capabilities', () => { await getFieldCapabilities(footballs[0], footballs[1]); sinon.assert.calledOnce(callFieldCapsApi); - calledWithExactly(callFieldCapsApi, [footballs[0], footballs[1]]); + calledWithExactly(callFieldCapsApi, [footballs[0], footballs[1], undefined]); }); }); diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index cd0369a5c4551..660f25a6f976b 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -687,6 +687,9 @@ export class IndexPatternsFetcher { getFieldsForWildcard(options: { pattern: string | string[]; metaFields?: string[]; + fieldCapsOptions?: { + allowNoIndices: boolean; + }; }): Promise; } diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js index 1fbaffd794c89..184207b40708a 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.js @@ -65,6 +65,7 @@ describe('AbstractSearchStrategy', () => { expect(fields).toBe(mockedFields); expect(req.pre.indexPatternsService.getFieldsForWildcard).toHaveBeenCalledWith({ pattern: indexPattern, + fieldCapsOptions: { allowNoIndices: true }, }); }); From 89de6faf9f8b47558abd5871329c46de12bf2a13 Mon Sep 17 00:00:00 2001 From: Diana Derevyankina Date: Wed, 16 Sep 2020 18:48:21 +0300 Subject: [PATCH 3/5] Add indexPatternsService to get default index pattern --- .../vis_type_timeseries/server/lib/get_fields.ts | 13 +++++++++---- src/plugins/vis_type_timeseries/server/plugin.ts | 12 ++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts index 18e10bbe4b2d2..9f08eb279b5fe 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts @@ -20,9 +20,12 @@ import { uniqBy, get } from 'lodash'; import { first, map } from 'rxjs/operators'; import { KibanaRequest, RequestHandlerContext } from 'kibana/server'; -import { indexPatterns } from '../../../data/server'; import { Framework } from '../plugin'; -import { IndexPatternFieldDescriptor, IndexPatternsFetcher } from '../../../data/server'; +import { + indexPatterns, + IndexPatternFieldDescriptor, + IndexPatternsFetcher, +} from '../../../data/server'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; export async function getFields( @@ -74,8 +77,10 @@ export async function getFields( let indexPatternString = indexPattern; if (!indexPatternString) { - const index = await reqFacade.getUiSettingsService().get('defaultIndex'); - indexPatternString = get(index, 'title', ''); + const [, { data }] = await framework.core.getStartServices(); + const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory(request); + const defaultIndexPattern = await indexPatternsService.getDefault(); + indexPatternString = get(defaultIndexPattern, 'title', ''); } const { diff --git a/src/plugins/vis_type_timeseries/server/plugin.ts b/src/plugins/vis_type_timeseries/server/plugin.ts index d863937a4e3dc..1c72db04ba8e8 100644 --- a/src/plugins/vis_type_timeseries/server/plugin.ts +++ b/src/plugins/vis_type_timeseries/server/plugin.ts @@ -38,6 +38,7 @@ import { visDataRoutes } from './routes/vis'; import { fieldsRoutes } from './routes/fields'; import { SearchStrategyRegistry } from './lib/search_strategies'; import { uiSettings } from './ui_settings'; +import { PluginStart as DataPluginStart } from '../../data/server'; export interface LegacySetup { server: Server; @@ -47,6 +48,10 @@ interface VisTypeTimeseriesPluginSetupDependencies { usageCollection?: UsageCollectionSetup; } +export interface VisTypeTimeseriesStartDependencies { + data: DataPluginStart; +} + export interface VisTypeTimeseriesSetup { getVisData: ( requestContext: RequestHandlerContext, @@ -57,7 +62,7 @@ export interface VisTypeTimeseriesSetup { } export interface Framework { - core: CoreSetup; + core: CoreSetup; plugins: any; config$: Observable; globalConfig$: PluginInitializerContext['config']['legacy']['globalConfig$']; @@ -74,7 +79,10 @@ export class VisTypeTimeseriesPlugin implements Plugin { this.validationTelementryService = new ValidationTelemetryService(); } - public setup(core: CoreSetup, plugins: VisTypeTimeseriesPluginSetupDependencies) { + public setup( + core: CoreSetup, + plugins: VisTypeTimeseriesPluginSetupDependencies + ) { const logger = this.initializerContext.logger.get('visTypeTimeseries'); core.uiSettings.register(uiSettings); const config$ = this.initializerContext.config.create(); From 3524b27b6bf4c12fc32e6ad6a8b780d8e1376cae Mon Sep 17 00:00:00 2001 From: Diana Derevyankina Date: Thu, 17 Sep 2020 14:46:44 +0300 Subject: [PATCH 4/5] Replace simple error message string with i18n translation --- .../public/application/components/visualization.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_timeseries/public/application/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js index 2774c1c6f24df..77ec52074a892 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/visualization.js +++ b/src/plugins/vis_type_timeseries/public/application/components/visualization.js @@ -20,6 +20,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import _ from 'lodash'; +import { i18n } from '@kbn/i18n'; import { TimeseriesVisualization } from './vis_types/timeseries/vis'; import { metric } from './vis_types/metric/vis'; @@ -45,7 +46,10 @@ export function Visualization(props) { const error = _.get(visData, `${model.id}.error`); if (_.get(error, 'error.type') === 'index_not_found_exception') { const index = _.get(error, 'error.index'); - error.message = `Index "${index}" is missing`; + error.message = i18n.translate('visTypeTimeseries.error.missingIndexErrorMessage', { + defaultMessage: 'Index "{index}" is missing', + values: { index }, + }); } if (error) { return ( From 5ff70cd2d2471b36a78018f1027389c2f926da9d Mon Sep 17 00:00:00 2001 From: Diana Derevyankina Date: Fri, 18 Sep 2020 11:45:31 +0300 Subject: [PATCH 5/5] Remove unnecessary displaying error code --- .../public/application/components/visualization.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/application/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js index 77ec52074a892..8b8218653f97c 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/visualization.js +++ b/src/plugins/vis_type_timeseries/public/application/components/visualization.js @@ -20,7 +20,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import _ from 'lodash'; -import { i18n } from '@kbn/i18n'; import { TimeseriesVisualization } from './vis_types/timeseries/vis'; import { metric } from './vis_types/metric/vis'; @@ -44,13 +43,6 @@ export function Visualization(props) { const { visData, model } = props; // Show the error panel const error = _.get(visData, `${model.id}.error`); - if (_.get(error, 'error.type') === 'index_not_found_exception') { - const index = _.get(error, 'error.index'); - error.message = i18n.translate('visTypeTimeseries.error.missingIndexErrorMessage', { - defaultMessage: 'Index "{index}" is missing', - values: { index }, - }); - } if (error) { return (