@ti-engine/core 1.0.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.
- package/components/auditing.js +163 -0
- package/components/connection-observer.js +53 -0
- package/components/exchange/default/default-message-exchange.js +133 -0
- package/components/exchange/default/default-message-receiver.js +89 -0
- package/components/exchange/default/default-message-sender.js +90 -0
- package/components/exchange/message-dispatcher.js +162 -0
- package/components/exchange/message-exchange.js +418 -0
- package/components/exchange/message-handler.js +173 -0
- package/components/exchange/message-memory-cache.js +150 -0
- package/components/exchange/message-observer.js +76 -0
- package/components/exchange/message-receiver.js +113 -0
- package/components/exchange/message-sender.js +133 -0
- package/components/exchange/message-tracer.js +146 -0
- package/components/service-caller.js +306 -0
- package/components/service-consumer.js +112 -0
- package/components/service-executor.js +231 -0
- package/components/service-instance.js +280 -0
- package/components/service-provider.js +221 -0
- package/integrations/gcloud-integration.js +61 -0
- package/integrations/redis-integration.js +261 -0
- package/package.json +54 -0
- package/settings.json +33 -0
- package/utils/cache.js +507 -0
- package/utils/config.js +146 -0
- package/utils/exceptions.js +241 -0
- package/utils/logger.js +69 -0
- package/utils/tools.js +537 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
3
|
+
* SPDX-License-Identifier: ICU
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const MessageObserver = require( "#message-observer" );
|
|
7
|
+
const _ = require( "lodash" );
|
|
8
|
+
const exceptions = require( "#exceptions" );
|
|
9
|
+
const messageTracer = require( "#message-tracer" );
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} MessageDestination
|
|
13
|
+
* @property {string|undefined} [instanceID] The instance ID of the message exchange by which the message was received (available after acceptance).
|
|
14
|
+
* @property {string} route The route to destination for the message. Exact structure will depend on the implementation of the message exchange.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} MessageSource
|
|
19
|
+
* @property {string} instanceID The instance ID of the message exchange from which the service call originated.
|
|
20
|
+
* @property {string} route The route from source of the message. Exact structure will depend on the implementation of the message exchange.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} Message
|
|
25
|
+
* @property {string} chainID Unique identifier of the message chain if the message is part of one.
|
|
26
|
+
* @property {number} chainLevel The node level of this message in the message chain tree.
|
|
27
|
+
* @property {MessageDestination} destination The destination of the message.
|
|
28
|
+
* @property {string} messageID Unique message identifier.
|
|
29
|
+
* @property {Object|string|undefined} payload The message contents to be processed in destination. If string, it is ID of the payload in the memory cache instead.
|
|
30
|
+
* Note that if this is not an Object or a string, there is no guarantee that it will be delivered in the same/proper format!
|
|
31
|
+
* @property {MessageSource} source The source of the message.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An abstract class that defines a message exchange behavior.
|
|
36
|
+
* <br/>
|
|
37
|
+
* NOTE: While this sets the basis frame for the message based communication between microservices, it has to be inherited and
|
|
38
|
+
* extended with additional logic that is NOT implemented here. For a working example please see {@link DefaultMessageExchange} class.
|
|
39
|
+
* <br/>
|
|
40
|
+
* NOTE: This class and its children are designed to be used internally by the {@link MessageDispatcher} and its related classes.
|
|
41
|
+
*
|
|
42
|
+
* @class MessageExchange
|
|
43
|
+
* @extends MessageObserver
|
|
44
|
+
* @abstract
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
class MessageExchange extends MessageObserver {
|
|
48
|
+
|
|
49
|
+
static #connectionNameRequestsOut = "connection-msg-requests-out";
|
|
50
|
+
static #connectionNameRequestsIn = "connection-msg-requests-in";
|
|
51
|
+
static #connectionNameResponsesOut = "connection-msg-responses-out";
|
|
52
|
+
static #connectionNameResponsesIn = "connection-msg-responses-in";
|
|
53
|
+
#instanceID;
|
|
54
|
+
#serviceDomainName;
|
|
55
|
+
#disruptedConnections;
|
|
56
|
+
#configuredOutbound = false;
|
|
57
|
+
#configuredInbound = false;
|
|
58
|
+
/** @type MessageSender */
|
|
59
|
+
#messageRequestsOut;
|
|
60
|
+
/** @type MessageSender */
|
|
61
|
+
#messageResponsesOut;
|
|
62
|
+
/** @type MessageReceiver */
|
|
63
|
+
#messageRequestsIn;
|
|
64
|
+
/** @type MessageReceiver */
|
|
65
|
+
#messageResponsesIn;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @constructor
|
|
69
|
+
* @param {string} instanceID The unique identifier of the microservice instance using the message exchange.
|
|
70
|
+
* @param {string} serviceDomainName The domain name of the microservice using the message exchange.
|
|
71
|
+
*/
|
|
72
|
+
constructor( instanceID, serviceDomainName ) {
|
|
73
|
+
super();
|
|
74
|
+
|
|
75
|
+
// make sure this abstract class cannot be instantiated:
|
|
76
|
+
if ( new.target === MessageExchange ) {
|
|
77
|
+
throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.#instanceID = instanceID;
|
|
81
|
+
this.#serviceDomainName = serviceDomainName;
|
|
82
|
+
this.#disruptedConnections = [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Public interface */
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Property returning the configured connection name for the outgoing message requests.
|
|
89
|
+
*
|
|
90
|
+
* @property
|
|
91
|
+
* @returns {string}
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
static get connectionNameRequestsOut() { return this.#connectionNameRequestsOut; }
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Used to set the connection name for the outgoing message requests.
|
|
98
|
+
*
|
|
99
|
+
* @property
|
|
100
|
+
* @param {string} value
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
103
|
+
static set connectionNameRequestsOut( value ) { this.#connectionNameRequestsOut = value; }
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Property returning the configured connection name for the incoming message requests.
|
|
107
|
+
*
|
|
108
|
+
* @property
|
|
109
|
+
* @returns {string}
|
|
110
|
+
* @public
|
|
111
|
+
*/
|
|
112
|
+
static get connectionNameRequestsIn() { return this.#connectionNameRequestsIn; }
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Used to set the connection name for the incoming message requests.
|
|
116
|
+
*
|
|
117
|
+
* @property
|
|
118
|
+
* @param {string} value
|
|
119
|
+
* @public
|
|
120
|
+
*/
|
|
121
|
+
static set connectionNameRequestsIn( value ) { this.#connectionNameRequestsIn = value; }
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Property returning the configured connection name for the outgoing message responses.
|
|
125
|
+
*
|
|
126
|
+
* @property
|
|
127
|
+
* @returns {string}
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
130
|
+
static get connectionNameResponsesOut() { return this.#connectionNameResponsesOut; }
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Used to set the connection name for the outgoing message responses.
|
|
134
|
+
*
|
|
135
|
+
* @property
|
|
136
|
+
* @param {string} value
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
static set connectionNameResponsesOut( value ) { this.#connectionNameResponsesOut = value; }
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Property returning the configured connection name for the incoming message responses.
|
|
143
|
+
*
|
|
144
|
+
* @property
|
|
145
|
+
* @returns {string}
|
|
146
|
+
* @public
|
|
147
|
+
*/
|
|
148
|
+
static get connectionNameResponsesIn() { return this.#connectionNameResponsesIn; }
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Used to set the connection name for the incoming message responses.
|
|
152
|
+
*
|
|
153
|
+
* @property
|
|
154
|
+
* @param {string} value
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
static set connectionNameResponsesIn( value ) { this.#connectionNameResponsesIn = value; }
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Property returning the identifier of the pending messages queue.
|
|
161
|
+
*
|
|
162
|
+
* @property
|
|
163
|
+
* @returns {string}
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
166
|
+
static get pendingQueue() { return "pending:"; }
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Property returning the identifier of the processed messages queue.
|
|
170
|
+
*
|
|
171
|
+
* @property
|
|
172
|
+
* @returns {string}
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
static get processedQueue() { return "processed:"; }
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Property returning the configured service instance ID.
|
|
179
|
+
*
|
|
180
|
+
* @property
|
|
181
|
+
* @returns {string}
|
|
182
|
+
* @public
|
|
183
|
+
*/
|
|
184
|
+
get instanceID() { return this.#instanceID; }
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Property returning the configured service domain name.
|
|
188
|
+
*
|
|
189
|
+
* @property
|
|
190
|
+
* @returns {string}
|
|
191
|
+
* @public
|
|
192
|
+
*/
|
|
193
|
+
get serviceDomainName() { return this.#serviceDomainName; }
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Returns the currently configured {@link MessageSender} for outbound message requests.
|
|
197
|
+
*
|
|
198
|
+
* @property
|
|
199
|
+
* @returns {MessageSender}
|
|
200
|
+
* @public
|
|
201
|
+
*/
|
|
202
|
+
get messageRequestsOut() { return this.#messageRequestsOut; }
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Returns the currently configured {@link MessageSender} for outbound message responses.
|
|
206
|
+
*
|
|
207
|
+
* @property
|
|
208
|
+
* @returns {MessageSender}
|
|
209
|
+
* @public
|
|
210
|
+
*/
|
|
211
|
+
get messageResponsesOut() { return this.#messageResponsesOut; }
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Returns the currently configured {@link MessageReceiver} for inbound message requests.
|
|
215
|
+
*
|
|
216
|
+
* @property
|
|
217
|
+
* @returns {MessageReceiver}
|
|
218
|
+
* @public
|
|
219
|
+
*/
|
|
220
|
+
get messageRequestsIn() { return this.#messageRequestsIn; }
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Returns the currently configured {@link MessageReceiver} for inbound message responses.
|
|
224
|
+
*
|
|
225
|
+
* @property
|
|
226
|
+
* @returns {MessageReceiver}
|
|
227
|
+
* @public
|
|
228
|
+
*/
|
|
229
|
+
get messageResponsesIn() { return this.#messageResponsesIn; }
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Returns a flag indicating if the message exchange is configured for outbound communication.
|
|
233
|
+
*
|
|
234
|
+
* @property
|
|
235
|
+
* @returns {boolean}
|
|
236
|
+
* @public
|
|
237
|
+
*/
|
|
238
|
+
get configuredOutbound() { return this.#configuredOutbound; }
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Returns a flag indicating if the message exchange is configured for inbound communication.
|
|
242
|
+
*
|
|
243
|
+
* @property
|
|
244
|
+
* @returns {boolean}
|
|
245
|
+
* @public
|
|
246
|
+
*/
|
|
247
|
+
get configuredInbound() { return this.#configuredInbound; }
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Should be used to enable all communication channels for messaging.
|
|
251
|
+
* <br/>
|
|
252
|
+
* NOTE: Override this to implement messaging initialization.
|
|
253
|
+
*
|
|
254
|
+
* @method
|
|
255
|
+
* @param {boolean} configureInbound If set to 'true' it tells the message exchange to setup inbound messaging.
|
|
256
|
+
* @param {boolean} configureOutbound If set to 'true' it tells the message exchange to setup outbound messaging.
|
|
257
|
+
* @returns {Promise}
|
|
258
|
+
* @abstract
|
|
259
|
+
* @public
|
|
260
|
+
*/
|
|
261
|
+
enableMessaging( configureInbound, configureOutbound ) {
|
|
262
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.enableMessaging.name } ) );
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Should be used to gracefully disable all communication channels for messaging.
|
|
267
|
+
* <br/>
|
|
268
|
+
* NOTE: Override this to implement graceful messaging shut down.
|
|
269
|
+
*
|
|
270
|
+
* @method
|
|
271
|
+
* @returns {Promise}
|
|
272
|
+
* @abstract
|
|
273
|
+
* @public
|
|
274
|
+
*/
|
|
275
|
+
disableMessaging() {
|
|
276
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.disableMessaging.name } ) );
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Used to configure the message exchange for receiving inbound messages and returning responses to them.
|
|
281
|
+
* Should typically be called from an implemented {@link enableMessaging} method.
|
|
282
|
+
*
|
|
283
|
+
* @method
|
|
284
|
+
* @param {MessageReceiver} messageReceiverRequestsIn A message receiver that will handle the inbound messages.
|
|
285
|
+
* @param {MessageSender} messageSenderResponsesOut A message sender that will handle the sending of responses for the inbound messages.
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
configureInboundMessaging( messageReceiverRequestsIn, messageSenderResponsesOut ) {
|
|
289
|
+
this.#messageRequestsIn = messageReceiverRequestsIn;
|
|
290
|
+
this.#messageResponsesOut = messageSenderResponsesOut;
|
|
291
|
+
this.#configuredInbound = true;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Used to configure message exchange for sending messages and receiving responses to them.
|
|
296
|
+
* Should typically be called from an implemented {@link enableMessaging} method.
|
|
297
|
+
*
|
|
298
|
+
* @method
|
|
299
|
+
* @param {MessageSender} messageSenderRequestsOut A message sender that will handle the outbound messages.
|
|
300
|
+
* @param {MessageReceiver} messageReceiverResponsesIn A message receiver that will handle the returned responses for the outbound messages.
|
|
301
|
+
* @public
|
|
302
|
+
*/
|
|
303
|
+
configureOutboundMessaging( messageSenderRequestsOut, messageReceiverResponsesIn ) {
|
|
304
|
+
this.#messageRequestsOut = messageSenderRequestsOut;
|
|
305
|
+
this.#messageResponsesIn = messageReceiverResponsesIn;
|
|
306
|
+
this.#configuredOutbound = true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Used to add an additional {@link MessageObserver} to the connection for the incoming message requests.
|
|
311
|
+
*
|
|
312
|
+
* @method
|
|
313
|
+
* @param {MessageObserver} messageObserver
|
|
314
|
+
* @public
|
|
315
|
+
*/
|
|
316
|
+
addMessageObserverRequestsIn( messageObserver ) {
|
|
317
|
+
this.#messageRequestsIn.addMessageObserver( messageObserver );
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Used to add an additional {@link MessageObserver} to the connection for the incoming message responses.
|
|
322
|
+
*
|
|
323
|
+
* @method
|
|
324
|
+
* @param {MessageObserver} messageObserver
|
|
325
|
+
* @public
|
|
326
|
+
*/
|
|
327
|
+
addMessageObserverResponsesIn( messageObserver ) {
|
|
328
|
+
this.#messageResponsesIn.addMessageObserver( messageObserver );
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Used to mark the connection with the provided identifier as disrupted.
|
|
333
|
+
*
|
|
334
|
+
* @method
|
|
335
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
336
|
+
* @override
|
|
337
|
+
* @public
|
|
338
|
+
*/
|
|
339
|
+
onConnectionDisrupted( identifier ) {
|
|
340
|
+
this.#disruptedConnections.push( identifier );
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Used to mark the connection with the provided identifier as recovered.
|
|
345
|
+
* <br/>
|
|
346
|
+
* NOTE: This will also result in enabling the message exchange if no connections are currently disrupted.
|
|
347
|
+
*
|
|
348
|
+
* @method
|
|
349
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
350
|
+
* @override
|
|
351
|
+
* @public
|
|
352
|
+
*/
|
|
353
|
+
onConnectionRecovered( identifier ) {
|
|
354
|
+
_.pull( this.#disruptedConnections, identifier );
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Used only for the purposes of the message tracer.
|
|
359
|
+
*
|
|
360
|
+
* @method
|
|
361
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
362
|
+
* @param {Message} message The message for processing.
|
|
363
|
+
* @override
|
|
364
|
+
* @public
|
|
365
|
+
*/
|
|
366
|
+
onMessage( identifier, message ) {
|
|
367
|
+
message.destination.instanceID = this.#instanceID;
|
|
368
|
+
|
|
369
|
+
if ( MessageExchange.connectionNameRequestsIn === identifier ) {
|
|
370
|
+
messageTracer.recordTraceEntry( message, messageTracer.messageType.MESSAGE_REQUEST, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PENDING );
|
|
371
|
+
} else if ( MessageExchange.connectionNameResponsesIn === identifier ) {
|
|
372
|
+
messageTracer.recordTraceEntry( message, messageTracer.messageType.MESSAGE_RESPONSE, messageTracer.dispatchEvent.RECEIVED, messageTracer.messageState.PROCESSED );
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Used to check whether the connection with the provided identifier is currently in recovery mode.
|
|
378
|
+
*
|
|
379
|
+
* @method
|
|
380
|
+
* @param {string} identifier The identifier of the connection.
|
|
381
|
+
* @returns {boolean} Will return 'true' if the connection is currently disrupted and not yet recovered.
|
|
382
|
+
* @public
|
|
383
|
+
*/
|
|
384
|
+
isConnectionInRecovery( identifier ) {
|
|
385
|
+
return this.#disruptedConnections.indexOf( identifier ) !== -1;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Used to send a message request. Override of this method assumes that the message itself contains enough
|
|
390
|
+
* information to determine the send destination.
|
|
391
|
+
*
|
|
392
|
+
* @method
|
|
393
|
+
* @param {Message} message The message request to send.
|
|
394
|
+
* @returns {Promise}
|
|
395
|
+
* @abstract
|
|
396
|
+
* @public
|
|
397
|
+
*/
|
|
398
|
+
sendMessageRequest( message ) {
|
|
399
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageRequest.name } ) );
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Used to send a message response. Override of this method assumes that the message itself contains enough
|
|
404
|
+
* information to determine the send destination.
|
|
405
|
+
*
|
|
406
|
+
* @method
|
|
407
|
+
* @param {Message} message The message response to send.
|
|
408
|
+
* @returns {Promise}
|
|
409
|
+
* @abstract
|
|
410
|
+
* @public
|
|
411
|
+
*/
|
|
412
|
+
sendMessageResponse( message ) {
|
|
413
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.sendMessageResponse.name } ) );
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
module.exports = MessageExchange;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
3
|
+
* SPDX-License-Identifier: ICU
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const ConnectionObserver = require( "#connection-observer" );
|
|
7
|
+
const _ = require( "lodash" );
|
|
8
|
+
const exceptions = require( "#exceptions" );
|
|
9
|
+
const logger = require( "#logger" );
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An abstract class that defines a basic message handler behavior.
|
|
13
|
+
* <br/>
|
|
14
|
+
* NOTE: This class and its children are designed to be used internally by classes extending the {@link MessageObserver} class.
|
|
15
|
+
*
|
|
16
|
+
* @class MessageHandler
|
|
17
|
+
* @extends ConnectionObserver
|
|
18
|
+
* @abstract
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
class MessageHandler extends ConnectionObserver {
|
|
22
|
+
|
|
23
|
+
#isAvailable = false;
|
|
24
|
+
#connectionIdentifier;
|
|
25
|
+
#messageObservers = [];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @constructor
|
|
29
|
+
* @param {string} identifier An identifier for this message handler. Should be unique in the context of the message exchange.
|
|
30
|
+
*/
|
|
31
|
+
constructor( identifier ) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
// make sure this abstract class cannot be instantiated:
|
|
35
|
+
if ( new.target === MessageHandler ) {
|
|
36
|
+
throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.#connectionIdentifier = identifier;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Public interface */
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Indicates whether the message handler is currently available.
|
|
46
|
+
*
|
|
47
|
+
* @property
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
get isAvailable() { return this.#isAvailable; }
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Used to set the isAvailable flag.
|
|
55
|
+
* <br/>
|
|
56
|
+
* NOTE: For use by implementing classes only!
|
|
57
|
+
*
|
|
58
|
+
* @property
|
|
59
|
+
* @param {boolean} value
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
set isAvailable( value ) { this.#isAvailable = value; }
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the connection identifier.
|
|
66
|
+
*
|
|
67
|
+
* @property
|
|
68
|
+
* @returns {string}
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
get connectionIdentifier() { return this.#connectionIdentifier; }
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Used to initialize and enable the communication capabilities of the handler.
|
|
75
|
+
* <br/>
|
|
76
|
+
* NOTE: Override this to add functionality.
|
|
77
|
+
*
|
|
78
|
+
* @method
|
|
79
|
+
* @returns {Promise}
|
|
80
|
+
* @abstract
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
enable() {
|
|
84
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.enable.name } ) );
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Used to shutdown and disable the communication behavior of the handler.
|
|
89
|
+
* <br/>
|
|
90
|
+
* NOTE: Override this to add functionality.
|
|
91
|
+
*
|
|
92
|
+
* @method
|
|
93
|
+
* @returns {Promise}
|
|
94
|
+
* @abstract
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
disable() {
|
|
98
|
+
return Promise.reject( exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_METHOD_CALL, { name: this.constructor.name + "." + this.disable.name } ) );
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Used to register a new {@link MessageObserver} for events related to the messages passing through this handler.
|
|
103
|
+
*
|
|
104
|
+
* @method
|
|
105
|
+
* @param {MessageObserver} messageObserver The {@link MessageObserver} that will be notified of any changes.
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
addMessageObserver( messageObserver ) {
|
|
109
|
+
const MessageObserver = require( "#message-observer" );
|
|
110
|
+
|
|
111
|
+
if ( messageObserver instanceof MessageObserver ) {
|
|
112
|
+
this.#messageObservers.push( messageObserver );
|
|
113
|
+
} else {
|
|
114
|
+
logger.log( `Attempting to add '${ messageObserver.constructor.name }' as message observer but it's not a child-class of 'MessageObserver'!`, logger.logSeverity.WARNING );
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* An event-triggered method that will notify any observers about a new message for handling.
|
|
120
|
+
*
|
|
121
|
+
* @method
|
|
122
|
+
* @param {Message} message
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
onMessage( message ) {
|
|
126
|
+
_.forEach( this.#messageObservers, ( messageObserver ) => {
|
|
127
|
+
messageObserver.onMessage( this.#connectionIdentifier, message );
|
|
128
|
+
} );
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* An event-triggered method that will notify any observers about primary connection recovered state.
|
|
133
|
+
* <br/>
|
|
134
|
+
* NOTE: You can override this to add custom functionality but make sure to also call the base method
|
|
135
|
+
* using: super.onConnectionRecovered( identifier )
|
|
136
|
+
*
|
|
137
|
+
* @method
|
|
138
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
139
|
+
* @override
|
|
140
|
+
* @private
|
|
141
|
+
*/
|
|
142
|
+
onConnectionRecovered( identifier ) {
|
|
143
|
+
if ( this.#isAvailable === false ) {
|
|
144
|
+
this.#isAvailable = true;
|
|
145
|
+
_.forEach( this.#messageObservers, ( messageObserver ) => {
|
|
146
|
+
messageObserver.onConnectionRecovered( this.#connectionIdentifier );
|
|
147
|
+
} );
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* An event-triggered method that will notify any observers about primary connection disrupted state.
|
|
153
|
+
* <br/>
|
|
154
|
+
* NOTE: You can override this to add custom functionality but make sure to also call the base method
|
|
155
|
+
* using: super.onConnectionDisrupted( identifier )
|
|
156
|
+
*
|
|
157
|
+
* @method
|
|
158
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
159
|
+
* @override
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
onConnectionDisrupted( identifier ) {
|
|
163
|
+
if ( this.#isAvailable === true ) {
|
|
164
|
+
this.#isAvailable = false;
|
|
165
|
+
_.forEach( this.#messageObservers, ( messageObserver ) => {
|
|
166
|
+
messageObserver.onConnectionDisrupted( this.#connectionIdentifier );
|
|
167
|
+
} );
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
module.exports = MessageHandler;
|