{"version":3,"file":"DataSourceWithBackend.mjs","sources":["../../../src/utils/DataSourceWithBackend.ts"],"sourcesContent":["import { lastValueFrom, merge, type Observable, of } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\n\nimport {\n  type DataFrame,\n  dataFrameToJSON,\n  type DataQuery,\n  type DataQueryRequest,\n  type DataQueryResponse,\n  type TestDataSourceResponse,\n  DataSourceApi,\n  type DataSourceInstanceSettings,\n  type DataSourceJsonData,\n  type DataSourceRef,\n  getDataSourceRef,\n  makeClassES5Compatible,\n  parseLiveChannelAddress,\n  type ScopedVars,\n  type AdHocVariableFilter,\n} from '@grafana/data';\n\nimport { reportInteraction } from '../analytics/utils';\nimport { config } from '../config';\nimport { getFeatureFlagClient } from '../internal/openFeature';\nimport {\n  type BackendSrvRequest,\n  type FetchResponse,\n  getBackendSrv,\n  getDataSourceSrv,\n  getGrafanaLiveSrv,\n  StreamingFrameAction,\n  type StreamingFrameOptions,\n} from '../services';\n\nimport { publicDashboardQueryHandler } from './publicDashboardQueryHandler';\nimport { isQueryServiceCompatible } from './qscheck';\nimport { type BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';\nimport { UserStorage } from './userStorage';\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  DashboardTitle = 'X-Dashboard-Title', // used by datasources to identify the dashboard title\n  PanelTitle = 'X-Panel-Title', // used by datasources to identify the panel title\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 * Response shape from the /apis/{group}/v0alpha1/.../datasources/{uid}/health endpoint.\n * Used when datasourcesApiServerEnableHealthEndpointFrontend is enabled.\n *\n * @internal\n */\nexport interface DatasourcesV0HealthCheckResult {\n  kind?: string;\n  apiVersion?: string;\n  status: string;\n  code?: number;\n  message: string;\n  details?: HealthCheckResultDetails;\n}\n\nfunction toHealthCheckResult(v: DatasourcesV0HealthCheckResult): HealthCheckResult {\n  const status: HealthStatus =\n    v.status === HealthStatus.OK || v.status === HealthStatus.Error || v.status === HealthStatus.Unknown\n      ? v.status\n      : HealthStatus.Unknown;\n  return {\n    status,\n    message: v.message,\n    details: v.details,\n  };\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  userStorage: UserStorage;\n\n  constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {\n    super(instanceSettings);\n    this.userStorage = new UserStorage(instanceSettings.type);\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 datasources: DataSourceInstanceSettings[] = [];\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        datasources.push(ds);\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\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    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      const allowedTypes = getFeatureFlagClient().getObjectValue('datasources.querier.fe-allowed-types', {\n        types: [],\n      });\n      if (isQueryServiceCompatible(datasources, allowedTypes)) {\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.dashboardTitle) {\n        headers[PluginRequestHeaders.DashboardTitle] = request.dashboardTitle;\n      }\n      if (request.panelId) {\n        headers[PluginRequestHeaders.PanelID] = `${request.panelId}`;\n      }\n      if (request.panelName) {\n        headers[PluginRequestHeaders.PanelTitle] = request.panelName;\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: this.buildResourcesDatasourceUrl(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: this.buildResourcesDatasourceUrl(path),\n      })\n    );\n    return result.data;\n  }\n\n  /**\n   * Internal function to build the datasource URL based on the feature toggle\n   */\n  buildResourcesDatasourceUrl(path: string): string {\n    const enabledRedirect = getFeatureFlagClient().getBooleanValue(\n      'datasources.apiserver.useNewAPIsForDatasourceResources',\n      false\n    );\n    if (enabledRedirect) {\n      // example:\n      // /apis/prometheus.datasource.grafana.app/v0alpha1/namespaces/stacks-1/datasources/local-prometheus/resources/api/v1/labels\n      const apiVersion = 'v0alpha1';\n      return `/apis/${this.type}.datasource.grafana.app/${apiVersion}/namespaces/${config.namespace}/datasources/${this.uid}/resources/${path}`;\n    }\n    return `/api/datasources/uid/${this.uid}/resources/${path}`;\n  }\n\n  /**\n   * Run the datasource healthcheck\n   */\n  async callHealthCheck(): Promise<HealthCheckResult> {\n    const useNewApi = config.featureToggles.datasourcesApiServerEnableHealthEndpointFrontend;\n    const healthCheckURL = useNewApi\n      ? `/apis/${this.type}.datasource.grafana.app/v0alpha1/namespaces/${config.namespace}/datasources/${this.uid}/health`\n      : `/api/datasources/uid/${this.uid}/health`;\n\n    if (useNewApi) {\n      return lastValueFrom(\n        getBackendSrv().fetch<DatasourcesV0HealthCheckResult>({\n          method: 'GET',\n          url: healthCheckURL,\n          showErrorAlert: false,\n          headers: this.getRequestHeaders(),\n        })\n      )\n        .then((v: FetchResponse<DatasourcesV0HealthCheckResult>) => toHealthCheckResult(v.data))\n        .catch((err) => {\n          const 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    return lastValueFrom(\n      getBackendSrv().fetch<HealthCheckResult>({\n        method: 'GET',\n        url: healthCheckURL,\n        showErrorAlert: false,\n        headers: this.getRequestHeaders(),\n      })\n    )\n      .then((v: FetchResponse<HealthCheckResult>) => v.data)\n      .catch((err) => {\n        const 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","PluginRequestHeaders","_a"],"mappings":"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"}