From 2b7338f8b6d296fbc75421874a6f7f25a3c655bd Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Mon, 8 Jul 2024 13:12:56 +0200 Subject: [PATCH] Add optional APIVersion to DatasourceRef (#90076) --- packages/grafana-data/src/types/datasource.ts | 17 ++++++++++++++-- packages/grafana-data/src/utils/datasource.ts | 9 +++++++-- .../grafana-schema/src/common/common.gen.ts | 4 ++++ .../src/common/dataquery_gen.cue | 2 ++ .../components/rule-editor/QueryRows.tsx | 11 +++------- .../query-and-alert-condition/reducer.ts | 14 ++++++++----- .../PanelDataPane/PanelDataQueriesTab.tsx | 11 ++++++---- .../panel-edit/VizPanelManager.tsx | 20 +++++-------------- .../editors/AdHocFiltersVariableEditor.tsx | 8 ++------ .../editors/GroupByVariableEditor.tsx | 7 ++----- .../variables/editors/QueryVariableEditor.tsx | 6 +++--- .../PanelEditor/PanelEditorQueries.tsx | 3 +-- .../features/dashboard/state/PanelModel.ts | 5 +---- .../query/components/QueryEditorRow.tsx | 3 ++- .../query/components/QueryEditorRows.tsx | 7 ++----- .../features/query/components/QueryGroup.tsx | 17 +++++++++++----- .../query/state/updateQueries.test.ts | 10 ++++++++++ .../app/features/query/state/updateQueries.ts | 2 +- 18 files changed, 88 insertions(+), 68 deletions(-) diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index eea3a841a70..524ef8b1c39 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -1,6 +1,8 @@ import { ComponentType } from 'react'; import { Observable } from 'rxjs'; +import { DataSourceRef } from '@grafana/schema'; + import { makeClassES5Compatible } from '../utils/makeClassES5Compatible'; import { ScopedVars } from './ScopedVars'; @@ -11,7 +13,7 @@ import { KeyValue, LoadingState, TableData, TimeSeries } from './data'; import { DataFrame, DataFrameDTO } from './dataFrame'; import { PanelData } from './panel'; import { GrafanaPlugin, PluginMeta } from './plugin'; -import { DataQuery, DataSourceRef } from './query'; +import { DataQuery } from './query'; import { Scope } from './scopes'; import { AdHocVariableFilter } from './templateVars'; import { RawTimeRange, TimeRange } from './time'; @@ -217,6 +219,11 @@ abstract class DataSourceApi< */ readonly uid: string; + /** + * Set in constructor + */ + readonly apiVersion?: string; + /** * min interval range */ @@ -229,6 +236,7 @@ abstract class DataSourceApi< this.meta = instanceSettings.meta; this.cachingConfig = instanceSettings.cachingConfig; this.uid = instanceSettings.uid; + this.apiVersion = instanceSettings.apiVersion; } /** @@ -322,7 +330,11 @@ abstract class DataSourceApi< /** Get an identifier object for this datasource instance */ getRef(): DataSourceRef { - return { type: this.type, uid: this.uid }; + const ref: DataSourceRef = { type: this.type, uid: this.uid }; + if (this.apiVersion) { + ref.apiVersion = this.apiVersion; + } + return ref; } /** @@ -660,6 +672,7 @@ export interface DataSourceInstanceSettings) => { const queries = this.getQueries(); const dsSettings = this._panelManager.state.dsSettings; - this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid })); + this.onQueriesChange( + addQuery(queries, query, dsSettings ? getDataSourceRef(dsSettings) : { type: undefined, uid: undefined }) + ); }; isExpressionsSupported(dsSettings: DataSourceInstanceSettings): boolean { diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx index 40ae36a0958..33e36101985 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx @@ -9,6 +9,7 @@ import { GrafanaTheme2, PanelModel, filterFieldConfigOverrides, + getDataSourceRef, isStandardFieldProp, restoreCustomOverrideRules, } from '@grafana/data'; @@ -159,8 +160,8 @@ export class VizPanelManager extends SceneObjectBase { this.queryRunner.setState({ datasource: { + ...getDataSourceRef(dsSettings), uid: lastUsedDatasource?.datasourceUid, - type: dsSettings.type, }, }); } @@ -173,12 +174,7 @@ export class VizPanelManager extends SceneObjectBase { if (datasource && dsSettings) { this.setState({ datasource, dsSettings }); - storeLastUsedDataSourceInLocalStorage( - { - type: dsSettings.type, - uid: dsSettings.uid, - } || { default: true } - ); + storeLastUsedDataSourceInLocalStorage(getDataSourceRef(dsSettings) || { default: true }); } } catch (err) { //set default datasource if we fail to load the datasource @@ -192,10 +188,7 @@ export class VizPanelManager extends SceneObjectBase { }); this.queryRunner.setState({ - datasource: { - uid: dsSettings.uid, - type: dsSettings.type, - }, + datasource: getDataSourceRef(dsSettings), }); } @@ -296,10 +289,7 @@ export class VizPanelManager extends SceneObjectBase { const queries = defaultQueries || (await updateQueries(nextDS, newSettings.uid, currentQueries, currentDS)); queryRunner.setState({ - datasource: { - type: newSettings.type, - uid: newSettings.uid, - }, + datasource: getDataSourceRef(newSettings), queries, }); if (defaultQueries) { diff --git a/public/app/features/dashboard-scene/settings/variables/editors/AdHocFiltersVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/AdHocFiltersVariableEditor.tsx index dc03d1b347b..5e5ff504462 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/AdHocFiltersVariableEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/AdHocFiltersVariableEditor.tsx @@ -1,9 +1,8 @@ import { useAsync } from 'react-use'; -import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data'; +import { DataSourceInstanceSettings, MetricFindValue, getDataSourceRef } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; import { AdHocFiltersVariable } from '@grafana/scenes'; -import { DataSourceRef } from '@grafana/schema'; import { AdHocVariableForm } from '../components/AdHocVariableForm'; @@ -25,10 +24,7 @@ export function AdHocFiltersVariableEditor(props: AdHocFiltersVariableEditorProp : 'This data source does not support ad hoc filters yet.'; const onDataSourceChange = (ds: DataSourceInstanceSettings) => { - const dsRef: DataSourceRef = { - uid: ds.uid, - type: ds.type, - }; + const dsRef = getDataSourceRef(ds); variable.setState({ datasource: dsRef, diff --git a/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx index 808dee6dad2..2663ab7c47c 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx @@ -1,6 +1,6 @@ import { useAsync } from 'react-use'; -import { DataSourceInstanceSettings, DataSourceRef, MetricFindValue } from '@grafana/data'; +import { DataSourceInstanceSettings, MetricFindValue, getDataSourceRef } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; import { GroupByVariable } from '@grafana/scenes'; @@ -24,10 +24,7 @@ export function GroupByVariableEditor(props: GroupByVariableEditorProps) { : 'This data source does not support group by variable yet.'; const onDataSourceChange = async (ds: DataSourceInstanceSettings) => { - const dsRef: DataSourceRef = { - uid: ds.uid, - type: ds.type, - }; + const dsRef = getDataSourceRef(ds); variable.setState({ datasource: dsRef }); onRunQuery(); diff --git a/public/app/features/dashboard-scene/settings/variables/editors/QueryVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/QueryVariableEditor.tsx index 539290d26e9..05ea0873e91 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/QueryVariableEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/QueryVariableEditor.tsx @@ -1,9 +1,9 @@ import { FormEvent } from 'react'; import * as React from 'react'; -import { SelectableValue, DataSourceInstanceSettings } from '@grafana/data'; +import { SelectableValue, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data'; import { QueryVariable, sceneGraph } from '@grafana/scenes'; -import { DataSourceRef, VariableRefresh, VariableSort } from '@grafana/schema'; +import { VariableRefresh, VariableSort } from '@grafana/schema'; import { QueryVariableEditorForm } from '../components/QueryVariableForm'; @@ -36,7 +36,7 @@ export function QueryVariableEditor({ variable, onRunQuery }: QueryVariableEdito variable.setState({ allValue: event.currentTarget.value }); }; const onDataSourceChange = (dsInstanceSettings: DataSourceInstanceSettings) => { - const datasource: DataSourceRef = { uid: dsInstanceSettings.uid, type: dsInstanceSettings.type }; + const datasource = getDataSourceRef(dsInstanceSettings); if (variable.state.datasource && variable.state.datasource.type !== datasource.type) { variable.setState({ datasource, query: '', definition: '' }); diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx index 7f87d410e20..0c81aafeea8 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx @@ -40,8 +40,7 @@ export class PanelEditorQueries extends PureComponent { cacheTimeout: datasourceSettings?.meta.queryOptions?.cacheTimeout ? panel.cacheTimeout : undefined, dataSource: { default: datasourceSettings?.isDefault, - type: datasourceSettings?.type, - uid: datasourceSettings?.uid, + ...(datasourceSettings ? getDataSourceRef(datasourceSettings) : { type: undefined, uid: undefined }), }, queryCachingTTL: datasourceSettings?.cachingConfig?.enabled ? panel.queryCachingTTL : undefined, queries: panel.targets, diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 56d76acd5ef..b8ca782906c 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -544,10 +544,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { updateQueries(options: QueryGroupOptions) { const { dataSource } = options; - this.datasource = { - uid: dataSource.uid, - type: dataSource.type, - }; + this.datasource = dataSource; this.cacheTimeout = options.cacheTimeout; this.queryCachingTTL = options.queryCachingTTL; diff --git a/public/app/features/query/components/QueryEditorRow.tsx b/public/app/features/query/components/QueryEditorRow.tsx index d58d80f4dcd..a68d235fe1f 100644 --- a/public/app/features/query/components/QueryEditorRow.tsx +++ b/public/app/features/query/components/QueryEditorRow.tsx @@ -20,6 +20,7 @@ import { PanelEvents, QueryResultMetaNotice, TimeRange, + getDataSourceRef, toLegacyResponseData, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; @@ -364,7 +365,7 @@ export class QueryEditorRow extends PureComponent { if (query.datasource === undefined) { - query.datasource = { type: this.props.dataSource.type, uid: this.props.dataSource.uid }; + query.datasource = getDataSourceRef(this.props.dataSource); } this.props.onChange({ diff --git a/public/app/features/query/components/QueryEditorRows.tsx b/public/app/features/query/components/QueryEditorRows.tsx index 024c1da6d80..c3854935f4b 100644 --- a/public/app/features/query/components/QueryEditorRows.tsx +++ b/public/app/features/query/components/QueryEditorRows.tsx @@ -5,10 +5,10 @@ import { CoreApp, DataQuery, DataSourceInstanceSettings, - DataSourceRef, EventBusExtended, HistoryItem, PanelData, + getDataSourceRef, } from '@grafana/data'; import { getDataSourceSrv, reportInteraction } from '@grafana/runtime'; @@ -65,10 +65,7 @@ export class QueryEditorRows extends PureComponent { return item; } - const dataSourceRef: DataSourceRef = { - type: dataSource.type, - uid: dataSource.uid, - }; + const dataSourceRef = getDataSourceRef(dataSource); if (item.datasource) { const previous = getDataSourceSrv().getInstanceSettings(item.datasource); diff --git a/public/app/features/query/components/QueryGroup.tsx b/public/app/features/query/components/QueryGroup.tsx index 79361af6ad3..ffa97a3fce2 100644 --- a/public/app/features/query/components/QueryGroup.tsx +++ b/public/app/features/query/components/QueryGroup.tsx @@ -7,6 +7,7 @@ import { CoreApp, DataSourceApi, DataSourceInstanceSettings, + getDataSourceRef, getDefaultTimeRange, LoadingState, PanelData, @@ -149,8 +150,7 @@ export class QueryGroup extends PureComponent { dataSource: { name: newSettings.name, uid: newSettings.uid, - type: newSettings.meta.id, - default: newSettings.isDefault, + ...getDataSourceRef(newSettings), }, }); @@ -174,11 +174,16 @@ export class QueryGroup extends PureComponent { newQuery(): Partial { const { dsSettings, defaultDataSource } = this.state; - const ds = !dsSettings?.meta.mixed ? dsSettings : defaultDataSource; + const ds = + dsSettings && !dsSettings.meta.mixed + ? getDataSourceRef(dsSettings) + : defaultDataSource + ? defaultDataSource.getRef() + : { type: undefined, uid: undefined }; return { ...this.state.dataSource?.getDefaultQuery?.(CoreApp.PanelEditor), - datasource: { uid: ds?.uid, type: ds?.type }, + datasource: ds, }; } @@ -241,7 +246,9 @@ export class QueryGroup extends PureComponent { onAddQuery = (query: Partial) => { const { dsSettings, queries } = this.state; - this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid })); + this.onQueriesChange( + addQuery(queries, query, dsSettings ? getDataSourceRef(dsSettings) : { type: undefined, uid: undefined }) + ); this.onScrollBottom(); }; diff --git a/public/app/features/query/state/updateQueries.test.ts b/public/app/features/query/state/updateQueries.test.ts index 155b70545af..f213f75a420 100644 --- a/public/app/features/query/state/updateQueries.test.ts +++ b/public/app/features/query/state/updateQueries.test.ts @@ -12,6 +12,7 @@ const oldUidDS = { meta: { id: 'old-type', }, + getRef: () => ({ uid: 'old-uid', type: 'old-type' }), } as DataSourceApi; const mixedDS = { @@ -20,6 +21,7 @@ const mixedDS = { id: 'mixed', mixed: true, }, + getRef: () => ({ uid: 'mixed' }), } as DataSourceApi; const newUidDS = { @@ -28,6 +30,7 @@ const newUidDS = { meta: { id: 'new-type', }, + getRef: () => ({ uid: 'new-uid', type: 'new-type' }), } as DataSourceApi; const newUidSameTypeDS = { @@ -36,6 +39,7 @@ const newUidSameTypeDS = { meta: { id: 'old-type', }, + getRef: () => ({ uid: 'new-uid-same-type', type: 'old-type' }), } as DataSourceApi; const templateSrv = new TemplateSrv(); @@ -376,6 +380,7 @@ describe('updateQueries with import', () => { const importedQueries = queries.map((q) => ({ ...q, imported: true })); return Promise.resolve(importedQueries); }, + getRef: () => ({ uid: 'new-uid', type: 'new-type' }), } as DataSourceWithQueryImportSupport; const oldUidDSWithAbstract = { @@ -389,6 +394,7 @@ describe('updateQueries with import', () => { const exportedQueries = queries.map((q) => ({ ...q, exported: true })); return Promise.resolve(exportedQueries); }, + getRef: () => ({ uid: 'old-uid', type: 'old-type' }), } as DataSourceWithQueryExportSupport; const queries = [ @@ -452,6 +458,7 @@ describe('updateQueries with import', () => { importFromAbstractQueries: () => { return Promise.resolve([]); }, + getRef: () => ({ uid: 'new-uid', type: 'new-type' }), } as DataSourceWithQueryImportSupport; const oldUidDSWithAbstract = { @@ -464,6 +471,7 @@ describe('updateQueries with import', () => { const exportedQueries = queries.map((q) => ({ ...q, exported: true })); return Promise.resolve(exportedQueries); }, + getRef: () => ({ uid: 'old-uid', type: 'old-type' }), } as DataSourceWithQueryExportSupport; const queries = [ @@ -510,6 +518,7 @@ describe('updateQueries with import', () => { const importedQueries = queries.map((q) => ({ ...q, imported: true })); return Promise.resolve(importedQueries); }, + getRef: () => ({ uid: 'new-uid', type: 'new-type' }), } as DataSourceApi; const oldUidDS = { @@ -573,6 +582,7 @@ describe('updateQueries with import', () => { importQueries: (queries, origin) => { return Promise.resolve([] as DataQuery[]); }, + getRef: () => ({ uid: 'new-uid', type: 'new-type' }), } as DataSourceApi; const oldUidDS = { diff --git a/public/app/features/query/state/updateQueries.ts b/public/app/features/query/state/updateQueries.ts index e8464ac40f5..f19030e6fd4 100644 --- a/public/app/features/query/state/updateQueries.ts +++ b/public/app/features/query/state/updateQueries.ts @@ -10,7 +10,7 @@ export async function updateQueries( currentDS?: DataSourceApi ): Promise { let nextQueries = queries; - const datasource = { type: nextDS.type, uid: nextDSUidOrVariableExpression }; + const datasource = { ...nextDS.getRef(), uid: nextDSUidOrVariableExpression }; const DEFAULT_QUERY = { ...nextDS?.getDefaultQuery?.(CoreApp.PanelEditor), datasource, refId: 'A' }; // we are changing data source type