diff --git a/src/datasource-zabbix/datasource.ts b/src/datasource-zabbix/datasource.ts index dd942c2..d250768 100644 --- a/src/datasource-zabbix/datasource.ts +++ b/src/datasource-zabbix/datasource.ts @@ -15,7 +15,7 @@ import problemsHandler from './problemsHandler'; import { Zabbix } from './zabbix/zabbix'; import { ZabbixAPIError } from './zabbix/connectors/zabbix_api/zabbixAPIConnector'; import { ZabbixMetricsQuery, ZabbixDSOptions, VariableQueryTypes, ShowProblemTypes, ProblemDTO } from './types'; -import { getBackendSrv, getTemplateSrv, toDataQueryResponse } from '@grafana/runtime'; +import { getBackendSrv, getTemplateSrv, toDataQueryError, toDataQueryResponse } from '@grafana/runtime'; import { DataFrame, DataQueryRequest, DataQueryResponse, DataSourceApi, DataSourceInstanceSettings, FieldType, isDataFrame, LoadingState } from '@grafana/data'; export class ZabbixDatasource extends DataSourceApi { @@ -101,18 +101,19 @@ export class ZabbixDatasource extends DataSourceApi): Promise | Observable { // Migrate old targets - request.targets = request.targets.map(t => { + const requestTargets = request.targets.map(t => { // Prevent changes of original object const target = _.cloneDeep(t); return migrations.migrate(target); }); - if (isBackendQuery(request)) { - return this.backendQuery(request); - } + const backendResponsePromise = this.backendQuery({...request, targets: requestTargets}); + // if (isBackendQuery(request)) { + // } // Create request for each target - const promises = _.map(request.targets, target => { + const frontendTargets = requestTargets.filter(t => !isBackendTarget(t)); + const promises = _.map(frontendTargets, target => { // Don't request for hidden targets if (target.hide) { return []; @@ -172,7 +173,7 @@ export class ZabbixDatasource extends DataSourceApi = Promise.all(_.flatten(promises)) .then(_.flatten) .then(data => { if (data && data.length > 0 && isDataFrame(data[0]) && !utils.isProblemsDataFrame(data[0])) { @@ -182,19 +183,28 @@ export class ZabbixDatasource extends DataSourceApi { + return { data }; + }); + + return Promise.all([backendResponsePromise, frontendResponsePromise]) + .then(rsp => { + // Merge backend and frontend queries results + const [backendRes, frontendRes] = rsp; + if (frontendRes.data) { + backendRes.data = backendRes.data.concat(frontendRes.data); + } + return { - data, + data: backendRes.data, state: LoadingState.Done, key: request.requestId, }; }); } - backendQuery(request: DataQueryRequest): Observable { + async backendQuery(request: DataQueryRequest): Promise { const { intervalMs, maxDataPoints, range, requestId } = request; - const targets = request.targets; + const targets = request.targets.filter(isBackendTarget); // Add range variables request.scopedVars = Object.assign({}, request.scopedVars, utils.getRangeScopedVars(request.range)); @@ -224,7 +234,7 @@ export class ZabbixDatasource extends DataSourceApi { - const resp = toDataQueryResponse(rsp); - this.sortByRefId(resp); - this.applyFrontendFunctions(resp, request); - if (responseHandler.isConvertibleToWide(resp.data)) { - console.log('Converting response to the wide format'); - resp.data = responseHandler.convertToWide(resp.data); - } - return resp; - }), - catchError((err) => { - return of(toDataQueryResponse(err)); - }) - ); - } - - doTsdbRequest(options) { - const tsdbRequestData: any = { - queries: options.targets.map(target => { - target.datasourceId = this.datasourceId; - target.queryType = 'zabbixAPI'; - return target; - }), - }; - - if (options.range) { - tsdbRequestData.from = options.range.from.valueOf().toString(); - tsdbRequestData.to = options.range.to.valueOf().toString(); + }).toPromise(); + } catch (err) { + return toDataQueryResponse(err); } - return getBackendSrv().post('/api/ds/query', tsdbRequestData); - } + const resp = toDataQueryResponse(rsp); + this.sortByRefId(resp); + this.applyFrontendFunctions(resp, request); + if (responseHandler.isConvertibleToWide(resp.data)) { + console.log('Converting response to the wide format'); + resp.data = responseHandler.convertToWide(resp.data); + } - /** - * @returns {Promise} - */ - doTSDBConnectionTest() { - /** - * @type {{ queries: ZabbixConnectionTestQuery[] }} - */ - const tsdbRequestData = { - queries: [ - { - datasourceId: this.datasourceId, - queryType: 'connectionTest' - } - ] - }; - - return getBackendSrv().post('/api/tsdb/query', tsdbRequestData); + return resp; } /** @@ -972,8 +945,10 @@ function getRequestTarget(request: DataQueryRequest, refId: string): any { } function isBackendQuery(request: DataQueryRequest): boolean { - return request.targets.every(q => - q.queryType === c.MODE_METRICS || - q.queryType === c.MODE_ITEMID - ); + return request.targets.every(isBackendTarget); +} + +function isBackendTarget(target: any): boolean { + return target.queryType === c.MODE_METRICS || + target.queryType === c.MODE_ITEMID; } diff --git a/src/datasource-zabbix/migrations.ts b/src/datasource-zabbix/migrations.ts index 0425aa0..4cae7be 100644 --- a/src/datasource-zabbix/migrations.ts +++ b/src/datasource-zabbix/migrations.ts @@ -51,7 +51,9 @@ function migrateQueryType(target) { } // queryType is a string in query model - target.queryType = (target.queryType as number).toString(); + if (typeof target.queryType === 'number') { + target.queryType = (target.queryType as number)?.toString(); + } } function migrateSLA(target) { diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts index 49299b9..0843f6e 100644 --- a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts @@ -76,7 +76,7 @@ export class ZabbixAPIConnector { requestOptions.headers.Authorization = this.requestOptions.basicAuth; } - const response = await getBackendSrv().datasourceRequest(requestOptions); + const response = await getBackendSrv().fetch(requestOptions).toPromise(); return response?.data?.result; }