1 import BaseError from
'../../../exception/BaseError';
2 import { Bootstrap
} from
'../../../internal';
6 ProtocolRequestHandler
,
11 } from
'../../../types/UIProtocol';
13 BroadcastChannelProcedureName
,
14 BroadcastChannelRequestPayload
,
15 } from
'../../../types/WorkerBroadcastChannel';
16 import logger from
'../../../utils/Logger';
17 import Utils from
'../../../utils/Utils';
18 import UIServiceWorkerBroadcastChannel from
'../../UIServiceWorkerBroadcastChannel';
19 import type { AbstractUIServer
} from
'../AbstractUIServer';
21 const moduleName
= 'AbstractUIService';
23 export default abstract class AbstractUIService
{
24 protected readonly requestHandlers
: Map
<ProcedureName
, ProtocolRequestHandler
>;
25 private readonly version
: ProtocolVersion
;
26 private readonly uiServer
: AbstractUIServer
;
27 private readonly uiServiceWorkerBroadcastChannel
: UIServiceWorkerBroadcastChannel
;
28 private readonly broadcastChannelRequests
: Map
<string, number>;
30 constructor(uiServer
: AbstractUIServer
, version
: ProtocolVersion
) {
31 this.version
= version
;
32 this.uiServer
= uiServer
;
33 this.requestHandlers
= new Map
<ProcedureName
, ProtocolRequestHandler
>([
34 [ProcedureName
.LIST_CHARGING_STATIONS
, this.handleListChargingStations
.bind(this)],
35 [ProcedureName
.START_SIMULATOR
, this.handleStartSimulator
.bind(this)],
36 [ProcedureName
.STOP_SIMULATOR
, this.handleStopSimulator
.bind(this)],
38 this.uiServiceWorkerBroadcastChannel
= new UIServiceWorkerBroadcastChannel(this);
39 this.broadcastChannelRequests
= new Map
<string, number>();
42 public async requestHandler(request
: ProtocolRequest
): Promise
<void> {
43 let messageId
: string;
44 let command
: ProcedureName
;
45 let requestPayload
: RequestPayload
| undefined;
46 let responsePayload
: ResponsePayload
;
48 [messageId
, command
, requestPayload
] = request
;
50 if (this.requestHandlers
.has(command
) === false) {
52 `${command} is not implemented to handle message payload ${JSON.stringify(
60 // Call the request handler to build the response payload
61 responsePayload
= await this.requestHandlers
.get(command
)(messageId
, requestPayload
);
64 logger
.error(`${this.logPrefix(moduleName, 'messageHandler')} Handle request error:`, error
);
66 status: ResponseStatus
.FAILURE
,
70 errorMessage
: (error
as Error).message
,
71 errorStack
: (error
as Error).stack
,
74 // Send response for payload not forwarded to broadcast channel
75 if (responsePayload
!== undefined) {
76 this.sendResponse(messageId
?? 'error', responsePayload
);
82 procedureName
: ProcedureName
,
83 requestPayload
: RequestPayload
85 this.uiServer
.sendRequest(
86 this.uiServer
.buildProtocolRequest(messageId
, procedureName
, requestPayload
)
90 public sendResponse(messageId
: string, responsePayload
: ResponsePayload
): void {
91 this.uiServer
.sendResponse(this.uiServer
.buildProtocolResponse(messageId
, responsePayload
));
94 public logPrefix(modName
: string, methodName
: string): string {
95 return this.uiServer
.logPrefix(modName
, methodName
, this.version
);
98 public deleteBroadcastChannelRequest(uuid
: string): void {
99 this.broadcastChannelRequests
.delete(uuid
);
102 public getBroadcastChannelExpectedResponses(uuid
: string): number {
103 return this.broadcastChannelRequests
.get(uuid
) ?? 0;
106 protected sendBroadcastChannelRequest(
108 procedureName
: BroadcastChannelProcedureName
,
109 payload
: BroadcastChannelRequestPayload
111 if (!Utils
.isEmptyArray(payload
.hashIds
)) {
112 payload
.hashIds
= payload
.hashIds
114 if (this.uiServer
.chargingStations
.has(hashId
) === true) {
120 'sendBroadcastChannelRequest'
121 )} Charging station with hashId '${hashId}' not found`
124 .filter((hashId
) => hashId
!== undefined);
126 const expectedNumberOfResponses
= !Utils
.isEmptyArray(payload
.hashIds
)
127 ? payload
.hashIds
.length
128 : this.uiServer
.chargingStations
.size
;
129 this.uiServiceWorkerBroadcastChannel
.sendRequest([uuid
, procedureName
, payload
]);
130 this.broadcastChannelRequests
.set(uuid
, expectedNumberOfResponses
);
133 private handleListChargingStations(): ResponsePayload
{
135 status: ResponseStatus
.SUCCESS
,
136 chargingStations
: [...this.uiServer
.chargingStations
.values()],
137 } as ResponsePayload
;
140 private async handleStartSimulator(): Promise
<ResponsePayload
> {
141 await Bootstrap
.getInstance().start();
142 return { status: ResponseStatus
.SUCCESS
};
145 private async handleStopSimulator(): Promise
<ResponsePayload
> {
146 await Bootstrap
.getInstance().stop();
147 return { status: ResponseStatus
.SUCCESS
};