grafana/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.ts
Hugo Häggmark 19739f4af2
Annotations: Adds DashboardQueryRunner (#32834)
* WIP: initial commit

* Fix: Fixed $timeout call when testing snapshots

* Chore: reverts changes to metrics_panel_ctrl.ts

* Chore: reverts changes to annotations_srv

* Refactor: adds DashboardQueryRunner.run to initdashboard

* Refactor: adds run to dashboard model start refresh

* Refactor: move to own folder and split up into smaller files

* Tests: adds tests for LegacyAnnotationQueryRunner

* Tests: adds tests for AnnotationsQueryRunner

* Tests: adds tests for SnapshotWorker

* Refactor: renames from canRun|run to canWork|work

* Tests: adds tests for AlertStatesWorker

* Tests: adds tests for AnnotationsWorker

* Refactor: renames operators

* Refactor: renames operators

* Tests: adds tests for DashboardQueryRunner

* Refactor: adds mergePanelAndDashboardData function

* Tests: fixes broken tests

* Chore: Fixes errors after merge with master

* Chore: Removes usage of AnnotationSrv from event_editor and initDashboard

* WIP: getting annotations and alerts working in graph (snapshot not working)

* Refactor: fixes snapshot data for React panels

* Refactor: Fixes so snapshots work for Graph

* Refactor: moves alert types to grafana-data

* Refactor: changes to some for readability

* Tests: skipping tests for now, needs rewrite

* Refactor: refactors out common static functions to utils

* Refactor: fixes resolving annotations from dataframes

* Refactor: removes getRunners/Workers functions

* Docs: fixes docs errors

* Docs: trying to fix doc error

* Refactor: changes after PR comments

* Refactor: hides everything behind a factory instead

* Refactor: adds cancellation between runs and explicitly
2021-04-26 06:13:03 +02:00

79 lines
2.8 KiB
TypeScript

import { cloneDeep } from 'lodash';
import { from, merge, Observable, of } from 'rxjs';
import { map, mergeAll, mergeMap, reduce } from 'rxjs/operators';
import { getDataSourceSrv } from '@grafana/runtime';
import { AnnotationQuery, DataSourceApi } from '@grafana/data';
import {
AnnotationQueryRunner,
DashboardQueryRunnerOptions,
DashboardQueryRunnerWorker,
DashboardQueryRunnerWorkerResult,
} from './types';
import { emptyResult, translateQueryResult } from './utils';
import { LegacyAnnotationQueryRunner } from './LegacyAnnotationQueryRunner';
import { AnnotationsQueryRunner } from './AnnotationsQueryRunner';
export class AnnotationsWorker implements DashboardQueryRunnerWorker {
constructor(
private readonly runners: AnnotationQueryRunner[] = [
new LegacyAnnotationQueryRunner(),
new AnnotationsQueryRunner(),
]
) {}
canWork({ dashboard }: DashboardQueryRunnerOptions): boolean {
const annotations = dashboard.annotations.list.find(AnnotationsWorker.getAnnotationsToProcessFilter);
return Boolean(annotations);
}
work(options: DashboardQueryRunnerOptions): Observable<DashboardQueryRunnerWorkerResult> {
if (!this.canWork(options)) {
return emptyResult();
}
const { dashboard, range } = options;
const annotations = dashboard.annotations.list.filter(AnnotationsWorker.getAnnotationsToProcessFilter);
const observables = annotations.map((annotation) => {
const datasourcePromise = getDataSourceSrv().get(annotation.datasource);
return from(datasourcePromise).pipe(
mergeMap((datasource: DataSourceApi) => {
const runner = this.runners.find((r) => r.canRun(datasource));
if (!runner) {
return of([]);
}
return runner.run({ annotation, datasource, dashboard, range }).pipe(
map((results) => {
// store response in annotation object if this is a snapshot call
if (dashboard.snapshot) {
annotation.snapshotData = cloneDeep(results);
}
// translate result
return translateQueryResult(annotation, results);
})
);
})
);
});
return merge(observables).pipe(
mergeAll(),
reduce((acc, value) => {
// should we use scan or reduce here
// reduce will only emit when all observables are completed
// scan will emit when any observable is completed
// choosing reduce to minimize re-renders
return acc.concat(value);
}),
map((annotations) => {
return { annotations, alertStates: [] };
})
);
}
private static getAnnotationsToProcessFilter(annotation: AnnotationQuery): boolean {
return annotation.enable && !Boolean(annotation.snapshotData);
}
}