perf: cache only JSON payload validation functions
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPResponseService.ts
CommitLineData
24d15716 1import _Ajv, { type ValidateFunction } from 'ajv'
66a7748d 2import _ajvFormats from 'ajv-formats'
844e496b 3
66a7748d
JB
4import { OCPPServiceUtils } from './OCPPServiceUtils.js'
5import type { ChargingStation } from '../../charging-station/index.js'
6import { OCPPError } from '../../exception/index.js'
a6ef1ece
JB
7import type {
8 IncomingRequestCommand,
9 JsonType,
10 OCPPVersion,
66a7748d
JB
11 RequestCommand
12} from '../../types/index.js'
fc5529db 13import { Constants, logger } from '../../utils/index.js'
66a7748d
JB
14type Ajv = _Ajv.default
15// eslint-disable-next-line @typescript-eslint/no-redeclare
16const Ajv = _Ajv.default
17const ajvFormats = _ajvFormats.default
c0560973 18
66a7748d 19const moduleName = 'OCPPResponseService'
e3018bc4 20
268a74bb 21export abstract class OCPPResponseService {
66a7748d 22 private static instance: OCPPResponseService | null = null
66a7748d 23 private readonly version: OCPPVersion
24d15716
JB
24 protected readonly ajv: Ajv
25 protected abstract jsonSchemasValidateFunction: Map<RequestCommand, ValidateFunction<JsonType>>
26 public abstract jsonSchemasIncomingRequestResponseValidateFunction: Map<
66a7748d 27 IncomingRequestCommand,
24d15716 28 ValidateFunction<JsonType>
66a7748d 29 >
10068088 30
66a7748d
JB
31 protected constructor (version: OCPPVersion) {
32 this.version = version
45988780 33 this.ajv = new Ajv({
98fc1389 34 keywords: ['javaType'],
66a7748d
JB
35 multipleOfPrecision: 2
36 })
37 ajvFormats(this.ajv)
ba9a56a6
JB
38 this.responseHandler = this.responseHandler.bind(this)
39 this.validateResponsePayload = this.validateResponsePayload.bind(this)
c0560973
JB
40 }
41
08f130a0 42 public static getInstance<T extends OCPPResponseService>(this: new () => T): T {
1ca780f9 43 if (OCPPResponseService.instance === null) {
66a7748d 44 OCPPResponseService.instance = new this()
9f2e3130 45 }
66a7748d 46 return OCPPResponseService.instance as T
9f2e3130
JB
47 }
48
844e496b
JB
49 protected validateResponsePayload<T extends JsonType>(
50 chargingStation: ChargingStation,
51 commandName: RequestCommand,
66a7748d 52 payload: T
844e496b 53 ): boolean {
5398cecf 54 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
66a7748d 55 return true
844e496b 56 }
24d15716
JB
57 const validate = this.jsonSchemasValidateFunction.get(commandName)
58 if (validate?.(payload) === true) {
66a7748d 59 return true
844e496b
JB
60 }
61 logger.error(
45988780 62 `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' response PDU is invalid: %j`,
24d15716 63 validate?.errors
66a7748d 64 )
844e496b 65 throw new OCPPError(
24d15716 66 OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
844e496b
JB
67 'Response PDU is invalid',
68 commandName,
24d15716 69 JSON.stringify(validate?.errors, undefined, 2)
66a7748d 70 )
844e496b
JB
71 }
72
fc5529db 73 protected emptyResponseHandler = Constants.EMPTY_FUNCTION
b52c969d 74
9429aa42 75 public abstract responseHandler<ReqType extends JsonType, ResType extends JsonType>(
08f130a0 76 chargingStation: ChargingStation,
e7aeea18 77 commandName: RequestCommand,
9429aa42 78 payload: ResType,
66a7748d
JB
79 requestPayload: ReqType
80 ): Promise<void>
c0560973 81}