@zetra/citrineos-util 1.8.3-fork.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/authorization/ApiAuthPlugin.d.ts +52 -0
  2. package/dist/authorization/ApiAuthPlugin.js +122 -0
  3. package/dist/authorization/ApiAuthPlugin.js.map +1 -0
  4. package/dist/authorization/OidcTokenProvider.d.ts +15 -0
  5. package/dist/authorization/OidcTokenProvider.js +47 -0
  6. package/dist/authorization/OidcTokenProvider.js.map +1 -0
  7. package/dist/authorization/index.d.ts +4 -0
  8. package/dist/authorization/index.js +8 -0
  9. package/dist/authorization/index.js.map +1 -0
  10. package/dist/authorization/provider/LocalByPassAuthProvider.d.ts +34 -0
  11. package/dist/authorization/provider/LocalByPassAuthProvider.js +62 -0
  12. package/dist/authorization/provider/LocalByPassAuthProvider.js.map +1 -0
  13. package/dist/authorization/provider/OIDCAuthProvider.d.ts +62 -0
  14. package/dist/authorization/provider/OIDCAuthProvider.js +173 -0
  15. package/dist/authorization/provider/OIDCAuthProvider.js.map +1 -0
  16. package/dist/authorization/rbac/RbacRulesLoader.d.ts +32 -0
  17. package/dist/authorization/rbac/RbacRulesLoader.js +105 -0
  18. package/dist/authorization/rbac/RbacRulesLoader.js.map +1 -0
  19. package/dist/authorization/rbac/UrlMatcher.d.ts +14 -0
  20. package/dist/authorization/rbac/UrlMatcher.js +44 -0
  21. package/dist/authorization/rbac/UrlMatcher.js.map +1 -0
  22. package/dist/authorizer/RealTimeAuthorizer.d.ts +28 -0
  23. package/dist/authorizer/RealTimeAuthorizer.js +152 -0
  24. package/dist/authorizer/RealTimeAuthorizer.js.map +1 -0
  25. package/dist/authorizer/index.d.ts +1 -0
  26. package/dist/authorizer/index.js +5 -0
  27. package/dist/authorizer/index.js.map +1 -0
  28. package/dist/cache/memory.d.ts +19 -0
  29. package/dist/cache/memory.js +147 -0
  30. package/dist/cache/memory.js.map +1 -0
  31. package/dist/cache/redis.d.ts +16 -0
  32. package/dist/cache/redis.js +120 -0
  33. package/dist/cache/redis.js.map +1 -0
  34. package/dist/certificate/CertificateAuthority.d.ts +38 -0
  35. package/dist/certificate/CertificateAuthority.js +233 -0
  36. package/dist/certificate/CertificateAuthority.js.map +1 -0
  37. package/dist/certificate/CertificateUtil.d.ts +60 -0
  38. package/dist/certificate/CertificateUtil.js +317 -0
  39. package/dist/certificate/CertificateUtil.js.map +1 -0
  40. package/dist/certificate/client/acme.d.ts +37 -0
  41. package/dist/certificate/client/acme.js +138 -0
  42. package/dist/certificate/client/acme.js.map +1 -0
  43. package/dist/certificate/client/hubject.d.ts +41 -0
  44. package/dist/certificate/client/hubject.js +221 -0
  45. package/dist/certificate/client/hubject.js.map +1 -0
  46. package/dist/certificate/client/interface.d.ts +12 -0
  47. package/dist/certificate/client/interface.js +5 -0
  48. package/dist/certificate/client/interface.js.map +1 -0
  49. package/dist/certificate/index.d.ts +2 -0
  50. package/dist/certificate/index.js +6 -0
  51. package/dist/certificate/index.js.map +1 -0
  52. package/dist/files/ftpServer.d.ts +4 -0
  53. package/dist/files/ftpServer.js +9 -0
  54. package/dist/files/ftpServer.js.map +1 -0
  55. package/dist/files/gcpCloudStorage.d.ts +39 -0
  56. package/dist/files/gcpCloudStorage.js +130 -0
  57. package/dist/files/gcpCloudStorage.js.map +1 -0
  58. package/dist/files/localStorage.d.ts +14 -0
  59. package/dist/files/localStorage.js +57 -0
  60. package/dist/files/localStorage.js.map +1 -0
  61. package/dist/files/s3Storage.d.ts +17 -0
  62. package/dist/files/s3Storage.js +118 -0
  63. package/dist/files/s3Storage.js.map +1 -0
  64. package/dist/index.d.ts +21 -0
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/networkconnection/WebsocketNetworkConnection.d.ts +135 -0
  68. package/dist/networkconnection/WebsocketNetworkConnection.js +474 -0
  69. package/dist/networkconnection/WebsocketNetworkConnection.js.map +1 -0
  70. package/dist/networkconnection/authenticator/Authenticator.d.ts +20 -0
  71. package/dist/networkconnection/authenticator/Authenticator.js +39 -0
  72. package/dist/networkconnection/authenticator/Authenticator.js.map +1 -0
  73. package/dist/networkconnection/authenticator/AuthenticatorFilter.d.ts +11 -0
  74. package/dist/networkconnection/authenticator/AuthenticatorFilter.js +30 -0
  75. package/dist/networkconnection/authenticator/AuthenticatorFilter.js.map +1 -0
  76. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.d.ts +17 -0
  77. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js +51 -0
  78. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js.map +1 -0
  79. package/dist/networkconnection/authenticator/ConnectedStationFilter.d.ts +14 -0
  80. package/dist/networkconnection/authenticator/ConnectedStationFilter.js +25 -0
  81. package/dist/networkconnection/authenticator/ConnectedStationFilter.js.map +1 -0
  82. package/dist/networkconnection/authenticator/NetworkProfileFilter.d.ts +16 -0
  83. package/dist/networkconnection/authenticator/NetworkProfileFilter.js +84 -0
  84. package/dist/networkconnection/authenticator/NetworkProfileFilter.js.map +1 -0
  85. package/dist/networkconnection/authenticator/UnknownStationFilter.d.ts +16 -0
  86. package/dist/networkconnection/authenticator/UnknownStationFilter.js +25 -0
  87. package/dist/networkconnection/authenticator/UnknownStationFilter.js.map +1 -0
  88. package/dist/networkconnection/authenticator/errors/AuthenticationError.d.ts +6 -0
  89. package/dist/networkconnection/authenticator/errors/AuthenticationError.js +25 -0
  90. package/dist/networkconnection/authenticator/errors/AuthenticationError.js.map +1 -0
  91. package/dist/networkconnection/authenticator/errors/IUpgradeError.d.ts +9 -0
  92. package/dist/networkconnection/authenticator/errors/IUpgradeError.js +5 -0
  93. package/dist/networkconnection/authenticator/errors/IUpgradeError.js.map +1 -0
  94. package/dist/networkconnection/authenticator/errors/UnknownError.d.ts +6 -0
  95. package/dist/networkconnection/authenticator/errors/UnknownError.js +24 -0
  96. package/dist/networkconnection/authenticator/errors/UnknownError.js.map +1 -0
  97. package/dist/networkconnection/index.d.ts +5 -0
  98. package/dist/networkconnection/index.js +9 -0
  99. package/dist/networkconnection/index.js.map +1 -0
  100. package/dist/queue/index.d.ts +4 -0
  101. package/dist/queue/index.js +8 -0
  102. package/dist/queue/index.js.map +1 -0
  103. package/dist/queue/kafka/receiver.d.ts +35 -0
  104. package/dist/queue/kafka/receiver.js +179 -0
  105. package/dist/queue/kafka/receiver.js.map +1 -0
  106. package/dist/queue/kafka/sender.d.ts +53 -0
  107. package/dist/queue/kafka/sender.js +189 -0
  108. package/dist/queue/kafka/sender.js.map +1 -0
  109. package/dist/queue/rabbit-mq/receiver.d.ts +89 -0
  110. package/dist/queue/rabbit-mq/receiver.js +472 -0
  111. package/dist/queue/rabbit-mq/receiver.js.map +1 -0
  112. package/dist/queue/rabbit-mq/sender.d.ts +90 -0
  113. package/dist/queue/rabbit-mq/sender.js +251 -0
  114. package/dist/queue/rabbit-mq/sender.js.map +1 -0
  115. package/dist/security/SignedMeterValuesUtil.d.ts +44 -0
  116. package/dist/security/SignedMeterValuesUtil.js +135 -0
  117. package/dist/security/SignedMeterValuesUtil.js.map +1 -0
  118. package/dist/security/authentication.d.ts +2 -0
  119. package/dist/security/authentication.js +26 -0
  120. package/dist/security/authentication.js.map +1 -0
  121. package/dist/util/RequestOperations.d.ts +14 -0
  122. package/dist/util/RequestOperations.js +25 -0
  123. package/dist/util/RequestOperations.js.map +1 -0
  124. package/dist/util/StringOperations.d.ts +1 -0
  125. package/dist/util/StringOperations.js +8 -0
  126. package/dist/util/StringOperations.js.map +1 -0
  127. package/dist/util/emaidCheckDigitCalculator.d.ts +15 -0
  128. package/dist/util/emaidCheckDigitCalculator.js +179 -0
  129. package/dist/util/emaidCheckDigitCalculator.js.map +1 -0
  130. package/dist/util/idGenerator.d.ts +7 -0
  131. package/dist/util/idGenerator.js +10 -0
  132. package/dist/util/idGenerator.js.map +1 -0
  133. package/dist/util/parser.d.ts +31 -0
  134. package/dist/util/parser.js +60 -0
  135. package/dist/util/parser.js.map +1 -0
  136. package/dist/util/swagger.d.ts +5 -0
  137. package/dist/util/swagger.js +154 -0
  138. package/dist/util/swagger.js.map +1 -0
  139. package/dist/util/validator.d.ts +110 -0
  140. package/dist/util/validator.js +534 -0
  141. package/dist/util/validator.js.map +1 -0
  142. package/package.json +46 -0
