From 777979965d2d9260569628fda5d9780c73ea75ec Mon Sep 17 00:00:00 2001 From: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com> Date: Wed, 30 Oct 2024 08:50:51 -0500 Subject: [PATCH] Loki: pass backendSrv request options (#95608) * chore: allow passthrough of options, reject promise on error --- .../datasource/loki/LanguageProvider.test.ts | 13 ++++-- .../datasource/loki/LanguageProvider.ts | 46 ++++++++++++------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/public/app/plugins/datasource/loki/LanguageProvider.test.ts b/public/app/plugins/datasource/loki/LanguageProvider.test.ts index 7ff7db74f7b..c397934b356 100644 --- a/public/app/plugins/datasource/loki/LanguageProvider.test.ts +++ b/public/app/plugins/datasource/loki/LanguageProvider.test.ts @@ -326,7 +326,7 @@ describe('Language completion provider', () => { const requestSpy = jest.spyOn(provider, 'request'); const labelValues = await provider.fetchDetectedLabelValues(labelName, options); - expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true); + expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true, undefined); expect(labelValues).toEqual(expectedResponse); }); @@ -340,7 +340,7 @@ describe('Language completion provider', () => { const nextLabelValues = await provider.fetchDetectedLabelValues(labelName, options); expect(requestSpy).toHaveBeenCalledTimes(1); - expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true); + expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true, undefined); expect(nextLabelValues).toEqual(expectedResponse); }); @@ -349,7 +349,12 @@ describe('Language completion provider', () => { const requestSpy = jest.spyOn(provider, 'request'); await provider.fetchDetectedLabelValues('`\\"testkey', options); - expect(requestSpy).toHaveBeenCalledWith('detected_field/%60%5C%22testkey/values', expectedOptions, true); + expect(requestSpy).toHaveBeenCalledWith( + 'detected_field/%60%5C%22testkey/values', + expectedOptions, + true, + undefined + ); }); it('should cache by label name', async () => { @@ -448,7 +453,7 @@ describe('Request URL', () => { const instance = new LanguageProvider(datasourceWithLabels); instance.fetchLabels(); const expectedUrl = 'labels'; - expect(datasourceSpy).toHaveBeenCalledWith(expectedUrl, rangeParams); + expect(datasourceSpy).toHaveBeenCalledWith(expectedUrl, rangeParams, undefined); }); }); diff --git a/public/app/plugins/datasource/loki/LanguageProvider.ts b/public/app/plugins/datasource/loki/LanguageProvider.ts index 6b4dd6b6fcb..e56acf6f3d7 100644 --- a/public/app/plugins/datasource/loki/LanguageProvider.ts +++ b/public/app/plugins/datasource/loki/LanguageProvider.ts @@ -2,7 +2,7 @@ import { flatten } from 'lodash'; import { LRUCache } from 'lru-cache'; import { LanguageProvider, AbstractQuery, KeyValue, getDefaultTimeRange, TimeRange, ScopedVars } from '@grafana/data'; -import { config } from '@grafana/runtime'; +import { BackendSrvRequest, config } from '@grafana/runtime'; import { DEFAULT_MAX_LINES_SAMPLE, LokiDatasource } from './datasource'; import { abstractQueryToExpr, mapAbstractOperatorsToOp, processLabels } from './languageUtils'; @@ -44,13 +44,19 @@ export default class LokiLanguageProvider extends LanguageProvider { Object.assign(this, initialValues); } - request = async (url: string, params?: Record, throwError?: boolean) => { + request = async ( + url: string, + params?: Record, + throwError?: boolean, + requestOptions?: Partial + ) => { try { - return await this.datasource.metadataRequest(url, params); + return await this.datasource.metadataRequest(url, params, requestOptions); } catch (error) { - console.error(error); if (throwError) { throw error; + } else { + console.error(error); } } @@ -245,20 +251,27 @@ export default class LokiLanguageProvider extends LanguageProvider { async fetchDetectedLabelValues( labelName: string, - options?: { expr?: string; timeRange?: TimeRange; limit?: number; scopedVars?: ScopedVars; throwError?: boolean } - ): Promise { + queryOptions?: { + expr?: string; + timeRange?: TimeRange; + limit?: number; + scopedVars?: ScopedVars; + throwError?: boolean; + }, + requestOptions?: Partial + ): Promise { const label = encodeURIComponent(this.datasource.interpolateString(labelName)); const interpolatedExpr = - options?.expr && options.expr !== EMPTY_SELECTOR - ? this.datasource.interpolateString(options.expr, options.scopedVars) + queryOptions?.expr && queryOptions.expr !== EMPTY_SELECTOR + ? this.datasource.interpolateString(queryOptions.expr, queryOptions.scopedVars) : undefined; const url = `detected_field/${label}/values`; - const range = options?.timeRange ?? this.getDefaultTimeRange(); + const range = queryOptions?.timeRange ?? this.getDefaultTimeRange(); const rangeParams = this.datasource.getTimeRangeParams(range); const { start, end } = rangeParams; - const params: KeyValue = { start, end, limit: options?.limit ?? 1000 }; + const params: KeyValue = { start, end, limit: queryOptions?.limit ?? 1000 }; let paramCacheKey = label; if (interpolatedExpr) { @@ -280,9 +293,9 @@ export default class LokiLanguageProvider extends LanguageProvider { return labelValuesPromise; } - labelValuesPromise = new Promise(async (resolve) => { + labelValuesPromise = new Promise(async (resolve, reject) => { try { - const data = await this.request(url, params, options?.throwError); + const data = await this.request(url, params, queryOptions?.throwError, requestOptions); if (Array.isArray(data)) { const labelValues = data.slice().sort(); this.detectedFieldValuesCache.set(cacheKey, labelValues); @@ -290,10 +303,11 @@ export default class LokiLanguageProvider extends LanguageProvider { resolve(labelValues); } } catch (error) { - console.error(error); - resolve([]); - if (options?.throwError) { - throw error; + if (queryOptions?.throwError) { + reject(error); + } else { + console.error(error); + resolve([]); } } });