mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DataSourceApi: convert interface to abstract class (#16979)
* DataSourceApi as class * add diff signature * Prometheus: moved directUrl to jsonData
This commit is contained in:
parent
5573d28582
commit
1d7bb2a763
@ -117,15 +117,30 @@ export interface DataSourceConstructor<
|
|||||||
/**
|
/**
|
||||||
* The main data source abstraction interface, represents an instance of a data source
|
* The main data source abstraction interface, represents an instance of a data source
|
||||||
*/
|
*/
|
||||||
export interface DataSourceApi<
|
export abstract class DataSourceApi<
|
||||||
TQuery extends DataQuery = DataQuery,
|
TQuery extends DataQuery = DataQuery,
|
||||||
TOptions extends DataSourceJsonData = DataSourceJsonData
|
TOptions extends DataSourceJsonData = DataSourceJsonData
|
||||||
> {
|
> {
|
||||||
|
/**
|
||||||
|
* Set in constructor
|
||||||
|
*/
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set in constructor
|
||||||
|
*/
|
||||||
|
readonly id: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* min interval range
|
* min interval range
|
||||||
*/
|
*/
|
||||||
interval?: string;
|
interval?: string;
|
||||||
|
|
||||||
|
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
|
||||||
|
this.name = instanceSettings.name;
|
||||||
|
this.id = instanceSettings.id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports queries from a different datasource
|
* Imports queries from a different datasource
|
||||||
*/
|
*/
|
||||||
@ -139,12 +154,12 @@ export interface DataSourceApi<
|
|||||||
/**
|
/**
|
||||||
* Main metrics / data query action
|
* Main metrics / data query action
|
||||||
*/
|
*/
|
||||||
query(options: DataQueryRequest<TQuery>, observer?: DataStreamObserver): Promise<DataQueryResponse>;
|
abstract query(options: DataQueryRequest<TQuery>, observer?: DataStreamObserver): Promise<DataQueryResponse>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test & verify datasource settings & connection details
|
* Test & verify datasource settings & connection details
|
||||||
*/
|
*/
|
||||||
testDatasource(): Promise<any>;
|
abstract testDatasource(): Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get hints for query improvements
|
* Get hints for query improvements
|
||||||
@ -156,16 +171,6 @@ export interface DataSourceApi<
|
|||||||
*/
|
*/
|
||||||
getQueryDisplayText?(query: TQuery): string;
|
getQueryDisplayText?(query: TQuery): string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set after constructor is called by Grafana
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set after constructor is called by Grafana
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set after constructor call, as the data source instance is the most common thing to pass around
|
* Set after constructor call, as the data source instance is the most common thing to pass around
|
||||||
* we attach the components to this instance for easy access
|
* we attach the components to this instance for easy access
|
||||||
@ -178,7 +183,7 @@ export interface DataSourceApi<
|
|||||||
meta?: DataSourcePluginMeta;
|
meta?: DataSourcePluginMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExploreDataSourceApi<
|
export abstract class ExploreDataSourceApi<
|
||||||
TQuery extends DataQuery = DataQuery,
|
TQuery extends DataQuery = DataQuery,
|
||||||
TOptions extends DataSourceJsonData = DataSourceJsonData
|
TOptions extends DataSourceJsonData = DataSourceJsonData
|
||||||
> extends DataSourceApi<TQuery, TOptions> {
|
> extends DataSourceApi<TQuery, TOptions> {
|
||||||
|
@ -59,6 +59,7 @@ export interface DateTime extends Object {
|
|||||||
subtract: (amount?: DateTimeInput, unit?: DurationUnit) => DateTime;
|
subtract: (amount?: DateTimeInput, unit?: DurationUnit) => DateTime;
|
||||||
toDate: () => Date;
|
toDate: () => Date;
|
||||||
toISOString: () => string;
|
toISOString: () => string;
|
||||||
|
diff: (amount: DateTimeInput, unit?: DurationUnit, truncate?: boolean) => number;
|
||||||
valueOf: () => number;
|
valueOf: () => number;
|
||||||
unix: () => number;
|
unix: () => number;
|
||||||
utc: () => DateTime;
|
utc: () => DateTime;
|
||||||
|
@ -3,6 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
@ -86,12 +87,13 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf
|
|||||||
defaultDatasource = ds.Name
|
defaultDatasource = ds.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds.JsonData != nil {
|
jsonData := ds.JsonData
|
||||||
dsMap["jsonData"] = ds.JsonData
|
if jsonData == nil {
|
||||||
} else {
|
jsonData = simplejson.New()
|
||||||
dsMap["jsonData"] = make(map[string]string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dsMap["jsonData"] = jsonData
|
||||||
|
|
||||||
if ds.Access == m.DS_ACCESS_DIRECT {
|
if ds.Access == m.DS_ACCESS_DIRECT {
|
||||||
if ds.BasicAuth {
|
if ds.BasicAuth {
|
||||||
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.DecryptedBasicAuthPassword())
|
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.DecryptedBasicAuthPassword())
|
||||||
@ -123,7 +125,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf
|
|||||||
|
|
||||||
if ds.Type == m.DS_PROMETHEUS {
|
if ds.Type == m.DS_PROMETHEUS {
|
||||||
// add unproxied server URL for link to Prometheus web UI
|
// add unproxied server URL for link to Prometheus web UI
|
||||||
dsMap["directUrl"] = ds.Url
|
jsonData.Set("directUrl", ds.Url)
|
||||||
}
|
}
|
||||||
|
|
||||||
datasources[ds.Name] = dsMap
|
datasources[ds.Name] = dsMap
|
||||||
|
@ -65,8 +65,6 @@ export class DatasourceSrv {
|
|||||||
instanceSettings: dsConfig,
|
instanceSettings: dsConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.id = dsConfig.id;
|
|
||||||
instance.name = name;
|
|
||||||
instance.components = dsPlugin.components;
|
instance.components = dsPlugin.components;
|
||||||
instance.meta = dsConfig.meta;
|
instance.meta = dsConfig.meta;
|
||||||
|
|
||||||
|
@ -9,9 +9,8 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
|
|||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
// import * as moment from 'moment';
|
// import * as moment from 'moment';
|
||||||
|
|
||||||
export default class CloudWatchDatasource implements DataSourceApi<CloudWatchQuery> {
|
export default class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery> {
|
||||||
type: any;
|
type: any;
|
||||||
name: any;
|
|
||||||
proxyUrl: any;
|
proxyUrl: any;
|
||||||
defaultRegion: any;
|
defaultRegion: any;
|
||||||
standardStatistics: any;
|
standardStatistics: any;
|
||||||
@ -24,8 +23,8 @@ export default class CloudWatchDatasource implements DataSourceApi<CloudWatchQue
|
|||||||
private templateSrv: TemplateSrv,
|
private templateSrv: TemplateSrv,
|
||||||
private timeSrv: TimeSrv
|
private timeSrv: TimeSrv
|
||||||
) {
|
) {
|
||||||
|
super(instanceSettings);
|
||||||
this.type = 'cloudwatch';
|
this.type = 'cloudwatch';
|
||||||
this.name = instanceSettings.name;
|
|
||||||
this.proxyUrl = instanceSettings.url;
|
this.proxyUrl = instanceSettings.url;
|
||||||
this.defaultRegion = instanceSettings.jsonData.defaultRegion;
|
this.defaultRegion = instanceSettings.jsonData.defaultRegion;
|
||||||
this.instanceSettings = instanceSettings;
|
this.instanceSettings = instanceSettings;
|
||||||
|
@ -7,9 +7,7 @@ import { DataSourceApi, DataQueryRequest, DataSourceInstanceSettings } from '@gr
|
|||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
export default class Datasource implements DataSourceApi<AzureMonitorQuery, AzureDataSourceJsonData> {
|
export default class Datasource extends DataSourceApi<AzureMonitorQuery, AzureDataSourceJsonData> {
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
azureMonitorDatasource: AzureMonitorDatasource;
|
azureMonitorDatasource: AzureMonitorDatasource;
|
||||||
appInsightsDatasource: AppInsightsDatasource;
|
appInsightsDatasource: AppInsightsDatasource;
|
||||||
azureLogAnalyticsDatasource: AzureLogAnalyticsDatasource;
|
azureLogAnalyticsDatasource: AzureLogAnalyticsDatasource;
|
||||||
@ -21,8 +19,7 @@ export default class Datasource implements DataSourceApi<AzureMonitorQuery, Azur
|
|||||||
private templateSrv: TemplateSrv,
|
private templateSrv: TemplateSrv,
|
||||||
private $q
|
private $q
|
||||||
) {
|
) {
|
||||||
this.name = instanceSettings.name;
|
super(instanceSettings);
|
||||||
this.id = instanceSettings.id;
|
|
||||||
this.azureMonitorDatasource = new AzureMonitorDatasource(instanceSettings, this.backendSrv, this.templateSrv);
|
this.azureMonitorDatasource = new AzureMonitorDatasource(instanceSettings, this.backendSrv, this.templateSrv);
|
||||||
this.appInsightsDatasource = new AppInsightsDatasource(
|
this.appInsightsDatasource = new AppInsightsDatasource(
|
||||||
instanceSettings,
|
instanceSettings,
|
||||||
|
@ -8,23 +8,13 @@ import {
|
|||||||
} from '@grafana/ui/src/types';
|
} from '@grafana/ui/src/types';
|
||||||
import { InputQuery, InputOptions } from './types';
|
import { InputQuery, InputOptions } from './types';
|
||||||
|
|
||||||
export class InputDatasource implements DataSourceApi<InputQuery, InputOptions> {
|
export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
|
||||||
data: SeriesData[];
|
data: SeriesData[];
|
||||||
|
|
||||||
// Filled in by grafana plugin system
|
|
||||||
name?: string;
|
|
||||||
|
|
||||||
// Filled in by grafana plugin system
|
|
||||||
id?: number;
|
|
||||||
|
|
||||||
constructor(instanceSettings: DataSourceInstanceSettings<InputOptions>) {
|
constructor(instanceSettings: DataSourceInstanceSettings<InputOptions>) {
|
||||||
if (instanceSettings.jsonData) {
|
super(instanceSettings);
|
||||||
this.data = instanceSettings.jsonData.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.data) {
|
this.data = instanceSettings.jsonData.data ? instanceSettings.jsonData.data : [];
|
||||||
this.data = [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDescription(data: SeriesData[]): string {
|
getDescription(data: SeriesData[]): string {
|
||||||
|
@ -2,6 +2,8 @@ import LokiDatasource from './datasource';
|
|||||||
import { LokiQuery } from './types';
|
import { LokiQuery } from './types';
|
||||||
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
||||||
import { SeriesData } from '@grafana/ui';
|
import { SeriesData } from '@grafana/ui';
|
||||||
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
describe('LokiDatasource', () => {
|
describe('LokiDatasource', () => {
|
||||||
const instanceSettings: any = {
|
const instanceSettings: any = {
|
||||||
@ -21,14 +23,15 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
describe('when querying', () => {
|
describe('when querying', () => {
|
||||||
const backendSrvMock = { datasourceRequest: jest.fn() };
|
const backendSrvMock = { datasourceRequest: jest.fn() };
|
||||||
|
const backendSrv = (backendSrvMock as unknown) as BackendSrv;
|
||||||
|
|
||||||
const templateSrvMock = {
|
const templateSrvMock = ({
|
||||||
getAdhocFilters: () => [],
|
getAdhocFilters: () => [],
|
||||||
replace: a => a,
|
replace: a => a,
|
||||||
};
|
} as unknown) as TemplateSrv;
|
||||||
|
|
||||||
test('should use default max lines when no limit given', () => {
|
test('should use default max lines when no limit given', () => {
|
||||||
const ds = new LokiDatasource(instanceSettings, backendSrvMock, templateSrvMock);
|
const ds = new LokiDatasource(instanceSettings, backendSrv, templateSrvMock);
|
||||||
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
||||||
const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
|
const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
|
||||||
|
|
||||||
@ -41,7 +44,7 @@ describe('LokiDatasource', () => {
|
|||||||
test('should use custom max lines if limit is set', () => {
|
test('should use custom max lines if limit is set', () => {
|
||||||
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
|
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
|
||||||
const customSettings = { ...instanceSettings, jsonData: customData };
|
const customSettings = { ...instanceSettings, jsonData: customData };
|
||||||
const ds = new LokiDatasource(customSettings, backendSrvMock, templateSrvMock);
|
const ds = new LokiDatasource(customSettings, backendSrv, templateSrvMock);
|
||||||
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
||||||
|
|
||||||
const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
|
const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
|
||||||
@ -54,7 +57,7 @@ describe('LokiDatasource', () => {
|
|||||||
test('should return series data', async done => {
|
test('should return series data', async done => {
|
||||||
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
|
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
|
||||||
const customSettings = { ...instanceSettings, jsonData: customData };
|
const customSettings = { ...instanceSettings, jsonData: customData };
|
||||||
const ds = new LokiDatasource(customSettings, backendSrvMock, templateSrvMock);
|
const ds = new LokiDatasource(customSettings, backendSrv, templateSrvMock);
|
||||||
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
|
||||||
|
|
||||||
const options = getQueryOptions<LokiQuery>({
|
const options = getQueryOptions<LokiQuery>({
|
||||||
@ -77,7 +80,7 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
describe('and call succeeds', () => {
|
describe('and call succeeds', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
status: 200,
|
status: 200,
|
||||||
@ -86,8 +89,8 @@ describe('LokiDatasource', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new LokiDatasource(instanceSettings, backendSrv, {});
|
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,7 +101,7 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
describe('and call fails with 401 error', () => {
|
describe('and call fails with 401 error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.reject({
|
return Promise.reject({
|
||||||
statusText: 'Unauthorized',
|
statusText: 'Unauthorized',
|
||||||
@ -108,8 +111,8 @@ describe('LokiDatasource', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new LokiDatasource(instanceSettings, backendSrv, {});
|
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -121,7 +124,7 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
describe('and call fails with 404 error', () => {
|
describe('and call fails with 404 error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.reject({
|
return Promise.reject({
|
||||||
statusText: 'Not found',
|
statusText: 'Not found',
|
||||||
@ -129,8 +132,8 @@ describe('LokiDatasource', () => {
|
|||||||
data: '404 page not found',
|
data: '404 page not found',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new LokiDatasource(instanceSettings, backendSrv, {});
|
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -142,7 +145,7 @@ describe('LokiDatasource', () => {
|
|||||||
|
|
||||||
describe('and call fails with 502 error', () => {
|
describe('and call fails with 502 error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.reject({
|
return Promise.reject({
|
||||||
statusText: 'Bad Gateway',
|
statusText: 'Bad Gateway',
|
||||||
@ -150,8 +153,8 @@ describe('LokiDatasource', () => {
|
|||||||
data: '',
|
data: '',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new LokiDatasource(instanceSettings, backendSrv, {});
|
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,8 +9,16 @@ import { logStreamToSeriesData } from './result_transformer';
|
|||||||
import { formatQuery, parseQuery } from './query_utils';
|
import { formatQuery, parseQuery } from './query_utils';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PluginMeta, DataQueryRequest, SeriesData } from '@grafana/ui/src/types';
|
import {
|
||||||
import { LokiQuery } from './types';
|
PluginMeta,
|
||||||
|
DataQueryRequest,
|
||||||
|
SeriesData,
|
||||||
|
DataSourceApi,
|
||||||
|
DataSourceInstanceSettings,
|
||||||
|
} from '@grafana/ui/src/types';
|
||||||
|
import { LokiQuery, LokiOptions } from './types';
|
||||||
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
export const DEFAULT_MAX_LINES = 1000;
|
export const DEFAULT_MAX_LINES = 1000;
|
||||||
|
|
||||||
@ -30,12 +38,17 @@ function serializeParams(data: any) {
|
|||||||
.join('&');
|
.join('&');
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LokiDatasource {
|
export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
||||||
languageProvider: LanguageProvider;
|
languageProvider: LanguageProvider;
|
||||||
maxLines: number;
|
maxLines: number;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private instanceSettings, private backendSrv, private templateSrv) {
|
constructor(
|
||||||
|
private instanceSettings: DataSourceInstanceSettings<LokiOptions>,
|
||||||
|
private backendSrv: BackendSrv,
|
||||||
|
private templateSrv: TemplateSrv
|
||||||
|
) {
|
||||||
|
super(instanceSettings);
|
||||||
this.languageProvider = new LanguageProvider(this);
|
this.languageProvider = new LanguageProvider(this);
|
||||||
const settingsData = instanceSettings.jsonData || {};
|
const settingsData = instanceSettings.jsonData || {};
|
||||||
this.maxLines = parseInt(settingsData.maxLines, 10) || DEFAULT_MAX_LINES;
|
this.maxLines = parseInt(settingsData.maxLines, 10) || DEFAULT_MAX_LINES;
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { DataQuery, Labels } from '@grafana/ui/src/types';
|
import { DataQuery, Labels, DataSourceJsonData } from '@grafana/ui/src/types';
|
||||||
|
|
||||||
export interface LokiQuery extends DataQuery {
|
export interface LokiQuery extends DataQuery {
|
||||||
expr: string;
|
expr: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LokiOptions extends DataSourceJsonData {
|
||||||
|
maxLines?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LokiLogsStream {
|
export interface LokiLogsStream {
|
||||||
labels: string;
|
labels: string;
|
||||||
entries: LokiLogsStreamEntry[];
|
entries: LokiLogsStreamEntry[];
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { DataSourceApi, DataQuery, DataQueryRequest } from '@grafana/ui';
|
import { DataSourceApi, DataQuery, DataQueryRequest, DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
||||||
|
|
||||||
class MixedDatasource implements DataSourceApi<DataQuery> {
|
class MixedDatasource extends DataSourceApi<DataQuery> {
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private datasourceSrv: DatasourceSrv) {}
|
constructor(instanceSettings: DataSourceInstanceSettings, private datasourceSrv: DatasourceSrv) {
|
||||||
|
super(instanceSettings);
|
||||||
|
}
|
||||||
|
|
||||||
query(options: DataQueryRequest<DataQuery>) {
|
query(options: DataQueryRequest<DataQuery>) {
|
||||||
const sets = _.groupBy(options.targets, 'datasource');
|
const sets = _.groupBy(options.targets, 'datasource');
|
||||||
|
@ -14,14 +14,15 @@ import { getQueryHints } from './query_hints';
|
|||||||
import { expandRecordingRules } from './language_utils';
|
import { expandRecordingRules } from './language_utils';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PromQuery } from './types';
|
import { PromQuery, PromOptions } from './types';
|
||||||
import { DataQueryRequest, DataSourceApi, AnnotationEvent } from '@grafana/ui/src/types';
|
import { DataQueryRequest, DataSourceApi, AnnotationEvent, DataSourceInstanceSettings } from '@grafana/ui/src/types';
|
||||||
import { ExploreUrlState } from 'app/types/explore';
|
import { ExploreUrlState } from 'app/types/explore';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
export class PrometheusDatasource implements DataSourceApi<PromQuery> {
|
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
||||||
type: string;
|
type: string;
|
||||||
editorSrc: string;
|
editorSrc: string;
|
||||||
name: string;
|
|
||||||
ruleMappings: { [index: string]: string };
|
ruleMappings: { [index: string]: string };
|
||||||
url: string;
|
url: string;
|
||||||
directUrl: string;
|
directUrl: string;
|
||||||
@ -35,25 +36,32 @@ export class PrometheusDatasource implements DataSourceApi<PromQuery> {
|
|||||||
resultTransformer: ResultTransformer;
|
resultTransformer: ResultTransformer;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(instanceSettings, private $q, private backendSrv: BackendSrv, private templateSrv, private timeSrv) {
|
constructor(
|
||||||
|
instanceSettings: DataSourceInstanceSettings<PromOptions>,
|
||||||
|
private $q,
|
||||||
|
private backendSrv: BackendSrv,
|
||||||
|
private templateSrv: TemplateSrv,
|
||||||
|
private timeSrv: TimeSrv
|
||||||
|
) {
|
||||||
|
super(instanceSettings);
|
||||||
|
|
||||||
this.type = 'prometheus';
|
this.type = 'prometheus';
|
||||||
this.editorSrc = 'app/features/prometheus/partials/query.editor.html';
|
this.editorSrc = 'app/features/prometheus/partials/query.editor.html';
|
||||||
this.name = instanceSettings.name;
|
|
||||||
this.url = instanceSettings.url;
|
this.url = instanceSettings.url;
|
||||||
this.directUrl = instanceSettings.directUrl;
|
|
||||||
this.basicAuth = instanceSettings.basicAuth;
|
this.basicAuth = instanceSettings.basicAuth;
|
||||||
this.withCredentials = instanceSettings.withCredentials;
|
this.withCredentials = instanceSettings.withCredentials;
|
||||||
this.interval = instanceSettings.jsonData.timeInterval || '15s';
|
this.interval = instanceSettings.jsonData.timeInterval || '15s';
|
||||||
this.queryTimeout = instanceSettings.jsonData.queryTimeout;
|
this.queryTimeout = instanceSettings.jsonData.queryTimeout;
|
||||||
this.httpMethod = instanceSettings.jsonData.httpMethod || 'GET';
|
this.httpMethod = instanceSettings.jsonData.httpMethod || 'GET';
|
||||||
|
this.directUrl = instanceSettings.jsonData.directUrl;
|
||||||
this.resultTransformer = new ResultTransformer(templateSrv);
|
this.resultTransformer = new ResultTransformer(templateSrv);
|
||||||
this.ruleMappings = {};
|
this.ruleMappings = {};
|
||||||
this.languageProvider = new PrometheusLanguageProvider(this);
|
this.languageProvider = new PrometheusLanguageProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init = () => {
|
||||||
this.loadRules();
|
this.loadRules();
|
||||||
}
|
};
|
||||||
|
|
||||||
getQueryDisplayText(query: PromQuery) {
|
getQueryDisplayText(query: PromQuery) {
|
||||||
return query.expr;
|
return query.expr;
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import { PromCompleter } from '../completer';
|
import { PromCompleter } from '../completer';
|
||||||
import { PrometheusDatasource } from '../datasource';
|
import { PrometheusDatasource } from '../datasource';
|
||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
|
import { PromOptions } from '../types';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
jest.mock('../datasource');
|
jest.mock('../datasource');
|
||||||
jest.mock('app/core/services/backend_srv');
|
jest.mock('app/core/services/backend_srv');
|
||||||
|
|
||||||
@ -16,7 +20,13 @@ describe('Prometheus editor completer', () => {
|
|||||||
const editor = {};
|
const editor = {};
|
||||||
|
|
||||||
const backendSrv = {} as BackendSrv;
|
const backendSrv = {} as BackendSrv;
|
||||||
const datasourceStub = new PrometheusDatasource({}, {}, backendSrv, {}, {});
|
const datasourceStub = new PrometheusDatasource(
|
||||||
|
{} as DataSourceInstanceSettings<PromOptions>,
|
||||||
|
{},
|
||||||
|
backendSrv,
|
||||||
|
{} as TemplateSrv,
|
||||||
|
{} as TimeSrv
|
||||||
|
);
|
||||||
|
|
||||||
datasourceStub.metadataRequest = jest.fn(() =>
|
datasourceStub.metadataRequest = jest.fn(() =>
|
||||||
Promise.resolve({ data: { data: [{ metric: { job: 'node', instance: 'localhost:9100' } }] } })
|
Promise.resolve({ data: { data: [{ metric: { job: 'node', instance: 'localhost:9100' } }] } })
|
||||||
|
@ -8,6 +8,10 @@ import {
|
|||||||
prometheusSpecialRegexEscape,
|
prometheusSpecialRegexEscape,
|
||||||
} from '../datasource';
|
} from '../datasource';
|
||||||
import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
||||||
|
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
|
import { PromOptions } from '../types';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
jest.mock('../metric_find_query');
|
jest.mock('../metric_find_query');
|
||||||
|
|
||||||
@ -18,13 +22,13 @@ const DEFAULT_TEMPLATE_SRV_MOCK = {
|
|||||||
|
|
||||||
describe('PrometheusDatasource', () => {
|
describe('PrometheusDatasource', () => {
|
||||||
const ctx: any = {};
|
const ctx: any = {};
|
||||||
const instanceSettings = {
|
const instanceSettings = ({
|
||||||
url: 'proxied',
|
url: 'proxied',
|
||||||
directUrl: 'direct',
|
directUrl: 'direct',
|
||||||
user: 'test',
|
user: 'test',
|
||||||
password: 'mupp',
|
password: 'mupp',
|
||||||
jsonData: {} as any,
|
jsonData: {} as any,
|
||||||
};
|
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||||
|
|
||||||
ctx.backendSrvMock = {};
|
ctx.backendSrvMock = {};
|
||||||
|
|
||||||
@ -347,27 +351,27 @@ const HOUR = 60 * MINUTE;
|
|||||||
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
||||||
|
|
||||||
const ctx = {} as any;
|
const ctx = {} as any;
|
||||||
const instanceSettings = {
|
const instanceSettings = ({
|
||||||
url: 'proxied',
|
url: 'proxied',
|
||||||
directUrl: 'direct',
|
directUrl: 'direct',
|
||||||
user: 'test',
|
user: 'test',
|
||||||
password: 'mupp',
|
password: 'mupp',
|
||||||
jsonData: { httpMethod: 'GET' },
|
jsonData: { httpMethod: 'GET' },
|
||||||
};
|
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||||
const backendSrv = {
|
const backendSrv = {
|
||||||
datasourceRequest: jest.fn(),
|
datasourceRequest: jest.fn(),
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
const templateSrv = {
|
const templateSrv = ({
|
||||||
getAdhocFilters: () => [],
|
getAdhocFilters: () => [],
|
||||||
replace: jest.fn(str => str),
|
replace: jest.fn(str => str),
|
||||||
};
|
} as unknown) as TemplateSrv;
|
||||||
|
|
||||||
const timeSrv = {
|
const timeSrv = ({
|
||||||
timeRange: () => {
|
timeRange: () => {
|
||||||
return { to: { diff: () => 2000 }, from: '' };
|
return { to: { diff: () => 2000 }, from: '' };
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as TimeSrv;
|
||||||
|
|
||||||
describe('PrometheusDatasource', () => {
|
describe('PrometheusDatasource', () => {
|
||||||
describe('When querying prometheus with one target using query editor target spec', () => {
|
describe('When querying prometheus with one target using query editor target spec', () => {
|
||||||
@ -1177,13 +1181,13 @@ describe('PrometheusDatasource', () => {
|
|||||||
|
|
||||||
describe('PrometheusDatasource for POST', () => {
|
describe('PrometheusDatasource for POST', () => {
|
||||||
// const ctx = new helpers.ServiceTestContext();
|
// const ctx = new helpers.ServiceTestContext();
|
||||||
const instanceSettings = {
|
const instanceSettings = ({
|
||||||
url: 'proxied',
|
url: 'proxied',
|
||||||
directUrl: 'direct',
|
directUrl: 'direct',
|
||||||
user: 'test',
|
user: 'test',
|
||||||
password: 'mupp',
|
password: 'mupp',
|
||||||
jsonData: { httpMethod: 'POST' },
|
jsonData: { httpMethod: 'POST' },
|
||||||
};
|
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||||
|
|
||||||
describe('When querying prometheus with one target using query editor target spec', () => {
|
describe('When querying prometheus with one target using query editor target spec', () => {
|
||||||
let results;
|
let results;
|
||||||
|
@ -2,15 +2,17 @@ import { PrometheusDatasource } from '../datasource';
|
|||||||
import PrometheusMetricFindQuery from '../metric_find_query';
|
import PrometheusMetricFindQuery from '../metric_find_query';
|
||||||
import q from 'q';
|
import q from 'q';
|
||||||
import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
|
import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
|
||||||
|
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
|
import { PromOptions } from '../types';
|
||||||
|
|
||||||
describe('PrometheusMetricFindQuery', () => {
|
describe('PrometheusMetricFindQuery', () => {
|
||||||
const instanceSettings = {
|
const instanceSettings = ({
|
||||||
url: 'proxied',
|
url: 'proxied',
|
||||||
directUrl: 'direct',
|
directUrl: 'direct',
|
||||||
user: 'test',
|
user: 'test',
|
||||||
password: 'mupp',
|
password: 'mupp',
|
||||||
jsonData: { httpMethod: 'GET' },
|
jsonData: { httpMethod: 'GET' },
|
||||||
};
|
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||||
const raw = {
|
const raw = {
|
||||||
from: toUtc('2018-04-25 10:00'),
|
from: toUtc('2018-04-25 10:00'),
|
||||||
to: toUtc('2018-04-25 11:00'),
|
to: toUtc('2018-04-25 11:00'),
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import { DataQuery } from '@grafana/ui/src/types';
|
import { DataQuery, DataSourceJsonData } from '@grafana/ui/src/types';
|
||||||
|
|
||||||
export interface PromQuery extends DataQuery {
|
export interface PromQuery extends DataQuery {
|
||||||
expr: string;
|
expr: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PromOptions extends DataSourceJsonData {
|
||||||
|
timeInterval: string;
|
||||||
|
queryTimeout: string;
|
||||||
|
httpMethod: string;
|
||||||
|
directUrl: string;
|
||||||
|
}
|
||||||
|
@ -2,11 +2,13 @@ import { stackdriverUnitMappings } from './constants';
|
|||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import StackdriverMetricFindQuery from './StackdriverMetricFindQuery';
|
import StackdriverMetricFindQuery from './StackdriverMetricFindQuery';
|
||||||
import { StackdriverQuery, MetricDescriptor } from './types';
|
import { StackdriverQuery, MetricDescriptor, StackdriverOptions } from './types';
|
||||||
import { DataSourceApi, DataQueryRequest } from '@grafana/ui/src/types';
|
import { DataSourceApi, DataQueryRequest, DataSourceInstanceSettings, ScopedVars } from '@grafana/ui/src/types';
|
||||||
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
export default class StackdriverDatasource implements DataSourceApi<StackdriverQuery> {
|
export default class StackdriverDatasource extends DataSourceApi<StackdriverQuery, StackdriverOptions> {
|
||||||
id: number;
|
|
||||||
url: string;
|
url: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
projectName: string;
|
projectName: string;
|
||||||
@ -15,10 +17,15 @@ export default class StackdriverDatasource implements DataSourceApi<StackdriverQ
|
|||||||
metricTypes: any[];
|
metricTypes: any[];
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(instanceSettings, private backendSrv, private templateSrv, private timeSrv) {
|
constructor(
|
||||||
|
instanceSettings: DataSourceInstanceSettings<StackdriverOptions>,
|
||||||
|
private backendSrv: BackendSrv,
|
||||||
|
private templateSrv: TemplateSrv,
|
||||||
|
private timeSrv: TimeSrv
|
||||||
|
) {
|
||||||
|
super(instanceSettings);
|
||||||
this.baseUrl = `/stackdriver/`;
|
this.baseUrl = `/stackdriver/`;
|
||||||
this.url = instanceSettings.url;
|
this.url = instanceSettings.url;
|
||||||
this.id = instanceSettings.id;
|
|
||||||
this.projectName = instanceSettings.jsonData.defaultProject || '';
|
this.projectName = instanceSettings.jsonData.defaultProject || '';
|
||||||
this.authenticationType = instanceSettings.jsonData.authenticationType || 'jwt';
|
this.authenticationType = instanceSettings.jsonData.authenticationType || 'jwt';
|
||||||
this.metricTypes = [];
|
this.metricTypes = [];
|
||||||
@ -62,7 +69,7 @@ export default class StackdriverDatasource implements DataSourceApi<StackdriverQ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolateFilters(filters: string[], scopedVars: object) {
|
interpolateFilters(filters: string[], scopedVars: ScopedVars) {
|
||||||
return (filters || []).map(f => {
|
return (filters || []).map(f => {
|
||||||
return this.templateSrv.replace(f, scopedVars || {}, 'regex');
|
return this.templateSrv.replace(f, scopedVars || {}, 'regex');
|
||||||
});
|
});
|
||||||
|
@ -3,26 +3,30 @@ import { metricDescriptors } from './testData';
|
|||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { CustomVariable } from 'app/features/templating/all';
|
import { CustomVariable } from 'app/features/templating/all';
|
||||||
import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
|
import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
|
||||||
|
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
|
import { StackdriverOptions } from '../types';
|
||||||
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
describe('StackdriverDataSource', () => {
|
describe('StackdriverDataSource', () => {
|
||||||
const instanceSettings = {
|
const instanceSettings = ({
|
||||||
jsonData: {
|
jsonData: {
|
||||||
defaultProject: 'testproject',
|
defaultProject: 'testproject',
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as DataSourceInstanceSettings<StackdriverOptions>;
|
||||||
const templateSrv = new TemplateSrv();
|
const templateSrv = new TemplateSrv();
|
||||||
const timeSrv = {};
|
const timeSrv = {} as TimeSrv;
|
||||||
|
|
||||||
describe('when performing testDataSource', () => {
|
describe('when performing testDataSource', () => {
|
||||||
describe('and call to stackdriver api succeeds', () => {
|
describe('and call to stackdriver api succeeds', () => {
|
||||||
let ds;
|
let ds;
|
||||||
let result;
|
let result;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.resolve({ status: 200 });
|
return Promise.resolve({ status: 200 });
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
@ -35,9 +39,9 @@ describe('StackdriverDataSource', () => {
|
|||||||
let ds;
|
let ds;
|
||||||
let result;
|
let result;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
datasourceRequest: async () => Promise.resolve({ status: 200, data: metricDescriptors }),
|
datasourceRequest: async () => Promise.resolve({ status: 200, data: metricDescriptors }),
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
@ -50,7 +54,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
let ds;
|
let ds;
|
||||||
let result;
|
let result;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
datasourceRequest: async () =>
|
datasourceRequest: async () =>
|
||||||
Promise.reject({
|
Promise.reject({
|
||||||
statusText: 'Bad Request',
|
statusText: 'Bad Request',
|
||||||
@ -58,7 +62,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
error: { code: 400, message: 'Field interval.endTime had an invalid value' },
|
error: { code: 400, message: 'Field interval.endTime had an invalid value' },
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
||||||
result = await ds.testDatasource();
|
result = await ds.testDatasource();
|
||||||
});
|
});
|
||||||
@ -103,9 +107,9 @@ describe('StackdriverDataSource', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
datasourceRequest: async () => Promise.resolve({ status: 200, data: response }),
|
datasourceRequest: async () => Promise.resolve({ status: 200, data: response }),
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -122,7 +126,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
let ds;
|
let ds;
|
||||||
let result;
|
let result;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const backendSrv = {
|
const backendSrv = ({
|
||||||
async datasourceRequest() {
|
async datasourceRequest() {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
data: {
|
data: {
|
||||||
@ -139,7 +143,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
} as unknown) as BackendSrv;
|
||||||
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
|
||||||
result = await ds.getMetricTypes();
|
result = await ds.getMetricTypes();
|
||||||
});
|
});
|
||||||
@ -155,12 +159,14 @@ describe('StackdriverDataSource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const noopBackendSrv = ({} as unknown) as BackendSrv;
|
||||||
|
|
||||||
describe('when interpolating a template variable for the filter', () => {
|
describe('when interpolating a template variable for the filter', () => {
|
||||||
let interpolated;
|
let interpolated;
|
||||||
describe('and is single value variable', () => {
|
describe('and is single value variable', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const filterTemplateSrv = initTemplateSrv('filtervalue1');
|
const filterTemplateSrv = initTemplateSrv('filtervalue1');
|
||||||
const ds = new StackdriverDataSource(instanceSettings, {}, filterTemplateSrv, timeSrv);
|
const ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, filterTemplateSrv, timeSrv);
|
||||||
interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -173,7 +179,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
describe('and is multi value variable', () => {
|
describe('and is multi value variable', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const filterTemplateSrv = initTemplateSrv(['filtervalue1', 'filtervalue2'], true);
|
const filterTemplateSrv = initTemplateSrv(['filtervalue1', 'filtervalue2'], true);
|
||||||
const ds = new StackdriverDataSource(instanceSettings, {}, filterTemplateSrv, timeSrv);
|
const ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, filterTemplateSrv, timeSrv);
|
||||||
interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '[[test]]'], {});
|
interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '[[test]]'], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -189,7 +195,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
describe('and is single value variable', () => {
|
describe('and is single value variable', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const groupByTemplateSrv = initTemplateSrv('groupby1');
|
const groupByTemplateSrv = initTemplateSrv('groupby1');
|
||||||
const ds = new StackdriverDataSource(instanceSettings, {}, groupByTemplateSrv, timeSrv);
|
const ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, groupByTemplateSrv, timeSrv);
|
||||||
interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -202,7 +208,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
describe('and is multi value variable', () => {
|
describe('and is multi value variable', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const groupByTemplateSrv = initTemplateSrv(['groupby1', 'groupby2'], true);
|
const groupByTemplateSrv = initTemplateSrv(['groupby1', 'groupby2'], true);
|
||||||
const ds = new StackdriverDataSource(instanceSettings, {}, groupByTemplateSrv, timeSrv);
|
const ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, groupByTemplateSrv, timeSrv);
|
||||||
interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -217,7 +223,7 @@ describe('StackdriverDataSource', () => {
|
|||||||
describe('unit parsing', () => {
|
describe('unit parsing', () => {
|
||||||
let ds, res;
|
let ds, res;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ds = new StackdriverDataSource(instanceSettings, {}, templateSrv, timeSrv);
|
ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, templateSrv, timeSrv);
|
||||||
});
|
});
|
||||||
describe('when theres only one target', () => {
|
describe('when theres only one target', () => {
|
||||||
describe('and the stackdriver unit doesnt have a corresponding grafana unit', () => {
|
describe('and the stackdriver unit doesnt have a corresponding grafana unit', () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DataQuery } from '@grafana/ui/src/types';
|
import { DataQuery, DataSourceJsonData } from '@grafana/ui/src/types';
|
||||||
|
|
||||||
export enum MetricFindQueryTypes {
|
export enum MetricFindQueryTypes {
|
||||||
Services = 'services',
|
Services = 'services',
|
||||||
@ -40,6 +40,11 @@ export interface StackdriverQuery extends DataQuery {
|
|||||||
view?: string;
|
view?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StackdriverOptions extends DataSourceJsonData {
|
||||||
|
defaultProject?: string;
|
||||||
|
authenticationType?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AnnotationTarget {
|
export interface AnnotationTarget {
|
||||||
defaultProject: string;
|
defaultProject: string;
|
||||||
metricType: string;
|
metricType: string;
|
||||||
|
@ -17,13 +17,12 @@ export interface TestDataRegistry {
|
|||||||
[key: string]: TestData[];
|
[key: string]: TestData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TestDataDatasource implements DataSourceApi<TestDataQuery> {
|
export class TestDataDatasource extends DataSourceApi<TestDataQuery> {
|
||||||
id: number;
|
|
||||||
streams = new StreamHandler();
|
streams = new StreamHandler();
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(instanceSettings: DataSourceInstanceSettings) {
|
constructor(instanceSettings: DataSourceInstanceSettings) {
|
||||||
this.id = instanceSettings.id;
|
super(instanceSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
query(options: DataQueryRequest<TestDataQuery>, observer: DataStreamObserver) {
|
query(options: DataQueryRequest<TestDataQuery>, observer: DataStreamObserver) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DataSourceApi, DataQueryRequest, DataQueryResponse } from '@grafana/ui';
|
import { DataSourceApi, DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
|
|
||||||
export class DatasourceSrvMock {
|
export class DatasourceSrvMock {
|
||||||
constructor(private defaultDS: DataSourceApi, private datasources: { [name: string]: DataSourceApi }) {
|
constructor(private defaultDS: DataSourceApi, private datasources: { [name: string]: DataSourceApi }) {
|
||||||
@ -17,14 +17,15 @@ export class DatasourceSrvMock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MockDataSourceApi implements DataSourceApi {
|
export class MockDataSourceApi extends DataSourceApi {
|
||||||
name: string;
|
|
||||||
|
|
||||||
result: DataQueryResponse = { data: [] };
|
result: DataQueryResponse = { data: [] };
|
||||||
queryResolver: Promise<DataQueryResponse>;
|
queryResolver: Promise<DataQueryResponse>;
|
||||||
|
|
||||||
constructor(DataQueryResponse, name?: string) {
|
constructor(name?: string, result?: DataQueryResponse) {
|
||||||
this.name = name ? name : 'MockDataSourceApi';
|
super({ name: name ? name : 'MockDataSourceApi' } as DataSourceInstanceSettings);
|
||||||
|
if (result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query(request: DataQueryRequest): Promise<DataQueryResponse> {
|
query(request: DataQueryRequest): Promise<DataQueryResponse> {
|
||||||
|
Loading…
Reference in New Issue
Block a user