From 34f2a72ff2b64ef44abc1ddf206cb232900451c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 1 Dec 2020 19:10:23 +0100 Subject: [PATCH] DataLinks: Removes getDataSourceSettingsByUid from applyFieldOverrides (#29447) * DataLinks: Removes getDataSourceSettingsByUid from applyFieldOverrides and data linking code * Fixed test * Fixed a few tests * Fixed unit tests * Removed old getDataSourceSettingsByUid from interface, still there for runtime backward compatability --- .../src/field/fieldOverrides.test.ts | 8 +-- .../grafana-data/src/field/fieldOverrides.ts | 26 ++++---- .../field/getFieldDisplayValuesProxy.test.tsx | 1 - packages/grafana-data/src/types/dataLink.ts | 12 ++-- .../grafana-data/src/types/fieldOverrides.ts | 11 +--- .../grafana-data/src/utils/dataLinks.test.ts | 37 ++++++------ packages/grafana-data/src/utils/dataLinks.ts | 40 +++++-------- .../src/services/dataSourceSrv.ts | 6 -- .../grafana-ui/src/utils/storybook/data.ts | 1 - .../getAlertingValidationMessage.test.ts | 5 -- .../components/Inspector/InspectDataTab.tsx | 2 - .../dashboard/state/PanelModel.test.ts | 7 --- .../features/dashboard/state/PanelModel.ts | 2 - .../dashboard/utils/loadSnapshotData.ts | 2 - .../explore/TraceView/createSpanLink.test.ts | 6 +- .../explore/TraceView/createSpanLink.tsx | 11 +++- public/app/features/explore/state/main.ts | 2 +- .../app/features/explore/utils/links.test.ts | 27 +-------- public/app/features/explore/utils/links.ts | 10 +++- .../panel/panellinks/linkSuppliers.test.ts | 1 - .../query/state/PanelQueryRunner.test.ts | 10 +--- .../elasticsearch/datasource.test.ts | 8 +++ .../datasource/elasticsearch/datasource.ts | 60 +++++++++++-------- .../loki/result_transformer.test.ts | 16 ++++- .../datasource/loki/result_transformer.ts | 7 ++- public/app/plugins/panel/live/LivePanel.tsx | 1 - 26 files changed, 143 insertions(+), 176 deletions(-) diff --git a/packages/grafana-data/src/field/fieldOverrides.test.ts b/packages/grafana-data/src/field/fieldOverrides.test.ts index d8ebd19e783..6dec551e88d 100644 --- a/packages/grafana-data/src/field/fieldOverrides.test.ts +++ b/packages/grafana-data/src/field/fieldOverrides.test.ts @@ -183,7 +183,6 @@ describe('applyFieldOverrides', () => { overrides: [], }, replaceVariables: (value: any) => value, - getDataSourceSettingsByUid: undefined as any, theme: getTestTheme(), fieldConfigRegistry: new FieldConfigOptionsRegistry(), }); @@ -245,7 +244,6 @@ describe('applyFieldOverrides', () => { overrides: [], }, fieldConfigRegistry: customFieldRegistry, - getDataSourceSettingsByUid: undefined as any, replaceVariables: v => v, theme: getTestTheme(), })[0]; @@ -263,7 +261,6 @@ describe('applyFieldOverrides', () => { data: [f0], // the frame fieldConfig: src as FieldConfigSource, // defaults + overrides replaceVariables: (undefined as any) as InterpolateFunction, - getDataSourceSettingsByUid: undefined as any, theme: getTestTheme(), fieldConfigRegistry: customFieldRegistry, })[0]; @@ -291,7 +288,6 @@ describe('applyFieldOverrides', () => { data: [f0], // the frame fieldConfig: src as FieldConfigSource, // defaults + overrides replaceVariables: (undefined as any) as InterpolateFunction, - getDataSourceSettingsByUid: undefined as any, theme: getTestTheme(), })[0]; const valueColumn = data.fields[1]; @@ -314,7 +310,6 @@ describe('applyFieldOverrides', () => { replaceVariablesCalls.push(variables); return value; }) as InterpolateFunction, - getDataSourceSettingsByUid: undefined as any, theme: getTestTheme(), fieldConfigRegistry: customFieldRegistry, })[0]; @@ -565,7 +560,6 @@ describe('getLinksSupplier', () => { {}, replaceSpy, // this is used only for internal links so isn't needed here - () => ({} as any), { theme: getTestTheme(), } @@ -598,6 +592,7 @@ describe('getLinksSupplier', () => { title: '', internal: { datasourceUid: '0', + datasourceName: 'testDS', query: '12345', }, }, @@ -613,7 +608,6 @@ describe('getLinksSupplier', () => { {}, // We do not need to interpolate anything for this test (value, vars, format) => value, - uid => ({ name: 'testDS' } as any), { theme: getTestTheme() } ); const links = supplier({ valueRowIndex: 0 }); diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index a1f141a80a1..40e56d6f882 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -2,7 +2,6 @@ import { ApplyFieldOverrideOptions, DataFrame, DataLink, - DataSourceInstanceSettings, DynamicConfigValue, Field, FieldColorModeId, @@ -130,7 +129,6 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra data: options.data!, dataFrameIndex: index, replaceVariables: options.replaceVariables, - getDataSourceSettingsByUid: options.getDataSourceSettingsByUid, fieldConfigRegistry: fieldConfigRegistry, }; @@ -211,17 +209,10 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra }); // Attach data links supplier - newField.getLinks = getLinksSupplier( - newFrame, - newField, - fieldScopedVars, - context.replaceVariables, - context.getDataSourceSettingsByUid, - { - theme: options.theme, - timeZone: options.timeZone, - } - ); + newField.getLinks = getLinksSupplier(newFrame, newField, fieldScopedVars, context.replaceVariables, { + theme: options.theme, + timeZone: options.timeZone, + }); return newField; }); @@ -336,7 +327,6 @@ export const getLinksSupplier = ( field: Field, fieldScopedVars: ScopedVars, replaceVariables: InterpolateFunction, - getDataSourceSettingsByUid: (uid: string) => DataSourceInstanceSettings | undefined, options: { theme: GrafanaTheme; timeZone?: TimeZone; @@ -401,9 +391,13 @@ export const getLinksSupplier = ( if (link.internal) { // For internal links at the moment only destination is Explore. - return mapInternalLinkToExplore(link, variables, {} as any, field, { + return mapInternalLinkToExplore({ + link, + internalLink: link.internal, + scopedVars: variables, + field, + range: {} as any, replaceVariables, - getDataSourceSettingsByUid, }); } else { let href = locationUtil.assureBaseUrl(link.url.replace(/\n/g, '')); diff --git a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx index 26aa02f9261..334069ec2ea 100644 --- a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx +++ b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx @@ -29,7 +29,6 @@ describe('getFieldDisplayValuesProxy', () => { overrides: [], }, replaceVariables: (val: string) => val, - getDataSourceSettingsByUid: (val: string) => ({} as any), timeZone: 'utc', theme: getTestTheme(), })[0]; diff --git a/packages/grafana-data/src/types/dataLink.ts b/packages/grafana-data/src/types/dataLink.ts index e27a65d0644..22bec524aea 100644 --- a/packages/grafana-data/src/types/dataLink.ts +++ b/packages/grafana-data/src/types/dataLink.ts @@ -36,10 +36,14 @@ export interface DataLink { // datas ource that we want to show to the user. Usually this results in a link to explore but can also lead to // more custom onClick behaviour if needed. // @internal and subject to change in future releases - internal?: { - query: T; - datasourceUid: string; - }; + internal?: InternalDataLink; +} + +/** @internal */ +export interface InternalDataLink { + query: T; + datasourceUid: string; + datasourceName: string; } export type LinkTarget = '_blank' | '_self' | undefined; diff --git a/packages/grafana-data/src/types/fieldOverrides.ts b/packages/grafana-data/src/types/fieldOverrides.ts index cedce20cbd2..3c8038e81e2 100644 --- a/packages/grafana-data/src/types/fieldOverrides.ts +++ b/packages/grafana-data/src/types/fieldOverrides.ts @@ -1,13 +1,5 @@ import { ComponentType } from 'react'; -import { - MatcherConfig, - FieldConfig, - Field, - DataFrame, - GrafanaTheme, - TimeZone, - DataSourceInstanceSettings, -} from '../types'; +import { MatcherConfig, FieldConfig, Field, DataFrame, GrafanaTheme, TimeZone } from '../types'; import { InterpolateFunction } from './panel'; import { StandardEditorProps, FieldConfigOptionsRegistry, StandardEditorContext } from '../field'; import { OptionsEditorItem } from './OptionsUIRegistryBuilder'; @@ -114,7 +106,6 @@ export interface ApplyFieldOverrideOptions { data?: DataFrame[]; fieldConfig: FieldConfigSource; replaceVariables: InterpolateFunction; - getDataSourceSettingsByUid: (uid: string) => DataSourceInstanceSettings | undefined; theme: GrafanaTheme; timeZone?: TimeZone; fieldConfigRegistry?: FieldConfigOptionsRegistry; diff --git a/packages/grafana-data/src/utils/dataLinks.test.ts b/packages/grafana-data/src/utils/dataLinks.test.ts index 087c2be4bd6..eaa21dd684d 100644 --- a/packages/grafana-data/src/utils/dataLinks.test.ts +++ b/packages/grafana-data/src/utils/dataLinks.test.ts @@ -4,33 +4,34 @@ import { ArrayVector } from '../vector'; describe('mapInternalLinkToExplore', () => { it('creates internal link', () => { - const link = mapInternalLinkToExplore( - { - url: '', - title: '', - internal: { - datasourceUid: 'uid', - query: { query: '12344' }, - }, + const dataLink = { + url: '', + title: '', + internal: { + datasourceUid: 'uid', + datasourceName: 'dsName', + query: { query: '12344' }, }, - {}, - {} as any, - { + }; + + const link = mapInternalLinkToExplore({ + link: dataLink, + internalLink: dataLink.internal, + scopedVars: {}, + range: {} as any, + field: { name: 'test', type: FieldType.number, config: {}, values: new ArrayVector([2]), }, - { - replaceVariables: val => val, - getDataSourceSettingsByUid: uid => ({ name: 'testDS' } as any), - } - ); + replaceVariables: val => val, + }); expect(link).toEqual( expect.objectContaining({ - title: 'testDS', - href: '/explore?left={"datasource":"testDS","queries":[{"query":"12344"}]}', + title: 'dsName', + href: '/explore?left={"datasource":"dsName","queries":[{"query":"12344"}]}', onClick: undefined, }) ); diff --git a/packages/grafana-data/src/utils/dataLinks.ts b/packages/grafana-data/src/utils/dataLinks.ts index 0783f59966d..957907a092b 100644 --- a/packages/grafana-data/src/utils/dataLinks.ts +++ b/packages/grafana-data/src/utils/dataLinks.ts @@ -1,8 +1,8 @@ import { DataLink, DataQuery, - DataSourceInstanceSettings, Field, + InternalDataLink, InterpolateFunction, LinkModel, ScopedVars, @@ -27,41 +27,31 @@ export const DataLinkBuiltInVars = { }; // We inject these because we cannot import them directly as they reside inside grafana main package. -type Options = { +export type LinkToExploreOptions = { + link: DataLink; + scopedVars: ScopedVars; + range: TimeRange; + field: Field; + internalLink: InternalDataLink; onClickFn?: (options: { datasourceUid: string; query: any; range?: TimeRange }) => void; replaceVariables: InterpolateFunction; - getDataSourceSettingsByUid: (uid: string) => DataSourceInstanceSettings | undefined; }; -export function mapInternalLinkToExplore( - link: DataLink, - scopedVars: ScopedVars, - range: TimeRange, - field: Field, - options: Options -): LinkModel { - if (!link.internal) { - throw new Error('Trying to map external link as internal'); - } - const { onClickFn, replaceVariables, getDataSourceSettingsByUid } = options; +export function mapInternalLinkToExplore(options: LinkToExploreOptions): LinkModel { + const { onClickFn, replaceVariables, link, scopedVars, range, field, internalLink } = options; const interpolatedQuery = interpolateQuery(link, scopedVars, replaceVariables); - return { - title: link.title - ? replaceVariables(link.title || '', scopedVars) - : getDataSourceSettingsByUid(link.internal.datasourceUid)?.name || 'Unknown datasource', + const title = link.title ? link.title : internalLink.datasourceName; + return { + title: replaceVariables(title), // In this case this is meant to be internal link (opens split view by default) the href will also points // to explore but this way you can open it in new tab. - href: generateInternalHref( - getDataSourceSettingsByUid(link.internal.datasourceUid)?.name || 'unknown', - interpolatedQuery, - range - ), + href: generateInternalHref(internalLink.datasourceName, interpolatedQuery, range), onClick: onClickFn ? () => { - onClickFn?.({ - datasourceUid: link.internal!.datasourceUid, + onClickFn({ + datasourceUid: internalLink.datasourceUid, query: interpolatedQuery, range, }); diff --git a/packages/grafana-runtime/src/services/dataSourceSrv.ts b/packages/grafana-runtime/src/services/dataSourceSrv.ts index f06d8408a2c..96758a0a4b2 100644 --- a/packages/grafana-runtime/src/services/dataSourceSrv.ts +++ b/packages/grafana-runtime/src/services/dataSourceSrv.ts @@ -15,12 +15,6 @@ export interface DataSourceSrv { */ get(name?: string | null, scopedVars?: ScopedVars): Promise; - /** - * Returns metadata based on UID. - * @deprecated use getInstanceSettings - */ - getDataSourceSettingsByUid(uid: string): DataSourceInstanceSettings | undefined; - /** * Get all data sources */ diff --git a/packages/grafana-ui/src/utils/storybook/data.ts b/packages/grafana-ui/src/utils/storybook/data.ts index be008d93ed6..0063fc482b7 100644 --- a/packages/grafana-ui/src/utils/storybook/data.ts +++ b/packages/grafana-ui/src/utils/storybook/data.ts @@ -9,6 +9,5 @@ export function prepDataForStorybook(data: DataFrame[], theme: GrafanaTheme) { }, theme, replaceVariables: (value: string) => value, - getDataSourceSettingsByUid: (value: string) => ({} as any), }); } diff --git a/public/app/features/alerting/getAlertingValidationMessage.test.ts b/public/app/features/alerting/getAlertingValidationMessage.test.ts index 57c06cdf507..e98c5c071a3 100644 --- a/public/app/features/alerting/getAlertingValidationMessage.test.ts +++ b/public/app/features/alerting/getAlertingValidationMessage.test.ts @@ -22,7 +22,6 @@ describe('getAlertingValidationMessage', () => { const getMock = jest.fn().mockResolvedValue(datasource); const datasourceSrv: DataSourceSrv = { get: getMock, - getDataSourceSettingsByUid(): any {}, getExternal(): DataSourceInstanceSettings[] { return []; }, @@ -66,7 +65,6 @@ describe('getAlertingValidationMessage', () => { return Promise.resolve(alertingDatasource); }, - getDataSourceSettingsByUid(): any {}, getInstanceSettings: (() => {}) as any, getExternal(): DataSourceInstanceSettings[] { return []; @@ -97,7 +95,6 @@ describe('getAlertingValidationMessage', () => { const getMock = jest.fn().mockResolvedValue(datasource); const datasourceSrv: DataSourceSrv = { get: getMock, - getDataSourceSettingsByUid(): any {}, getInstanceSettings: (() => {}) as any, getExternal(): DataSourceInstanceSettings[] { return []; @@ -130,7 +127,6 @@ describe('getAlertingValidationMessage', () => { const getMock = jest.fn().mockResolvedValue(datasource); const datasourceSrv: DataSourceSrv = { get: getMock, - getDataSourceSettingsByUid(): any {}, getInstanceSettings: (() => {}) as any, getExternal(): DataSourceInstanceSettings[] { return []; @@ -163,7 +159,6 @@ describe('getAlertingValidationMessage', () => { const getMock = jest.fn().mockResolvedValue(datasource); const datasourceSrv: DataSourceSrv = { get: getMock, - getDataSourceSettingsByUid(): any {}, getInstanceSettings: (() => {}) as any, getExternal(): DataSourceInstanceSettings[] { return []; diff --git a/public/app/features/dashboard/components/Inspector/InspectDataTab.tsx b/public/app/features/dashboard/components/Inspector/InspectDataTab.tsx index 65d90e5f985..ec3979d0563 100644 --- a/public/app/features/dashboard/components/Inspector/InspectDataTab.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectDataTab.tsx @@ -23,7 +23,6 @@ import { GetDataOptions } from '../../../query/state/PanelQueryRunner'; import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow'; import { PanelModel } from 'app/features/dashboard/state'; import { DetailText } from './DetailText'; -import { getDatasourceSrv } from '../../../plugins/datasource_srv'; interface Props { panel: PanelModel; @@ -125,7 +124,6 @@ export class InspectDataTab extends PureComponent { replaceVariables: (value: string) => { return value; }, - getDataSourceSettingsByUid: getDatasourceSrv().getDataSourceSettingsByUid, }); } diff --git a/public/app/features/dashboard/state/PanelModel.test.ts b/public/app/features/dashboard/state/PanelModel.test.ts index 3af984340c9..8087ac5bb2f 100644 --- a/public/app/features/dashboard/state/PanelModel.test.ts +++ b/public/app/features/dashboard/state/PanelModel.test.ts @@ -7,13 +7,11 @@ import { standardEditorsRegistry, standardFieldConfigEditorRegistry, PanelData, - DataSourceInstanceSettings, FieldColorModeId, FieldColorConfigSettings, } from '@grafana/data'; import { ComponentClass } from 'react'; import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; -import { setDataSourceSrv } from '@grafana/runtime'; class TablePanelCtrl {} @@ -192,11 +190,6 @@ describe('PanelModel', () => { }); it('should apply field config defaults', () => { - setDataSourceSrv({ - getDataSourceSettingsByUid(uid: string): DataSourceInstanceSettings | undefined { - return undefined; - }, - } as any); // default unit is overriden by model expect(model.getFieldOverrideOptions().fieldConfig.defaults.unit).toBe('mpg'); // default decimals are aplied diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 4496c7a44fb..36e7525749b 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -26,7 +26,6 @@ import { import { EDIT_PANEL_ID } from 'app/core/constants'; import config from 'app/core/config'; import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; -import { getDatasourceSrv } from '../../plugins/datasource_srv'; import { PanelOptionsChangedEvent, PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events'; export interface GridPos { @@ -462,7 +461,6 @@ export class PanelModel implements DataConfigSource { return { fieldConfig: this.fieldConfig, replaceVariables: this.replaceVariables, - getDataSourceSettingsByUid: getDatasourceSrv().getDataSourceSettingsByUid.bind(getDatasourceSrv()), fieldConfigRegistry: this.plugin.fieldConfigRegistry, theme: config.theme, }; diff --git a/public/app/features/dashboard/utils/loadSnapshotData.ts b/public/app/features/dashboard/utils/loadSnapshotData.ts index 64b1e40c5cb..0168a64ef4e 100644 --- a/public/app/features/dashboard/utils/loadSnapshotData.ts +++ b/public/app/features/dashboard/utils/loadSnapshotData.ts @@ -1,6 +1,5 @@ import { applyFieldOverrides, DefaultTimeRange, LoadingState, PanelData } from '@grafana/data'; import { config } from 'app/core/config'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { DashboardModel, PanelModel } from '../state'; import { getProcessedDataFrames } from '../../query/state/runRequest'; @@ -17,7 +16,6 @@ export function loadSnapshotData(panel: PanelModel, dashboard: DashboardModel): overrides: [], }, replaceVariables: panel.replaceVariables, - getDataSourceSettingsByUid: getDatasourceSrv().getDataSourceSettingsByUid.bind(getDatasourceSrv()), fieldConfigRegistry: panel.plugin!.fieldConfigRegistry, theme: config.theme, timeZone: dashboard.getTimezone(), diff --git a/public/app/features/explore/TraceView/createSpanLink.test.ts b/public/app/features/explore/TraceView/createSpanLink.test.ts index 40da9256870..46088b4e198 100644 --- a/public/app/features/explore/TraceView/createSpanLink.test.ts +++ b/public/app/features/explore/TraceView/createSpanLink.test.ts @@ -41,10 +41,10 @@ describe('createSpanLinkFactory', () => { } as DataSourceInstanceSettings, ]; }, - getDataSourceSettingsByUid(uid: string): DataSourceInstanceSettings | undefined { + getInstanceSettings(uid: string): DataSourceInstanceSettings | undefined { if (uid === 'lokiUid') { return { - name: 'Loki1', + name: 'loki1', } as any; } return undefined; @@ -82,7 +82,7 @@ describe('createSpanLinkFactory', () => { } as any); expect(linkDef.href).toBe( - `/explore?left={"range":{"from":"20201014T000000","to":"20201014T010006"},"datasource":"Loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"}","refId":""}]}` + `/explore?left={"range":{"from":"20201014T000000","to":"20201014T010006"},"datasource":"loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"}","refId":""}]}` ); }); }); diff --git a/public/app/features/explore/TraceView/createSpanLink.tsx b/public/app/features/explore/TraceView/createSpanLink.tsx index 2a85d45d0cf..b9ac8dc5f7c 100644 --- a/public/app/features/explore/TraceView/createSpanLink.tsx +++ b/public/app/features/explore/TraceView/createSpanLink.tsx @@ -34,17 +34,24 @@ export function createSpanLinkFactory(splitOpenFn: (options: { datasourceUid: st url: '', internal: { datasourceUid: lokiDs.uid, + datasourceName: lokiDs.name, query: { expr: getLokiQueryFromSpan(span), refId: '', }, }, }; - const link = mapInternalLinkToExplore(dataLink, {}, getTimeRangeFromSpan(span), {} as Field, { + + const link = mapInternalLinkToExplore({ + link: dataLink, + internalLink: dataLink.internal!, + scopedVars: {}, + range: getTimeRangeFromSpan(span), + field: {} as Field, onClickFn: splitOpenFn, replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()), - getDataSourceSettingsByUid: getDataSourceSrv().getDataSourceSettingsByUid.bind(getDataSourceSrv()), }); + return { href: link.href, onClick: link.onClick, diff --git a/public/app/features/explore/state/main.ts b/public/app/features/explore/state/main.ts index 4ee5c1281ac..5e2bf7a5351 100644 --- a/public/app/features/explore/state/main.ts +++ b/public/app/features/explore/state/main.ts @@ -109,7 +109,7 @@ export function splitOpen(options?: { } as DataQuery, ]; - const dataSourceSettings = getDatasourceSrv().getDataSourceSettingsByUid(options.datasourceUid); + const dataSourceSettings = getDatasourceSrv().getInstanceSettings(options.datasourceUid); await dispatch(changeDatasource(ExploreId.right, dataSourceSettings!.name)); await dispatch(setQueriesAction({ exploreId: ExploreId.right, queries })); diff --git a/public/app/features/explore/utils/links.test.ts b/public/app/features/explore/utils/links.test.ts index 8d1c66c96be..57b275dcf1a 100644 --- a/public/app/features/explore/utils/links.test.ts +++ b/public/app/features/explore/utils/links.test.ts @@ -1,17 +1,6 @@ import { getFieldLinksForExplore } from './links'; -import { - ArrayVector, - DataLink, - DataSourceInstanceSettings, - dateTime, - Field, - FieldType, - LinkModel, - ScopedVars, - TimeRange, -} from '@grafana/data'; +import { ArrayVector, DataLink, dateTime, Field, FieldType, LinkModel, ScopedVars, TimeRange } from '@grafana/data'; import { setLinkSrv } from '../../panel/panellinks/link_srv'; -import { setDataSourceSrv } from '@grafana/runtime'; describe('getFieldLinksForExplore', () => { it('returns correct link model for external link', () => { @@ -43,6 +32,7 @@ describe('getFieldLinksForExplore', () => { internal: { query: { query: 'query_1' }, datasourceUid: 'uid_1', + datasourceName: 'test_ds', }, }); const splitfn = jest.fn(); @@ -82,18 +72,7 @@ function setup(link: DataLink) { return link.url; }, }); - setDataSourceSrv({ - getDataSourceSettingsByUid(uid: string) { - return { - id: 1, - uid: 'uid_1', - type: 'metrics', - name: 'test_ds', - meta: {}, - jsonData: {}, - } as DataSourceInstanceSettings; - }, - } as any); + const field: Field = { name: 'flux-dimensions', type: FieldType.string, diff --git a/public/app/features/explore/utils/links.ts b/public/app/features/explore/utils/links.ts index eb601f4b550..fc1a7c54842 100644 --- a/public/app/features/explore/utils/links.ts +++ b/public/app/features/explore/utils/links.ts @@ -1,6 +1,6 @@ import { Field, LinkModel, TimeRange, mapInternalLinkToExplore } from '@grafana/data'; import { getLinkSrv } from '../../panel/panellinks/link_srv'; -import { getDataSourceSrv, getTemplateSrv } from '@grafana/runtime'; +import { getTemplateSrv } from '@grafana/runtime'; import { splitOpen } from '../state/main'; /** @@ -33,10 +33,14 @@ export const getFieldLinksForExplore = ( } return linkModel; } else { - return mapInternalLinkToExplore(link, scopedVars, range, field, { + return mapInternalLinkToExplore({ + link, + internalLink: link.internal, + scopedVars: scopedVars, + range, + field, onClickFn: splitOpenFn, replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()), - getDataSourceSettingsByUid: getDataSourceSrv().getDataSourceSettingsByUid.bind(getDataSourceSrv()), }); } }) diff --git a/public/app/features/panel/panellinks/linkSuppliers.test.ts b/public/app/features/panel/panellinks/linkSuppliers.test.ts index d75a097d137..4abf5a4a3aa 100644 --- a/public/app/features/panel/panellinks/linkSuppliers.test.ts +++ b/public/app/features/panel/panellinks/linkSuppliers.test.ts @@ -90,7 +90,6 @@ describe('getFieldLinksSupplier', () => { overrides: [], }, replaceVariables: (val: string) => val, - getDataSourceSettingsByUid: (val: string) => ({} as any), timeZone: 'utc', theme: getTheme(), })[0]; diff --git a/public/app/features/query/state/PanelQueryRunner.test.ts b/public/app/features/query/state/PanelQueryRunner.test.ts index 092b33e16a0..f0362a8eecf 100644 --- a/public/app/features/query/state/PanelQueryRunner.test.ts +++ b/public/app/features/query/state/PanelQueryRunner.test.ts @@ -88,11 +88,8 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn }, ], }; - setDataSourceSrv({ - getDataSourceSettingsByUid() { - return {} as any; - }, - } as any); + + setDataSourceSrv({} as any); beforeEach(async () => { setEchoSrv(new Echo()); @@ -241,7 +238,6 @@ describe('PanelQueryRunner', () => { overrides: [], }, replaceVariables: v => v, - getDataSourceSettingsByUid: undefined as any, theme: {} as GrafanaTheme, }), getTransformations: () => undefined, @@ -306,7 +302,6 @@ describe('PanelQueryRunner', () => { overrides: [], }, replaceVariables: v => v, - getDataSourceSettingsByUid: undefined as any, theme: {} as GrafanaTheme, }), // @ts-ignore @@ -349,7 +344,6 @@ describe('PanelQueryRunner', () => { overrides: [], }, replaceVariables: v => v, - getDataSourceSettingsByUid: undefined as any, theme: {} as GrafanaTheme, }), // @ts-ignore diff --git a/public/app/plugins/datasource/elasticsearch/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/datasource.test.ts index 84f58745445..15a570c0498 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.test.ts @@ -22,6 +22,13 @@ const ELASTICSEARCH_MOCK_URL = 'http://elasticsearch.local'; jest.mock('@grafana/runtime', () => ({ ...((jest.requireActual('@grafana/runtime') as unknown) as object), getBackendSrv: () => backendSrv, + getDataSourceSrv: () => { + return { + getInstanceSettings: () => { + return { name: 'elastic25' }; + }, + }; + }, })); describe('ElasticDatasource', function(this: any) { @@ -932,6 +939,7 @@ describe('enhanceDataFrame', () => { url: '', internal: { query: { query: 'query' }, + datasourceName: 'elastic25', datasourceUid: 'dsUid', }, }); diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 520a06dafb2..05665a5a302 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -17,7 +17,7 @@ import { IndexPattern } from './index_pattern'; import { ElasticQueryBuilder } from './query_builder'; import { toUtc } from '@grafana/data'; import * as queryDef from './query_def'; -import { getBackendSrv } from '@grafana/runtime'; +import { getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { DataLinkConfig, ElasticsearchOptions, ElasticsearchQuery } from './types'; @@ -661,29 +661,41 @@ export class ElasticDatasource extends DataSourceApi field.name && field.name.match(dataLink.field)); - if (dataLinkConfig) { - let link: DataLink; - if (dataLinkConfig.datasourceUid) { - link = { - title: '', - url: '', - internal: { - query: { query: dataLinkConfig.url }, - datasourceUid: dataLinkConfig.datasourceUid, - }, - }; - } else { - link = { - title: '', - url: dataLinkConfig.url, - }; - } - field.config = field.config || {}; - field.config.links = [...(field.config.links || []), link]; - } + const dataSourceSrv = getDataSourceSrv(); + + if (!dataLinks.length) { + return; + } + + for (const field of dataFrame.fields) { + const dataLinkConfig = dataLinks.find(dataLink => field.name && field.name.match(dataLink.field)); + + if (!dataLinkConfig) { + continue; } + + let link: DataLink; + + if (dataLinkConfig.datasourceUid) { + const dsSettings = dataSourceSrv.getInstanceSettings(dataLinkConfig.datasourceUid); + + link = { + title: '', + url: '', + internal: { + query: { query: dataLinkConfig.url }, + datasourceUid: dataLinkConfig.datasourceUid, + datasourceName: dsSettings?.name ?? 'Data source not found', + }, + }; + } else { + link = { + title: '', + url: dataLinkConfig.url, + }; + } + + field.config = field.config || {}; + field.config.links = [...(field.config.links || []), link]; } } diff --git a/public/app/plugins/datasource/loki/result_transformer.test.ts b/public/app/plugins/datasource/loki/result_transformer.test.ts index 73d20dbfd84..9933d26e48d 100644 --- a/public/app/plugins/datasource/loki/result_transformer.test.ts +++ b/public/app/plugins/datasource/loki/result_transformer.test.ts @@ -33,6 +33,18 @@ const lokiResponse: LokiStreamResponse = { }, }; +jest.mock('@grafana/runtime', () => ({ + // @ts-ignore + ...jest.requireActual('@grafana/runtime'), + getDataSourceSrv: () => { + return { + getInstanceSettings: () => { + return { name: 'Loki1' }; + }, + }; + }, +})); + describe('loki result transformer', () => { beforeAll(() => { setTemplateSrv(new TemplateSrv()); @@ -167,12 +179,12 @@ describe('enhanceDataFrame', () => { expect(fc.getFieldByName('trace2')!.config.links!.length).toBe(2); expect(fc.getFieldByName('trace2')!.config.links![0]).toEqual({ title: '', - internal: { datasourceUid: 'uid', query: { query: 'test' } }, + internal: { datasourceName: 'Loki1', datasourceUid: 'uid', query: { query: 'test' } }, url: '', }); expect(fc.getFieldByName('trace2')!.config.links![1]).toEqual({ title: '', - internal: { datasourceUid: 'uid2', query: { query: 'test' } }, + internal: { datasourceName: 'Loki1', datasourceUid: 'uid2', query: { query: 'test' } }, url: '', }); }); diff --git a/public/app/plugins/datasource/loki/result_transformer.ts b/public/app/plugins/datasource/loki/result_transformer.ts index 3788224d568..b79ae0178db 100644 --- a/public/app/plugins/datasource/loki/result_transformer.ts +++ b/public/app/plugins/datasource/loki/result_transformer.ts @@ -19,7 +19,7 @@ import { ScopedVars, } from '@grafana/data'; -import { getTemplateSrv } from '@grafana/runtime'; +import { getTemplateSrv, getDataSourceSrv } from '@grafana/runtime'; import TableModel from 'app/core/table_model'; import { formatQuery, getHighlighterExpressionsFromQuery } from './query_utils'; import { @@ -387,9 +387,13 @@ export const enhanceDataFrame = (dataFrame: DataFrame, config: LokiOptions | nul * Transform derivedField config into dataframe field with config that contains link. */ function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field { + const dataSourceSrv = getDataSourceSrv(); + const dataLinks = derivedFieldConfigs.reduce((acc, derivedFieldConfig) => { // Having field.datasourceUid means it is an internal link. if (derivedFieldConfig.datasourceUid) { + const dsSettings = dataSourceSrv.getInstanceSettings(derivedFieldConfig.datasourceUid); + acc.push({ // Will be filled out later title: '', @@ -398,6 +402,7 @@ function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): internal: { query: { query: derivedFieldConfig.url }, datasourceUid: derivedFieldConfig.datasourceUid, + datasourceName: dsSettings?.name ?? 'Data source not found', }, }); } else if (derivedFieldConfig.url) { diff --git a/public/app/plugins/panel/live/LivePanel.tsx b/public/app/plugins/panel/live/LivePanel.tsx index 2567140735a..40859581203 100755 --- a/public/app/plugins/panel/live/LivePanel.tsx +++ b/public/app/plugins/panel/live/LivePanel.tsx @@ -174,7 +174,6 @@ export class LivePanel extends PureComponent { series: applyFieldOverrides({ data: message.getData(), theme: config.theme, - getDataSourceSettingsByUid: () => undefined, replaceVariables: (v: string) => v, fieldConfig: { defaults: {},