build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPIncomingRequestService.ts
CommitLineData
54510a60
JB
1import { EventEmitter } from 'node:events'
2
24d15716 3import _Ajv, { type ValidateFunction } from 'ajv'
66a7748d 4import _ajvFormats from 'ajv-formats'
e3018bc4 5
66a7748d
JB
6import { type ChargingStation, getIdTagsFile } from '../../charging-station/index.js'
7import { OCPPError } from '../../exception/index.js'
268a74bb
JB
8import type {
9 ClearCacheResponse,
268a74bb 10 IncomingRequestCommand,
268a74bb 11 JsonType,
66a7748d
JB
12 OCPPVersion
13} from '../../types/index.js'
2d4928a7 14import { logger } from '../../utils/index.js'
4c3f6c20 15import { OCPPConstants } from './OCPPConstants.js'
01b82de5 16import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
66a7748d
JB
17type Ajv = _Ajv.default
18// eslint-disable-next-line @typescript-eslint/no-redeclare
19const Ajv = _Ajv.default
20const ajvFormats = _ajvFormats.default
c0560973 21
66a7748d 22const moduleName = 'OCPPIncomingRequestService'
e3018bc4 23
54510a60 24export abstract class OCPPIncomingRequestService extends EventEmitter {
66a7748d
JB
25 private static instance: OCPPIncomingRequestService | null = null
26 private readonly version: OCPPVersion
24d15716 27 protected readonly ajv: Ajv
d5490a13 28 protected abstract payloadValidateFunctions: Map<
24d15716
JB
29 IncomingRequestCommand,
30 ValidateFunction<JsonType>
31 >
10068088 32
66a7748d 33 protected constructor (version: OCPPVersion) {
54510a60 34 super()
66a7748d 35 this.version = version
45988780 36 this.ajv = new Ajv({
98fc1389 37 keywords: ['javaType'],
66a7748d
JB
38 multipleOfPrecision: 2
39 })
40 ajvFormats(this.ajv)
ba9a56a6
JB
41 this.incomingRequestHandler = this.incomingRequestHandler.bind(this)
42 this.validateIncomingRequestPayload = this.validateIncomingRequestPayload.bind(this)
c0560973
JB
43 }
44
08f130a0 45 public static getInstance<T extends OCPPIncomingRequestService>(this: new () => T): T {
1ca780f9 46 if (OCPPIncomingRequestService.instance === null) {
66a7748d 47 OCPPIncomingRequestService.instance = new this()
9f2e3130 48 }
66a7748d 49 return OCPPIncomingRequestService.instance as T
9f2e3130
JB
50 }
51
e3018bc4
JB
52 protected validateIncomingRequestPayload<T extends JsonType>(
53 chargingStation: ChargingStation,
54 commandName: IncomingRequestCommand,
66a7748d 55 payload: T
e3018bc4 56 ): boolean {
5398cecf 57 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
66a7748d 58 return true
e3018bc4 59 }
d5490a13 60 const validate = this.payloadValidateFunctions.get(commandName)
24d15716 61 if (validate?.(payload) === true) {
66a7748d 62 return true
e3018bc4
JB
63 }
64 logger.error(
45988780 65 `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestPayload: Command '${commandName}' incoming request PDU is invalid: %j`,
24d15716 66 validate?.errors
66a7748d 67 )
e3018bc4 68 throw new OCPPError(
01b82de5 69 ajvErrorsToErrorType(validate?.errors),
e3018bc4
JB
70 'Incoming request PDU is invalid',
71 commandName,
24d15716 72 JSON.stringify(validate?.errors, undefined, 2)
66a7748d 73 )
e3018bc4
JB
74 }
75
66a7748d
JB
76 protected handleRequestClearCache (chargingStation: ChargingStation): ClearCacheResponse {
77 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
5199f9fd 78 if (chargingStation.idTagsCache.deleteIdTags(getIdTagsFile(chargingStation.stationInfo!)!)) {
66a7748d 79 return OCPPConstants.OCPP_RESPONSE_ACCEPTED
26a17d93 80 }
66a7748d 81 return OCPPConstants.OCPP_RESPONSE_REJECTED
22e0d48e
JB
82 }
83
9429aa42
JB
84 // eslint-disable-next-line @typescript-eslint/no-unused-vars
85 public abstract incomingRequestHandler<ReqType extends JsonType, ResType extends JsonType>(
08f130a0 86 chargingStation: ChargingStation,
e7aeea18
JB
87 messageId: string,
88 commandName: IncomingRequestCommand,
66a7748d
JB
89 commandPayload: ReqType
90 ): Promise<void>
c0560973 91}