mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PublicDashboards: Data discrepancy fix. Use real datasource plugin when it is a public dashboard. (#73708)
Co-authored-by: Torkel Ödegaard <torkel@grafana.com> Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com> Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
@@ -11,12 +11,15 @@ import {
|
||||
createDataFrame,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { config } from '../config';
|
||||
|
||||
import {
|
||||
DataSourceWithBackend,
|
||||
isExpressionReference,
|
||||
standardStreamOptionsProvider,
|
||||
toStreamingDataResponse,
|
||||
} from './DataSourceWithBackend';
|
||||
import { publicDashboardQueryHandler } from './publicDashboardQueryHandler';
|
||||
|
||||
class MyDataSource extends DataSourceWithBackend<DataQuery, DataSourceJsonData> {
|
||||
constructor(instanceSettings: DataSourceInstanceSettings<DataSourceJsonData>) {
|
||||
@@ -44,6 +47,7 @@ jest.mock('../services', () => ({
|
||||
};
|
||||
},
|
||||
}));
|
||||
jest.mock('./publicDashboardQueryHandler');
|
||||
|
||||
describe('DataSourceWithBackend', () => {
|
||||
test('check the executed queries', () => {
|
||||
@@ -313,6 +317,43 @@ describe('DataSourceWithBackend', () => {
|
||||
expect(isExpressionReference(undefined)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('public dashboard scope', () => {
|
||||
test("check public dashboard handler is not executed when it's not public dashboard scope", () => {
|
||||
const { ds } = createMockDatasource();
|
||||
|
||||
const request = {
|
||||
maxDataPoints: 10,
|
||||
intervalMs: 5000,
|
||||
targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: 'sample' } }],
|
||||
dashboardUID: 'dashA',
|
||||
panelId: 123,
|
||||
queryGroupId: 'abc',
|
||||
} as DataQueryRequest;
|
||||
|
||||
ds.query(request);
|
||||
|
||||
expect(publicDashboardQueryHandler).not.toHaveBeenCalledWith(request);
|
||||
});
|
||||
|
||||
test("check public dashboard handler is executed when it's public dashboard scope", () => {
|
||||
config.publicDashboardAccessToken = 'abc123';
|
||||
const { ds } = createMockDatasource();
|
||||
|
||||
const request = {
|
||||
maxDataPoints: 10,
|
||||
intervalMs: 5000,
|
||||
targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: 'sample' } }],
|
||||
dashboardUID: 'dashA',
|
||||
panelId: 123,
|
||||
queryGroupId: 'abc',
|
||||
} as DataQueryRequest;
|
||||
|
||||
ds.query(request);
|
||||
|
||||
expect(publicDashboardQueryHandler).toHaveBeenCalledWith(request);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createMockDatasource() {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
StreamingFrameOptions,
|
||||
} from '../services';
|
||||
|
||||
import { publicDashboardQueryHandler } from './publicDashboardQueryHandler';
|
||||
import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';
|
||||
|
||||
/**
|
||||
@@ -123,6 +124,10 @@ class DataSourceWithBackend<
|
||||
* Ideally final -- any other implementation may not work as expected
|
||||
*/
|
||||
query(request: DataQueryRequest<TQuery>): Observable<DataQueryResponse> {
|
||||
if (config.publicDashboardAccessToken) {
|
||||
return publicDashboardQueryHandler(request);
|
||||
}
|
||||
|
||||
const { intervalMs, maxDataPoints, queryCachingTTL, range, requestId, hideFromInspector = false } = request;
|
||||
let targets = request.targets;
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { catchError, Observable, of, switchMap } from 'rxjs';
|
||||
|
||||
import { DataQuery, DataQueryRequest, DataQueryResponse } from '@grafana/data';
|
||||
|
||||
import { config } from '../config';
|
||||
import { getBackendSrv } from '../services/backendSrv';
|
||||
|
||||
import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';
|
||||
|
||||
export function publicDashboardQueryHandler(request: DataQueryRequest<DataQuery>): Observable<DataQueryResponse> {
|
||||
const {
|
||||
intervalMs,
|
||||
maxDataPoints,
|
||||
requestId,
|
||||
panelId,
|
||||
queryCachingTTL,
|
||||
range: { from: fromRange, to: toRange },
|
||||
} = request;
|
||||
// Return early if no queries exist
|
||||
if (!request.targets.length) {
|
||||
return of({ data: [] });
|
||||
}
|
||||
|
||||
const body = {
|
||||
intervalMs,
|
||||
maxDataPoints,
|
||||
queryCachingTTL,
|
||||
timeRange: {
|
||||
from: fromRange.valueOf().toString(),
|
||||
to: toRange.valueOf().toString(),
|
||||
timezone: request.timezone,
|
||||
},
|
||||
};
|
||||
|
||||
return getBackendSrv()
|
||||
.fetch<BackendDataSourceResponse>({
|
||||
url: `/api/public/dashboards/${config.publicDashboardAccessToken!}/panels/${panelId}/query`,
|
||||
method: 'POST',
|
||||
data: body,
|
||||
requestId,
|
||||
})
|
||||
.pipe(
|
||||
switchMap((raw) => {
|
||||
return of(toDataQueryResponse(raw, request.targets));
|
||||
}),
|
||||
catchError((err) => {
|
||||
return of(toDataQueryResponse(err));
|
||||
})
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user