From fe94fce08a020e0c35e354c2282ec0587a605f4e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 13 May 2022 14:31:34 +0200 Subject: [PATCH] Add UI server factory with server class abstraction MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/charging-station/Bootstrap.ts | 8 ++++--- .../ui-server/AbstractUIServer.ts | 20 ++++++++++++++++ .../ui-server/UIServerFactory.ts | 24 +++++++++++++++++++ .../ui-server/UIWebSocketServer.ts | 19 ++++++--------- .../ui-services/AbstractUIService.ts | 6 ++--- .../ui-server/ui-services/UIService001.ts | 4 ++-- .../ui-server/ui-services/UIServiceFactory.ts | 4 ++-- 7 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 src/charging-station/ui-server/AbstractUIServer.ts create mode 100644 src/charging-station/ui-server/UIServerFactory.ts diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index 3701b170..1f5c898f 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -6,13 +6,15 @@ import { ChargingStationWorkerMessageEvents, } from '../types/ChargingStationWorker'; +import { AbstractUIServer } from './ui-server/AbstractUIServer'; +import { ApplicationProtocol } from '../types/UIProtocol'; import Configuration from '../utils/Configuration'; import { StationTemplateUrl } from '../types/ConfigurationData'; import Statistics from '../types/Statistics'; import { Storage } from '../performance/storage/Storage'; import { StorageFactory } from '../performance/storage/StorageFactory'; +import UIServerFactory from './ui-server/UIServerFactory'; import { UIServiceUtils } from './ui-server/ui-services/UIServiceUtils'; -import UIWebSocketServer from './ui-server/UIWebSocketServer'; import Utils from '../utils/Utils'; import WorkerAbstract from '../worker/WorkerAbstract'; import WorkerFactory from '../worker/WorkerFactory'; @@ -24,7 +26,7 @@ import { version } from '../../package.json'; export default class Bootstrap { private static instance: Bootstrap | null = null; private workerImplementation: WorkerAbstract | null = null; - private readonly uiServer!: UIWebSocketServer; + private readonly uiServer!: AbstractUIServer; private readonly storage!: Storage; private numberOfChargingStations: number; private readonly version: string = version; @@ -40,7 +42,7 @@ export default class Bootstrap { ); this.initWorkerImplementation(); Configuration.getUIServer().enabled && - (this.uiServer = new UIWebSocketServer({ + (this.uiServer = UIServerFactory.getUIServerImplementation(ApplicationProtocol.WS, { ...Configuration.getUIServer().options, handleProtocols: UIServiceUtils.handleProtocols, })); diff --git a/src/charging-station/ui-server/AbstractUIServer.ts b/src/charging-station/ui-server/AbstractUIServer.ts new file mode 100644 index 00000000..2608e834 --- /dev/null +++ b/src/charging-station/ui-server/AbstractUIServer.ts @@ -0,0 +1,20 @@ +import AbstractUIService from './ui-services/AbstractUIService'; +import { Server as HttpServer } from 'http'; +import { ProtocolVersion } from '../../types/UIProtocol'; +import { Server as WSServer } from 'ws'; + +export abstract class AbstractUIServer { + public readonly chargingStations: Set; + protected readonly uiServices: Map; + protected uiServer: WSServer | HttpServer; + + public constructor() { + this.chargingStations = new Set(); + this.uiServices = new Map(); + } + + public abstract start(): void; + public abstract stop(): void; + public abstract sendResponse(message: string): void; + public abstract logPrefix(): string; +} diff --git a/src/charging-station/ui-server/UIServerFactory.ts b/src/charging-station/ui-server/UIServerFactory.ts new file mode 100644 index 00000000..cdcd251a --- /dev/null +++ b/src/charging-station/ui-server/UIServerFactory.ts @@ -0,0 +1,24 @@ +import { AbstractUIServer } from './AbstractUIServer'; +import { ApplicationProtocol } from '../../types/UIProtocol'; +import Configuration from '../../utils/Configuration'; +import { ServerOptions } from '../../types/ConfigurationData'; +import UIWebSocketServer from './UIWebSocketServer'; + +export default class UIServerFactory { + private constructor() { + // This is intentional + } + + public static getUIServerImplementation( + applicationProtocol: ApplicationProtocol, + options?: ServerOptions, + callback?: () => void + ): AbstractUIServer | null { + switch (applicationProtocol) { + case ApplicationProtocol.WS: + return new UIWebSocketServer(options ?? Configuration.getUIServer().options, callback); + default: + return null; + } + } +} diff --git a/src/charging-station/ui-server/UIWebSocketServer.ts b/src/charging-station/ui-server/UIWebSocketServer.ts index 2e03ebc2..da476895 100644 --- a/src/charging-station/ui-server/UIWebSocketServer.ts +++ b/src/charging-station/ui-server/UIWebSocketServer.ts @@ -1,7 +1,7 @@ import { Protocol, ProtocolVersion } from '../../types/UIProtocol'; import WebSocket, { OPEN, Server } from 'ws'; -import AbstractUIService from './ui-services/AbstractUIService'; +import { AbstractUIServer } from './AbstractUIServer'; import Configuration from '../../utils/Configuration'; import { IncomingMessage } from 'http'; import { ServerOptions } from '../../types/ConfigurationData'; @@ -9,19 +9,14 @@ import UIServiceFactory from './ui-services/UIServiceFactory'; import Utils from '../../utils/Utils'; import logger from '../../utils/Logger'; -export default class UIWebSocketServer extends Server { - public readonly chargingStations: Set; - private readonly uiServices: Map; - +export default class UIWebSocketServer extends AbstractUIServer { public constructor(options?: ServerOptions, callback?: () => void) { - // Create the WebSocket server - super(options ?? Configuration.getUIServer().options, callback); - this.chargingStations = new Set(); - this.uiServices = new Map(); + super(); + this.uiServer = new Server(options ?? Configuration.getUIServer().options, callback); } public start(): void { - this.on('connection', (socket: WebSocket, request: IncomingMessage): void => { + this.uiServer.on('connection', (socket: WebSocket, request: IncomingMessage): void => { const protocolIndex = socket.protocol.indexOf(Protocol.UI); const version = socket.protocol.substring( protocolIndex + Protocol.UI.length @@ -45,7 +40,7 @@ export default class UIWebSocketServer extends Server { } public stop(): void { - this.close(); + this.uiServer.close(); } public sendResponse(message: string): void { @@ -57,7 +52,7 @@ export default class UIWebSocketServer extends Server { } private broadcastToClients(message: string): void { - for (const client of this.clients) { + for (const client of (this.uiServer as Server).clients) { if (client?.readyState === OPEN) { client.send(message); } diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index d4ad3398..151cff33 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -4,18 +4,18 @@ import { ProtocolRequestHandler, } from '../../../types/UIProtocol'; +import { AbstractUIServer } from '../AbstractUIServer'; import BaseError from '../../../exception/BaseError'; import { JsonType } from '../../../types/JsonType'; import { RawData } from 'ws'; -import UIWebSocketServer from '../UIWebSocketServer'; import Utils from '../../../utils/Utils'; import logger from '../../../utils/Logger'; export default abstract class AbstractUIService { - protected readonly uiServer: UIWebSocketServer; + protected readonly uiServer: AbstractUIServer; protected readonly messageHandlers: Map; - constructor(uiServer: UIWebSocketServer) { + constructor(uiServer: AbstractUIServer) { this.uiServer = uiServer; this.messageHandlers = new Map([ [ProtocolCommand.LIST_CHARGING_STATIONS, this.handleListChargingStations.bind(this)], diff --git a/src/charging-station/ui-server/ui-services/UIService001.ts b/src/charging-station/ui-server/ui-services/UIService001.ts index eecdcd34..cbe4c8c3 100644 --- a/src/charging-station/ui-server/ui-services/UIService001.ts +++ b/src/charging-station/ui-server/ui-services/UIService001.ts @@ -1,11 +1,11 @@ import { ProtocolCommand, ProtocolRequestHandler } from '../../../types/UIProtocol'; +import { AbstractUIServer } from '../AbstractUIServer'; import AbstractUIService from './AbstractUIService'; import { JsonType } from '../../../types/JsonType'; -import UIWebSocketServer from '../UIWebSocketServer'; export default class UIService001 extends AbstractUIService { - constructor(uiServer: UIWebSocketServer) { + constructor(uiServer: AbstractUIServer) { super(uiServer); this.messageHandlers.set( ProtocolCommand.START_TRANSACTION, diff --git a/src/charging-station/ui-server/ui-services/UIServiceFactory.ts b/src/charging-station/ui-server/ui-services/UIServiceFactory.ts index d4f92c10..7136e447 100644 --- a/src/charging-station/ui-server/ui-services/UIServiceFactory.ts +++ b/src/charging-station/ui-server/ui-services/UIServiceFactory.ts @@ -1,7 +1,7 @@ +import { AbstractUIServer } from '../AbstractUIServer'; import AbstractUIService from './AbstractUIService'; import { ProtocolVersion } from '../../../types/UIProtocol'; import UIService001 from './UIService001'; -import UIWebSocketServer from '../UIWebSocketServer'; export default class UIServiceFactory { private constructor() { @@ -10,7 +10,7 @@ export default class UIServiceFactory { public static getUIServiceImplementation( version: ProtocolVersion, - uiServer: UIWebSocketServer + uiServer: AbstractUIServer ): AbstractUIService | null { switch (version) { case ProtocolVersion['0.0.1']: -- 2.34.1