build: switch to NodeNext module resolution
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPResponseService.ts
CommitLineData
ec0eebcc 1import Ajv, { type JSONSchemaType, type ValidateFunction } from 'ajv';
844e496b
JB
2import ajvFormats from 'ajv-formats';
3
a6ef1ece
JB
4import { OCPPServiceUtils } from './OCPPServiceUtils.js';
5import type { ChargingStation } from '../../charging-station/index.js';
6import { OCPPError } from '../../exception/index.js';
7import type {
8 IncomingRequestCommand,
9 JsonType,
10 OCPPVersion,
11 RequestCommand,
12} from '../../types/index.js';
13import { logger } from '../../utils/index.js';
c0560973 14
e3018bc4
JB
15const moduleName = 'OCPPResponseService';
16
268a74bb 17export abstract class OCPPResponseService {
08f130a0 18 private static instance: OCPPResponseService | null = null;
ec0eebcc
JB
19
20 public jsonIncomingRequestResponseValidateFunctions: Map<
21 IncomingRequestCommand,
291b5ec8 22 ValidateFunction<JsonType>
ec0eebcc
JB
23 >;
24
d270cc87 25 private readonly version: OCPPVersion;
012ae1a9 26 private readonly ajv: Ajv;
291b5ec8 27 private jsonRequestValidateFunctions: Map<RequestCommand, ValidateFunction<JsonType>>;
ec0eebcc 28
b3fc3ff5
JB
29 public abstract jsonIncomingRequestResponseSchemas: Map<
30 IncomingRequestCommand,
291b5ec8 31 JSONSchemaType<JsonType>
b3fc3ff5 32 >;
10068088 33
d270cc87
JB
34 protected constructor(version: OCPPVersion) {
35 this.version = version;
45988780 36 this.ajv = new Ajv({
98fc1389 37 keywords: ['javaType'],
45988780
JB
38 multipleOfPrecision: 2,
39 });
844e496b 40 ajvFormats(this.ajv);
291b5ec8 41 this.jsonRequestValidateFunctions = new Map<RequestCommand, ValidateFunction<JsonType>>();
ec0eebcc
JB
42 this.jsonIncomingRequestResponseValidateFunctions = new Map<
43 IncomingRequestCommand,
291b5ec8 44 ValidateFunction<JsonType>
ec0eebcc 45 >();
9429aa42
JB
46 this.responseHandler = this.responseHandler.bind(this) as <
47 ReqType extends JsonType,
48 ResType extends JsonType,
49 >(
31f59c6d
JB
50 chargingStation: ChargingStation,
51 commandName: RequestCommand,
9429aa42
JB
52 payload: ResType,
53 requestPayload: ReqType,
31f59c6d
JB
54 ) => Promise<void>;
55 this.validateResponsePayload = this.validateResponsePayload.bind(this) as <T extends JsonType>(
56 chargingStation: ChargingStation,
57 commandName: RequestCommand,
58 schema: JSONSchemaType<T>,
5edd8ba0 59 payload: T,
31f59c6d 60 ) => boolean;
c0560973
JB
61 }
62
08f130a0 63 public static getInstance<T extends OCPPResponseService>(this: new () => T): T {
1ca780f9 64 if (OCPPResponseService.instance === null) {
08f130a0 65 OCPPResponseService.instance = new this();
9f2e3130 66 }
08f130a0 67 return OCPPResponseService.instance as T;
9f2e3130
JB
68 }
69
844e496b
JB
70 protected validateResponsePayload<T extends JsonType>(
71 chargingStation: ChargingStation,
72 commandName: RequestCommand,
73 schema: JSONSchemaType<T>,
5edd8ba0 74 payload: T,
844e496b 75 ): boolean {
5398cecf 76 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
844e496b
JB
77 return true;
78 }
0b0ca54f 79 const validate = this.getJsonRequestValidateFunction<T>(commandName, schema);
844e496b
JB
80 if (validate(payload)) {
81 return true;
82 }
83 logger.error(
45988780 84 `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' response PDU is invalid: %j`,
5edd8ba0 85 validate.errors,
844e496b
JB
86 );
87 throw new OCPPError(
9ff486f4 88 OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
844e496b
JB
89 'Response PDU is invalid',
90 commandName,
4ed03b6e 91 JSON.stringify(validate.errors, undefined, 2),
844e496b
JB
92 );
93 }
94
81e3cc38 95 protected emptyResponseHandler() {
bd770dde 96 /* This is intentional */
81e3cc38 97 }
b52c969d 98
0b0ca54f
JB
99 private getJsonRequestValidateFunction<T extends JsonType>(
100 commandName: RequestCommand,
101 schema: JSONSchemaType<T>,
102 ) {
103 if (this.jsonRequestValidateFunctions.has(commandName) === false) {
104 this.jsonRequestValidateFunctions.set(commandName, this.ajv.compile<T>(schema).bind(this));
105 }
106 return this.jsonRequestValidateFunctions.get(commandName)!;
107 }
108
9429aa42 109 public abstract responseHandler<ReqType extends JsonType, ResType extends JsonType>(
08f130a0 110 chargingStation: ChargingStation,
e7aeea18 111 commandName: RequestCommand,
9429aa42
JB
112 payload: ResType,
113 requestPayload: ReqType,
e7aeea18 114 ): Promise<void>;
c0560973 115}