From 0857f1ec25c3877b178b2dd4d3913f9902b1f567 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 28 Oct 2019 19:45:59 +0100 Subject: [PATCH] before adding plugin logic --- package-lock.json | 6 ++-- package.json | 2 +- src/backend/Admin.ts | 68 ++++++++++++++++++++++++++++++++----- src/backend/Eventbus.ts | 60 ++++++++++++++++++++++++++++++++ src/backend/Interfaces.ts | 5 +++ src/backend/Plugin.ts | 22 ++++++++++++ src/backend/PluginLoader.ts | 19 +++++++++++ src/backend/Types.ts | 5 +++ 8 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 src/backend/Eventbus.ts create mode 100644 src/backend/Interfaces.ts create mode 100644 src/backend/Plugin.ts create mode 100644 src/backend/PluginLoader.ts diff --git a/package-lock.json b/package-lock.json index 8cfb4ae..a6dea1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5763,9 +5763,9 @@ "dev": true }, "upgiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.1.tgz", - "integrity": "sha512-HHWZ4/SWXVXC80fnNW/E1gsNT8D5mlAG6i2JcGG9akr5Q+sDrt+NPbaeMuLMSJJY6LI0CiIbzE59duWEQQINJg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.4.tgz", + "integrity": "sha512-+6McoJqbKvEr32ixlX/+r+z7v2JTmoCooxvDPBm3kv2uWQ/s+XDVMgxR69QRDYrTyc1nTyqlNJ+fNVxfm2bDKw==", "requires": { "fs": "0.0.1-security", "git-describe": "^4.0.4", diff --git a/package.json b/package.json index 4cac037..bf74afd 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "spawn-sync": "^2.0.0", "sqlite3": "^4.1.0", "trash": "^6.0.0", - "upgiter": "^1.0.1", + "upgiter": "^1.0.4", "uuid": "^3.3.2" }, "devDependencies": { diff --git a/src/backend/Admin.ts b/src/backend/Admin.ts index 6739426..7b50990 100644 --- a/src/backend/Admin.ts +++ b/src/backend/Admin.ts @@ -1,10 +1,9 @@ 'use strict' import { getLogger } from 'frontblock-generic/Types'; -import { ConfigLoader } from 'loadson'; -import { promises as fs } from "fs" +import { promises as fs, mkdirSync } from "fs" import { RPCServer } from 'rpclibrary/js/src/Backend' -import { AdminConf } from './Types'; +import { AdminConf, TableDefiniton } from './Types'; import { RPCConfigLoader } from './RPCConfigLoader'; import * as Path from 'path' @@ -12,20 +11,47 @@ import * as Path from 'path' import Knex = require('knex'); import http = require('http'); import express = require('express'); +import { TableDefinitionExporter } from './Interfaces'; +import { FrontworkEventBus } from './Eventbus'; +import { Plugin } from './Plugin'; const logger = getLogger("admin", 'debug') -export class FrontworkAdmin { +export class FrontworkAdmin +implements TableDefinitionExporter { + private express private httpServer - private config: RPCConfigLoader + private eventBus:FrontworkEventBus = new FrontworkEventBus(this) + private plugins: Plugin[] = [] + config: RPCConfigLoader + knex:Knex constructor(){ + this.eventBus = new FrontworkEventBus(this) + } + + async start(){ this.initConfig() + await this.makeKnex() this.startWebsocket() this.startWebserver() } + protected configChangeHandler = (conf:AdminConf, key?:string) => { + if(key === 'dbConf'){ + this.makeKnex() + } + } + + getConfigKey(key:string){ + return this.config.getConfigKey(key) + } + + setConfigKey(key:string, value:any){ + return this.config.setConfigKey(key, value) + } + private initConfig(){ this.config = new RPCConfigLoader({ name: "FrontworkAdminConf", @@ -42,13 +68,13 @@ export class FrontworkAdmin { } } } - }, './config', console.log) + }, './config', this.configChangeHandler) } private startWebsocket(){ - console.log() new RPCServer(20000, [ - this.config + this.config, + ...this.plugins ]) } @@ -108,6 +134,32 @@ export class FrontworkAdmin { logger.info("Webserver stopped") } + protected async makeKnex():Promise{ + const conf:Knex.Config = this.config.getConfigKey("dbConf") + + logger.debug("Making new knex:", conf) + if(conf.client === 'sqlite3'){ + mkdirSync(Path.dirname((conf.connection).filename), {recursive: true}) + } + + this.knex = Knex(conf) + + await Promise.all(this.getTableDefinitions().map(async (def)=>{ + const hasTable = await this.knex.schema.hasTable(def.name) + if(!hasTable){ + await this.knex.schema.createTable(def.name, def.tableBuilder) + } + })) + + return this.knex + } + + getTableDefinitions(): TableDefiniton[]{ + return [ + this.eventBus, + ...this.plugins + ].flatMap(exporter => exporter.getTableDefinitions()) + } } process.on( 'SIGINT', function() { diff --git a/src/backend/Eventbus.ts b/src/backend/Eventbus.ts new file mode 100644 index 0000000..5e33a06 --- /dev/null +++ b/src/backend/Eventbus.ts @@ -0,0 +1,60 @@ +import { RPCExporter } from "rpclibrary/js/src/Interfaces"; +import { SubscriptionResponse, ErrorResponse } from "rpclibrary/js/src/Types"; +import { makeSubResponse } from "rpclibrary/js/src/Utils"; +import { FrontworkAdmin } from "./Admin"; +import { TableDefinitionExporter } from "./Interfaces"; + +export type NotificationSeverity = 'Info' | 'Important' | 'Error' + +export type Notification = { + ID?:number, + severity: NotificationSeverity, + topic: string, + message:string, + time?: number +} + +export type EventbusIfc = { + Eventbus: { + getNotificationLog: () => Promise + pushNotification: (notification:Notification) => Promise + subscribeNotifications: (callback:Function) => Promise + } +} + +export class FrontworkEventBus +implements RPCExporter, TableDefinitionExporter { + name = "Eventbus" as "Eventbus" + + constructor(private admin: FrontworkAdmin){ + this.admin + } + + exportRPCs(){ + return [{ + name: 'getNotificationLog' as 'getNotificationLog', + call: async () => [] + },{ + name: 'pushNotification' as 'pushNotification', + call: async () => {} + },{ + name: 'subscribeNotificaitons' as 'subscribeNotifications', + hook: async (callback: Function) => { + return makeSubResponse({}) + } + }] + } + + getTableDefinitions(){ + return [{ + name: 'notifications', + tableBuilder: (table) => { + table.increments('ID'); + table.string('severity'); + table.string('topic'); + table.string('message'); + table.timestamp('time'); + } + }] + } +} \ No newline at end of file diff --git a/src/backend/Interfaces.ts b/src/backend/Interfaces.ts new file mode 100644 index 0000000..890f95f --- /dev/null +++ b/src/backend/Interfaces.ts @@ -0,0 +1,5 @@ +import { TableDefiniton } from "./Types"; + +export interface TableDefinitionExporter{ + getTableDefinitions(): TableDefiniton[] +} \ No newline at end of file diff --git a/src/backend/Plugin.ts b/src/backend/Plugin.ts new file mode 100644 index 0000000..364524c --- /dev/null +++ b/src/backend/Plugin.ts @@ -0,0 +1,22 @@ +import { FrontworkAdmin } from "./Admin" +import { RPC } from "rpclibrary/js/src/Types" +import { TableDefiniton } from "./Types" +import { RPCExporter } from "rpclibrary/js/src/Interfaces" +import { TableDefinitionExporter } from "./Interfaces" +import { ConfigExporter } from "loadson" + +export abstract class Plugin +implements ConfigExporter, RPCExporter, TableDefinitionExporter{ + + constructor (protected admin: FrontworkAdmin, public name:string){ + if(!this.getConfig()){ + this.setConfig(this.getDefaultConfig()) + } + } + public setConfig = (conf:ConfType) => this.admin.setConfigKey(this.name, conf) + public getConfig = () => this.admin.getConfigKey(this.name) + + abstract getTableDefinitions(): TableDefiniton[] + abstract getDefaultConfig(): ConfType + abstract exportRPCs(): RPC[] +} \ No newline at end of file diff --git a/src/backend/PluginLoader.ts b/src/backend/PluginLoader.ts new file mode 100644 index 0000000..36a4ad0 --- /dev/null +++ b/src/backend/PluginLoader.ts @@ -0,0 +1,19 @@ +import { RPCExporter } from "rpclibrary/js/src/Interfaces"; +import { Git, Types } from "upgiter" + +export type GitUpdaterIfc = { + cloneRepo: (force:boolean) => Promise + getStatus: () => Promise + checkoutTag: (tag:string) => Promise + isOutdated: () => Promise +} + +class RPCUpgiter +extends Git.Updater +implements RPCExporter{ + name = "PluginLoader" as "PluginLoader"; + + exportRPCs(){ + return [] + } +} \ No newline at end of file diff --git a/src/backend/Types.ts b/src/backend/Types.ts index 44f4700..dad1c03 100644 --- a/src/backend/Types.ts +++ b/src/backend/Types.ts @@ -6,4 +6,9 @@ export type AdminConf = { httpPort: number, dbConf:Knex.Config, eventBusConf: { [topic in string]: NotificationSeverity} +} + +export type TableDefiniton = { + name: string, + tableBuilder: (table: Knex.CreateTableBuilder) => void } \ No newline at end of file