Skip to content

Commit

Permalink
Variables: Interpolate datasource uid when used with datasource varia…
Browse files Browse the repository at this point in the history
…ble (#996)
  • Loading branch information
Sergej-Vlasov authored Dec 18, 2024
1 parent f92e93c commit a5e7915
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 7 deletions.
8 changes: 4 additions & 4 deletions packages/scenes/src/querying/SceneQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> implemen
const datasource = this.state.datasource ?? findFirstDatasource(queries);
const ds = await getDataSource(datasource, this._scopedVars);

this.findAndSubscribeToAdHocFilters(datasource?.uid);
this.findAndSubscribeToAdHocFilters(ds.uid);

const runRequest = getRunRequest();
const { primary, secondaries, processors } = this.prepareRequests(timeRange, ds);
Expand Down Expand Up @@ -654,15 +654,15 @@ export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> implemen
/**
* Walk up scene graph and find the closest filterset with matching data source
*/
private findAndSubscribeToAdHocFilters(uid: string | undefined) {
const filtersVar = findActiveAdHocFilterVariableByUid(uid);
private findAndSubscribeToAdHocFilters(interpolatedUid: string | undefined) {
const filtersVar = findActiveAdHocFilterVariableByUid(interpolatedUid);

if (this._adhocFiltersVar !== filtersVar) {
this._adhocFiltersVar = filtersVar;
this._updateExplicitVariableDependencies();
}

const groupByVar = findActiveGroupByVariablesByUid(uid);
const groupByVar = findActiveGroupByVariablesByUid(interpolatedUid);
if (this._groupByVar !== groupByVar) {
this._groupByVar = groupByVar;
this._updateExplicitVariableDependencies();
Expand Down
3 changes: 2 additions & 1 deletion packages/scenes/src/variables/adhoc/patchGetAdhocFilters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getDataSourceSrv, getTemplateSrv } from '@grafana/runtime';
import { AdHocVariableFilter } from '@grafana/data';
import { AdHocFiltersVariable } from './AdHocFiltersVariable';
import { interpolate } from '../../core/sceneGraph/sceneGraph';

let originalGetAdhocFilters: any = undefined;
let allActiveFilterSets = new Set<AdHocFiltersVariable>();
Expand Down Expand Up @@ -45,7 +46,7 @@ export function patchGetAdhocFilters(filterVar: AdHocFiltersVariable) {

export function findActiveAdHocFilterVariableByUid(dsUid: string | undefined): AdHocFiltersVariable | undefined {
for (const filter of allActiveFilterSets.values()) {
if (filter.state.datasource?.uid === dsUid) {
if (interpolate(filter, filter.state.datasource?.uid) === dsUid) {
return filter;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { interpolate } from '../../core/sceneGraph/sceneGraph';
import { GroupByVariable } from './GroupByVariable';

export const allActiveGroupByVariables = new Set<GroupByVariable>();

export function findActiveGroupByVariablesByUid(dsUid: string | undefined): GroupByVariable | undefined {
for (const groupByVariable of allActiveGroupByVariables.values()) {
if (groupByVariable.state.datasource?.uid === dsUid) {
if (interpolate(groupByVariable, groupByVariable.state.datasource?.uid) === dsUid) {
return groupByVariable;
}
}
Expand Down
88 changes: 88 additions & 0 deletions packages/scenes/src/variables/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { SceneObjectBase } from '../core/SceneObjectBase';
import { SceneObjectState } from '../core/types';
import { SceneQueryRunner } from '../querying/SceneQueryRunner';
import { getFuzzySearcher, getQueriesForVariables } from './utils';
import { SceneVariableSet } from './sets/SceneVariableSet';
import { DataSourceVariable } from './variants/DataSourceVariable';
import { GetDataSourceListFilters } from '@grafana/runtime';

describe('getQueriesForVariables', () => {
it('should resolve queries', () => {
Expand Down Expand Up @@ -176,6 +179,91 @@ describe('getQueriesForVariables', () => {
});
});

const getDataSourceListMock = jest.fn().mockImplementation((filters: GetDataSourceListFilters) => {
if (filters.pluginId === 'prometheus') {
return [
{
id: 1,
uid: 'interpolatedDs',
type: 'prometheus',
name: 'interpolatedDs-name',
isDefault: true,
},
];
}

return [];
});

jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getDataSourceSrv: () => {
return {
getList: getDataSourceListMock,
};
},
}));

describe('getQueriesForVariables', () => {
const original = console.error;

beforeAll(() => {
console.error = jest.fn();
});

afterAll(() => {
console.error = original;
jest.resetAllMocks();
});

it.only('should get queries for interpolated source object and query datasource uuids', () => {
const runner1 = new SceneQueryRunner({
datasource: {
uid: '${dsVar}',
},
queries: [{ refId: 'A' }],
});

const runner2 = new SceneQueryRunner({
datasource: {
uid: '${dsVar}',
},
queries: [{ refId: 'B' }],
});

const source = new TestObject({
$variables: new SceneVariableSet({
variables: [
new DataSourceVariable({
name: 'dsVar',
options: [],
value: 'interpolatedDs',
text: 'interpolatedDs-name',
pluginId: 'prometheus',
}),
],
}),
datasource: { uid: '${dsVar}', type: 'prometheus' },
});
new EmbeddedScene({
$data: runner1,
body: new SceneFlexLayout({
children: [
new SceneFlexItem({
$data: runner2,
body: source,
}),
],
}),
});

runner1.activate();
runner2.activate();
source.activate();
expect(getQueriesForVariables(source)).toEqual([{ refId: 'A' }, { refId: 'B' }]);
});
});

describe('getFuzzySearcher orders by match quality with case-sensitivity', () => {
it('Can filter options by search query', async () => {
const haystack = [
Expand Down
6 changes: 5 additions & 1 deletion packages/scenes/src/variables/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ export function getQueriesForVariables(
(o) => o instanceof SceneQueryRunner
) as SceneQueryRunner[];

const interpolatedDsUuid = sceneGraph.interpolate(sourceObject, sourceObject.state.datasource?.uid);

const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {
return r.state.datasource?.uid === sourceObject.state.datasource?.uid;
const interpolatedQueryDsUuid = sceneGraph.interpolate(sourceObject, r.state.datasource?.uid);

return interpolatedQueryDsUuid === interpolatedDsUuid;
});

if (applicableRunners.length === 0) {
Expand Down

0 comments on commit a5e7915

Please sign in to comment.