Fix sending RelativeTimeRange when requesting eval with resample expressions (#57076)

This commit is contained in:
Sonia Aguilar
2022-10-18 09:11:42 +02:00
committed by GitHub
parent 7b12482512
commit cbdc5e59cf
2 changed files with 60 additions and 1 deletions
@@ -5,6 +5,7 @@ import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import {
DataQuery,
DataSourceInstanceSettings,
getDefaultRelativeTimeRange,
LoadingState,
PanelData,
RelativeTimeRange,
@@ -14,6 +15,8 @@ import {
import { config, getDataSourceSrv } from '@grafana/runtime';
import { Button, Card, Icon } from '@grafana/ui';
import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow';
import { findDataSourceFromExpressionRecursive } from 'app/features/alerting/utils/dataSourceFromExpression';
import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource';
import { isExpressionQuery } from 'app/features/expressions/guards';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto';
@@ -56,7 +59,17 @@ export class QueryRows extends PureComponent<Props, State> {
onQueriesChange(
queries.map((item, itemIndex) => {
if (itemIndex !== index) {
return item;
// It's an expression , let's update the relativeTimeRange with this new relativeTimeRange
if (item.datasourceUid === ExpressionDatasourceUID) {
const dataSource = this.findDataSourceFromExpression(queries, item.model.expression);
const timeRangeToUpdate: RelativeTimeRange =
dataSource?.datasourceUid === queries[index].datasourceUid
? timeRange
: dataSource?.relativeTimeRange ?? getDefaultRelativeTimeRange();
return { ...item, relativeTimeRange: timeRangeToUpdate };
} else {
return item;
}
}
return {
...item,
@@ -116,6 +129,12 @@ export class QueryRows extends PureComponent<Props, State> {
onQueriesChange(updatedQueries);
};
findDataSourceFromExpression(queries: AlertQuery[], expression: string | undefined): AlertQuery | null | undefined {
const firstReference = queries.find((alertQuery) => alertQuery.refId === expression);
const dataSource = firstReference && findDataSourceFromExpressionRecursive(queries, firstReference);
return dataSource;
}
onChangeQuery = (query: DataQuery, index: number) => {
const { queries, onQueriesChange } = this.props;
@@ -128,6 +147,11 @@ export class QueryRows extends PureComponent<Props, State> {
if (itemIndex !== index) {
return item;
}
const dataSourceAlertQuery = this.findDataSourceFromExpression(queries, item.refId);
const relativeTimeRange = dataSourceAlertQuery
? dataSourceAlertQuery.relativeTimeRange
: getDefaultRelativeTimeRange();
return {
...item,
@@ -138,6 +162,7 @@ export class QueryRows extends PureComponent<Props, State> {
...query,
datasource: query.datasource!,
},
relativeTimeRange: relativeTimeRange,
};
})
);
@@ -0,0 +1,34 @@
import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource';
import { AlertQuery } from 'app/types/unified-alerting-dto';
export const hasCyclicalReferences = (queries: AlertQuery[]) => {
try {
JSON.stringify(queries);
return false;
} catch (e) {
return true;
}
};
export const findDataSourceFromExpressionRecursive = (
queries: AlertQuery[],
alertQuery: AlertQuery
): AlertQuery | null | undefined => {
//Check if this is not cyclical structre
if (hasCyclicalReferences(queries)) {
return null;
}
// We have the data source in this dataQuery
if (alertQuery.datasourceUid !== ExpressionDatasourceUID) {
return alertQuery;
}
// alertQuery it's an expression, we have to traverse all the tree up to the data source
else {
const alertQueryReferenced = queries.find((alertQuery_) => alertQuery_.refId === alertQuery.model.expression);
if (alertQueryReferenced) {
return findDataSourceFromExpressionRecursive(queries, alertQueryReferenced);
} else {
return null;
}
}
};