From 28d72f740235570300b661bc2f619ff785c6e56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 8 Feb 2022 14:08:31 +0100 Subject: [PATCH 1/3] Add `dataViews` service to observability plugin --- x-pack/plugins/observability/kibana.json | 1 + x-pack/plugins/observability/public/plugin.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/x-pack/plugins/observability/kibana.json b/x-pack/plugins/observability/kibana.json index 1887764f6f72d..650d437a229ff 100644 --- a/x-pack/plugins/observability/kibana.json +++ b/x-pack/plugins/observability/kibana.json @@ -23,6 +23,7 @@ "alerting", "cases", "data", + "dataViews", "features", "inspector", "ruleRegistry", diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index 36a7600a58f25..38f300af9aa1e 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -24,6 +24,7 @@ import type { DataPublicPluginSetup, DataPublicPluginStart, } from '../../../../src/plugins/data/public'; +import type { DataViewsPublicPluginStart } from '../../../../src/plugins/data_views/public'; import type { DiscoverStart } from '../../../../src/plugins/discover/public'; import type { EmbeddableStart } from '../../../../src/plugins/embeddable/public'; import type { @@ -60,6 +61,7 @@ export interface ObservabilityPublicPluginsStart { home?: HomePublicPluginStart; triggersActionsUi: TriggersAndActionsUIPublicPluginStart; data: DataPublicPluginStart; + dataViews: DataViewsPublicPluginStart; lens: LensPublicStart; discover: DiscoverStart; } From eef83024d31eddb4e9cf1a9432257590b7bd5140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 8 Feb 2022 14:10:46 +0100 Subject: [PATCH 2/3] Use `dataViews` service inside `ObservabilityDataViews` --- .../exploratory_view/embeddable/index.tsx | 2 +- .../hooks/use_app_index_pattern.tsx | 6 ++-- .../containers/alerts_page/alerts_page.tsx | 2 +- .../observability_data_views.test.ts | 32 +++++++++---------- .../observability_data_views.ts | 23 +++++++------ 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/index.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/index.tsx index 7b0e2d10c0d3b..4b68e9d5f6fa3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/index.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/index.tsx @@ -43,7 +43,7 @@ export function getExploratoryViewEmbeddable( setLoading(true); try { - const obsvIndexP = new ObservabilityDataViews(plugins.data); + const obsvIndexP = new ObservabilityDataViews(plugins.dataViews); const indPattern = await obsvIndexP.getDataView( dataType, dataTypesIndexPatterns?.[dataType] diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx index c865d8e6dca5e..2688812f76c9a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx @@ -44,7 +44,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { const [hasAppData, setHasAppData] = useState({} as HasAppDataState); const { - services: { data }, + services: { dataViews }, } = useKibana(); const { indexPatterns: indexPatternsList } = useExploratoryView(); @@ -83,7 +83,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { setHasAppData((prevState) => ({ ...prevState, [dataType]: hasDataT })); if (hasDataT && indices) { - const obsvIndexP = new ObservabilityDataViews(data); + const obsvIndexP = new ObservabilityDataViews(dataViews); const indPattern = await obsvIndexP.getDataView(dataType, indices); setIndexPatterns((prevState) => ({ ...prevState, [dataType]: indPattern })); @@ -100,7 +100,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { } } }, - [data, hasAppData, indexPatternsList, loading] + [dataViews, hasAppData, indexPatternsList, loading] ); return ( diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx index dc7eab6b0ca40..a8e78410e13c5 100644 --- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx @@ -165,7 +165,7 @@ function AlertsPage() { { id: 'dynamic-observability-alerts-table-index-pattern', title: indexNames.join(','), - fields: await plugins.data.indexPatterns.getFieldsForWildcard({ + fields: await plugins.dataViews.getFieldsForWildcard({ pattern: indexNames.join(','), allowNoIndex: true, }), diff --git a/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.test.ts b/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.test.ts index 78899e9cabca0..0a24f35a498cc 100644 --- a/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.test.ts +++ b/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.test.ts @@ -68,49 +68,49 @@ const fieldFormats = { }; describe('ObservabilityIndexPatterns', function () { - const { data } = mockCore(); - data!.indexPatterns.get = jest.fn().mockReturnValue({ title: 'index-*' }); - data!.indexPatterns.createAndSave = jest.fn().mockReturnValue({ id: dataViewList.ux }); - data!.indexPatterns.updateSavedObject = jest.fn(); + const { dataViews } = mockCore(); + dataViews!.get = jest.fn().mockReturnValue({ title: 'index-*' }); + dataViews!.createAndSave = jest.fn().mockReturnValue({ id: dataViewList.ux }); + dataViews!.updateSavedObject = jest.fn(); it('should return index pattern for app', async function () { - const obsv = new ObservabilityDataViews(data!); + const obsv = new ObservabilityDataViews(dataViews!); const indexP = await obsv.getDataView('ux', 'heartbeat-8*,synthetics-*'); expect(indexP).toEqual({ id: 'rum_static_index_pattern_id' }); - expect(data?.indexPatterns.get).toHaveBeenCalledWith( + expect(dataViews?.get).toHaveBeenCalledWith( 'rum_static_index_pattern_id_heartbeat_8_synthetics_' ); - expect(data?.indexPatterns.get).toHaveBeenCalledTimes(1); + expect(dataViews?.get).toHaveBeenCalledTimes(1); }); it('should creates missing index pattern', async function () { - data!.indexPatterns.get = jest.fn().mockImplementation(() => { + dataViews!.get = jest.fn().mockImplementation(() => { throw new SavedObjectNotFound('index_pattern'); }); - data!.indexPatterns.createAndSave = jest.fn().mockReturnValue({ id: dataViewList.ux }); + dataViews!.createAndSave = jest.fn().mockReturnValue({ id: dataViewList.ux }); - const obsv = new ObservabilityDataViews(data!); + const obsv = new ObservabilityDataViews(dataViews!); const indexP = await obsv.getDataView('ux', 'trace-*,apm-*'); expect(indexP).toEqual({ id: dataViewList.ux }); - expect(data?.indexPatterns.createAndSave).toHaveBeenCalledWith({ + expect(dataViews?.createAndSave).toHaveBeenCalledWith({ fieldFormats, id: 'rum_static_index_pattern_id_trace_apm_', timeFieldName: '@timestamp', title: '(rum-data-view)*,trace-*,apm-*', }); - expect(data?.indexPatterns.createAndSave).toHaveBeenCalledTimes(1); + expect(dataViews?.createAndSave).toHaveBeenCalledTimes(1); }); it('should return getFieldFormats', function () { - const obsv = new ObservabilityDataViews(data!); + const obsv = new ObservabilityDataViews(dataViews!); expect(obsv.getFieldFormats('ux')).toEqual(fieldFormats); }); @@ -118,12 +118,12 @@ describe('ObservabilityIndexPatterns', function () { it('should validate field formats', async function () { mockIndexPattern.getFormatterForField = jest.fn().mockReturnValue({ params: () => {} }); - const obsv = new ObservabilityDataViews(data!); + const obsv = new ObservabilityDataViews(dataViews!); await obsv.validateFieldFormats('ux', mockIndexPattern); - expect(data?.indexPatterns.updateSavedObject).toHaveBeenCalledTimes(1); - expect(data?.indexPatterns.updateSavedObject).toHaveBeenCalledWith( + expect(dataViews?.updateSavedObject).toHaveBeenCalledTimes(1); + expect(dataViews?.updateSavedObject).toHaveBeenCalledWith( expect.objectContaining({ fieldFormatMap: fieldFormats }) ); }); diff --git a/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.ts b/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.ts index eb66894772dfd..8a74482bb14ca 100644 --- a/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.ts +++ b/x-pack/plugins/observability/public/utils/observability_data_views/observability_data_views.ts @@ -7,8 +7,11 @@ import type { FieldFormat as IFieldFormat } from 'src/plugins/field_formats/common'; import { SavedObjectNotFound } from '../../../../../../src/plugins/kibana_utils/public'; -import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public'; -import type { DataView, DataViewSpec } from '../../../../../../src/plugins/data/common'; +import type { + DataViewsPublicPluginStart, + DataView, + DataViewSpec, +} from '../../../../../../src/plugins/data_views/public'; import { rumFieldFormats } from '../../components/shared/exploratory_view/configurations/rum/field_formats'; import { syntheticsFieldFormats } from '../../components/shared/exploratory_view/configurations/synthetics/field_formats'; import { @@ -77,19 +80,19 @@ export function isParamsSame(param1: IFieldFormat['_params'], param2: FieldForma } export class ObservabilityDataViews { - data?: DataPublicPluginStart; + dataViews?: DataViewsPublicPluginStart; - constructor(data: DataPublicPluginStart) { - this.data = data; + constructor(dataViews: DataViewsPublicPluginStart) { + this.dataViews = dataViews; } async createDataView(app: AppDataType, indices: string) { - if (!this.data) { + if (!this.dataViews) { throw new Error('data is not defined'); } const appIndicesPattern = getAppIndicesWithPattern(app, indices); - return await this.data.dataViews.createAndSave({ + return await this.dataViews.createAndSave({ title: appIndicesPattern, id: getAppDataViewId(app, indices), timeFieldName: '@timestamp', @@ -113,7 +116,7 @@ export class ObservabilityDataViews { } }); if (isParamsDifferent) { - await this.data?.dataViews.updateSavedObject(dataView); + await this.dataViews?.updateSavedObject(dataView); } } } @@ -142,7 +145,7 @@ export class ObservabilityDataViews { } async getDataView(app: AppDataType, indices?: string): Promise { - if (!this.data) { + if (!this.dataViews) { throw new Error('data is not defined'); } let appIndices = indices; @@ -155,7 +158,7 @@ export class ObservabilityDataViews { const dataViewId = getAppDataViewId(app, appIndices); const dataViewTitle = getAppIndicesWithPattern(app, appIndices); // we will get the data view by id - const dataView = await this.data?.indexPatterns.get(dataViewId); + const dataView = await this.dataViews?.get(dataViewId); // and make sure title matches, otherwise, we will need to create it if (dataView.title !== dataViewTitle) { From 8d28e2d01c41924941ad9c4e806389774fbd5075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 8 Feb 2022 15:55:41 +0100 Subject: [PATCH 3/3] Add missing mock --- .../public/components/shared/exploratory_view/rtl_helpers.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx index 55e90db755eaf..84a52bd0d7e22 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx @@ -49,6 +49,7 @@ import { IndexPattern, IndexPatternsContract } from '../../../../../../../src/pl import { AppDataType, SeriesUrl, UrlFilter } from './types'; import { createStubIndexPattern } from '../../../../../../../src/plugins/data/common/stubs'; import { dataPluginMock } from '../../../../../../../src/plugins/data/public/mocks'; +import { dataViewPluginMocks } from '../../../../../../../src/plugins/data_views/public/mocks'; import { ListItem } from '../../../hooks/use_values_list'; import { TRANSACTION_DURATION } from './configurations/constants/elasticsearch_fieldnames'; import { casesPluginMock } from '../../../../../cases/public/mocks'; @@ -133,6 +134,7 @@ export const mockCore: () => Partial