@ti-engine/core 1.7.1 → 1.8.0

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 (33) hide show
  1. package/CHANGELOG.md +393 -377
  2. package/LICENSE.md +321 -321
  3. package/README.md +599 -597
  4. package/bin/localization/labels.json +122 -122
  5. package/bin/settings.json +41 -41
  6. package/bin/start-instance.js +164 -164
  7. package/components/auditing.js +191 -191
  8. package/components/connection-observer.js +72 -72
  9. package/components/definitions.types.js +248 -248
  10. package/components/exchange/default/default-message-exchange.js +136 -136
  11. package/components/exchange/default/default-message-receiver.js +101 -101
  12. package/components/exchange/default/default-message-sender.js +100 -100
  13. package/components/exchange/message-dispatcher.js +168 -168
  14. package/components/exchange/message-exchange.js +449 -449
  15. package/components/exchange/message-handler.js +235 -235
  16. package/components/exchange/message-memory-cache.js +190 -190
  17. package/components/exchange/message-observer.js +126 -126
  18. package/components/exchange/message-receiver.js +181 -181
  19. package/components/exchange/message-sender.js +143 -143
  20. package/components/exchange/message-tracer.js +212 -212
  21. package/components/service-caller.js +370 -370
  22. package/components/service-consumer.js +131 -131
  23. package/components/service-executor.js +278 -278
  24. package/components/service-instance.js +316 -316
  25. package/components/service-provider.js +251 -251
  26. package/integrations/redis-integration.js +591 -591
  27. package/package.json +89 -89
  28. package/utils/cache.js +772 -772
  29. package/utils/config.js +103 -103
  30. package/utils/exceptions.js +368 -368
  31. package/utils/localization.js +298 -298
  32. package/utils/logger.js +82 -82
  33. package/utils/tools.js +632 -632
