Broadcast Channel: optimize requests handling implementation
[e-mobility-charging-stations-simulator.git] / src / charging-station / ui-server / ui-services / AbstractUIService.ts
index 9120f19976e8a682afd136afc1d469ee0af2fe30..a393986e8f3b2ae7f9db6f741382440183810ad0 100644 (file)
@@ -1,8 +1,6 @@
-import type { RawData } from 'ws';
-
 import BaseError from '../../../exception/BaseError';
+import type OCPPError from '../../../exception/OCPPError';
 import { Bootstrap } from '../../../internal';
-import type { JsonType } from '../../../types/JsonType';
 import {
   ProcedureName,
   ProtocolRequest,
@@ -24,10 +22,10 @@ import type { AbstractUIServer } from '../AbstractUIServer';
 const moduleName = 'AbstractUIService';
 
 export default abstract class AbstractUIService {
-  protected readonly version: ProtocolVersion;
-  protected readonly uiServer: AbstractUIServer;
   protected readonly requestHandlers: Map<ProcedureName, ProtocolRequestHandler>;
-  private uiServiceWorkerBroadcastChannel: UIServiceWorkerBroadcastChannel;
+  private readonly version: ProtocolVersion;
+  private readonly uiServer: AbstractUIServer;
+  private readonly uiServiceWorkerBroadcastChannel: UIServiceWorkerBroadcastChannel;
   private readonly broadcastChannelRequests: Map<string, number>;
 
   constructor(uiServer: AbstractUIServer, version: ProtocolVersion) {
@@ -42,13 +40,13 @@ export default abstract class AbstractUIService {
     this.broadcastChannelRequests = new Map<string, number>();
   }
 
-  public async requestHandler(request: RawData | JsonType): Promise<void> {
+  public async requestHandler(request: ProtocolRequest): Promise<void> {
     let messageId: string;
     let command: ProcedureName;
     let requestPayload: RequestPayload | undefined;
     let responsePayload: ResponsePayload;
     try {
-      [messageId, command, requestPayload] = this.requestValidation(request);
+      [messageId, command, requestPayload] = request;
 
       if (this.requestHandlers.has(command) === false) {
         throw new BaseError(
@@ -66,12 +64,14 @@ export default abstract class AbstractUIService {
       // Log
       logger.error(`${this.logPrefix(moduleName, 'messageHandler')} Handle request error:`, error);
       responsePayload = {
+        hashIds: requestPayload.hashIds,
         status: ResponseStatus.FAILURE,
         command,
         requestPayload,
         responsePayload,
         errorMessage: (error as Error).message,
         errorStack: (error as Error).stack,
+        errorDetails: (error as OCPPError).details,
       };
     }
     // Send response for payload not forwarded to broadcast channel
@@ -129,38 +129,15 @@ export default abstract class AbstractUIService {
     const expectedNumberOfResponses = !Utils.isEmptyArray(payload.hashIds)
       ? payload.hashIds.length
       : this.uiServer.chargingStations.size;
-    this.broadcastChannelRequests.set(uuid, expectedNumberOfResponses);
     this.uiServiceWorkerBroadcastChannel.sendRequest([uuid, procedureName, payload]);
-  }
-
-  // Validate the raw data received from the UI server
-  private requestValidation(rawData: RawData | JsonType): ProtocolRequest {
-    // logger.debug(
-    //   `${this.logPrefix(
-    //     moduleName,
-    //     'requestValidation'
-    //   )} Data received in string format: ${rawData.toString()}`
-    // );
-
-    const data = JSON.parse(rawData.toString()) as JsonType[];
-
-    if (Array.isArray(data) === false) {
-      throw new BaseError('UI protocol request is not an array');
-    }
-
-    if (data.length !== 3) {
-      throw new BaseError('UI protocol request is malformed');
-    }
-
-    return data as ProtocolRequest;
+    this.broadcastChannelRequests.set(uuid, expectedNumberOfResponses);
   }
 
   private handleListChargingStations(): ResponsePayload {
-    // TODO: remove cast to unknown
     return {
       status: ResponseStatus.SUCCESS,
-      ...[...this.uiServer.chargingStations.values()],
-    } as unknown as ResponsePayload;
+      chargingStations: [...this.uiServer.chargingStations.values()],
+    } as ResponsePayload;
   }
 
   private async handleStartSimulator(): Promise<ResponsePayload> {