X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Fui-server%2FAbstractUIServer.ts;h=a786fbbddc2ed43623316f297a7f5ac94503d474;hb=4c6f35659fb67d395adc035ef80c566eb6eef79e;hp=b17dec30110aea46abae4ec911782c6eb8f690d5;hpb=75adc3d83c35b843b824a8564504de6ff732df24;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ui-server/AbstractUIServer.ts b/src/charging-station/ui-server/AbstractUIServer.ts index b17dec30..a786fbbd 100644 --- a/src/charging-station/ui-server/AbstractUIServer.ts +++ b/src/charging-station/ui-server/AbstractUIServer.ts @@ -1,16 +1,14 @@ import { type IncomingMessage, Server, type ServerResponse } from 'node:http' -import { type Http2Server, createServer } from 'node:http2' +import { createServer, type Http2Server } from 'node:http2' import type { WebSocket } from 'ws' -import type { AbstractUIService } from './ui-services/AbstractUIService.js' -import { UIServiceFactory } from './ui-services/UIServiceFactory.js' -import { getUsernameAndPasswordFromAuthorizationToken } from './UIServerUtils.js' import { BaseError } from '../../exception/index.js' import { ApplicationProtocolVersion, AuthenticationType, type ChargingStationData, + ConfigurationSection, type ProcedureName, type ProtocolRequest, type ProtocolResponse, @@ -19,12 +17,22 @@ import { type ResponsePayload, type UIServerConfiguration } from '../../types/index.js' +import { logger } from '../../utils/index.js' +import type { AbstractUIService } from './ui-services/AbstractUIService.js' +import { UIServiceFactory } from './ui-services/UIServiceFactory.js' +import { getUsernameAndPasswordFromAuthorizationToken } from './UIServerUtils.js' + +const moduleName = 'AbstractUIServer' export abstract class AbstractUIServer { public readonly chargingStations: Map public readonly chargingStationTemplates: Set protected readonly httpServer: Server | Http2Server - protected readonly responseHandlers: Map + protected readonly responseHandlers: Map< + `${string}-${string}-${string}-${string}-${string}`, + ServerResponse | WebSocket + > + protected readonly uiServices: Map public constructor (protected readonly uiServerConfiguration: UIServerConfiguration) { @@ -39,23 +47,29 @@ export abstract class AbstractUIServer { break default: throw new BaseError( - `Unsupported application protocol version ${this.uiServerConfiguration.version}` + `Unsupported application protocol version ${this.uiServerConfiguration.version} in '${ConfigurationSection.uiServer}' configuration section` ) } - this.responseHandlers = new Map() + this.responseHandlers = new Map< + `${string}-${string}-${string}-${string}-${string}`, + ServerResponse | WebSocket + >() this.uiServices = new Map() } public buildProtocolRequest ( - id: string, + uuid: `${string}-${string}-${string}-${string}-${string}`, procedureName: ProcedureName, requestPayload: RequestPayload ): ProtocolRequest { - return [id, procedureName, requestPayload] + return [uuid, procedureName, requestPayload] } - public buildProtocolResponse (id: string, responsePayload: ResponsePayload): ProtocolResponse { - return [id, responsePayload] + public buildProtocolResponse ( + uuid: `${string}-${string}-${string}-${string}-${string}`, + responsePayload: ResponsePayload + ): ProtocolResponse { + return [uuid, responsePayload] } public stop (): void { @@ -63,6 +77,10 @@ export abstract class AbstractUIServer { for (const uiService of this.uiServices.values()) { uiService.stop() } + this.clearCaches() + } + + public clearCaches (): void { this.chargingStations.clear() this.chargingStationTemplates.clear() } @@ -75,11 +93,17 @@ export abstract class AbstractUIServer { ?.requestHandler(request) as Promise) } - public hasResponseHandler (id: string): boolean { - return this.responseHandlers.has(id) + public hasResponseHandler (uuid: `${string}-${string}-${string}-${string}-${string}`): boolean { + return this.responseHandlers.has(uuid) } protected startHttpServer (): void { + this.httpServer.on('error', error => { + logger.error( + `${this.logPrefix(moduleName, 'start.httpServer.on.error')} HTTP server error:`, + error + ) + }) if (!this.httpServer.listening) { this.httpServer.listen(this.uiServerConfiguration.options) } @@ -112,6 +136,7 @@ export abstract class AbstractUIServer { private stopHttpServer (): void { if (this.httpServer.listening) { this.httpServer.close() + this.httpServer.removeAllListeners() } } @@ -141,7 +166,9 @@ export abstract class AbstractUIServer { const authorizationProtocol = req.headers['sec-websocket-protocol']?.split(/,\s+/).pop() const [username, password] = getUsernameAndPasswordFromAuthorizationToken( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - `${authorizationProtocol}${Array(((4 - (authorizationProtocol!.length % 4)) % 4) + 1).join('=')}` + `${authorizationProtocol}${Array(((4 - (authorizationProtocol!.length % 4)) % 4) + 1).join( + '=' + )}` .split('.') .pop() ?? '', next