refactor(simulator): switch utils to internal module export/import
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 2.0 / OCPP20IncomingRequestService.ts
CommitLineData
edd13439 1// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
953d6b02
JB
2
3import type { JSONSchemaType } from 'ajv';
4
2896e06d 5import type { ChargingStation } from '../../../charging-station';
268a74bb 6import { OCPPError } from '../../../exception';
d270cc87 7import {
268a74bb
JB
8 ErrorType,
9 type IncomingRequestHandler,
10 type JsonObject,
11 type JsonType,
81533a20 12 type OCPP20ClearCacheRequest,
d270cc87 13 OCPP20IncomingRequestCommand,
268a74bb
JB
14 OCPPVersion,
15} from '../../../types';
60a74391 16import { logger } from '../../../utils';
2896e06d 17import { OCPP20ServiceUtils, OCPPIncomingRequestService } from '../internal';
953d6b02
JB
18
19const moduleName = 'OCPP20IncomingRequestService';
20
268a74bb 21export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
b3fc3ff5 22 protected jsonSchemas: Map<OCPP20IncomingRequestCommand, JSONSchemaType<JsonObject>>;
953d6b02 23 private incomingRequestHandlers: Map<OCPP20IncomingRequestCommand, IncomingRequestHandler>;
953d6b02
JB
24
25 public constructor() {
26 if (new.target?.name === moduleName) {
27 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
28 }
d270cc87
JB
29 super(OCPPVersion.VERSION_20);
30 this.incomingRequestHandlers = new Map<OCPP20IncomingRequestCommand, IncomingRequestHandler>([
31 [OCPP20IncomingRequestCommand.CLEAR_CACHE, this.handleRequestClearCache.bind(this)],
32 ]);
33 this.jsonSchemas = new Map<OCPP20IncomingRequestCommand, JSONSchemaType<JsonObject>>([
34 [
35 OCPP20IncomingRequestCommand.CLEAR_CACHE,
130783a7 36 OCPP20ServiceUtils.parseJsonSchemaFile<OCPP20ClearCacheRequest>(
1b271a54
JB
37 '../../../assets/json-schemas/ocpp/2.0/ClearCacheRequest.json',
38 moduleName,
39 'constructor'
e9a4164c 40 ),
d270cc87
JB
41 ],
42 ]);
953d6b02
JB
43 this.validatePayload.bind(this);
44 }
45
46 public async incomingRequestHandler(
47 chargingStation: ChargingStation,
48 messageId: string,
49 commandName: OCPP20IncomingRequestCommand,
50 commandPayload: JsonType
51 ): Promise<void> {
52 let response: JsonType;
53 if (
54 chargingStation.getOcppStrictCompliance() === true &&
81533a20
JB
55 chargingStation.isInPendingState() === true &&
56 (commandName === OCPP20IncomingRequestCommand.REQUEST_START_TRANSACTION ||
57 commandName === OCPP20IncomingRequestCommand.REQUEST_STOP_TRANSACTION)
953d6b02
JB
58 ) {
59 throw new OCPPError(
60 ErrorType.SECURITY_ERROR,
61 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
62 commandPayload,
63 null,
64 2
65 )} while the charging station is in pending state on the central server`,
66 commandName,
67 commandPayload
68 );
69 }
70 if (
71 chargingStation.isRegistered() === true ||
72 (chargingStation.getOcppStrictCompliance() === false &&
73 chargingStation.isInUnknownState() === true)
74 ) {
75 if (
76 this.incomingRequestHandlers.has(commandName) === true &&
77 OCPP20ServiceUtils.isIncomingRequestCommandSupported(chargingStation, commandName) === true
78 ) {
79 try {
80 this.validatePayload(chargingStation, commandName, commandPayload);
81 // Call the method to build the response
82 response = await this.incomingRequestHandlers.get(commandName)(
83 chargingStation,
84 commandPayload
85 );
86 } catch (error) {
87 // Log
88 logger.error(
89 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
90 error
91 );
92 throw error;
93 }
94 } else {
95 // Throw exception
96 throw new OCPPError(
97 ErrorType.NOT_IMPLEMENTED,
98 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
99 commandPayload,
100 null,
101 2
102 )}`,
103 commandName,
104 commandPayload
105 );
106 }
107 } else {
108 throw new OCPPError(
109 ErrorType.SECURITY_ERROR,
110 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
111 commandPayload,
112 null,
113 2
114 )} while the charging station is not registered on the central server.`,
115 commandName,
116 commandPayload
117 );
118 }
119 // Send the built response
120 await chargingStation.ocppRequestService.sendResponse(
121 chargingStation,
122 messageId,
123 response,
124 commandName
125 );
126 }
127
128 private validatePayload(
129 chargingStation: ChargingStation,
130 commandName: OCPP20IncomingRequestCommand,
131 commandPayload: JsonType
132 ): boolean {
45988780 133 if (this.jsonSchemas.has(commandName) === true) {
953d6b02
JB
134 return this.validateIncomingRequestPayload(
135 chargingStation,
136 commandName,
137 this.jsonSchemas.get(commandName),
138 commandPayload
139 );
140 }
141 logger.warn(
b3fc3ff5 142 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
953d6b02
JB
143 );
144 return false;
145 }
146}