Browse Source

Not sent request to hastic server on deletion #96 (#97)

* delete request to hastic-server
* sync plugin with hastic-server state
master
Alexey Velikiy 6 years ago committed by GitHub
parent
commit
613775c882
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 53
      src/controllers/analytic_controller.ts
  2. 2
      src/graph_renderer.ts
  3. 9
      src/models/analytic_unit.ts
  4. 40
      src/module.ts
  5. 106
      src/services/analytic_service.ts

53
src/controllers/analytic_controller.ts

@ -45,12 +45,12 @@ export class AnalyticController {
private _serverInfo: ServerInfo;
constructor(private _panelObject: any, private _analyticService: AnalyticService, private _emitter: Emitter) {
if(_panelObject.anomalyTypes === undefined) {
_panelObject.anomalyTypes = [];
if(_panelObject.analyticUnits === undefined) {
_panelObject.analyticUnits = _panelObject.anomalyTypes || [];
}
this._labelingDataAddedSegments = new SegmentArray<AnalyticSegment>();
this._labelingDataDeletedSegments = new SegmentArray<AnalyticSegment>();
this._analyticUnitsSet = new AnalyticUnitsSet(this._panelObject.anomalyTypes);
this._analyticUnitsSet = new AnalyticUnitsSet(this._panelObject.analyticUnits);
// this.analyticUnits.forEach(a => this.runEnabledWaiter(a));
}
@ -101,15 +101,15 @@ export class AnalyticController {
get graphLocked() { return this._graphLocked; }
set graphLocked(value) { this._graphLocked = value; }
get labelingAnomaly(): AnalyticUnit {
get labelingUnit(): AnalyticUnit {
if(this._selectedAnalyticUnitId === null) {
return null;
}
return this._analyticUnitsSet.byId(this._selectedAnalyticUnitId);
}
async toggleAnomalyTypeLabelingMode(id: AnalyticUnitId) {
if(this.labelingAnomaly && this.labelingAnomaly.saving) {
async toggleUnitTypeLabelingMode(id: AnalyticUnitId) {
if(this.labelingUnit && this.labelingUnit.saving) {
throw new Error('Can`t toggle during saving');
}
if(this._selectedAnalyticUnitId === id) {
@ -117,7 +117,7 @@ export class AnalyticController {
}
await this.disableLabeling();
this._selectedAnalyticUnitId = id;
this.labelingAnomaly.selected = true;
this.labelingUnit.selected = true;
this.toggleVisibility(id, true);
}
@ -125,22 +125,22 @@ export class AnalyticController {
if(this._selectedAnalyticUnitId === null) {
return;
}
this.labelingAnomaly.saving = true;
this.labelingUnit.saving = true;
var newIds = await this._saveLabelingData();
this._labelingDataAddedSegments.getSegments().forEach((s, i) => {
this.labelingAnomaly.segments.updateId(s.id, newIds[i]);
this.labelingUnit.segments.updateId(s.id, newIds[i]);
});
this.labelingAnomaly.saving = false;
this.labelingUnit.saving = false;
var anomaly = this.labelingAnomaly;
var anomaly = this.labelingUnit;
this.dropLabeling();
this._runStatusWaiter(anomaly);
}
undoLabeling() {
this._labelingDataAddedSegments.getSegments().forEach(s => {
this.labelingAnomaly.segments.remove(s.id);
this.labelingUnit.segments.remove(s.id);
});
this._labelingDataDeletedSegments.getSegments().forEach(s => {
s.deleted = false;
@ -151,7 +151,7 @@ export class AnalyticController {
dropLabeling() {
this._labelingDataAddedSegments.clear();
this._labelingDataDeletedSegments.clear();
this.labelingAnomaly.selected = false;
this.labelingUnit.selected = false;
this._selectedAnalyticUnitId = null;
this._tempIdCounted = -1;
}
@ -164,11 +164,11 @@ export class AnalyticController {
if(!this.labelingMode) {
return false;
}
return this.labelingAnomaly.deleteMode;
return this.labelingUnit.deleteMode;
}
addLabelSegment(segment: Segment) {
var asegment = this.labelingAnomaly.addLabeledSegment(segment);
var asegment = this.labelingUnit.addLabeledSegment(segment);
this._labelingDataAddedSegments.addSegment(asegment);
}
@ -183,11 +183,11 @@ export class AnalyticController {
this._analyticUnitsSet.byId(id).color = value;
}
fetchAnomalyTypesStatuses() {
fetchAnalyticUnitsStatuses() {
this.analyticUnits.forEach(a => this._runStatusWaiter(a));
}
async fetchAnomalyTypesSegments(from: number, to: number) {
async fetchAnalyticUnitsSegments(from: number, to: number) {
if(!_.isNumber(+from)) {
throw new Error('from isn`t number');
}
@ -215,9 +215,9 @@ export class AnalyticController {
}
private async _saveLabelingData(): Promise<SegmentId[]> {
var anomaly = this.labelingAnomaly;
if(anomaly === null) {
throw new Error('anomaly is not selected');
var unit = this.labelingUnit;
if(unit === null) {
throw new Error('analytic unit is not selected');
}
if(
@ -228,7 +228,7 @@ export class AnalyticController {
}
return this._analyticService.updateSegments(
anomaly.id, this._labelingDataAddedSegments, this._labelingDataDeletedSegments
unit.id, this._labelingDataAddedSegments, this._labelingDataDeletedSegments
);
}
@ -304,7 +304,7 @@ export class AnalyticController {
}
deleteLabelingAnomalySegmentsInRange(from: number, to: number) {
var allRemovedSegs = this.labelingAnomaly.removeSegmentsInRange(from, to);
var allRemovedSegs = this.labelingUnit.removeSegmentsInRange(from, to);
allRemovedSegs.forEach(s => {
if(!this._labelingDataAddedSegments.has(s.id)) {
this._labelingDataDeletedSegments.addSegment(s);
@ -317,14 +317,17 @@ export class AnalyticController {
if(!this.labelingMode) {
throw new Error('Cant enter delete mode is labeling mode disabled');
}
this.labelingAnomaly.deleteMode = !this.labelingAnomaly.deleteMode;
this.labelingUnit.deleteMode = !this.labelingUnit.deleteMode;
}
removeAnalyticUnit(id: AnalyticUnitId) {
async removeAnalyticUnit(id: AnalyticUnitId, silent: boolean = false) {
if(id === this._selectedAnalyticUnitId) {
this.dropLabeling();
}
this._analyticUnitsSet.removeItem(id);
if(!silent) {
await this._analyticService.removeAnalyticUnit(id);
}
}
private async _runStatusWaiter(analyticUnit: AnalyticUnit) {
@ -354,7 +357,7 @@ export class AnalyticController {
if(error !== undefined) {
analyticUnit.error = error;
}
this._emitter.emit('anomaly-type-status-change', analyticUnit);
this._emitter.emit('analytic-unit-status-change', analyticUnit);
}
if(!analyticUnit.isActiveStatus) {
break;

2
src/graph_renderer.ts

@ -352,7 +352,7 @@ export class GraphRenderer {
ANOMALY_REGION_DELETE_COLOR_LIGHT :
ANOMALY_REGION_DELETE_COLOR_DARK;
} else {
color = this._analyticController.labelingAnomaly.color;
color = this._analyticController.labelingUnit.color;
}
fillAlpha = ANOMALY_REGION_FILL_ALPHA;
strokeAlpha = ANOMALY_REGION_STROKE_ALPHA;

9
src/models/analytic_unit.ts

@ -100,6 +100,7 @@ export class AnalyticUnit {
get status() { return this._status; }
set status(value) {
if(
value !== '404' &&
value !== 'READY' &&
value !== 'LEARNING' &&
value !== 'PENDING' &&
@ -114,7 +115,13 @@ export class AnalyticUnit {
set error(value) { this._error = value; }
get isActiveStatus() {
return this.status !== 'READY' && this.status !== 'FAILED';
switch(this.status) {
case '404':
case 'READY':
case 'FAILED':
return false;
}
return true;
}
get panelObject() { return this._panelObject; }

40
src/module.ts

@ -17,6 +17,9 @@ import { axesEditorComponent } from './axes_editor';
import { MetricsPanelCtrl, alertTab } from 'grafana/app/plugins/sdk';
import { appEvents } from 'grafana/app/core/core'
import { BackendSrv } from 'grafana/app/core/services/backend_srv';
import { AlertSrv } from 'grafana/app/core/services/alert_srv';
import config from 'grafana/app/core/config';
import _ from 'lodash';
@ -148,10 +151,13 @@ class GraphCtrl extends MetricsPanelCtrl {
/** @ngInject */
constructor(
$scope, $injector, $http, private annotationsSrv,
private keybindingSrv, private backendSrv,
private popoverSrv, private contextSrv,
private alertSrv
$scope, $injector, $http,
private annotationsSrv,
private keybindingSrv,
private backendSrv: BackendSrv,
private popoverSrv,
private contextSrv,
private alertSrv: AlertSrv
) {
super($scope, $injector);
@ -162,8 +168,7 @@ class GraphCtrl extends MetricsPanelCtrl {
this.processor = new DataProcessor(this.panel);
this.analyticService = new AnalyticService(this.backendURL, $http, this.alertSrv);
this.analyticService = new AnalyticService(this.backendURL, $http, this.backendSrv, this.alertSrv);
this.runBackendConnectivityCheck();
@ -180,12 +185,15 @@ class GraphCtrl extends MetricsPanelCtrl {
this.events.on('anomaly-type-alert-change', () => {
this.$scope.$digest()
});
this.events.on('anomaly-type-status-change', async (anomalyType: AnalyticUnit) => {
if(anomalyType === undefined) {
throw new Error('anomalyType is undefined');
this.events.on('analytic-unit-status-change', async (analyticUnit: AnalyticUnit) => {
if(analyticUnit === undefined) {
throw new Error('analyticUnit is undefined');
}
if(analyticUnit.status === '404') {
await this.analyticsController.removeAnalyticUnit(analyticUnit.id, true);
}
if(anomalyType.status === 'READY') {
await this.analyticsController.fetchSegments(anomalyType, +this.range.from, +this.range.to);
if(analyticUnit.status === 'READY') {
await this.analyticsController.fetchSegments(analyticUnit, +this.range.from, +this.range.to);
}
this.render(this.seriesList);
this.$scope.$digest();
@ -203,7 +211,7 @@ class GraphCtrl extends MetricsPanelCtrl {
};
});
this.analyticsController.fetchAnomalyTypesStatuses();
this.analyticsController.fetchAnalyticUnitsStatuses();
}
@ -326,7 +334,7 @@ class GraphCtrl extends MetricsPanelCtrl {
var loadTasks = [
// this.annotationsPromise,
this.analyticsController.fetchAnomalyTypesSegments(+this.range.from, +this.range.to)
this.analyticsController.fetchAnalyticUnitsSegments(+this.range.from, +this.range.to)
];
var results = await Promise.all(loadTasks);
@ -558,11 +566,11 @@ class GraphCtrl extends MetricsPanelCtrl {
this.render();
}
onRemove(id: AnalyticUnitId) {
async onRemove(id: AnalyticUnitId) {
if(id === undefined) {
throw new Error('id is undefined');
}
this.analyticsController.removeAnalyticUnit(id);
await this.analyticsController.removeAnalyticUnit(id);
this.render();
}
@ -584,7 +592,7 @@ class GraphCtrl extends MetricsPanelCtrl {
}
async onToggleLabelingMode(key) {
await this.analyticsController.toggleAnomalyTypeLabelingMode(key as AnalyticUnitId);
await this.analyticsController.toggleUnitTypeLabelingMode(key as AnalyticUnitId);
this.$scope.$digest();
this.render();
}

106
src/services/analytic_service.ts

@ -4,36 +4,45 @@ import { DatasourceRequest } from '../models/datasource';
import { SegmentsSet } from '../models/segment_set';
import { AnalyticUnitId, AnalyticUnit, AnalyticSegment } from '../models/analytic_unit';
import { ServerInfo } from '../models/info';
import { BackendSrv } from 'grafana/app/core/services/backend_srv';
import { AlertSrv } from 'grafana/app/core/services/alert_srv';
export class AnalyticService {
private _isUp = false;
constructor(private _backendURL: string, private $http, private alertSrv) {
constructor(
private _backendURL: string, private $http,
private _backendSrv: BackendSrv,
private _alertSrv: AlertSrv
) {
this.isBackendOk();
}
async postNewItem(
metric: MetricExpanded, datasourceRequest: DatasourceRequest,
metric: MetricExpanded, datasourceRequest: DatasourceRequest,
newItem: AnalyticUnit, panelId: number
): Promise<AnalyticUnitId> {
let datasource = await this.get(`/api/datasources/name/${metric.datasource}`);
let datasource = await this._backendSrv.get(`/api/datasources/name/${metric.datasource}`);
datasourceRequest.type = datasource.type;
const response = await this.post(this._backendURL + '/analyticUnits', {
const response = await this.post('/analyticUnits', {
panelUrl: window.location.origin + window.location.pathname + `?panelId=${panelId}&fullscreen`,
type: newItem.type,
name: newItem.name,
metric: metric.toJSON(),
datasource: datasourceRequest
});
return response.id as AnalyticUnitId;
}
async isBackendOk(): Promise<boolean> {
await this.get(this._backendURL);
async removeAnalyticUnit(id: AnalyticUnitId) {
return this.delete('/analyticUnits', { id });
}
async isBackendOk(): Promise<boolean> {
await this.get('/');
return this._isUp;
}
@ -51,7 +60,7 @@ export class AnalyticService {
removedSegments: removedSegments.getSegments().map(s => s.id)
};
var data = await this.patch(this._backendURL + '/segments', payload);
var data = await this.patch('/segments', payload);
if(data.addedIds === undefined) {
throw new Error('Server didn`t send addedIds');
}
@ -69,7 +78,7 @@ export class AnalyticService {
if(to !== undefined) {
payload['to'] = to;
}
var data = await this.get(this._backendURL + '/segments', payload);
var data = await this.get('/segments', payload);
if(data.segments === undefined) {
throw new Error('Server didn`t return segments array');
}
@ -77,13 +86,21 @@ export class AnalyticService {
return segments.map(s => new AnalyticSegment(s.labeled, s.id, s.from, s.to, s.deleted));
}
async * getStatusGenerator(id: AnalyticUnitId, duration: number) {
async * getStatusGenerator(id: AnalyticUnitId, duration: number):
AsyncIterableIterator<{ status: string, errorMessage?: string }> {
if(id === undefined) {
throw new Error('id is undefined');
}
let statusCheck = async () => {
var data = await this.get(this._backendURL + '/analyticUnits/status', { id });
return data;
try {
return await this.get('/analyticUnits/status', { id });
} catch(error) {
if(error.status === 404) {
return { status: '404' };
}
throw error;
}
}
let timeout = async () => new Promise(
@ -100,7 +117,7 @@ export class AnalyticService {
if(id === undefined) {
throw new Error('id is undefined');
}
var data = await this.get(this._backendURL + '/alerts', { id });
var data = await this.get('/alerts', { id });
if(data.enabled === undefined) {
throw new Error('Server didn`t return "enabled"');
}
@ -111,12 +128,11 @@ export class AnalyticService {
if(id === undefined) {
throw new Error('id is undefined');
}
return await this.post(this._backendURL + '/alerts', { id, enabled });
return await this.post('/alerts', { id, enabled });
}
async getServerInfo(): Promise<ServerInfo> {
let data = await this.get(this._backendURL);
console.log(data);
let data = await this.get('/');
return {
nodeVersion: data.nodeVersion,
packageVersion: data.packageVersion,
@ -129,44 +145,48 @@ export class AnalyticService {
};
}
private async get(url, params?) {
private async _analyticRequest(method: string, url: string, data?) {
try {
let response = await this.$http({ method: 'GET', url, params });
method = method.toUpperCase();
url = this._backendURL + url;
let requestObject: any = { method, url };
if(method === 'GET' || method === 'DELETE') {
requestObject.params = data;
} else {
requestObject.data = data;
}
let response = await this.$http(requestObject);
this._isUp = true;
return response.data;
} catch(error) {
this.displayConnectionAlert();
console.error(error);
this._isUp = false;
}
if(error.xhrStatus === 'error') {
this.displayConnectionAlert();
this._isUp = false;
} else {
this._isUp = true;
}
throw error;
}
}
private async post(url, data) {
try {
let response = await this.$http({ method: 'POST', url, data });
this._isUp = true;
return response.data;
} catch(error) {
this.displayConnectionAlert();
console.error(error);
this._isUp = false;
}
private async get(url, params?) {
return this._analyticRequest('GET', url, params);
}
private async patch(url, data) {
try {
let response = await this.$http({ method: 'PATCH', url, data });
this._isUp = true;
return response.data;
} catch(error) {
this.displayConnectionAlert();
console.error(error);
this._isUp = false;
}
private async post(url, data?) {
return this._analyticRequest('POST', url, data);
}
private async patch(url, data?) {
return this._analyticRequest('PATCH', url, data);
}
private async delete(url, data?) {
return this._analyticRequest('DELETE', url, data);
}
private displayConnectionAlert() {
this.alertSrv.set(
this._alertSrv.set(
'No connection to Hastic server',
`Hastic server: "${this._backendURL}"`,
'warning', 4000

Loading…
Cancel
Save