Apply dependencies update
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPIncomingRequestService.ts
CommitLineData
e6159ce8
JB
1import { AsyncResource } from 'async_hooks';
2
d270cc87
JB
3import Ajv, { type JSONSchemaType } from 'ajv';
4import AjvDraft04 from 'ajv-draft-04';
e3018bc4
JB
5import ajvFormats from 'ajv-formats';
6
7import OCPPError from '../../exception/OCPPError';
6c1761d4
JB
8import type { HandleErrorParams } from '../../types/Error';
9import type { JsonType } from '../../types/JsonType';
d270cc87 10import { OCPPVersion } from '../../types/ocpp/OCPPVersion';
6c1761d4 11import type { IncomingRequestCommand } from '../../types/ocpp/Requests';
9f2e3130 12import logger from '../../utils/Logger';
8114d10e 13import type ChargingStation from '../ChargingStation';
cbb3711f 14import { OCPPServiceUtils } from './OCPPServiceUtils';
c0560973 15
e3018bc4
JB
16const moduleName = 'OCPPIncomingRequestService';
17
c0560973 18export default abstract class OCPPIncomingRequestService {
08f130a0 19 private static instance: OCPPIncomingRequestService | null = null;
e6159ce8 20 protected asyncResource: AsyncResource;
d270cc87 21 private readonly version: OCPPVersion;
012ae1a9 22 private readonly ajv: Ajv;
10068088 23
d270cc87
JB
24 protected constructor(version: OCPPVersion) {
25 this.version = version;
26 switch (this.version) {
27 case OCPPVersion.VERSION_16:
28 this.ajv = new AjvDraft04();
29 break;
30 case OCPPVersion.VERSION_20:
31 case OCPPVersion.VERSION_201:
32 this.ajv = new Ajv();
33 break;
34 }
e3018bc4 35 ajvFormats(this.ajv);
d270cc87 36 this.asyncResource = new AsyncResource(moduleName);
9952c548
JB
37 this.incomingRequestHandler.bind(this);
38 this.validateIncomingRequestPayload.bind(this);
c0560973
JB
39 }
40
08f130a0 41 public static getInstance<T extends OCPPIncomingRequestService>(this: new () => T): T {
1ca780f9 42 if (OCPPIncomingRequestService.instance === null) {
08f130a0 43 OCPPIncomingRequestService.instance = new this();
9f2e3130 44 }
08f130a0 45 return OCPPIncomingRequestService.instance as T;
9f2e3130
JB
46 }
47
e7aeea18 48 protected handleIncomingRequestError<T>(
08f130a0 49 chargingStation: ChargingStation,
e7aeea18
JB
50 commandName: IncomingRequestCommand,
51 error: Error,
52 params: HandleErrorParams<T> = { throwError: true }
51581a20 53 ): T | undefined {
e7aeea18 54 logger.error(
60ddad53 55 `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
e7aeea18
JB
56 error
57 );
717c1e56
JB
58 if (!params?.throwError && params?.errorResponse) {
59 return params?.errorResponse;
e64c0923 60 }
717c1e56 61 if (params?.throwError && !params?.errorResponse) {
e0a50bcd
JB
62 throw error;
63 }
717c1e56
JB
64 if (params?.throwError && params?.errorResponse) {
65 return params?.errorResponse;
66 }
47e22477
JB
67 }
68
e3018bc4
JB
69 protected validateIncomingRequestPayload<T extends JsonType>(
70 chargingStation: ChargingStation,
71 commandName: IncomingRequestCommand,
72 schema: JSONSchemaType<T>,
73 payload: T
74 ): boolean {
0638ddd2 75 if (chargingStation.getPayloadSchemaValidation() === false) {
e3018bc4
JB
76 return true;
77 }
78 const validate = this.ajv.compile(schema);
79 if (validate(payload)) {
80 return true;
81 }
82 logger.error(
83 `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestPayload: Incoming request PDU is invalid: %j`,
84 validate.errors
85 );
86 throw new OCPPError(
01a4dcbb 87 OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
e3018bc4
JB
88 'Incoming request PDU is invalid',
89 commandName,
90 JSON.stringify(validate.errors, null, 2)
91 );
92 }
93
f7f98c68 94 public abstract incomingRequestHandler(
08f130a0 95 chargingStation: ChargingStation,
e7aeea18
JB
96 messageId: string,
97 commandName: IncomingRequestCommand,
5cc4b63b 98 commandPayload: JsonType
e7aeea18 99 ): Promise<void>;
c0560973 100}