c66a16dad839a4fbcd47e250341d4d6e15b9a823
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPResponseService.ts
1 import Ajv, { type JSONSchemaType } from 'ajv';
2 import ajvFormats from 'ajv-formats';
3
4 import { OCPPServiceUtils } from './internal';
5 import type { ChargingStation } from '../../charging-station';
6 import { OCPPError } from '../../exception';
7 import type {
8 IncomingRequestCommand,
9 JsonObject,
10 JsonType,
11 OCPPVersion,
12 RequestCommand,
13 } from '../../types';
14 import { logger } from '../../utils/Logger';
15
16 const moduleName = 'OCPPResponseService';
17
18 export abstract class OCPPResponseService {
19 private static instance: OCPPResponseService | null = null;
20 private readonly version: OCPPVersion;
21 private readonly ajv: Ajv;
22 public abstract jsonIncomingRequestResponseSchemas: Map<
23 IncomingRequestCommand,
24 JSONSchemaType<JsonObject>
25 >;
26
27 protected constructor(version: OCPPVersion) {
28 this.version = version;
29 this.ajv = new Ajv({
30 keywords: ['javaType'],
31 multipleOfPrecision: 2,
32 });
33 ajvFormats(this.ajv);
34 this.responseHandler.bind(this);
35 this.validateResponsePayload.bind(this);
36 }
37
38 public static getInstance<T extends OCPPResponseService>(this: new () => T): T {
39 if (OCPPResponseService.instance === null) {
40 OCPPResponseService.instance = new this();
41 }
42 return OCPPResponseService.instance as T;
43 }
44
45 protected validateResponsePayload<T extends JsonType>(
46 chargingStation: ChargingStation,
47 commandName: RequestCommand,
48 schema: JSONSchemaType<T>,
49 payload: T
50 ): boolean {
51 if (chargingStation.getPayloadSchemaValidation() === false) {
52 return true;
53 }
54 const validate = this.ajv.compile(schema);
55 if (validate(payload)) {
56 return true;
57 }
58 logger.error(
59 `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' response PDU is invalid: %j`,
60 validate.errors
61 );
62 throw new OCPPError(
63 OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
64 'Response PDU is invalid',
65 commandName,
66 JSON.stringify(validate.errors, null, 2)
67 );
68 }
69
70 protected emptyResponseHandler() {
71 /* This is intentional */
72 }
73
74 public abstract responseHandler(
75 chargingStation: ChargingStation,
76 commandName: RequestCommand,
77 payload: JsonType,
78 requestPayload: JsonType
79 ): Promise<void>;
80 }