mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Backend Plugins: add a common implementation (#21408)
* add common backend * use const for range * likely not differnt * send the right orgId * Add DataSourceWithBackend to @grafana/runtime mock in root reducer test Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
parent
d135f1229d
commit
a0d43de761
@ -3,3 +3,5 @@ export * from './config';
|
|||||||
export * from './types';
|
export * from './types';
|
||||||
export { loadPluginCss, SystemJS } from './utils/plugin';
|
export { loadPluginCss, SystemJS } from './utils/plugin';
|
||||||
export { reportMetaAnalytics } from './utils/analytics';
|
export { reportMetaAnalytics } from './utils/analytics';
|
||||||
|
|
||||||
|
export { DataSourceWithBackend } from './utils/DataSourceWithBackend';
|
||||||
|
87
packages/grafana-runtime/src/utils/DataSourceWithBackend.ts
Normal file
87
packages/grafana-runtime/src/utils/DataSourceWithBackend.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import {
|
||||||
|
DataSourceApi,
|
||||||
|
DataQueryRequest,
|
||||||
|
DataQueryResponse,
|
||||||
|
DataSourceInstanceSettings,
|
||||||
|
DataQuery,
|
||||||
|
DataSourceJsonData,
|
||||||
|
} from '@grafana/data';
|
||||||
|
import { Observable, from } from 'rxjs';
|
||||||
|
import { config } from '..';
|
||||||
|
import { getBackendSrv } from '../services';
|
||||||
|
|
||||||
|
// Ideally internal (exported for consistency)
|
||||||
|
const ExpressionDatasourceID = '__expr__';
|
||||||
|
|
||||||
|
export class DataSourceWithBackend<
|
||||||
|
TQuery extends DataQuery = DataQuery,
|
||||||
|
TOptions extends DataSourceJsonData = DataSourceJsonData
|
||||||
|
> extends DataSourceApi<TQuery, TOptions> {
|
||||||
|
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
|
||||||
|
super(instanceSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ideally final -- any other implementation would be wrong!
|
||||||
|
*/
|
||||||
|
query(request: DataQueryRequest): Observable<DataQueryResponse> {
|
||||||
|
const { targets, intervalMs, maxDataPoints, range } = request;
|
||||||
|
|
||||||
|
let expressionCount = 0;
|
||||||
|
const orgId = config.bootData.user.orgId;
|
||||||
|
const queries = targets.map(q => {
|
||||||
|
if (q.datasource === ExpressionDatasourceID) {
|
||||||
|
expressionCount++;
|
||||||
|
return {
|
||||||
|
...q,
|
||||||
|
datasourceId: this.id,
|
||||||
|
orgId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const dsName = q.datasource && q.datasource !== 'default' ? q.datasource : config.defaultDatasource;
|
||||||
|
const ds = config.datasources[dsName];
|
||||||
|
if (!ds) {
|
||||||
|
throw new Error('Unknown Datasource: ' + q.datasource);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...q,
|
||||||
|
datasourceId: ds.id,
|
||||||
|
intervalMs,
|
||||||
|
maxDataPoints,
|
||||||
|
orgId,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const body: any = {
|
||||||
|
expressionCount,
|
||||||
|
queries,
|
||||||
|
};
|
||||||
|
if (range) {
|
||||||
|
body.range = range;
|
||||||
|
body.from = range.from.valueOf().toString();
|
||||||
|
body.to = range.to.valueOf().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const req: Promise<DataQueryResponse> = getBackendSrv()
|
||||||
|
.post('/api/ds/query', body)
|
||||||
|
.then((rsp: any) => {
|
||||||
|
return this.toDataQueryResponse(rsp);
|
||||||
|
});
|
||||||
|
return from(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This makes the arrow libary loading async.
|
||||||
|
*/
|
||||||
|
async toDataQueryResponse(rsp: any): Promise<DataQueryResponse> {
|
||||||
|
const { resultsToDataFrames } = await import(
|
||||||
|
/* webpackChunkName: "apache-arrow-util" */ '@grafana/data/src/dataframe/ArrowDataFrame'
|
||||||
|
);
|
||||||
|
return { data: resultsToDataFrames(rsp) };
|
||||||
|
}
|
||||||
|
|
||||||
|
testDatasource() {
|
||||||
|
// TODO, this will call the backend healthcheck endpoint
|
||||||
|
return Promise.resolve({});
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ jest.mock('@grafana/runtime', () => ({
|
|||||||
user: {},
|
user: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DataSourceWithBackend: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('recursiveCleanState', () => {
|
describe('recursiveCleanState', () => {
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
import {
|
import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data';
|
||||||
DataSourceApi,
|
|
||||||
DataQueryRequest,
|
|
||||||
DataQueryResponse,
|
|
||||||
DataSourceInstanceSettings,
|
|
||||||
DataSourcePluginMeta,
|
|
||||||
} from '@grafana/data';
|
|
||||||
import { ExpressionQuery, GELQueryType } from './types';
|
import { ExpressionQuery, GELQueryType } from './types';
|
||||||
import { ExpressionQueryEditor } from './ExpressionQueryEditor';
|
import { ExpressionQueryEditor } from './ExpressionQueryEditor';
|
||||||
import { Observable, from } from 'rxjs';
|
import { DataSourceWithBackend } from '@grafana/runtime';
|
||||||
import { config } from '@grafana/runtime';
|
|
||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a singleton instance that just pretends to be a DataSource
|
* This is a singleton instance that just pretends to be a DataSource
|
||||||
*/
|
*/
|
||||||
export class ExpressionDatasourceApi extends DataSourceApi<ExpressionQuery> {
|
export class ExpressionDatasourceApi extends DataSourceWithBackend<ExpressionQuery> {
|
||||||
constructor(instanceSettings: DataSourceInstanceSettings) {
|
constructor(instanceSettings: DataSourceInstanceSettings) {
|
||||||
super(instanceSettings);
|
super(instanceSettings);
|
||||||
}
|
}
|
||||||
@ -23,61 +15,6 @@ export class ExpressionDatasourceApi extends DataSourceApi<ExpressionQuery> {
|
|||||||
return `Expression: ${query.type}`;
|
return `Expression: ${query.type}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
query(request: DataQueryRequest): Observable<DataQueryResponse> {
|
|
||||||
const { targets, intervalMs, maxDataPoints, range } = request;
|
|
||||||
|
|
||||||
let expressionCount = 0;
|
|
||||||
const orgId = (window as any).grafanaBootData.user.orgId;
|
|
||||||
const queries = targets.map(q => {
|
|
||||||
if (q.datasource === ExpressionDatasourceID) {
|
|
||||||
expressionCount++;
|
|
||||||
return {
|
|
||||||
...q,
|
|
||||||
datasourceId: this.id,
|
|
||||||
orgId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const dsName = q.datasource && q.datasource !== 'default' ? q.datasource : config.defaultDatasource;
|
|
||||||
const ds = config.datasources[dsName];
|
|
||||||
if (!ds) {
|
|
||||||
throw new Error('Unknown Datasource: ' + q.datasource);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...q,
|
|
||||||
datasourceId: ds.id,
|
|
||||||
intervalMs,
|
|
||||||
maxDataPoints,
|
|
||||||
orgId,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const req: Promise<DataQueryResponse> = getBackendSrv()
|
|
||||||
.post('/api/ds/query', {
|
|
||||||
from: range.from.valueOf().toString(),
|
|
||||||
to: range.to.valueOf().toString(),
|
|
||||||
queries: queries,
|
|
||||||
range,
|
|
||||||
expressionCount,
|
|
||||||
})
|
|
||||||
.then((rsp: any) => {
|
|
||||||
return this.toDataQueryResponse(rsp);
|
|
||||||
});
|
|
||||||
return from(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This makes the arrow libary loading async.
|
|
||||||
*/
|
|
||||||
async toDataQueryResponse(rsp: any): Promise<DataQueryResponse> {
|
|
||||||
const { resultsToDataFrames } = await import(
|
|
||||||
/* webpackChunkName: "apache-arrow-util" */ '@grafana/data/src/dataframe/ArrowDataFrame'
|
|
||||||
);
|
|
||||||
return { data: resultsToDataFrames(rsp) };
|
|
||||||
}
|
|
||||||
|
|
||||||
testDatasource() {
|
|
||||||
return Promise.resolve({});
|
|
||||||
}
|
|
||||||
|
|
||||||
newQuery(): ExpressionQuery {
|
newQuery(): ExpressionQuery {
|
||||||
return {
|
return {
|
||||||
refId: '--', // Replaced with query
|
refId: '--', // Replaced with query
|
||||||
@ -87,7 +24,9 @@ export class ExpressionDatasourceApi extends DataSourceApi<ExpressionQuery> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MATCHES the constant in DataSourceWithBackend
|
||||||
export const ExpressionDatasourceID = '__expr__';
|
export const ExpressionDatasourceID = '__expr__';
|
||||||
|
|
||||||
export const expressionDatasource = new ExpressionDatasourceApi({
|
export const expressionDatasource = new ExpressionDatasourceApi({
|
||||||
id: -100,
|
id: -100,
|
||||||
name: ExpressionDatasourceID,
|
name: ExpressionDatasourceID,
|
||||||
|
Loading…
Reference in New Issue
Block a user