From 45b7de1910819ad0faa7a8aeac2481e675870ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 27 Dec 2019 09:11:16 +0100 Subject: [PATCH] Explore: Moves PromContext from query level to DataQueryRequest level (#21260) Closes #19598 Fixes bug introduced recently where the new PromQueryEditor did not preserve the PromContext.Explore set on the query model by PromQueryField which caused the table to be empty for Prometheus in explore. --- packages/grafana-data/src/types/app.ts | 5 +++ packages/grafana-data/src/types/datasource.ts | 2 ++ public/app/core/utils/explore.ts | 2 ++ .../dashboard/state/PanelQueryRunner.ts | 2 ++ .../app/features/explore/TableContainer.tsx | 5 +-- .../datasource/loki/language_provider.ts | 2 +- .../prometheus/components/PromQueryField.tsx | 4 +-- .../datasource/prometheus/datasource.test.ts | 35 +++++++++---------- .../datasource/prometheus/datasource.ts | 12 +++---- .../plugins/datasource/prometheus/types.ts | 6 ---- public/test/helpers/getQueryOptions.ts | 3 +- 11 files changed, 40 insertions(+), 38 deletions(-) diff --git a/packages/grafana-data/src/types/app.ts b/packages/grafana-data/src/types/app.ts index 421b565f623..e0146803928 100644 --- a/packages/grafana-data/src/types/app.ts +++ b/packages/grafana-data/src/types/app.ts @@ -3,6 +3,11 @@ import { KeyValue } from './data'; import { NavModel } from './navModel'; import { PluginMeta, GrafanaPlugin, PluginIncludeType } from './plugin'; +export enum CoreApp { + Dashboard = 'dashboard', + Explore = 'explore', +} + export interface AppRootProps { meta: AppPluginMeta; diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 4c2b9721061..71b77da0ba3 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -7,6 +7,7 @@ import { AnnotationEvent, KeyValue, LoadingState, TableData, TimeSeries } from ' import { DataFrame, DataFrameDTO } from './dataFrame'; import { RawTimeRange, TimeRange, AbsoluteTimeRange } from './time'; import { ScopedVars } from './ScopedVars'; +import { CoreApp } from './app'; export interface DataSourcePluginOptionsEditorProps { options: DataSourceSettings; @@ -449,6 +450,7 @@ export interface DataQueryRequest { scopedVars: ScopedVars; targets: TQuery[]; timezone: string; + app: CoreApp | string; cacheTimeout?: string; exploreMode?: 'Logs' | 'Metrics'; diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index ff6f172627f..b9e4e44246c 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -4,6 +4,7 @@ import { Unsubscribable } from 'rxjs'; // Services & Utils import { DataQuery, + CoreApp, DataQueryError, DataQueryRequest, DataSourceApi, @@ -130,6 +131,7 @@ export function buildQueryTransaction( const panelId = `${key}`; const request: DataQueryRequest = { + app: CoreApp.Explore, dashboardId: 0, // TODO probably should be taken from preferences but does not seem to be used anyway. timezone: DefaultTimeZone, diff --git a/public/app/features/dashboard/state/PanelQueryRunner.ts b/public/app/features/dashboard/state/PanelQueryRunner.ts index 62537dca961..efb47c20039 100644 --- a/public/app/features/dashboard/state/PanelQueryRunner.ts +++ b/public/app/features/dashboard/state/PanelQueryRunner.ts @@ -15,6 +15,7 @@ import { runSharedRequest, isSharedDashboardQuery } from '../../../plugins/datas import { PanelData, DataQuery, + CoreApp, DataQueryRequest, DataSourceApi, DataSourceJsonData, @@ -106,6 +107,7 @@ export class PanelQueryRunner { } const request: DataQueryRequest = { + app: CoreApp.Dashboard, requestId: getNextRequestId(), timezone, panelId, diff --git a/public/app/features/explore/TableContainer.tsx b/public/app/features/explore/TableContainer.tsx index 2e7452ffc81..ea5a2425163 100644 --- a/public/app/features/explore/TableContainer.tsx +++ b/public/app/features/explore/TableContainer.tsx @@ -6,6 +6,8 @@ import { Table, Collapse } from '@grafana/ui'; import { ExploreId, ExploreItemState } from 'app/types/explore'; import { StoreState } from 'app/types'; import { toggleTable } from './state/actions'; +import { config } from 'app/core/config'; +import { PANEL_BORDER } from 'app/core/constants'; interface TableContainerProps { exploreId: ExploreId; @@ -37,8 +39,7 @@ export class TableContainer extends PureComponent { const { loading, onClickCell, showingTable, tableResult, width } = this.props; const height = this.getTableHeight(); - const paddingWidth = 16; - const tableWidth = width - paddingWidth; + const tableWidth = width - config.theme.panelPadding * 2 - PANEL_BORDER; return ( diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts index 331cae75e4f..a1c8d757104 100644 --- a/public/app/plugins/datasource/loki/language_provider.ts +++ b/public/app/plugins/datasource/loki/language_provider.ts @@ -262,7 +262,7 @@ export default class LokiLanguageProvider extends LanguageProvider { return Promise.all( queries.map(async query => { const expr = await this.importPrometheusQuery(query.expr); - const { context, ...rest } = query as PromQuery; + const { ...rest } = query as PromQuery; return { ...rest, expr, diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index 6ba778bbbfa..fc88968f164 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -15,7 +15,7 @@ import { import Prism from 'prismjs'; // dom also includes Element polyfills -import { PromQuery, PromContext, PromOptions, PromMetricsMetadata } from '../types'; +import { PromQuery, PromOptions, PromMetricsMetadata } from '../types'; import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise'; import { ExploreQueryFieldProps, QueryHint, isDataFrame, toLegacyResponseData, HistoryItem } from '@grafana/data'; import { DOMUtil, SuggestionsState } from '@grafana/ui'; @@ -220,7 +220,7 @@ class PromQueryField extends React.PureComponent { it('returns empty array when no queries', done => { expect.assertions(2); - ds.query(makeQuery([])).subscribe({ + ds.query(createDataRequest([])).subscribe({ next(next) { expect(next.data).toEqual([]); expect(next.state).toBe(LoadingState.Done); @@ -84,7 +85,7 @@ describe('PrometheusDatasource', () => { it('performs time series queries', done => { expect.assertions(2); - ds.query(makeQuery([{}])).subscribe({ + ds.query(createDataRequest([{}])).subscribe({ next(next) { expect(next.data.length).not.toBe(0); expect(next.state).toBe(LoadingState.Done); @@ -99,7 +100,7 @@ describe('PrometheusDatasource', () => { expect.assertions(4); const responseStatus = [LoadingState.Loading, LoadingState.Done]; - ds.query(makeQuery([{ context: PromContext.Explore }, { context: PromContext.Explore }])).subscribe({ + ds.query(createDataRequest([{}, {}], { app: CoreApp.Explore })).subscribe({ next(next) { expect(next.data.length).not.toBe(0); expect(next.state).toBe(responseStatus.shift()); @@ -112,7 +113,7 @@ describe('PrometheusDatasource', () => { it('with 2 queries and used from Panel, waits for all to finish until sending Done status', done => { expect.assertions(2); - ds.query(makeQuery([{ context: PromContext.Panel }, { context: PromContext.Panel }])).subscribe({ + ds.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard })).subscribe({ next(next) { expect(next.data.length).not.toBe(0); expect(next.state).toBe(LoadingState.Done); @@ -1552,7 +1553,7 @@ describe('PrometheusDatasource for POST', () => { }); }); -const getPrepareTargetsContext = (target: PromQuery) => { +const getPrepareTargetsContext = (target: PromQuery, app?: CoreApp) => { const instanceSettings = ({ url: 'proxied', directUrl: 'direct', @@ -1563,7 +1564,7 @@ const getPrepareTargetsContext = (target: PromQuery) => { const start = 0; const end = 1; const panelId = '2'; - const options = ({ targets: [target], interval: '1s', panelId } as any) as DataQueryRequest; + const options = ({ targets: [target], interval: '1s', panelId, app } as any) as DataQueryRequest; const ds = new PrometheusDatasource(instanceSettings); const { queries, activeTargets } = ds.prepareTargets(options, start, end); @@ -1583,7 +1584,6 @@ describe('prepareTargets', () => { const target: PromQuery = { refId: 'A', expr: 'up', - context: PromContext.Panel, }; const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target); @@ -1614,12 +1614,11 @@ describe('prepareTargets', () => { const target: PromQuery = { refId: 'A', expr: 'up', - context: PromContext.Explore, showingGraph: true, showingTable: true, }; - const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target); + const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore); expect(queries.length).toBe(2); expect(activeTargets.length).toBe(2); @@ -1672,12 +1671,11 @@ describe('prepareTargets', () => { const target: PromQuery = { refId: 'A', expr: 'up', - context: PromContext.Explore, showingGraph: false, showingTable: false, }; - const { queries, activeTargets } = getPrepareTargetsContext(target); + const { queries, activeTargets } = getPrepareTargetsContext(target, CoreApp.Explore); expect(queries.length).toBe(0); expect(activeTargets.length).toBe(0); @@ -1689,12 +1687,11 @@ describe('prepareTargets', () => { const target: PromQuery = { refId: 'A', expr: 'up', - context: PromContext.Explore, showingGraph: false, showingTable: true, }; - const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target); + const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore); expect(queries.length).toBe(1); expect(activeTargets.length).toBe(1); @@ -1727,12 +1724,11 @@ describe('prepareTargets', () => { const target: PromQuery = { refId: 'A', expr: 'up', - context: PromContext.Explore, showingGraph: true, showingTable: false, }; - const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target); + const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore); expect(queries.length).toBe(1); expect(activeTargets.length).toBe(1); @@ -1761,8 +1757,9 @@ describe('prepareTargets', () => { }); }); -function makeQuery(targets: any[]): any { - return { +function createDataRequest(targets: any[], overrides?: Partial): DataQueryRequest { + const defaults = { + app: CoreApp.Dashboard, targets: targets.map(t => { return { instant: false, @@ -1779,4 +1776,6 @@ function makeQuery(targets: any[]): any { }, interval: '15s', }; + + return Object.assign(defaults, overrides || {}) as DataQueryRequest; } diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 454ef8e164d..c3ece16eb39 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -11,6 +11,7 @@ import { LoadingState, TimeRange, TimeSeries, + CoreApp, DataQueryError, DataQueryRequest, DataQueryResponse, @@ -29,7 +30,7 @@ import addLabelToQuery from './add_label_to_query'; import { getQueryHints } from './query_hints'; import { expandRecordingRules } from './language_utils'; // Types -import { PromContext, PromOptions, PromQuery, PromQueryRequest } from './types'; +import { PromOptions, PromQuery, PromQueryRequest } from './types'; import { safeStringifyValue } from 'app/core/utils/explore'; import templateSrv from 'app/features/templating/template_srv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; @@ -202,7 +203,7 @@ export class PrometheusDatasource extends DataSourceApi target.requestId = options.panelId + target.refId; - if (target.context !== PromContext.Explore) { + if (options.app !== CoreApp.Explore) { activeTargets.push(target); queries.push(this.createQuery(target, options, start, end)); continue; @@ -237,11 +238,6 @@ export class PrometheusDatasource extends DataSourceApi }; }; - calledFromExplore = (options: DataQueryRequest): boolean => { - const exploreTargets = options.targets.filter(target => target.context === PromContext.Explore).length; - return exploreTargets === options.targets.length; - }; - query(options: DataQueryRequest): Observable { const start = this.getPrometheusTime(options.range.from, false); const end = this.getPrometheusTime(options.range.to, true); @@ -255,7 +251,7 @@ export class PrometheusDatasource extends DataSourceApi }); } - if (this.calledFromExplore(options)) { + if (options.app === CoreApp.Explore) { return this.exploreQuery(queries, activeTargets, end); } diff --git a/public/app/plugins/datasource/prometheus/types.ts b/public/app/plugins/datasource/prometheus/types.ts index 4199370a39f..49e20f7a888 100644 --- a/public/app/plugins/datasource/prometheus/types.ts +++ b/public/app/plugins/datasource/prometheus/types.ts @@ -1,13 +1,7 @@ import { DataQuery, DataSourceJsonData } from '@grafana/data'; -export enum PromContext { - Explore = 'explore', - Panel = 'panel', -} - export interface PromQuery extends DataQuery { expr: string; - context?: PromContext; format?: string; instant?: boolean; hinting?: boolean; diff --git a/public/test/helpers/getQueryOptions.ts b/public/test/helpers/getQueryOptions.ts index b5340b804fe..47b3308f60c 100644 --- a/public/test/helpers/getQueryOptions.ts +++ b/public/test/helpers/getQueryOptions.ts @@ -1,4 +1,4 @@ -import { DataQueryRequest, DataQuery } from '@grafana/data'; +import { DataQueryRequest, DataQuery, CoreApp } from '@grafana/data'; import { dateTime } from '@grafana/data'; export function getQueryOptions( @@ -9,6 +9,7 @@ export function getQueryOptions( const defaults: DataQueryRequest = { requestId: 'TEST', + app: CoreApp.Dashboard, range: range, targets: [], scopedVars: {},