Browse Source

Connection alerts are displayed for each panel #374 (#379)

master
Alexandr Velikiy 5 years ago committed by rozetko
parent
commit
726f8bf5c5
  1. 2
      src/datasource/config_ctrl.ts
  2. 2
      src/datasource/hastic_api.ts
  3. 31
      src/panel/graph_panel/graph_ctrl.ts
  4. 102
      src/panel/graph_panel/services/analytic_service.ts
  5. 0
      src/utils.ts
  6. 2
      tests/utils.jest.ts

2
src/datasource/config_ctrl.ts

@ -1,4 +1,4 @@
import { normalizeUrl } from '../utlis'; import { normalizeUrl } from '../utils';
import configTemplate from './partials/config.html'; import configTemplate from './partials/config.html';

2
src/datasource/hastic_api.ts

@ -1,4 +1,4 @@
import { isHasticServerResponse, isSupportedServerVersion, SUPPORTED_SERVER_VERSION } from '../utlis'; import { isHasticServerResponse, isSupportedServerVersion, SUPPORTED_SERVER_VERSION } from '../utils';
import { BackendSrv } from 'grafana/app/core/services/backend_srv'; import { BackendSrv } from 'grafana/app/core/services/backend_srv';

31
src/panel/graph_panel/graph_ctrl.ts

