|
|
@@ -4,13 +4,23 @@ import moment from 'moment';
|
|
|
import path from 'path';
|
|
|
import { Database as SQLiteDB, OPEN_CREATE, OPEN_READWRITE } from 'sqlite3';
|
|
|
|
|
|
+import defaults from '../../../common/defaults.module';
|
|
|
import { ServiceConfig, validateParamType } from '../../../common/interfaces/service-config.interface';
|
|
|
+import { HttpCheckData, HttpCheckStatus } from '../../../common/lib/http-check-data.module';
|
|
|
import { Logger } from '../../../common/util/logger.class';
|
|
|
|
|
|
import { ValidationException } from '../lib/validation-exception.class';
|
|
|
import { DBMigration } from './db-migration.class';
|
|
|
import { SQLiteController } from './sqlite-controller.base';
|
|
|
|
|
|
+export enum ServiceChangedStatus {
|
|
|
+ None,
|
|
|
+ Created,
|
|
|
+ Activated,
|
|
|
+ Deactivated,
|
|
|
+ Rescheduled
|
|
|
+}
|
|
|
+
|
|
|
export class Database extends SQLiteController {
|
|
|
public set onError(listener: (error: any) => void) {
|
|
|
this._onError = listener;
|
|
|
@@ -235,7 +245,7 @@ export class Database extends SQLiteController {
|
|
|
return result.rows.map(r => ({ time: new Date(r.Timegroup), avg: r.avg, peak: r.peak, max: r.max }));
|
|
|
}
|
|
|
|
|
|
- private async getHealthCheckConfigs(serverID: number) {
|
|
|
+ private async getHealthCheckConfigs(serverID?: number, type = 'http') {
|
|
|
const res = await this.stmt(
|
|
|
`SELECT
|
|
|
HealthCheckConfig.*,
|
|
|
@@ -244,15 +254,16 @@ export class Database extends SQLiteController {
|
|
|
HealthCheckParams.Value as '_ParamValue'
|
|
|
FROM HealthCheckConfig
|
|
|
LEFT OUTER JOIN HealthCheckParams ON HealthCheckConfig.ID = HealthCheckParams.ConfigID
|
|
|
- WHERE HealthCheckConfig.ServerID = ?
|
|
|
+ WHERE HealthCheckConfig.Type = ?
|
|
|
+ ${!!serverID ? 'AND HealthCheckConfig.ServerID = ?' : ''}
|
|
|
ORDER BY HealthCheckConfig.Title, _ParamType, _ParamKey`,
|
|
|
- [serverID]
|
|
|
+ [type, serverID]
|
|
|
);
|
|
|
|
|
|
return this.configFromResultRows(res.rows);
|
|
|
}
|
|
|
|
|
|
- public async getHttpCheckConfigs(serverID: number) {
|
|
|
+ public async getHttpCheckConfigs(serverID?: number) {
|
|
|
return (await this.getHealthCheckConfigs(serverID)).map(this.httpCheckConfigFrom);
|
|
|
}
|
|
|
|
|
|
@@ -289,6 +300,7 @@ export class Database extends SQLiteController {
|
|
|
if (validationErrors) throw new ValidationException('Validation of HttpCheckConfig object failed', validationErrors);
|
|
|
|
|
|
conf.serverId = serverID;
|
|
|
+ let status = ServiceChangedStatus.None;
|
|
|
|
|
|
const oldConf = await this.getHttpCheckConfigByID(serverID, conf.id);
|
|
|
await this.beginTransaction();
|
|
|
@@ -300,8 +312,16 @@ export class Database extends SQLiteController {
|
|
|
}
|
|
|
|
|
|
let updValues: any[][] = [];
|
|
|
- if (oldConf.interval !== conf.interval) updValues.push([conf.interval, conf.id, 'interval']);
|
|
|
if (oldConf.url !== conf.url) updValues.push([conf.url, conf.id, 'url']);
|
|
|
+ if (oldConf.interval !== conf.interval) {
|
|
|
+ updValues.push([conf.interval, conf.id, 'interval']);
|
|
|
+ status = ServiceChangedStatus.Rescheduled;
|
|
|
+ }
|
|
|
+ if (oldConf.timeout !== conf.timeout) updValues.push([conf.timeout ?? defaults.serviceChecks.httpTimeout, conf.id, 'timeout']);
|
|
|
+ if (oldConf.active !== conf.active) {
|
|
|
+ updValues.push([conf.active ?? defaults.serviceChecks.active ? 1 : 0, conf.id, 'active']);
|
|
|
+ status = conf.active ?? defaults.serviceChecks.active ? ServiceChangedStatus.Activated : ServiceChangedStatus.Deactivated;
|
|
|
+ }
|
|
|
if (updValues.length) {
|
|
|
for (const data of updValues) {
|
|
|
await this.run(`UPDATE HealthCheckParams SET Value = ? WHERE ConfigID = ? AND Key = ?;`, data);
|
|
|
@@ -339,22 +359,29 @@ export class Database extends SQLiteController {
|
|
|
// INSERT
|
|
|
const res = await this.run('INSERT INTO HealthCheckConfig(ServerID, Type, Title) VALUES(?, ?, ?);', [serverID, 'http', conf.title]);
|
|
|
conf.id = res.lastID;
|
|
|
+ if (conf.active ?? defaults.serviceChecks.active) {
|
|
|
+ status = ServiceChangedStatus.Created;
|
|
|
+ }
|
|
|
|
|
|
const insCheckValues = conf.checks.map(c => [res.lastID, 'regexp', 'check', c]);
|
|
|
await this.run(
|
|
|
`INSERT INTO HealthCheckParams(ConfigID, Type, Key, Value) VALUES
|
|
|
(?, ?, ?, ?),
|
|
|
+ (?, ?, ?, ?),
|
|
|
+ (?, ?, ?, ?),
|
|
|
(?, ?, ?, ?)${conf.checks.length ? `,${insCheckValues.map(() => '(?, ?, ?, ?)').join(',')}` : ''}`,
|
|
|
[
|
|
|
...[res.lastID, 'text', 'url', conf.url],
|
|
|
+ ...[res.lastID, 'boolean', 'active', conf.active ?? defaults.serviceChecks.active ? 1 : 0],
|
|
|
...[res.lastID, 'number', 'interval', conf.interval],
|
|
|
+ ...[res.lastID, 'number', 'timeout', conf.timeout ?? defaults.serviceChecks.httpTimeout],
|
|
|
...conf.checks.reduce((ret, check) => [...ret, res.lastID, 'regexp', 'check', check], [] as any[])
|
|
|
]
|
|
|
);
|
|
|
}
|
|
|
|
|
|
await this.commit();
|
|
|
- return conf;
|
|
|
+ return { status, result: conf };
|
|
|
} catch (err) {
|
|
|
await this.rollback();
|
|
|
throw err;
|
|
|
@@ -369,6 +396,23 @@ export class Database extends SQLiteController {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ async insertHealthCheckData(confID: number, time: Date, status: HttpCheckStatus, message: string) {
|
|
|
+ const res = await this.run('INSERT INTO HealthCheckDataEntry(ConfigID, Timestamp, Status, Message) VALUES(?, ?, ?, ?);', [
|
|
|
+ confID,
|
|
|
+ time.getTime(),
|
|
|
+ status,
|
|
|
+ message
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return {
|
|
|
+ id: res.lastID,
|
|
|
+ configId: confID,
|
|
|
+ time,
|
|
|
+ status,
|
|
|
+ message
|
|
|
+ } as HttpCheckData;
|
|
|
+ }
|
|
|
+
|
|
|
private configFromResultRows(rows: any[]) {
|
|
|
return rows.reduce((res: ServiceConfig[], line, i) => {
|
|
|
const configID = line['ID'];
|
|
|
@@ -378,6 +422,7 @@ export class Database extends SQLiteController {
|
|
|
id: configID,
|
|
|
title: line['Title'],
|
|
|
type: line['Type'],
|
|
|
+ serverId: line['ServerID'],
|
|
|
params: []
|
|
|
};
|
|
|
res.push(config);
|
|
|
@@ -404,7 +449,7 @@ export class Database extends SQLiteController {
|
|
|
config.params.push({
|
|
|
type,
|
|
|
key,
|
|
|
- value: type === 'number' ? Number(line['_ParamValue']) : line['_ParamValue']
|
|
|
+ value: type === 'number' ? Number(line['_ParamValue']) : type === 'boolean' ? Boolean(Number(line['_ParamValue'])) : line['_ParamValue']
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -417,13 +462,16 @@ export class Database extends SQLiteController {
|
|
|
if (!hcConf) return null;
|
|
|
const params = {
|
|
|
url: hcConf.params?.find(p => p.key === 'url')?.value as string,
|
|
|
+ active: (hcConf.params?.find(p => p.key === 'active')?.value as boolean) ?? defaults.serviceChecks.active,
|
|
|
interval: hcConf.params?.find(p => p.key === 'interval')?.value as number,
|
|
|
+ timeout: (hcConf.params?.find(p => p.key === 'timeout')?.value as number) ?? defaults.serviceChecks.httpTimeout,
|
|
|
checks: hcConf.params?.reduce((res, p) => (p.key === 'check' && Array.isArray(p.value) ? [...res, ...p.value] : res), [] as string[])
|
|
|
};
|
|
|
return {
|
|
|
id: hcConf.id,
|
|
|
title: hcConf.title,
|
|
|
type: hcConf.type,
|
|
|
+ serverId: hcConf.serverId,
|
|
|
...params
|
|
|
};
|
|
|
}
|
|
|
@@ -440,4 +488,8 @@ export class Database extends SQLiteController {
|
|
|
|
|
|
return Object.keys(errors).length ? errors : null;
|
|
|
}
|
|
|
+
|
|
|
+ async close() {
|
|
|
+ return new Promise<void>((res, rej) => this.db.close(err => (err ? rej(err) : res())));
|
|
|
+ }
|
|
|
}
|