UNPKG

@grafana/runtime

Version:
1 lines • 24.2 kB
{"version":3,"file":"DataSourceWithBackend.mjs","sources":["../../../src/utils/DataSourceWithBackend.ts"],"sourcesContent":["import { lastValueFrom, merge, Observable, of } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\n\nimport {\n DataFrame,\n dataFrameToJSON,\n DataQuery,\n DataQueryRequest,\n DataQueryResponse,\n TestDataSourceResponse,\n DataSourceApi,\n DataSourceInstanceSettings,\n DataSourceJsonData,\n DataSourceRef,\n getDataSourceRef,\n makeClassES5Compatible,\n parseLiveChannelAddress,\n ScopedVars,\n AdHocVariableFilter,\n} from '@grafana/data';\n\nimport { reportInteraction } from '../analytics/utils';\nimport { config } from '../config';\nimport {\n BackendSrvRequest,\n FetchResponse,\n getBackendSrv,\n getDataSourceSrv,\n getGrafanaLiveSrv,\n StreamingFrameAction,\n StreamingFrameOptions,\n} from '../services';\n\nimport { publicDashboardQueryHandler } from './publicDashboardQueryHandler';\nimport { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';\n\n/**\n * @internal\n */\nexport const ExpressionDatasourceRef = Object.freeze({\n type: '__expr__',\n uid: '__expr__',\n name: 'Expression',\n});\n\n/**\n * @public\n */\nexport function isExpressionReference(ref?: DataSourceRef | string | null): boolean {\n if (!ref) {\n return false;\n }\n const v = typeof ref === 'string' ? ref : ref.type;\n return v === ExpressionDatasourceRef.type || v === ExpressionDatasourceRef.name || v === '-100'; // -100 was a legacy accident that should be removed\n}\n\nexport class HealthCheckError extends Error {\n details: HealthCheckResultDetails;\n\n constructor(message: string, details: HealthCheckResultDetails) {\n super(message);\n this.details = details;\n this.name = 'HealthCheckError';\n }\n}\n\n/**\n * Describes the current health status of a data source plugin.\n *\n * @public\n */\nexport enum HealthStatus {\n Unknown = 'UNKNOWN',\n OK = 'OK',\n Error = 'ERROR',\n}\n\n// Internal for now\nenum PluginRequestHeaders {\n PluginID = 'X-Plugin-Id', // can be used for routing\n DatasourceUID = 'X-Datasource-Uid', // can be used for routing/ load balancing\n DashboardUID = 'X-Dashboard-Uid', // mainly useful for debugging slow queries\n PanelID = 'X-Panel-Id', // mainly useful for debugging slow queries\n PanelPluginId = 'X-Panel-Plugin-Id',\n QueryGroupID = 'X-Query-Group-Id', // mainly useful to find related queries with query splitting\n FromExpression = 'X-Grafana-From-Expr', // used by datasources to identify expression queries\n SkipQueryCache = 'X-Cache-Skip', // used by datasources to skip the query cache\n}\n\n/**\n * Describes the details in the payload returned when checking the health of a data source\n * plugin.\n *\n * If the 'message' key exists, this will be displayed in the error message in DataSourceSettingsPage\n * If the 'verboseMessage' key exists, this will be displayed in the expandable details in the error message in DataSourceSettingsPage\n *\n * @public\n */\nexport type HealthCheckResultDetails = Record<string, unknown> | undefined;\n\n/**\n * Describes the payload returned when checking the health of a data source\n * plugin.\n *\n * @public\n */\nexport interface HealthCheckResult {\n status: HealthStatus;\n message: string;\n details: HealthCheckResultDetails;\n}\n\n/**\n * Extend this class to implement a data source plugin that is depending on the Grafana\n * backend API.\n *\n * @public\n */\nclass DataSourceWithBackend<\n TQuery extends DataQuery = DataQuery,\n TOptions extends DataSourceJsonData = DataSourceJsonData,\n> extends DataSourceApi<TQuery, TOptions> {\n constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {\n super(instanceSettings);\n }\n\n /**\n * Ideally final -- any other implementation may not work as expected\n */\n query(request: DataQueryRequest<TQuery>): Observable<DataQueryResponse> {\n if (config.publicDashboardAccessToken) {\n return publicDashboardQueryHandler(request);\n }\n\n const { intervalMs, maxDataPoints, queryCachingTTL, range, requestId, hideFromInspector = false } = request;\n let targets = request.targets;\n\n let hasExpr = false;\n const pluginIDs = new Set<string>();\n const dsUIDs = new Set<string>();\n const queries: DataQuery[] = targets.map((q) => {\n let datasource = this.getRef();\n let datasourceId = this.id;\n let shouldApplyTemplateVariables = true;\n\n if (isExpressionReference(q.datasource)) {\n hasExpr = true;\n return {\n ...q,\n datasource: ExpressionDatasourceRef,\n };\n }\n\n if (q.datasource) {\n const ds = getDataSourceSrv().getInstanceSettings(q.datasource, request.scopedVars);\n\n if (!ds) {\n throw new Error(`Unknown Datasource: ${JSON.stringify(q.datasource)}`);\n }\n\n const dsRef = ds.rawRef ?? getDataSourceRef(ds);\n const dsId = ds.id;\n if (dsRef.uid !== datasource.uid || datasourceId !== dsId) {\n datasource = dsRef;\n datasourceId = dsId;\n // If the query is using a different datasource, we would need to retrieve the datasource\n // instance (async) and apply the template variables but it seems it's not necessary for now.\n shouldApplyTemplateVariables = false;\n }\n }\n if (datasource.type?.length) {\n pluginIDs.add(datasource.type);\n }\n if (datasource.uid?.length) {\n dsUIDs.add(datasource.uid);\n }\n return {\n ...(shouldApplyTemplateVariables ? this.applyTemplateVariables(q, request.scopedVars, request.filters) : q),\n datasource,\n datasourceId, // deprecated!\n intervalMs,\n maxDataPoints,\n queryCachingTTL,\n };\n });\n\n // Return early if no queries exist\n if (!queries.length) {\n return of({ data: [] });\n }\n\n const body = {\n queries,\n from: range?.from.valueOf().toString(),\n to: range?.to.valueOf().toString(),\n };\n\n if (config.featureToggles.queryOverLive) {\n return getGrafanaLiveSrv().getQueryData({\n request,\n body,\n });\n }\n\n const headers: Record<string, string> = request.headers ?? {};\n headers[PluginRequestHeaders.PluginID] = Array.from(pluginIDs).join(', ');\n headers[PluginRequestHeaders.DatasourceUID] = Array.from(dsUIDs).join(', ');\n\n let url = '/api/ds/query?ds_type=' + this.type;\n\n // Use the new query service\n if (config.featureToggles.queryServiceFromUI) {\n if (!(config.featureToggles.queryService || config.featureToggles.grafanaAPIServerWithExperimentalAPIs)) {\n console.warn('feature toggle queryServiceFromUI also requires the queryService to be running');\n } else {\n if (!hasExpr && dsUIDs.size === 1) {\n // TODO? can we talk directly to the apiserver?\n }\n url = `/apis/query.grafana.app/v0alpha1/namespaces/${config.namespace}/query?ds_type=' + this.type`;\n }\n }\n\n if (hasExpr) {\n headers[PluginRequestHeaders.FromExpression] = 'true';\n url += '&expression=true';\n }\n\n // Appending request ID to url to facilitate client-side performance metrics. See #65244 for more context.\n if (requestId) {\n url += `&requestId=${requestId}`;\n }\n\n if (request.dashboardUID) {\n headers[PluginRequestHeaders.DashboardUID] = request.dashboardUID;\n if (request.panelId) {\n headers[PluginRequestHeaders.PanelID] = `${request.panelId}`;\n }\n }\n if (request.panelPluginId) {\n headers[PluginRequestHeaders.PanelPluginId] = `${request.panelPluginId}`;\n }\n if (request.queryGroupId) {\n headers[PluginRequestHeaders.QueryGroupID] = `${request.queryGroupId}`;\n }\n if (request.skipQueryCache) {\n headers[PluginRequestHeaders.SkipQueryCache] = 'true';\n }\n return getBackendSrv()\n .fetch<BackendDataSourceResponse>({\n url,\n method: 'POST',\n data: body,\n requestId,\n hideFromInspector,\n headers,\n })\n .pipe(\n switchMap((raw) => {\n const rsp = toDataQueryResponse(raw, queries);\n // Check if any response should subscribe to a live stream\n if (rsp.data?.length && rsp.data.find((f: DataFrame) => f.meta?.channel)) {\n return toStreamingDataResponse(rsp, request, this.streamOptionsProvider);\n }\n return of(rsp);\n }),\n catchError((err) => {\n return of(toDataQueryResponse(err));\n })\n );\n }\n\n /** Get request headers with plugin ID+UID set */\n protected getRequestHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n headers[PluginRequestHeaders.PluginID] = this.type;\n headers[PluginRequestHeaders.DatasourceUID] = this.uid;\n return headers;\n }\n\n /**\n * Apply template variables for explore\n */\n interpolateVariablesInQueries(queries: TQuery[], scopedVars: ScopedVars, filters?: AdHocVariableFilter[]): TQuery[] {\n return queries.map((q) => this.applyTemplateVariables(q, scopedVars, filters));\n }\n\n /**\n * Override to apply template variables and adhoc filters. The result is usually also `TQuery`, but sometimes this can\n * be used to modify the query structure before sending to the backend.\n *\n * NOTE: if you do modify the structure or use template variables, alerting queries may not work\n * as expected\n *\n * @virtual\n */\n applyTemplateVariables(query: TQuery, scopedVars: ScopedVars, filters?: AdHocVariableFilter[]) {\n return query;\n }\n\n /**\n * Optionally override the streaming behavior\n */\n streamOptionsProvider: StreamOptionsProvider<TQuery> = standardStreamOptionsProvider;\n\n /**\n * Make a GET request to the datasource resource path\n */\n async getResource<T = any>(\n path: string,\n params?: BackendSrvRequest['params'],\n options?: Partial<BackendSrvRequest>\n ): Promise<T> {\n const headers = this.getRequestHeaders();\n const result = await lastValueFrom(\n getBackendSrv().fetch<T>({\n ...options,\n method: 'GET',\n headers: options?.headers ? { ...options.headers, ...headers } : headers,\n params: params ?? options?.params,\n url: `/api/datasources/uid/${this.uid}/resources/${path}`,\n })\n );\n return result.data;\n }\n\n /**\n * Send a POST request to the datasource resource path\n */\n async postResource<T = unknown>(\n path: string,\n data?: BackendSrvRequest['data'],\n options?: Partial<BackendSrvRequest>\n ): Promise<T> {\n const headers = this.getRequestHeaders();\n const result = await lastValueFrom(\n getBackendSrv().fetch<T>({\n ...options,\n method: 'POST',\n headers: options?.headers ? { ...options.headers, ...headers } : headers,\n data: data ?? { ...data },\n url: `/api/datasources/uid/${this.uid}/resources/${path}`,\n })\n );\n return result.data;\n }\n\n /**\n * Run the datasource healthcheck\n */\n async callHealthCheck(): Promise<HealthCheckResult> {\n return lastValueFrom(\n getBackendSrv().fetch<HealthCheckResult>({\n method: 'GET',\n url: `/api/datasources/uid/${this.uid}/health`,\n showErrorAlert: false,\n headers: this.getRequestHeaders(),\n })\n )\n .then((v: FetchResponse<HealthCheckResult>) => v.data)\n .catch((err) => {\n let properties: Record<string, string> = {\n plugin_id: this.meta?.id || '',\n plugin_version: this.meta?.info?.version || '',\n datasource_healthcheck_status: err?.data?.status || 'error',\n datasource_healthcheck_message: err?.data?.message || '',\n };\n reportInteraction('datasource_health_check_completed', properties);\n return err.data;\n });\n }\n\n /**\n * Checks the plugin health\n * see public/app/features/datasources/state/actions.ts for what needs to be returned here\n */\n async testDatasource(): Promise<TestDataSourceResponse> {\n return this.callHealthCheck().then((res) => {\n if (res.status === HealthStatus.OK) {\n return {\n status: 'success',\n message: res.message,\n };\n }\n\n return Promise.reject({\n status: 'error',\n message: res.message,\n error: new HealthCheckError(res.message, res.details),\n });\n });\n }\n}\n\n/**\n * @internal exported for tests\n */\nexport function toStreamingDataResponse<TQuery extends DataQuery = DataQuery>(\n rsp: DataQueryResponse,\n req: DataQueryRequest<TQuery>,\n getter: (req: DataQueryRequest<TQuery>, frame: DataFrame) => Partial<StreamingFrameOptions>\n): Observable<DataQueryResponse> {\n const live = getGrafanaLiveSrv();\n if (!live) {\n return of(rsp); // add warning?\n }\n\n const staticdata: DataFrame[] = [];\n const streams: Array<Observable<DataQueryResponse>> = [];\n for (const f of rsp.data) {\n const addr = parseLiveChannelAddress(f.meta?.channel);\n if (addr) {\n const frame: DataFrame = f;\n streams.push(\n live.getDataStream({\n addr,\n buffer: getter(req, frame),\n frame: dataFrameToJSON(f),\n })\n );\n } else {\n staticdata.push(f);\n }\n }\n if (staticdata.length) {\n streams.push(of({ ...rsp, data: staticdata }));\n }\n if (streams.length === 1) {\n return streams[0]; // avoid merge wrapper\n }\n return merge(...streams);\n}\n\n/**\n * This allows data sources to customize the streaming connection query\n *\n * @public\n */\nexport type StreamOptionsProvider<TQuery extends DataQuery = DataQuery> = (\n request: DataQueryRequest<TQuery>,\n frame: DataFrame\n) => Partial<StreamingFrameOptions>;\n\n/**\n * @public\n */\nexport const standardStreamOptionsProvider: StreamOptionsProvider = (request: DataQueryRequest, frame: DataFrame) => {\n const opts: Partial<StreamingFrameOptions> = {\n maxLength: request.maxDataPoints ?? 500,\n action: StreamingFrameAction.Append,\n };\n\n // For recent queries, clamp to the current time range\n if (request.rangeRaw?.to === 'now') {\n opts.maxDelta = request.range.to.valueOf() - request.range.from.valueOf();\n }\n return opts;\n};\n\n//@ts-ignore\nDataSourceWithBackend = makeClassES5Compatible(DataSourceWithBackend);\n\nexport { DataSourceWithBackend };\n"],"names":["HealthStatus","_a"],"mappings":"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"}