@@ -0,0 +1,53 @@
1
+ import type { IMessage, IMessageConfirmation, IMessageSender, OcppRequest, OcppResponse, SystemConfig } from '@citrineos/base';
2
+ import { AbstractMessageSender, CircuitBreaker, MessageState, OcppError } from '@citrineos/base';
3
+ import type { ILogObj } from 'tslog';
4
+ import { Logger } from 'tslog';
5
+ /**
6
+ * Implementation of a {@link IMessageSender} using Kafka as the underlying transport.
7
+ */
8
+ export declare class KafkaSender extends AbstractMessageSender implements IMessageSender {
9
+ /**
10
+ * Fields
11
+ */
12
+ private _client;
13
+ private _topicName;
14
+ private _producers;
15
+ private _circuitBreaker;
16
+ private _reconnectInterval?;
17
+ /**
18
+ * Constructor
19
+ *
20
+ * @param topicPrefix Custom topic prefix, defaults to "ocpp"
21
+ */
22
+ constructor(config: SystemConfig, logger?: Logger<ILogObj>, circuitBreaker?: CircuitBreaker);
23
+ private _initAdmin;
24
+ /**
25
+ * Convenience method to send a request message.
26
+ *
27
+ * @param message The {@link IMessage} to send
28
+ * @param payload The payload to send
29
+ * @returns
30
+ */
31
+ sendRequest(message: IMessage<OcppRequest>, payload?: OcppRequest): Promise<IMessageConfirmation>;
32
+ /**
33
+ * Convenience method to send a confirmation message.
34
+ * @param message The {@link IMessage} to send
35
+ * @param payload The payload to send
36
+ * @returns
37
+ */
38
+ sendResponse(message: IMessage<OcppResponse | OcppError>, payload?: OcppResponse | OcppError): Promise<IMessageConfirmation>;
39
+ /**
40
+ * Publishes the given message to kafka.
41
+ *
42
+ * @param message The {@link IMessage} to publish
43
+ * @param payload The payload to within the {@link IMessage}
44
+ * @param state The {@link MessageState} of the {@link IMessage}
45
+ * @returns
46
+ */
47
+ send(message: IMessage<OcppRequest | OcppResponse | OcppError>, payload?: OcppRequest | OcppResponse | OcppError, state?: MessageState): Promise<IMessageConfirmation>;
48
+ /**
49
+ * Interface implementation
50
+ */
51
+ shutdown(): Promise<void>;
52
+ private _onCircuitBreakerStateChange;
53
+ }
@@ -0,0 +1,189 @@
1
+ import { AbstractMessageSender, CircuitBreaker, MessageState, OcppError } from '@citrineos/base';
2
+ import { Kafka } from 'kafkajs';
3
+ import { Logger } from 'tslog';
4
+ /**
5
+ * Implementation of a {@link IMessageSender} using Kafka as the underlying transport.
6
+ */
7
+ export class KafkaSender extends AbstractMessageSender {
8
+ /**
9
+ * Fields
10
+ */
11
+ _client;
12
+ _topicName;
13
+ _producers;
14
+ _circuitBreaker;
15
+ _reconnectInterval;
16
+ /**
17
+ * Constructor
18
+ *
19
+ * @param topicPrefix Custom topic prefix, defaults to "ocpp"
20
+ */
21
+ constructor(config, logger, circuitBreaker) {
22
+ super(config, logger);
23
+ this._circuitBreaker = circuitBreaker ?? new CircuitBreaker();
24
+ this._circuitBreaker.onStateChange(this._onCircuitBreakerStateChange.bind(this));
25
+ this._client = new Kafka({
26
+ brokers: config.util.messageBroker.kafka?.brokers || [],
27
+ ssl: true,
28
+ sasl: {
29
+ mechanism: 'plain',
30
+ username: config.util.messageBroker.kafka?.sasl.username || '',
31
+ password: config.util.messageBroker.kafka?.sasl.password || '',
32
+ },
33
+ });
34
+ this._producers = new Array();
35
+ this._topicName = `${this._config.util.messageBroker.kafka?.topicPrefix}-${this._config.util.messageBroker.kafka?.topicName}`;
36
+ this._initAdmin();
37
+ }
38
+ _initAdmin() {
39
+ const admin = this._client.admin();
40
+ admin
41
+ .connect()
42
+ .then(() => admin.listTopics())
43
+ .then((topics) => {
44
+ if (!topics || topics.filter((topic) => topic === this._topicName).length === 0) {
45
+ this._client
46
+ .admin()
47
+ .createTopics({ topics: [{ topic: this._topicName }] })
48
+ .then(() => {
49
+ this._logger.debug(`Topic ${this._topicName} created.`);
50
+ this._circuitBreaker.triggerSuccess();
51
+ })
52
+ .catch((error) => {
53
+ this._logger.error('Failed to create topic', error);
54
+ this._circuitBreaker.triggerFailure(error?.message);
55
+ });
56
+ }
57
+ else {
58
+ this._circuitBreaker.triggerSuccess();
59
+ }
60
+ })
61
+ .then(() => admin.disconnect())
62
+ .catch((error) => {
63
+ this._logger.error('Failed to connect to Kafka', error);
64
+ this._circuitBreaker.triggerFailure(error?.message);
65
+ });
66
+ }
67
+ /**
68
+ * Convenience method to send a request message.
69
+ *
70
+ * @param message The {@link IMessage} to send
71
+ * @param payload The payload to send
72
+ * @returns
73
+ */
74
+ sendRequest(message, payload) {
75
+ return this.send(message, payload, MessageState.Request);
76
+ }
77
+ /**
78
+ * Convenience method to send a confirmation message.
79
+ * @param message The {@link IMessage} to send
80
+ * @param payload The payload to send
81
+ * @returns
82
+ */
83
+ sendResponse(message, payload) {
84
+ return this.send(message, payload, MessageState.Response);
85
+ }
86
+ /**
87
+ * Publishes the given message to kafka.
88
+ *
89
+ * @param message The {@link IMessage} to publish
90
+ * @param payload The payload to within the {@link IMessage}
91
+ * @param state The {@link MessageState} of the {@link IMessage}
92
+ * @returns
93
+ */
94
+ send(message, payload, state) {
95
+ if (this._circuitBreaker.state === 'CLOSED') {
96
+ return Promise.resolve({
97
+ success: false,
98
+ payload: 'Circuit breaker is CLOSED. Cannot send message.',
99
+ });
100
+ }
101
+ if (payload) {
102
+ message.payload = payload;
103
+ }
104
+ if (state) {
105
+ message.state = state;
106
+ }
107
+ if (!message.state) {
108
+ throw new Error('Message state must be set');
109
+ }
110
+ if (!message.payload) {
111
+ throw new Error('Message payload must be set');
112
+ }
113
+ this._logger.debug(`Publishing to ${this._topicName}:`, message);
114
+ const producer = this._client.producer();
115
+ return producer
116
+ .connect()
117
+ .then(() => producer.send({
118
+ topic: this._topicName,
119
+ messages: [
120
+ {
121
+ headers: {
122
+ origin: message.origin.toString(),
123
+ eventGroup: message.eventGroup.toString(),
124
+ action: message.action.toString(),
125
+ state: message.state.toString(),
126
+ ...message.context,
127
+ tenantId: message.context.tenantId.toString(),
128
+ },
129
+ value: JSON.stringify(message),
130
+ },
131
+ ],
132
+ }))
133
+ .then(() => this._producers.push(producer))
134
+ .then((result) => ({ success: true, result }))
135
+ .catch((error) => {
136
+ this._circuitBreaker.triggerFailure(error?.message);
137
+ return { success: false, error };
138
+ });
139
+ }
140
+ /**
141
+ * Interface implementation
142
+ */
143
+ async shutdown() {
144
+ for (const producer of this._producers) {
145
+ await producer.disconnect();
146
+ }
147
+ }
148
+ _onCircuitBreakerStateChange(state, reason) {
149
+ this._logger.info(`[CircuitBreaker] State changed to ${state}${reason ? `: ${reason}` : ''}`);
150
+ switch (state) {
151
+ case 'FAILING':
152
+ this._logger.warn('Circuit breaker is FAILING. Kafka sender will not send messages until recovery. Reason:', reason);
153
+ break;
154
+ case 'CLOSED': {
155
+ this._logger.error('Circuit breaker is CLOSED. Shutting down Kafka sender. Reason:', reason);
156
+ void this.shutdown();
157
+ if (this._reconnectInterval) {
158
+ clearInterval(this._reconnectInterval);
159
+ }
160
+ const delay = (this._config.maxReconnectDelay || 30) * 1000;
161
+ this._logger.warn(`Starting continuous reconnect attempts every ${delay / 1000} seconds while circuit breaker is CLOSED.`);
162
+ this._reconnectInterval = setInterval(() => {
163
+ this._logger.info('Attempting Kafka reconnect due to circuit breaker CLOSED...');
164
+ try {
165
+ this._initAdmin();
166
+ this._logger.info('Kafka reconnect attempt finished (success or already open).');
167
+ }
168
+ catch (err) {
169
+ this._logger.error('Kafka reconnect attempt failed.', err);
170
+ }
171
+ }, delay);
172
+ break;
173
+ }
174
+ case 'OPEN':
175
+ this._logger.info('Circuit breaker is OPEN. Will attempt to (re)initialize Kafka admin connection.');
176
+ if (this._reconnectInterval) {
177
+ this._logger.info('Clearing reconnect interval as circuit breaker is now OPEN.');
178
+ clearInterval(this._reconnectInterval);
179
+ this._reconnectInterval = undefined;
180
+ }
181
+ this._initAdmin();
182
+ break;
183
+ default:
184
+ this._logger.warn('Unknown circuit breaker state:', state);
185
+ break;
186
+ }
187
+ }
188
+ }
189
+ //# sourceMappingURL=sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../src/queue/kafka/sender.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import type { CallAction, ICache, IModule, SystemConfig } from '@citrineos/base';
2
+ import { AbstractMessageHandler, CircuitBreaker } from '@citrineos/base';
3
+ import * as amqplib from 'amqplib';
4
+ import type { ILogObj } from 'tslog';
5
+ import { Logger } from 'tslog';
6
+ /**
7
+ * Implementation of a {@link IMessageHandler} using RabbitMQ as the underlying transport.
8
+ */
9
+ export declare class RabbitMqReceiver extends AbstractMessageHandler {
10
+ /**
11
+ * Constants
12
+ */
13
+ private static readonly QUEUE_PREFIX;
14
+ private static readonly CACHE_PREFIX;
15
+ private static readonly METADATA_PREFIX;
16
+ private static readonly REGISTRY_KEY;
17
+ private static readonly RECONNECT_DELAY;
18
+ /**
19
+ * Fields
20
+ */
21
+ protected _cache: ICache;
22
+ protected _connection?: amqplib.Connection;
23
+ protected _channel?: amqplib.Channel;
24
+ private _abortReconnectController?;
25
+ private _circuitBreaker;
26
+ private _reconnectInterval?;
27
+ constructor(config: SystemConfig, logger?: Logger<ILogObj>, module?: IModule, cache?: ICache, circuitBreaker?: CircuitBreaker);
28
+ initConnection(): Promise<any>;
29
+ /**
30
+ * Methods
31
+ */
32
+ /**
33
+ * Binds queue to an exchange given identifier and optional actions and filter.
34
+ * Note: Due to the nature of AMQP 0-9-1 model, if you need to filter for the identifier, you **MUST** provide it in the filter object.
35
+ *
36
+ * @param {string} identifier - The identifier of the channel to subscribe to.
37
+ * @param {CallAction[]} actions - Optional. An array of actions to filter the messages.
38
+ * @param {{ [k: string]: string; }} filter - Optional. An object representing the filter to apply on the messages.
39
+ * @return {Promise<boolean>} A promise that resolves to true if the subscription is successful, false otherwise.
40
+ */
41
+ subscribe(identifier: string, actions?: CallAction[], filter?: {
42
+ [k: string]: string;
43
+ }): Promise<boolean>;
44
+ unsubscribe(identifier: string): Promise<boolean>;
45
+ shutdown(): Promise<void>;
46
+ /**
47
+ * Protected Methods
48
+ */
49
+ /**
50
+ * Connect to RabbitMQ with retry logic.
51
+ * This method will keep trying to connect until successful, unless aborted.
52
+ *
53
+ * @param {AbortSignal} [abortSignal] - Optional abort signal to stop retrying.
54
+ * @return {Promise<amqplib.Channel>} A promise that resolves to the AMQP channel.
55
+ */
56
+ protected _connectWithRetry(abortSignal?: AbortSignal): Promise<amqplib.Channel>;
57
+ private _startReconnectInterval;
58
+ private _onCircuitBreakerStateChange;
59
+ /**
60
+ * Setup listeners for connection and channel events.
61
+ * This will handle disconnections and errors.
62
+ * Ensures listeners are not attached multiple times to the same connection.
63
+ */
64
+ private _setupConnectionListeners;
65
+ /**
66
+ * Handle RabbitMQ disconnection.
67
+ * This method will attempt to reconnect to RabbitMQ when the connection is lost.
68
+ * Debounces concurrent reconnects.
69
+ */
70
+ private _handleDisconnect;
71
+ /**
72
+ * Re-subscribe to all cached subscriptions after reconnection.
73
+ * This ensures queues are recreated with the same bindings.
74
+ * Uses cache to retrieve subscription metadata.
75
+ */
76
+ private _resubscribeAll;
77
+ /**
78
+ * Internal method to re-subscribe without the channel check.
79
+ * Used during reconnection to recreate queues.
80
+ */
81
+ private _resubscribe;
82
+ /**
83
+ * Underlying RabbitMQ message handler.
84
+ *
85
+ * @param message The AMQPMessage to process
86
+ * @param channel
87
+ */
88
+ protected _onMessage(message: amqplib.ConsumeMessage | null, channel: amqplib.Channel): Promise<void>;
89
+ }