Files
grafana/public/app/plugins/datasource/testdata/datasource.ts
Torkel Ödegaard 140ecbcf79 QueryProcessing: Observable query interface and RxJS for query & stream processing (#18899)
* I needed to learn some rxjs and understand this more, so just playing around

* Updated

* Removed all the complete calls

* Refactoring

* StreamHandler -> observable start

* progress

* simple singal works

* Handle update time range

* added error handling

* wrap old function

* minor changes

* handle data format in the subscribe function

* Use replay subject to return last value to subscribers

* Set loading state after no response in 50ms

* added missing file

* updated comment

* Added cancelation of network requests

* runRequest: Added unit test scenario framework

* Progress on tests

* minor refactor of unit tests

* updated test

* removed some old code

* Shared queries work again, and also became so much simplier

* unified query and observe methods

* implict any fix

* Fixed closed subject issue

* removed comment

* Use last returned data for loading state

* WIP: Explore to runRequest makover step1

* Minor progress

* Minor progress on explore and runRequest

* minor progress

* Things are starting to work in explore

* Updated prometheus to use new observable query response, greatly simplified code

* Revert refId change

* Found better solution for key/refId/requestId problem

* use observable with loki

* tests compile

* fix loki query prep

* Explore: correct first response handling

* Refactorings

* Refactoring

* Explore: Fixes LoadingState and GraphResults between runs (#18986)

* Refactor: Adds state to DataQueryResponse

* Fix: Fixes so we do not empty results before new data arrives
Fixes: #17409

* Transformations work

* observable test data

* remove single() from loki promise

* Fixed comment

* Explore: Fixes failing Loki and Prometheus unit tests (#18995)

* Tests: Makes datasource tests work again

* Fix: Fixes loki datasource so highligthing works

* Chore: Runs Prettier

* Fixed query runner tests

* Delay loading state indication to 200ms

* Fixed test

* fixed unit tests

* Clear cached calcs

* Fixed bug getProcesedDataFrames

* Fix the correct test is a better idea

* Fix: Fixes so queries in Explore are only run if Graph/Table is shown (#19000)

* Fix: Fixes so queries in Explore are only run if Graph/Table is shown
Fixes: #18618

* Refactor: Removes unnecessary condition

* PanelData: provide legacy data only when needed  (#19018)

* no legacy

* invert logic... now compiles

* merge getQueryResponseData and getDataRaw

* update comment about query editor

* use single getData() function

* only send legacy when it is used in explore

* pre process rather than post process

* pre process rather than post process

* Minor refactoring

* Add missing tags to test datasource response

* MixedDatasource: Adds query observable pattern to MixedDatasource (#19037)

* start mixed datasource

* Refactor: Refactors into observable parttern

* Tests: Fixes tests

* Tests: Removes console.log

* Refactor: Adds unique requestId
2019-09-12 17:28:46 +02:00

132 lines
3.7 KiB
TypeScript

import _ from 'lodash';
import {
DataSourceApi,
DataQueryRequest,
DataSourceInstanceSettings,
DataQueryResponse,
MetricFindValue,
} from '@grafana/ui';
import { TableData, TimeSeries } from '@grafana/data';
import { TestDataQuery, Scenario } from './types';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { queryMetricTree } from './metricTree';
import { Observable, from, merge } from 'rxjs';
import { runStream } from './runStreams';
import templateSrv from 'app/features/templating/template_srv';
type TestData = TimeSeries | TableData;
export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
constructor(instanceSettings: DataSourceInstanceSettings) {
super(instanceSettings);
}
query(options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
const queries: any[] = [];
const streams: Array<Observable<DataQueryResponse>> = [];
// Start streams and prepare queries
for (const target of options.targets) {
if (target.scenarioId === 'streaming_client') {
streams.push(runStream(target, options));
} else {
queries.push({
...target,
intervalMs: options.intervalMs,
maxDataPoints: options.maxDataPoints,
datasourceId: this.id,
alias: templateSrv.replace(target.alias || ''),
});
}
}
if (queries.length) {
const req: Promise<DataQueryResponse> = getBackendSrv()
.datasourceRequest({
method: 'POST',
url: '/api/tsdb/query',
data: {
from: options.range.from.valueOf().toString(),
to: options.range.to.valueOf().toString(),
queries: queries,
},
// This sets up a cancel token
requestId: options.requestId,
})
.then((res: any) => this.processQueryResult(queries, res));
streams.push(from(req));
}
return merge(...streams);
}
processQueryResult(queries: any, res: any): DataQueryResponse {
const data: TestData[] = [];
for (const query of queries) {
const results = res.data.results[query.refId];
for (const t of results.tables || []) {
const table = t as TableData;
table.refId = query.refId;
table.name = query.alias;
data.push(table);
}
for (const series of results.series || []) {
data.push({ target: series.name, datapoints: series.points, refId: query.refId, tags: series.tags });
}
}
return { data };
}
annotationQuery(options: any) {
let timeWalker = options.range.from.valueOf();
const to = options.range.to.valueOf();
const events = [];
const eventCount = 10;
const step = (to - timeWalker) / eventCount;
for (let i = 0; i < eventCount; i++) {
events.push({
annotation: options.annotation,
time: timeWalker,
text: 'This is the text, <a href="https://grafana.com">Grafana.com</a>',
tags: ['text', 'server'],
});
timeWalker += step;
}
return Promise.resolve(events);
}
getQueryDisplayText(query: TestDataQuery) {
if (query.alias) {
return query.scenarioId + ' as ' + query.alias;
}
return query.scenarioId;
}
testDatasource() {
return Promise.resolve({
status: 'success',
message: 'Data source is working',
});
}
getScenarios(): Promise<Scenario[]> {
return getBackendSrv().get('/api/tsdb/testdata/scenarios');
}
metricFindQuery(query: string) {
return new Promise<MetricFindValue[]>((resolve, reject) => {
setTimeout(() => {
const children = queryMetricTree(templateSrv.replace(query));
const items = children.map(item => ({ value: item.name, text: item.name }));
resolve(items);
}, 100);
});
}
}