@@ -1,450 +1,450 @@
1
- /*
2
- * The ti-engine is an open source, free to use—both for personal and commercial projects—framework for the creation of microservice-based solutions using node.js.
3
- * Copyright © 2021-2026 Boris Kostadinov <kostadinov.boris@gmail.com>
4
- * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6
- * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
7
- */
8
-
9
- const MessageObserver = require( "#message-observer" );
10
- const _ = require( "lodash" );
11
- const exceptions = require( "#exceptions" );
12
- const messageTracer = require( "#message-tracer" );
13
-
14
- /**
15
- * An abstract class that defines a message exchange behavior.
16
- * <br/>
17
- * NOTE: While this sets the basis frame for the message-based communication between microservices, it has to be inherited and
18
- * extended with additional logic that is NOT implemented here. For a working example please see {@link DefaultMessageExchange} class.
19
- * <br/>
20
- * NOTE: This class and its children are designed to be used internally by the {@link MessageDispatcher} and its related classes.
21
- *
22
- * @class MessageExchange
23
- * @extends MessageObserver
24
- * @abstract
25
- * @public
26
- */
27
- class MessageExchange extends MessageObserver {
28
-
29
- static #connectionNameRequestsOut = "connection-msg-requests-out";
30
- static #connectionNameRequestsIn = "connection-msg-requests-in";
31
- static #connectionNameResponsesOut = "connection-msg-responses-out";
32
- static #connectionNameResponsesIn = "connection-msg-responses-in";
33
- #instanceID;
34
- #serviceDomainName;
35
- #disruptedConnections;
36
- #configuredOutbound = false;
37
- #configuredInbound = false;
38
- /** @type MessageSender */
39
- #messageRequestsOut;
40
- /** @type MessageSender */
41
- #messageResponsesOut;
42
- /** @type MessageReceiver */
43
- #messageRequestsIn;
44
- /** @type MessageReceiver */
45
- #messageResponsesIn;
46
-
47
- /**
48
- * @constructor
49
- * @param {string} instanceID The unique identifier of the microservice instance using the message exchange.
50
- * @param {string} serviceDomainName The domain name of the microservice using the message exchange.
51
- * @throws {TiException.E_GEN_ABSTRACT_CLASS_INIT} If this class is instantiated directly.
52
- */
53
- constructor( instanceID, serviceDomainName ) {
54
- super( 9 );
55
-
56
- // make sure this abstract class cannot be instantiated:
57
- if ( new.target === MessageExchange ) {
58
- throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
59
- }
60
-
61
- this.#instanceID = instanceID;
62
- this.#serviceDomainName = serviceDomainName;
63
- this.#disruptedConnections = [];
64
- }
65
-
66
- /* Public interface */
67
-
68
- /**
69
- * Property returning the configured connection name for the outgoing message requests.
70
- *
71
- * @property
72
- * @returns {string}
73
- * @public
74
- */
75
- static get connectionNameRequestsOut() {
76
- return this.#connectionNameRequestsOut;
77
- }
78
-
79
- /**
80
- * Used to set the connection name for the outgoing message requests.
81
- *
82
- * @property
83
- * @param {string} value
84
- * @public
85
- */
86
- static set connectionNameRequestsOut( value ) {
87
- this.#connectionNameRequestsOut = value;
88
- }
89
-
90
- /**
91
- * Property returning the configured connection name for the incoming message requests.
92
- *
93
- * @property
94
- * @returns {string}
95
- * @public
96
- */
97
- static get connectionNameRequestsIn() {
98
- return this.#connectionNameRequestsIn;
99
- }
100
-
101
- /**
102
- * Used to set the connection name for the incoming message requests.
103
- *
104
- * @property
105
- * @param {string} value
106
- * @public
107
- */
108
- static set connectionNameRequestsIn( value ) {
109
- this.#connectionNameRequestsIn = value;
110
- }
111
-
112
- /**
113
- * Property returning the configured connection name for the outgoing message responses.
114
- *
115
- * @property
116
- * @returns {string}
117
- * @public
118
- */
119
- static get connectionNameResponsesOut() {
120
- return this.#connectionNameResponsesOut;
121
- }
122
-
123
- /**
124
- * Used to set the connection name for the outgoing message responses.
125
- *
126
- * @property
127
- * @param {string} value
128
- * @public
129
- */
130
- static set connectionNameResponsesOut( value ) {
131
- this.#connectionNameResponsesOut = value;
132
- }
133
-
134
- /**
135
- * Property returning the configured connection name for the incoming message responses.
136
- *
137
- * @property
138
- * @returns {string}
139
- * @public
140
- */
141
- static get connectionNameResponsesIn() {
142
- return this.#connectionNameResponsesIn;
143
- }
144
-
145
- /**
146
- * Used to set the connection name for the incoming message responses.
147
- *
148
- * @property
149
- * @param {string} value
150
- * @public
151
- */
152
- static set connectionNameResponsesIn( value ) {
153
- this.#connectionNameResponsesIn = value;
154
- }
155
-
156
- /**
157
- * Property returning the identifier of the pending messages queue.
158
- *
159
- * @property
160
- * @returns {string}
161
- * @public
162
- */
163
- static get pendingQueue() {
164
- return "pending:";
165
- }
166
-
167
- /**
168
- * Property returning the identifier of the processed messages queue.
169
- *
170
- * @property
171
- * @returns {string}
172
- * @public
173
- */
174
- static get processedQueue() {
175
- return "processed:";
176
- }
177
-
178
- /**
179
- * Property returning the configured service instance ID.
180
- *
181
- * @property
182
- * @returns {string}
183
- * @public
184
- */
185
- get instanceID() {
186
- return this.#instanceID;
187
- }
188
-
189
- /**
190
- * Property returning the configured service domain name.
191
- *
192
- * @property
193
- * @returns {string}
194
- * @public
195
- */
196
- get serviceDomainName() {
197
- return this.#serviceDomainName;
198
- }
199
-
200
- /**
201
- * Returns the currently configured {@link MessageSender} for outbound message requests.
202
- *
203
- * @property
204
- * @returns {MessageSender}
205
- * @public
206
- */
207
- get messageRequestsOut() {
208
- return this.#messageRequestsOut;
209
- }
210
-
211
- /**
212
- * Returns the currently configured {@link MessageSender} for outbound message responses.
213
- *
214
- * @property
215
- * @returns {MessageSender}
216
- * @public
217
- */
218
- get messageResponsesOut() {
219
- return this.#messageResponsesOut;
220
- }
221
-
222
- /**
223
- * Returns the currently configured {@link MessageReceiver} for inbound message requests.
224
- *
225
- * @property
226
- * @returns {MessageReceiver}
227
- * @public
228
- */
229
- get messageRequestsIn() {
230
- return this.#messageRequestsIn;
231
- }
232
-
233
- /**
234
- * Returns the currently configured {@link MessageReceiver} for inbound message responses.
235
- *
236
- * @property
237
- * @returns {MessageReceiver}
238
- * @public
239
- */
240
- get messageResponsesIn() {
241
- return this.#messageResponsesIn;
242
- }
243
-
244
- /**
245
- * Returns a flag indicating if the message exchange is configured for outbound communication.
246
- *
247
- * @property
248
- * @returns {boolean}
249
- * @public
250
- */
251
- get configuredOutbound() {
252
- return this.#configuredOutbound;
253
- }
254
-
255
- /**
256
- * Returns a flag indicating if the message exchange is configured for inbound communication.
257
- *
258
- * @property
259
- * @returns {boolean}
260
- * @public
261
- */
262
- get configuredInbound() {
263
- return this.#configuredInbound;
264
- }
265
-
266
- /**
267
- * Should be used to enable all communication channels for messaging.
268
- * <br/>
269
- * NOTE: Override this to implement messaging initialization.
270
- *
271
- * @method
272
- * @param {boolean} configureInbound If set to 'true' it tells the message exchange to set up inbound messaging.
273
- * @param {boolean} configureOutbound If set to 'true' it tells the message exchange to set up outbound messaging.
274
- * @returns {Promise}
275
- * @abstract
276
- * @public
277
- */
278
- enableMessaging( configureInbound, configureOutbound ) {
279
- return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.enableMessaging.name } ) );
280
- }
281
-
282
- /**
283
- * Should be used to gracefully disable all communication channels for messaging.
284
- * <br/>
285
- * NOTE: Override this to implement graceful messaging shut down.
286
- *
287
- * @method
288
- * @returns {Promise}
289
- * @abstract
290
- * @public
291
- */
292
- disableMessaging() {
293
- return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.disableMessaging.name } ) );
294
- }
295
-
296
- /**
297
- * Used to configure the message exchange for receiving inbound messages and returning responses to them.
298
- * Should typically be called from an implemented {@link enableMessaging} method.
299
- *
300
- * @method
301
- * @param {MessageReceiver} messageReceiverRequestsIn A message receiver that will handle the inbound messages.
302
- * @param {MessageSender} messageSenderResponsesOut A message sender that will handle the sending of responses for the inbound messages.
303
- * @public
304
- */
305
- configureInboundMessaging( messageReceiverRequestsIn, messageSenderResponsesOut ) {
306
- this.#messageRequestsIn = messageReceiverRequestsIn;
307
- this.#messageResponsesOut = messageSenderResponsesOut;
308
- this.#configuredInbound = true;
309
- }
310
-
311
- /**
312
- * Used to configure message exchange for sending messages and receiving responses to them.
313
- * Should typically be called from an implemented {@link enableMessaging} method.
314
- *
315
- * @method
316
- * @param {MessageSender} messageSenderRequestsOut A message sender that will handle the outbound messages.
317
- * @param {MessageReceiver} messageReceiverResponsesIn A message receiver that will handle the returned responses for the outbound messages.
318
- * @public
319
- */
320
- configureOutboundMessaging( messageSenderRequestsOut, messageReceiverResponsesIn ) {
321
- this.#messageRequestsOut = messageSenderRequestsOut;
322
- this.#messageResponsesIn = messageReceiverResponsesIn;
323
- this.#configuredOutbound = true;
324
- }
325
-
326
- /**
327
- * Used to add an additional {@link MessageObserver} to the connection for the incoming message requests.
328
- *
329
- * @method
330
- * @param {MessageObserver} messageObserver
331
- * @public
332
- */
333
- addMessageObserverRequestsIn( messageObserver ) {
334
- this.#messageRequestsIn.addMessageObserver( messageObserver );
335
- }
336
-
337
- /**
338
- * Used to add an additional {@link MessageObserver} to the connection for the incoming message responses.
339
- *
340
- * @method
341
- * @param {MessageObserver} messageObserver
342
- * @public
343
- */
344
- addMessageObserverResponsesIn( messageObserver ) {
345
- this.#messageResponsesIn.addMessageObserver( messageObserver );
346
- }
347
-
348
- /**
349
- * Used to mark the connection with the provided identifier as disrupted.
350
- *
351
- * @method
352
- * @param {string} identifier The identifier of the observed connection.
353
- * @override
354
- * @public
355
- */
356
- onConnectionDisrupted( identifier ) {
357
- this.#disruptedConnections.push( identifier );
358
- }
359
-
360
- /**
361
- * Used to mark the connection with the provided identifier as recovered.
362
- * <br/>
363
- * NOTE: This will also result in enabling the message exchange if no connections are currently disrupted.
364
- *
365
- * @method
366
- * @param {string} identifier The identifier of the observed connection.
367
- * @override
368
- * @public
369
- */
370
- onConnectionRecovered( identifier ) {
371
- _.pull( this.#disruptedConnections, identifier );
372
- }
373
-
374
- /**
375
- * Used to mark the connection with the provided identifier as disrupted.
376
- *
377
- * @method
378
- * @param {string} identifier The identifier of the observed connection.
379
- * @override
380
- * @public
381
- */
382
- onConnectionLost( identifier ) {
383
- // TODO: implement triggering of a graceful shutdown of the service instance
384
- }
385
-
386
- /**
387
- * Used only for the message tracer.
388
- *
389
- * @method
390
- * @param {string} identifier The identifier of the observed connection.
391
- * @param {Message} message The message for processing.
392
- * @returns {Message} The message that was received.
393
- * @override
394
- * @public
395
- */
396
- onMessage( identifier, message ) {
397
- message.destination.instanceID = this.#instanceID;
398
-
399
- if ( MessageExchange.connectionNameRequestsIn === identifier ) {
400
- messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_REQUEST, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PENDING );
401
- } else if ( MessageExchange.connectionNameResponsesIn === identifier ) {
402
- messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_RESPONSE, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PROCESSED );
403
- }
404
-
405
- return message;
406
- }
407
-
408
- /**
409
- * Used to check whether the connection with the provided identifier is currently in recovery mode.
410
- *
411
- * @method
412
- * @param {string} identifier The identifier of the connection.
413
- * @returns {boolean} Will return 'true' if the connection is currently disrupted and not yet recovered.
414
- * @public
415
- */
416
- isConnectionInRecovery( identifier ) {
417
- return this.#disruptedConnections.indexOf( identifier ) !== -1;
418
- }
419
-
420
- /**
421
- * Used to send a message request. Override of this method assumes that the message itself contains enough
422
- * information to determine the sending destination.
423
- *
424
- * @method
425
- * @param {Message} message The message request to send.
426
- * @returns {Promise}
427
- * @abstract
428
- * @public
429
- */
430
- sendMessageRequest( message ) {
431
- return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageRequest.name } ) );
432
- }
433
-
434
- /**
435
- * Used to send a message response. Override of this method assumes that the message itself contains enough
436
- * information to determine the sending destination.
437
- *
438
- * @method
439
- * @param {Message} message The message response to send.
440
- * @returns {Promise}
441
- * @abstract
442
- * @public
443
- */
444
- sendMessageResponse( message ) {
445
- return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageResponse.name } ) );
446
- }
447
-
448
- }
449
-
1
+ /*
2
+ * The ti-engine is an open source, free to use—both for personal and commercial projects—framework for the creation of microservice-based solutions using node.js.
3
+ * Copyright © 2021-2026 Boris Kostadinov <kostadinov.boris@gmail.com>
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6
+ * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
7
+ */
8
+
9
+ const MessageObserver = require( "#message-observer" );
10
+ const _ = require( "lodash" );
11
+ const exceptions = require( "#exceptions" );
12
+ const messageTracer = require( "#message-tracer" );
13
+
14
+ /**
15
+ * An abstract class that defines a message exchange behavior.
16
+ * <br/>
17
+ * NOTE: While this sets the basis frame for the message-based communication between microservices, it has to be inherited and
18
+ * extended with additional logic that is NOT implemented here. For a working example please see {@link DefaultMessageExchange} class.
19
+ * <br/>
20
+ * NOTE: This class and its children are designed to be used internally by the {@link MessageDispatcher} and its related classes.
21
+ *
22
+ * @class MessageExchange
23
+ * @extends MessageObserver
24
+ * @abstract
25
+ * @public
26
+ */
27
+ class MessageExchange extends MessageObserver {
28
+
29
+ static #connectionNameRequestsOut = "connection-msg-requests-out";
30
+ static #connectionNameRequestsIn = "connection-msg-requests-in";
31
+ static #connectionNameResponsesOut = "connection-msg-responses-out";
32
+ static #connectionNameResponsesIn = "connection-msg-responses-in";
33
+ #instanceID;
34
+ #serviceDomainName;
35
+ #disruptedConnections;
36
+ #configuredOutbound = false;
37
+ #configuredInbound = false;
38
+ /** @type MessageSender */
39
+ #messageRequestsOut;
40
+ /** @type MessageSender */
41
+ #messageResponsesOut;
42
+ /** @type MessageReceiver */
43
+ #messageRequestsIn;
44
+ /** @type MessageReceiver */
45
+ #messageResponsesIn;
46
+
47
+ /**
48
+ * @constructor
49
+ * @param {string} instanceID The unique identifier of the microservice instance using the message exchange.
50
+ * @param {string} serviceDomainName The domain name of the microservice using the message exchange.
51
+ * @throws {TiException.E_GEN_ABSTRACT_CLASS_INIT} If this class is instantiated directly.
52
+ */
53
+ constructor( instanceID, serviceDomainName ) {
54
+ super( 9 );
55
+
56
+ // make sure this abstract class cannot be instantiated:
57
+ if ( new.target === MessageExchange ) {
58
+ throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
59
+ }
60
+
61
+ this.#instanceID = instanceID;
62
+ this.#serviceDomainName = serviceDomainName;
63
+ this.#disruptedConnections = [];
64
+ }
65
+
66
+ /* Public interface */
67
+
68
+ /**
69
+ * Property returning the configured connection name for the outgoing message requests.
70
+ *
71
+ * @property
72
+ * @returns {string}
73
+ * @public
74
+ */
75
+ static get connectionNameRequestsOut() {
76
+ return this.#connectionNameRequestsOut;
77
+ }
78
+
79
+ /**
80
+ * Used to set the connection name for the outgoing message requests.
81
+ *
82
+ * @property
83
+ * @param {string} value
84
+ * @public
85
+ */
86
+ static set connectionNameRequestsOut( value ) {
87
+ this.#connectionNameRequestsOut = value;
88
+ }
89
+
90
+ /**
91
+ * Property returning the configured connection name for the incoming message requests.
92
+ *
93
+ * @property
94
+ * @returns {string}
95
+ * @public
96
+ */
97
+ static get connectionNameRequestsIn() {
98
+ return this.#connectionNameRequestsIn;
99
+ }
100
+
101
+ /**
102
+ * Used to set the connection name for the incoming message requests.
103
+ *
104
+ * @property
105
+ * @param {string} value
106
+ * @public
107
+ */
108
+ static set connectionNameRequestsIn( value ) {
109
+ this.#connectionNameRequestsIn = value;
110
+ }
111
+
112
+ /**
113
+ * Property returning the configured connection name for the outgoing message responses.
114
+ *
115
+ * @property
116
+ * @returns {string}
117
+ * @public
118
+ */
119
+ static get connectionNameResponsesOut() {
120
+ return this.#connectionNameResponsesOut;
121
+ }
122
+
123
+ /**
124
+ * Used to set the connection name for the outgoing message responses.
125
+ *
126
+ * @property
127
+ * @param {string} value
128
+ * @public
129
+ */
130
+ static set connectionNameResponsesOut( value ) {
131
+ this.#connectionNameResponsesOut = value;
132
+ }
133
+
134
+ /**
135
+ * Property returning the configured connection name for the incoming message responses.
136
+ *
137
+ * @property
138
+ * @returns {string}
139
+ * @public
140
+ */
141
+ static get connectionNameResponsesIn() {
142
+ return this.#connectionNameResponsesIn;
143
+ }
144
+
145
+ /**
146
+ * Used to set the connection name for the incoming message responses.
147
+ *
148
+ * @property
149
+ * @param {string} value
150
+ * @public
151
+ */
152
+ static set connectionNameResponsesIn( value ) {
153
+ this.#connectionNameResponsesIn = value;
154
+ }
155
+
156
+ /**
157
+ * Property returning the identifier of the pending messages queue.
158
+ *
159
+ * @property
160
+ * @returns {string}
161
+ * @public
162
+ */
163
+ static get pendingQueue() {
164
+ return "pending:";
165
+ }
166
+
167
+ /**
168
+ * Property returning the identifier of the processed messages queue.
169
+ *
170
+ * @property
171
+ * @returns {string}
172
+ * @public
173
+ */
174
+ static get processedQueue() {
175
+ return "processed:";
176
+ }
177
+
178
+ /**
179
+ * Property returning the configured service instance ID.
180
+ *
181
+ * @property
182
+ * @returns {string}
183
+ * @public
184
+ */
185
+ get instanceID() {
186
+ return this.#instanceID;
187
+ }
188
+
189
+ /**
190
+ * Property returning the configured service domain name.
191
+ *
192
+ * @property
193
+ * @returns {string}
194
+ * @public
195
+ */
196
+ get serviceDomainName() {
197
+ return this.#serviceDomainName;
198
+ }
199
+
200
+ /**
201
+ * Returns the currently configured {@link MessageSender} for outbound message requests.
202
+ *
203
+ * @property
204
+ * @returns {MessageSender}
205
+ * @public
206
+ */
207
+ get messageRequestsOut() {
208
+ return this.#messageRequestsOut;
209
+ }
210
+
211
+ /**
212
+ * Returns the currently configured {@link MessageSender} for outbound message responses.
213
+ *
214
+ * @property
215
+ * @returns {MessageSender}
216
+ * @public
217
+ */
218
+ get messageResponsesOut() {
219
+ return this.#messageResponsesOut;
220
+ }
221
+
222
+ /**
223
+ * Returns the currently configured {@link MessageReceiver} for inbound message requests.
224
+ *
225
+ * @property
226
+ * @returns {MessageReceiver}
227
+ * @public
228
+ */
229
+ get messageRequestsIn() {
230
+ return this.#messageRequestsIn;
231
+ }
232
+
233
+ /**
234
+ * Returns the currently configured {@link MessageReceiver} for inbound message responses.
235
+ *
236
+ * @property
237
+ * @returns {MessageReceiver}
238
+ * @public
239
+ */
240
+ get messageResponsesIn() {
241
+ return this.#messageResponsesIn;
242
+ }
243
+
244
+ /**
245
+ * Returns a flag indicating if the message exchange is configured for outbound communication.
246
+ *
247
+ * @property
248
+ * @returns {boolean}
249
+ * @public
250
+ */
251
+ get configuredOutbound() {
252
+ return this.#configuredOutbound;
253
+ }
254
+
255
+ /**
256
+ * Returns a flag indicating if the message exchange is configured for inbound communication.
257
+ *
258
+ * @property
259
+ * @returns {boolean}
260
+ * @public
261
+ */
262
+ get configuredInbound() {
263
+ return this.#configuredInbound;
264
+ }
265
+
266
+ /**
267
+ * Should be used to enable all communication channels for messaging.
268
+ * <br/>
269
+ * NOTE: Override this to implement messaging initialization.
270
+ *
271
+ * @method
272
+ * @param {boolean} configureInbound If set to 'true' it tells the message exchange to set up inbound messaging.
273
+ * @param {boolean} configureOutbound If set to 'true' it tells the message exchange to set up outbound messaging.
274
+ * @returns {Promise}
275
+ * @abstract
276
+ * @public
277
+ */
278
+ enableMessaging( configureInbound, configureOutbound ) {
279
+ return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.enableMessaging.name } ) );
280
+ }
281
+
282
+ /**
283
+ * Should be used to gracefully disable all communication channels for messaging.
284
+ * <br/>
285
+ * NOTE: Override this to implement graceful messaging shut down.
286
+ *
287
+ * @method
288
+ * @returns {Promise}
289
+ * @abstract
290
+ * @public
291
+ */
292
+ disableMessaging() {
293
+ return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.disableMessaging.name } ) );
294
+ }
295
+
296
+ /**
297
+ * Used to configure the message exchange for receiving inbound messages and returning responses to them.
298
+ * Should typically be called from an implemented {@link enableMessaging} method.
299
+ *
300
+ * @method
301
+ * @param {MessageReceiver} messageReceiverRequestsIn A message receiver that will handle the inbound messages.
302
+ * @param {MessageSender} messageSenderResponsesOut A message sender that will handle the sending of responses for the inbound messages.
303
+ * @public
304
+ */
305
+ configureInboundMessaging( messageReceiverRequestsIn, messageSenderResponsesOut ) {
306
+ this.#messageRequestsIn = messageReceiverRequestsIn;
307
+ this.#messageResponsesOut = messageSenderResponsesOut;
308
+ this.#configuredInbound = true;
309
+ }
310
+
311
+ /**
312
+ * Used to configure message exchange for sending messages and receiving responses to them.
313
+ * Should typically be called from an implemented {@link enableMessaging} method.
314
+ *
315
+ * @method
316
+ * @param {MessageSender} messageSenderRequestsOut A message sender that will handle the outbound messages.
317
+ * @param {MessageReceiver} messageReceiverResponsesIn A message receiver that will handle the returned responses for the outbound messages.
318
+ * @public
319
+ */
320
+ configureOutboundMessaging( messageSenderRequestsOut, messageReceiverResponsesIn ) {
321
+ this.#messageRequestsOut = messageSenderRequestsOut;
322
+ this.#messageResponsesIn = messageReceiverResponsesIn;
323
+ this.#configuredOutbound = true;
324
+ }
325
+
326
+ /**
327
+ * Used to add an additional {@link MessageObserver} to the connection for the incoming message requests.
328
+ *
329
+ * @method
330
+ * @param {MessageObserver} messageObserver
331
+ * @public
332
+ */
333
+ addMessageObserverRequestsIn( messageObserver ) {
334
+ this.#messageRequestsIn.addMessageObserver( messageObserver );
335
+ }
336
+
337
+ /**
338
+ * Used to add an additional {@link MessageObserver} to the connection for the incoming message responses.
339
+ *
340
+ * @method
341
+ * @param {MessageObserver} messageObserver
342
+ * @public
343
+ */
344
+ addMessageObserverResponsesIn( messageObserver ) {
345
+ this.#messageResponsesIn.addMessageObserver( messageObserver );
346
+ }
347
+
348
+ /**
349
+ * Used to mark the connection with the provided identifier as disrupted.
350
+ *
351
+ * @method
352
+ * @param {string} identifier The identifier of the observed connection.
353
+ * @override
354
+ * @public
355
+ */
356
+ onConnectionDisrupted( identifier ) {
357
+ this.#disruptedConnections.push( identifier );
358
+ }
359
+
360
+ /**
361
+ * Used to mark the connection with the provided identifier as recovered.
362
+ * <br/>
363
+ * NOTE: This will also result in enabling the message exchange if no connections are currently disrupted.
364
+ *
365
+ * @method
366
+ * @param {string} identifier The identifier of the observed connection.
367
+ * @override
368
+ * @public
369
+ */
370
+ onConnectionRecovered( identifier ) {
371
+ _.pull( this.#disruptedConnections, identifier );
372
+ }
373
+
374
+ /**
375
+ * Used to mark the connection with the provided identifier as disrupted.
376
+ *
377
+ * @method
378
+ * @param {string} identifier The identifier of the observed connection.
379
+ * @override
380
+ * @public
381
+ */
382
+ onConnectionLost( identifier ) {
383
+ // TODO: implement triggering of a graceful shutdown of the service instance
384
+ }
385
+
386
+ /**
387
+ * Used only for the message tracer.
388
+ *
389
+ * @method
390
+ * @param {string} identifier The identifier of the observed connection.
391
+ * @param {Message} message The message for processing.
392
+ * @returns {Message} The message that was received.
393
+ * @override
394
+ * @public
395
+ */
396
+ onMessage( identifier, message ) {
397
+ message.destination.instanceID = this.#instanceID;
398
+
399
+ if ( MessageExchange.connectionNameRequestsIn === identifier ) {
400
+ messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_REQUEST, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PENDING );
401
+ } else if ( MessageExchange.connectionNameResponsesIn === identifier ) {
402
+ messageTracer.instance.recordTraceEntry( message, messageTracer.messageType.MESSAGE_RESPONSE, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PROCESSED );
403
+ }
404
+
405
+ return message;
406
+ }
407
+
408
+ /**
409
+ * Used to check whether the connection with the provided identifier is currently in recovery mode.
410
+ *
411
+ * @method
412
+ * @param {string} identifier The identifier of the connection.
413
+ * @returns {boolean} Will return 'true' if the connection is currently disrupted and not yet recovered.
414
+ * @public
415
+ */
416
+ isConnectionInRecovery( identifier ) {
417
+ return this.#disruptedConnections.indexOf( identifier ) !== -1;
418
+ }
419
+
420
+ /**
421
+ * Used to send a message request. Override of this method assumes that the message itself contains enough
422
+ * information to determine the sending destination.
423
+ *
424
+ * @method
425
+ * @param {Message} message The message request to send.
426
+ * @returns {Promise}
427
+ * @abstract
428
+ * @public
429
+ */
430
+ sendMessageRequest( message ) {
431
+ return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageRequest.name } ) );
432
+ }
433
+
434
+ /**
435
+ * Used to send a message response. Override of this method assumes that the message itself contains enough
436
+ * information to determine the sending destination.
437
+ *
438
+ * @method
439
+ * @param {Message} message The message response to send.
440
+ * @returns {Promise}
441
+ * @abstract
442
+ * @public
443
+ */
444
+ sendMessageResponse( message ) {
445
+ return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageResponse.name } ) );
446
+ }
447
+
448
+ }
449
+
450
450
  module.exports = MessageExchange;