@ -12,7 +12,6 @@ import { BOUND_TYPES } from './models/analytic_units/anomaly_analytic_unit';
import { AnalyticService } from './services/analytic_service'; import { AnalyticService } from './services/analytic_service';
import { AnalyticController } from './controllers/analytic_controller'; import { AnalyticController } from './controllers/analytic_controller';
import { HasticPanelInfo } from './models/hastic_panel_info'; import { HasticPanelInfo } from './models/hastic_panel_info';
import { axesEditorComponent } from './axes_editor'; import { axesEditorComponent } from './axes_editor';
import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk'; import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk';
@ -241,25 +240,6 @@ class GraphCtrl extends MetricsPanelCtrl {
return _.keys(this._analyticUnitTypes); return _.keys(this._analyticUnitTypes);
} }
async runDatasourceConnectivityCheck() {
try {
const connected = await this.analyticService.isDatasourceOk();
if(connected) {
this.updateAnalyticUnitTypes();
appEvents.emit(
'alert-success',
[
'Connected to Hastic Datasource',
`Hastic datasource URL: "${this.analyticService.hasticDatasourceURL}"`
]
);
}
}
catch(err) {
console.error(err);
}
}
async link(scope, elem, attrs, ctrl) { async link(scope, elem, attrs, ctrl) {
this.$graphElem = $(elem[0]).find('#graphPanel'); this.$graphElem = $(elem[0]).find('#graphPanel');
this.$legendElem = $(elem[0]).find('#graphLegend'); this.$legendElem = $(elem[0]).find('#graphLegend');
@ -293,6 +273,12 @@ class GraphCtrl extends MetricsPanelCtrl {
type: undefined type: undefined
}; };
}); });
appEvents.on('hastic-datasource-status-changed', (url: string) => {
if(url === this.analyticService.hasticDatasourceURL) {
this.refresh();
}
});
} }
onInitEditMode() { onInitEditMode() {
@ -323,7 +309,10 @@ class GraphCtrl extends MetricsPanelCtrl {
delete this.analyticService; delete this.analyticService;
} else { } else {
this.analyticService = new AnalyticService(hasticDatasource.url, this.$http); this.analyticService = new AnalyticService(hasticDatasource.url, this.$http);
this.runDatasourceConnectivityCheck(); const isDatasourceAvailable = await this.analyticService.isDatasourceAvailable();
if(isDatasourceAvailable) {
this.updateAnalyticUnitTypes();
}
} }
this.analyticsController = new AnalyticController(this._grafanaUrl, this._panelId, this.panel, this.events, this.analyticService); this.analyticsController = new AnalyticController(this._grafanaUrl, this._panelId, this.panel, this.events, this.analyticService);

102
src/panel/graph_panel/services/analytic_service.ts

@ -6,18 +6,33 @@ import { AnalyticUnitId, AnalyticUnit, AnalyticSegment } from '../models/analyti
import { HasticServerInfo, HasticServerInfoUnknown } from '../models/hastic_server_info'; import { HasticServerInfo, HasticServerInfoUnknown } from '../models/hastic_server_info';
import { DetectionSpan } from '../models/detection'; import { DetectionSpan } from '../models/detection';
import { isHasticServerResponse, isSupportedServerVersion, SUPPORTED_SERVER_VERSION } from '../../../utlis'; import { isHasticServerResponse, isSupportedServerVersion, SUPPORTED_SERVER_VERSION } from '../../../utils';
import { appEvents } from 'grafana/app/core/core'; import { appEvents } from 'grafana/app/core/core';
import * as _ from 'lodash'; import * as _ from 'lodash';
declare global {
interface Window { hasticDatasourcesStatuses: { [key: string]: HasticDatasourceStatus } }
}
// TODO: TableTimeSeries is bad name // TODO: TableTimeSeries is bad name
export type TableTimeSeries = { export type TableTimeSeries = {
values: [number, number][]; values: [number, number][];
columns: string[]; columns: string[];
}; };
export enum HasticDatasourceStatus {
AVAILABLE,
NOT_AVAILABLE
};
const STATUS_TO_ALERT_TYPE_MAPPING = new Map<HasticDatasourceStatus, string>([
[HasticDatasourceStatus.AVAILABLE, 'alert-success'],
[HasticDatasourceStatus.NOT_AVAILABLE, 'alert-error']
]);
export class AnalyticService { export class AnalyticService {
private _isUp: boolean = false; private _isUp: boolean = false;
@ -81,7 +96,7 @@ export class AnalyticService {
return this.delete('/analyticUnits', { id }); return this.delete('/analyticUnits', { id });
} }
async isDatasourceOk(): Promise<boolean> { private async _isDatasourceOk(): Promise<boolean> {
if(!this._checkDatasourceConfig()) { if(!this._checkDatasourceConfig()) {
this._isUp = false; this._isUp = false;
return false; return false;
@ -224,6 +239,19 @@ export class AnalyticService {
}); });
} }
async isDatasourceAvailable(): Promise<boolean> {
const connected = await this._isDatasourceOk();
if(!connected) {
return false;
}
const message = [
'Connected to Hastic Datasource',
`Hastic datasource URL: "${this._hasticDatasourceURL}"`
];
this._displayConnectionAlert(HasticDatasourceStatus.AVAILABLE, message);
return true;
}
async updateAnalyticUnit(updateObj: any) { async updateAnalyticUnit(updateObj: any) {
return this.patch('/analyticUnits', updateObj); return this.patch('/analyticUnits', updateObj);
} }
@ -296,38 +324,66 @@ export class AnalyticService {
} }
private displayConnectionErrorAlert() { private displayConnectionErrorAlert() {
appEvents.emit( const message = [
'alert-error', 'Timeout when connecting to Hastic Server',
[ `Hastic Datasource URL: "${this._hasticDatasourceURL}"`,
'Timeout when connecting to Hastic Server', ]
`Hastic Datasource URL: "${this._hasticDatasourceURL}"`, this._displayConnectionAlert(HasticDatasourceStatus.NOT_AVAILABLE, message);
]
);
} }
private displayWrongUrlAlert() { private displayWrongUrlAlert() {
appEvents.emit( const message = [
'alert-error', 'Please check Hastic Server URL',
[ `Something is working at "${this._hasticDatasourceURL}" but it's not Hastic Server`,
'Please check Hastic Server URL', ]
`Something is working at "${this._hasticDatasourceURL}" but it's not Hastic Server`, this._displayConnectionAlert(HasticDatasourceStatus.NOT_AVAILABLE, message);
]
);
} }
private displayUnsupportedVersionAlert(actual: string) { private displayUnsupportedVersionAlert(actual: string) {
appEvents.emit( const message = [
'alert-error', 'Unsupported Hastic Server version',
[ `Hastic Server at "${this._hasticDatasourceURL}" has unsupported version (got ${actual}, should be ${SUPPORTED_SERVER_VERSION})`,
'Unsupported Hastic Server version', ]
`Hastic Server at "${this._hasticDatasourceURL}" has unsupported version (got ${actual}, should be ${SUPPORTED_SERVER_VERSION})`, this._displayConnectionAlert(HasticDatasourceStatus.NOT_AVAILABLE, message);
]
);
} }
public get isUp(): boolean { public get isUp(): boolean {
return this._isUp; return this._isUp;
} }
private _displayConnectionAlert(status: HasticDatasourceStatus, message: string[]) {
const statusChanged = this._updateHasticUrlStatus(status);
if(!statusChanged) {
return;
}
appEvents.emit(
STATUS_TO_ALERT_TYPE_MAPPING.get(status),
message
);
}
/**
* Updates hastic datasource status
* @returns true if status has been changed
*/
private _updateHasticUrlStatus(status: HasticDatasourceStatus): boolean {
if(!window.hasOwnProperty('hasticDatasourcesStatuses')) {
window.hasticDatasourcesStatuses = {};
}
if(!window.hasticDatasourcesStatuses.hasOwnProperty(this._hasticDatasourceURL)) {
window.hasticDatasourcesStatuses[this._hasticDatasourceURL] = status;
return true;
}
if(window.hasticDatasourcesStatuses[this._hasticDatasourceURL] !== status) {
appEvents.emit('hastic-datasource-status-changed', this._hasticDatasourceURL);
window.hasticDatasourcesStatuses[this._hasticDatasourceURL] = status;
return true;
}
return false;
}
} }
async function *getGenerator<T>( async function *getGenerator<T>(

0
src/utlis.ts → src/utils.ts

2
tests/utils.jest.ts

@ -1,4 +1,4 @@
import { normalizeUrl } from '../src/utlis'; import { normalizeUrl } from '../src/utils';
describe('Normalize URL', function() { describe('Normalize URL', function() {
const cases = [ const cases = [

Loading…
Cancel
Save