mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Change datasourceName usage to datasourceUID or datasourceRef where appropriate (#52479)
* First pass at using datasource UID when appropriate * Fix tests * be more lenient with lookup to accomodate different URLs * Make test setup get mock work like real datasource get * Fix the typing issue and remaining tests * Fix PR feedback
This commit is contained in:
parent
cb35729553
commit
0e13ee345d
@ -1,4 +1,4 @@
|
||||
Right now Tempo is before stable release so this uses :latest tag which means there can be changes depending on when
|
||||
you pull the image.
|
||||
|
||||
For adding some traces easily you can run Loki block and enable tracing (see ../loki/README.md)
|
||||
For adding some traces easily you can run Loki block and enable tracing (see ../loki-promtail/README.md)
|
||||
|
@ -606,6 +606,7 @@ describe('getLinksSupplier', () => {
|
||||
getTimeRangeForUrl: (() => {}) as any,
|
||||
});
|
||||
|
||||
const datasourceUid = '1234';
|
||||
const f0 = new MutableDataFrame({
|
||||
name: 'A',
|
||||
fields: [
|
||||
@ -619,7 +620,7 @@ describe('getLinksSupplier', () => {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: '0',
|
||||
datasourceUid: datasourceUid,
|
||||
datasourceName: 'testDS',
|
||||
query: '12345',
|
||||
},
|
||||
@ -640,12 +641,12 @@ describe('getLinksSupplier', () => {
|
||||
);
|
||||
|
||||
const links = supplier({ valueRowIndex: 0 });
|
||||
|
||||
const encodeURIParams = `{"datasource":"${datasourceUid}","queries":["12345"],"panelsState":{}}`;
|
||||
expect(links.length).toBe(1);
|
||||
expect(links[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
title: 'testDS',
|
||||
href: `/explore?left=${encodeURIComponent('{"datasource":"testDS","queries":["12345"],"panelsState":{}}')}`,
|
||||
href: `/explore?left=${encodeURIComponent(encodeURIParams)}`,
|
||||
onClick: undefined,
|
||||
})
|
||||
);
|
||||
|
@ -44,7 +44,7 @@ export interface DataLink<T extends DataQuery = any> {
|
||||
export interface InternalDataLink<T extends DataQuery = any> {
|
||||
query: T;
|
||||
datasourceUid: string;
|
||||
datasourceName: string;
|
||||
datasourceName: string; // used as a title if `DataLink.title` is empty
|
||||
panelsState?: ExplorePanelsState;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ describe('mapInternalLinkToExplore', () => {
|
||||
expect.objectContaining({
|
||||
title: 'dsName',
|
||||
href: `/explore?left=${encodeURIComponent(
|
||||
'{"datasource":"dsName","queries":[{"query":"12344"}],"panelsState":{}}'
|
||||
'{"datasource":"uid","queries":[{"query":"12344"}],"panelsState":{}}'
|
||||
)}`,
|
||||
onClick: undefined,
|
||||
})
|
||||
@ -76,7 +76,7 @@ describe('mapInternalLinkToExplore', () => {
|
||||
expect.objectContaining({
|
||||
title: 'dsName',
|
||||
href: `/explore?left=${encodeURIComponent(
|
||||
'{"datasource":"dsName","queries":[{"query":"12344"}],"panelsState":{"trace":{"spanId":"abcdef"}}}'
|
||||
'{"datasource":"uid","queries":[{"query":"12344"}],"panelsState":{"trace":{"spanId":"abcdef"}}}'
|
||||
)}`,
|
||||
onClick: undefined,
|
||||
})
|
||||
|
@ -51,7 +51,7 @@ export function mapInternalLinkToExplore(options: LinkToExploreOptions): LinkMod
|
||||
title: replaceVariables(title, scopedVars),
|
||||
// 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(internalLink.datasourceName, interpolatedQuery, range, interpolatedPanelsState),
|
||||
href: generateInternalHref(internalLink.datasourceUid, interpolatedQuery, range, interpolatedPanelsState),
|
||||
onClick: onClickFn
|
||||
? () => {
|
||||
onClickFn({
|
||||
@ -71,7 +71,7 @@ export function mapInternalLinkToExplore(options: LinkToExploreOptions): LinkMod
|
||||
* Generates href for internal derived field link.
|
||||
*/
|
||||
function generateInternalHref<T extends DataQuery = any>(
|
||||
datasourceName: string,
|
||||
datasourceUid: string,
|
||||
query: T,
|
||||
range: TimeRange,
|
||||
panelsState?: ExplorePanelsState
|
||||
@ -80,7 +80,7 @@ function generateInternalHref<T extends DataQuery = any>(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
serializeStateToUrlParam({
|
||||
range: range.raw,
|
||||
datasource: datasourceName,
|
||||
datasource: datasourceUid,
|
||||
queries: [query],
|
||||
panelsState: panelsState,
|
||||
})
|
||||
|
@ -146,7 +146,7 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
|
||||
<DataSourcePicker
|
||||
key={`${exploreId}-ds-picker`}
|
||||
onChange={this.onChangeDatasource}
|
||||
current={this.props.datasourceName}
|
||||
current={this.props.datasourceRef}
|
||||
hideTextValue={showSmallDataSourcePicker}
|
||||
width={showSmallDataSourcePicker ? 8 : undefined}
|
||||
/>
|
||||
@ -233,7 +233,7 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps) => {
|
||||
|
||||
return {
|
||||
datasourceMissing,
|
||||
datasourceName: datasourceInstance?.name,
|
||||
datasourceRef: datasourceInstance?.getRef(),
|
||||
datasourceType: datasourceInstance?.type,
|
||||
loading,
|
||||
range,
|
||||
|
@ -164,21 +164,21 @@ export function RichHistoryCard(props: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
const getQueryDsInstance = async () => {
|
||||
const ds = await getDataSourceSrv().get(query.datasourceName);
|
||||
const ds = await getDataSourceSrv().get(query.datasourceUid);
|
||||
setQueryDsInstance(ds);
|
||||
};
|
||||
|
||||
getQueryDsInstance();
|
||||
}, [query.datasourceName]);
|
||||
}, [query.datasourceUid]);
|
||||
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme, isRemoved);
|
||||
|
||||
const onRunQuery = async () => {
|
||||
const queriesToRun = query.queries;
|
||||
const differentDataSource = query.datasourceName !== datasourceInstance?.name;
|
||||
const differentDataSource = query.datasourceUid !== datasourceInstance?.uid;
|
||||
if (differentDataSource) {
|
||||
await changeDatasource(exploreId, query.datasourceName, { importQueries: true });
|
||||
await changeDatasource(exploreId, query.datasourceUid, { importQueries: true });
|
||||
setQueries(exploreId, queriesToRun);
|
||||
} else {
|
||||
setQueries(exploreId, queriesToRun);
|
||||
@ -329,7 +329,7 @@ export function RichHistoryCard(props: Props) {
|
||||
{!activeUpdateComment && (
|
||||
<div className={styles.runButton}>
|
||||
<Button variant="secondary" onClick={onRunQuery} disabled={isRemoved}>
|
||||
{datasourceInstance?.name === query.datasourceName ? 'Run query' : 'Switch data source and run query'}
|
||||
{datasourceInstance?.uid === query.datasourceUid ? 'Run query' : 'Switch data source and run query'}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -243,7 +243,7 @@ export function RichHistoryQueriesTab(props: Props) {
|
||||
</span>
|
||||
</div>
|
||||
{mappedQueriesToHeadings[heading].map((q: RichHistoryQuery) => {
|
||||
const idx = listOfDatasources.findIndex((d) => d.name === q.datasourceName);
|
||||
const idx = listOfDatasources.findIndex((d) => d.uid === q.datasourceUid);
|
||||
return (
|
||||
<RichHistoryCard
|
||||
query={q}
|
||||
|
@ -154,7 +154,7 @@ export function RichHistoryStarredTab(props: Props) {
|
||||
{loading && <span>Loading results...</span>}
|
||||
{!loading &&
|
||||
queries.map((q) => {
|
||||
const idx = listOfDatasources.findIndex((d) => d.name === q.datasourceName);
|
||||
const idx = listOfDatasources.findIndex((d) => d.uid === q.datasourceUid);
|
||||
return (
|
||||
<RichHistoryCard
|
||||
query={q}
|
||||
|
@ -24,7 +24,7 @@ describe('createSpanLinkFactory', () => {
|
||||
beforeAll(() => {
|
||||
setDataSourceSrv({
|
||||
getInstanceSettings(uid: string): DataSourceInstanceSettings | undefined {
|
||||
return { uid: 'loki1', name: 'loki1', type: 'loki' } as any;
|
||||
return { uid: 'loki1_uid', name: 'loki1', type: 'loki' } as any;
|
||||
},
|
||||
} as any);
|
||||
|
||||
@ -40,7 +40,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -65,7 +65,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{ip=\\"192.168.0.1\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{ip=\\"192.168.0.1\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -90,7 +90,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{ip=\\"192.168.0.1\\", host=\\"host\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{ip=\\"192.168.0.1\\", host=\\"host\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -116,7 +116,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:01:00.000Z","to":"2020-10-14T01:01:01.000Z"},"datasource":"loki1","queries":[{"expr":"{hostname=\\"hostname1\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:01:00.000Z","to":"2020-10-14T01:01:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{hostname=\\"hostname1\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -133,7 +133,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"} |=\\"7946b05c2e2e4e5a\\" |=\\"6605c7b08e715d6c\\"","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"} |=\\"7946b05c2e2e4e5a\\" |=\\"6605c7b08e715d6c\\"","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -186,7 +186,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{service=\\"serviceName\\", pod=\\"podName\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{service=\\"serviceName\\", pod=\\"podName\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -216,7 +216,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{service.name=\\"serviceName\\", pod=\\"podName\\"}","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1_uid","queries":[{"expr":"{service.name=\\"serviceName\\", pod=\\"podName\\"}","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -263,8 +263,8 @@ describe('createSpanLinkFactory', () => {
|
||||
|
||||
const linkDef = links?.logLinks?.[0];
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toContain(`${encodeURIComponent('datasource":"Splunk 8","queries":[{"query"')}`);
|
||||
expect(linkDef!.href).not.toContain(`${encodeURIComponent('datasource":"Splunk 8","queries":[{"expr"')}`);
|
||||
expect(linkDef!.href).toContain(`${encodeURIComponent('datasource":"splunkUID","queries":[{"query"')}`);
|
||||
expect(linkDef!.href).not.toContain(`${encodeURIComponent('datasource":"splunkUID","queries":[{"expr"')}`);
|
||||
});
|
||||
|
||||
it('automatically timeshifts the timerange by one second in a splunk query', () => {
|
||||
@ -297,7 +297,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"Splunk 8","queries":[{"query":"cluster=\\"cluster1\\" hostname=\\"hostname1\\" \\"7946b05c2e2e4e5a\\" \\"6605c7b08e715d6c\\"","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"splunkUID","queries":[{"query":"cluster=\\"cluster1\\" hostname=\\"hostname1\\" \\"7946b05c2e2e4e5a\\" \\"6605c7b08e715d6c\\"","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -320,7 +320,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"Splunk 8","queries":[{"query":"ip=\\"192.168.0.1\\"","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"splunkUID","queries":[{"query":"ip=\\"192.168.0.1\\"","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -346,7 +346,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"Splunk 8","queries":[{"query":"hostname=\\"hostname1\\" ip=\\"192.168.0.1\\"","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"splunkUID","queries":[{"query":"hostname=\\"hostname1\\" ip=\\"192.168.0.1\\"","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -376,7 +376,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"Splunk 8","queries":[{"query":"service=\\"serviceName\\" pod=\\"podName\\"","refId":""}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"splunkUID","queries":[{"query":"service=\\"serviceName\\" pod=\\"podName\\"","refId":""}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -386,7 +386,7 @@ describe('createSpanLinkFactory', () => {
|
||||
beforeAll(() => {
|
||||
setDataSourceSrv({
|
||||
getInstanceSettings(uid: string): DataSourceInstanceSettings | undefined {
|
||||
return { uid: 'prom1', name: 'prom1', type: 'prometheus' } as any;
|
||||
return { uid: 'prom1Uid', name: 'prom1', type: 'prometheus' } as any;
|
||||
},
|
||||
} as any);
|
||||
|
||||
@ -399,7 +399,7 @@ describe('createSpanLinkFactory', () => {
|
||||
const createLink = createSpanLinkFactory({
|
||||
splitOpenFn,
|
||||
traceToMetricsOptions: {
|
||||
datasourceUid: 'prom1',
|
||||
datasourceUid: 'prom1Uid',
|
||||
queries: [{ query: 'customQuery' }],
|
||||
},
|
||||
});
|
||||
@ -411,7 +411,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(linkDef).toBeDefined();
|
||||
expect(linkDef!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1","queries":[{"expr":"customQuery","refId":"A"}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1Uid","queries":[{"expr":"customQuery","refId":"A"}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -435,7 +435,7 @@ describe('createSpanLinkFactory', () => {
|
||||
const createLink = createSpanLinkFactory({
|
||||
splitOpenFn,
|
||||
traceToMetricsOptions: {
|
||||
datasourceUid: 'prom1',
|
||||
datasourceUid: 'prom1Uid',
|
||||
queries: [
|
||||
{ name: 'Named Query', query: 'customQuery' },
|
||||
{ name: 'defaultQuery', query: '' },
|
||||
@ -454,7 +454,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(namedLink!.title).toBe('Named Query');
|
||||
expect(namedLink!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1","queries":[{"expr":"customQuery","refId":"A"}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1Uid","queries":[{"expr":"customQuery","refId":"A"}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
|
||||
@ -463,7 +463,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(defaultLink!.title).toBe('defaultQuery');
|
||||
expect(defaultLink!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1","queries":[{"expr":"histogram_quantile(0.5, sum(rate(tempo_spanmetrics_latency_bucket{operation=\\"operation\\"}[5m])) by (le))","refId":"A"}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1Uid","queries":[{"expr":"histogram_quantile(0.5, sum(rate(tempo_spanmetrics_latency_bucket{operation=\\"operation\\"}[5m])) by (le))","refId":"A"}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
|
||||
@ -472,7 +472,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(unnamedQuery!.title).toBeUndefined();
|
||||
expect(unnamedQuery!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1","queries":[{"expr":"no_name_here","refId":"A"}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1Uid","queries":[{"expr":"no_name_here","refId":"A"}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
@ -483,7 +483,7 @@ describe('createSpanLinkFactory', () => {
|
||||
const createLink = createSpanLinkFactory({
|
||||
splitOpenFn,
|
||||
traceToMetricsOptions: {
|
||||
datasourceUid: 'prom1',
|
||||
datasourceUid: 'prom1Uid',
|
||||
queries: [{ name: 'Named Query', query: 'metric{$__tags}[5m]' }],
|
||||
tags: [
|
||||
{ key: 'job', value: '' },
|
||||
@ -507,7 +507,7 @@ describe('createSpanLinkFactory', () => {
|
||||
expect(links).toBeDefined();
|
||||
expect(links!.metricLinks![0]!.href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1","queries":[{"expr":"metric{job=\\"tns/app\\", pod=\\"sample-pod\\"}[5m]","refId":"A"}],"panelsState":{}}'
|
||||
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"prom1Uid","queries":[{"expr":"metric{job=\\"tns/app\\", pod=\\"sample-pod\\"}[5m]","refId":"A"}],"panelsState":{}}'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
|
@ -58,9 +58,14 @@ export function setupExplore(options?: SetupOptions): {
|
||||
getInstanceSettings(ref: DataSourceRef) {
|
||||
return dsSettings.map((d) => d.settings).find((x) => x.name === ref || x.uid === ref || x.uid === ref.uid);
|
||||
},
|
||||
get(name?: string | null, scopedVars?: ScopedVars): Promise<DataSourceApi> {
|
||||
get(datasource?: string | DataSourceRef | null, scopedVars?: ScopedVars): Promise<DataSourceApi> {
|
||||
const datasourceStr = typeof datasource === 'string';
|
||||
return Promise.resolve(
|
||||
(name ? dsSettings.find((d) => d.api.name === name || d.api.uid === name) : dsSettings[0])!.api
|
||||
(datasource
|
||||
? dsSettings.find((d) =>
|
||||
datasourceStr ? d.api.name === datasource || d.api.uid === datasource : d.api.uid === datasource?.uid
|
||||
)
|
||||
: dsSettings[0])!.api
|
||||
);
|
||||
},
|
||||
} as any);
|
||||
|
@ -41,7 +41,7 @@ export function changeDatasource(
|
||||
): ThunkResult<void> {
|
||||
return async (dispatch, getState) => {
|
||||
const orgId = getState().user.orgId;
|
||||
const { history, instance } = await loadAndInitDatasource(orgId, datasourceUid);
|
||||
const { history, instance } = await loadAndInitDatasource(orgId, { uid: datasourceUid });
|
||||
const currentDataSourceInstance = getState().explore[exploreId]!.datasourceInstance;
|
||||
|
||||
dispatch(
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
DataSourceApi,
|
||||
ExplorePanelsState,
|
||||
PreferredVisualisationType,
|
||||
DataSourceRef,
|
||||
} from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { keybindingSrv } from 'app/core/services/keybindingSrv';
|
||||
@ -135,10 +136,14 @@ export function changeGraphStyle(exploreId: ExploreId, graphStyle: ExploreGraphS
|
||||
/**
|
||||
* Initialize Explore state with state from the URL and the React component.
|
||||
* Call this only on components for with the Explore state has not been initialized.
|
||||
*
|
||||
* The `datasource` param will be passed to the datasource service `get` function
|
||||
* and can be either a string that is the name or uid, or a datasourceRef
|
||||
* This is to maximize compatability with how datasources are accessed from the URL param.
|
||||
*/
|
||||
export function initializeExplore(
|
||||
exploreId: ExploreId,
|
||||
datasourceNameOrUid: string,
|
||||
datasource: DataSourceRef | string,
|
||||
queries: DataQuery[],
|
||||
range: TimeRange,
|
||||
containerWidth: number,
|
||||
@ -152,7 +157,7 @@ export function initializeExplore(
|
||||
|
||||
if (exploreDatasources.length >= 1) {
|
||||
const orgId = getState().user.orgId;
|
||||
const loadResult = await loadAndInitDatasource(orgId, datasourceNameOrUid);
|
||||
const loadResult = await loadAndInitDatasource(orgId, datasource);
|
||||
instance = loadResult.instance;
|
||||
history = loadResult.history;
|
||||
}
|
||||
@ -201,6 +206,7 @@ export function refreshExplore(exploreId: ExploreId, newUrlQuery: string): Thunk
|
||||
|
||||
const { containerWidth, eventBridge } = itemState;
|
||||
|
||||
// datasource will either be name or UID here
|
||||
const { datasource, queries, range: urlRange, panelsState } = newUrlState;
|
||||
const refreshQueries: DataQuery[] = [];
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { createAction } from '@reduxjs/toolkit';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { ExploreUrlState, serializeStateToUrlParam, SplitOpen, UrlQueryMap } from '@grafana/data';
|
||||
import { DataSourceSrv, getDataSourceSrv, locationService } from '@grafana/runtime';
|
||||
import { DataSourceSrv, locationService } from '@grafana/runtime';
|
||||
import { GetExploreUrlArguments, stopQueryState } from 'app/core/utils/explore';
|
||||
import { PanelModel } from 'app/features/dashboard/state';
|
||||
import { ExploreId, ExploreItemState, ExploreState } from 'app/types/explore';
|
||||
@ -108,9 +108,8 @@ export const splitOpen: SplitOpen = (options): ThunkResult<void> => {
|
||||
let rightUrlState: ExploreUrlState = leftUrlState;
|
||||
|
||||
if (options) {
|
||||
const datasourceName = getDataSourceSrv().getInstanceSettings(options.datasourceUid)?.name || '';
|
||||
rightUrlState = {
|
||||
datasource: datasourceName,
|
||||
datasource: options.datasourceUid,
|
||||
queries: [options.query],
|
||||
range: options.range || leftState.range,
|
||||
panelsState: options.panelsState,
|
||||
|
@ -24,10 +24,10 @@ describe('loadAndInitDatasource', () => {
|
||||
dataSourceMock.get.mockRejectedValueOnce(new Error('Datasource not found'));
|
||||
dataSourceMock.get.mockResolvedValue(DEFAULT_DATASOURCE);
|
||||
|
||||
const { instance } = await loadAndInitDatasource(1, 'Unknown');
|
||||
const { instance } = await loadAndInitDatasource(1, { uid: 'Unknown' });
|
||||
|
||||
expect(dataSourceMock.get).toBeCalledTimes(2);
|
||||
expect(dataSourceMock.get).toBeCalledWith('Unknown');
|
||||
expect(dataSourceMock.get).toBeCalledWith({ uid: 'Unknown' });
|
||||
expect(dataSourceMock.get).toBeCalledWith();
|
||||
expect(instance).toMatchObject(DEFAULT_DATASOURCE);
|
||||
expect(store.set).toBeCalledWith(lastUsedDatasourceKeyForOrgId(1), DEFAULT_DATASOURCE.uid);
|
||||
@ -36,10 +36,10 @@ describe('loadAndInitDatasource', () => {
|
||||
it('saves last loaded data source uid', async () => {
|
||||
dataSourceMock.get.mockResolvedValue(TEST_DATASOURCE);
|
||||
|
||||
const { instance } = await loadAndInitDatasource(1, 'Test');
|
||||
const { instance } = await loadAndInitDatasource(1, { uid: 'Test' });
|
||||
|
||||
expect(dataSourceMock.get).toBeCalledTimes(1);
|
||||
expect(dataSourceMock.get).toBeCalledWith('Test');
|
||||
expect(dataSourceMock.get).toBeCalledWith({ uid: 'Test' });
|
||||
expect(instance).toMatchObject(TEST_DATASOURCE);
|
||||
expect(store.set).toBeCalledWith(lastUsedDatasourceKeyForOrgId(1), TEST_DATASOURCE.uid);
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import { isEmpty, isObject, mapValues, omitBy } from 'lodash';
|
||||
import {
|
||||
AbsoluteTimeRange,
|
||||
DataSourceApi,
|
||||
DataSourceRef,
|
||||
EventBusExtended,
|
||||
ExploreUrlState,
|
||||
getDefaultTimeRange,
|
||||
@ -86,11 +87,12 @@ export const createEmptyQueryResponse = (): ExplorePanelData => ({
|
||||
|
||||
export async function loadAndInitDatasource(
|
||||
orgId: number,
|
||||
datasourceUid?: string
|
||||
datasource: DataSourceRef | string
|
||||
): Promise<{ history: HistoryItem[]; instance: DataSourceApi }> {
|
||||
let instance;
|
||||
try {
|
||||
instance = await getDatasourceSrv().get(datasourceUid);
|
||||
// let datasource be a ref if we have the info, otherwise a name or uid will do for lookup
|
||||
instance = await getDatasourceSrv().get(datasource);
|
||||
} catch (error) {
|
||||
// Falling back to the default data source in case the provided data source was not found.
|
||||
// It may happen if last used data source or the data source provided in the URL has been
|
||||
@ -129,7 +131,7 @@ export function getUrlStateFromPaneState(pane: ExploreItemState): ExploreUrlStat
|
||||
return {
|
||||
// datasourceInstance should not be undefined anymore here but in case there is some path for it to be undefined
|
||||
// lets just fallback instead of crashing.
|
||||
datasource: pane.datasourceInstance?.name || '',
|
||||
datasource: pane.datasourceInstance?.uid || '',
|
||||
queries: pane.queries.map(clearQueryKeys),
|
||||
range: toRawTimeRange(pane.range),
|
||||
// don't include panelsState in the url unless a piece of state is actually set
|
||||
|
@ -73,7 +73,7 @@ describe('getFieldLinksForExplore', () => {
|
||||
|
||||
expect(links[0].href).toBe(
|
||||
`/explore?left=${encodeURIComponent(
|
||||
'{"range":{"from":"now-1h","to":"now"},"datasource":"test_ds","queries":[{"query":"query_1"}],"panelsState":{"trace":{"spanId":"abcdef"}}}'
|
||||
'{"range":{"from":"now-1h","to":"now"},"datasource":"uid_1","queries":[{"query":"query_1"}],"panelsState":{"trace":{"spanId":"abcdef"}}}'
|
||||
)}`
|
||||
);
|
||||
expect(links[0].title).toBe('test_ds');
|
||||
|
Loading…
Reference in New Issue
Block a user