소스 검색

Server: + API Endpoint GET /services/:serverID

Christian Kahlau 3 년 전
부모
커밋
f8603c47cc

+ 21 - 0
common/interfaces/service-config.interface.ts

@@ -0,0 +1,21 @@
+export interface ServiceConfig {
+  id: number;
+  type: 'http';
+  serverId?: number;
+
+  title: string;
+  params: Array<{
+    type: ParamType;
+    key: string;
+    value: string | number;
+  }>;
+}
+
+export const ParamTypes = ['text', 'number', 'regexp'] as const;
+export type ParamType = typeof ParamTypes[number];
+
+export function validateParamType(input: string): ParamType {
+  const found = ParamTypes.find(k => k === input);
+  if (!found) throw new Error(`'${input}' is not a valid param type`);
+  return found;
+}

+ 44 - 0
server/src/ctrl/database.class.ts

@@ -4,7 +4,9 @@ import moment from 'moment';
 import path from 'path';
 import { Database as SQLiteDB, OPEN_CREATE, OPEN_READWRITE } from 'sqlite3';
 
+import { ServiceConfig, validateParamType } from '../../../common/interfaces/service-config.interface';
 import { Logger } from '../../../common/util/logger.class';
+
 import { DBMigration } from './db-migration.class';
 import { SQLiteController } from './sqlite-controller.base';
 
@@ -221,4 +223,46 @@ export class Database extends SQLiteController {
 
     return result.rows.map(r => ({ time: new Date(r.Timegroup), avg: r.avg, peak: r.peak, max: r.max }));
   }
+
+  async getHealthCheckConfigs(serverID: number) {
+    const res = await this.stmt(
+      `SELECT 
+        HealthCheckConfig.*,
+        HealthCheckParams.Type as '_ParamType',
+        HealthCheckParams.Key as '_ParamKey',
+        HealthCheckParams.Value as '_ParamValue'
+        FROM HealthCheckConfig
+        LEFT OUTER JOIN HealthCheckParams ON HealthCheckConfig.ID = HealthCheckParams.ConfigID
+        WHERE HealthCheckConfig.ServerID = ?
+        ORDER BY HealthCheckConfig.Title, _ParamType, _ParamKey`,
+      [serverID]
+    );
+
+    return res.rows.reduce((res: ServiceConfig[], line, i) => {
+      const configID = line['ID'];
+      let config: ServiceConfig;
+      if (i === 0 || res[res.length - 1].id !== configID) {
+        config = {
+          id: configID,
+          title: line['Title'],
+          type: line['Type'],
+          params: []
+        };
+        res.push(config);
+      } else {
+        config = res[res.length - 1];
+      }
+
+      if (!!line['_ParamKey']) {
+        const type = validateParamType(line['_ParamType']);
+        config.params.push({
+          type,
+          key: line['_ParamKey'],
+          value: type === 'number' ? Number(line['_ParamValue']) : line['_ParamValue']
+        });
+      }
+
+      return res;
+    }, [] as ServiceConfig[]);
+  }
 }

+ 30 - 0
server/src/webhdl/services-api-handler.class.ts

@@ -0,0 +1,30 @@
+import { RouterOptions } from 'express';
+
+import { HttpStatusException } from '../../../common/lib/http-status.exception';
+
+import { ControllerPool } from '../ctrl/controller-pool.interface';
+import { WebHandler } from './web-handler.base';
+
+export class ServicesAPIHandler extends WebHandler {
+  constructor(protected ctrlPool: ControllerPool, options?: RouterOptions) {
+    super(ctrlPool, options);
+
+    this.router.use(this.avoidCache);
+
+    this.router.get('/:serverID', async (req, res, next) => {
+      try {
+        const serverID = Number(req.params.serverID);
+
+        if (Number.isNaN(serverID)) {
+          throw new HttpStatusException(`Not a valid server id: ${req.params.serverID}`, 400);
+        }
+
+        const services = await this.ctrlPool.db.getHealthCheckConfigs(serverID);
+
+        res.send(services);
+      } catch (err) {
+        next(err);
+      }
+    });
+  }
+}

+ 3 - 0
server/src/webserver.class.ts

@@ -6,6 +6,7 @@ import { Logger } from '../../common/util/logger.class';
 
 import { ControllerPool } from './ctrl/controller-pool.interface';
 import { ServerAPIHandler } from './webhdl/server-api-handler.class';
+import { ServicesAPIHandler } from './webhdl/services-api-handler.class';
 
 export class Webserver {
   private app: Express;
@@ -15,6 +16,8 @@ export class Webserver {
 
     const serverApi = new ServerAPIHandler(ctrlPool);
     this.app.use('/server', serverApi.router);
+    const servicesApi = new ServicesAPIHandler(ctrlPool);
+    this.app.use('/services', servicesApi.router);
 
     this.app.use('/', express.static(process.env.STATIC_DIR || 'public'));