@ti-engine/core 1.1.10 → 1.2.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/CHANGELOG.md +144 -132
- package/README.md +2 -2
- package/bin/localization/labels.json +64 -64
- package/bin/settings.json +1 -1
- package/components/exchange/default/default-message-receiver.js +11 -4
- package/components/exchange/default/default-message-sender.js +8 -4
- package/components/exchange/message-handler.js +3 -3
- package/components/exchange/message-memory-cache.js +18 -8
- package/components/exchange/message-receiver.js +43 -13
- package/components/exchange/message-tracer.js +8 -3
- package/components/service-executor.js +26 -28
- package/components/service-instance.js +2 -2
- package/components/service-provider.js +9 -6
- package/integrations/redis-integration.js +160 -102
- package/package.json +65 -63
- package/utils/config.js +2 -2
- package/utils/exceptions.js +1 -0
- package/utils/localization.js +32 -29
- package/testRedis.js +0 -22
|
@@ -78,7 +78,8 @@ class RedisClient {
|
|
|
78
78
|
#clientIdentifier;
|
|
79
79
|
#retryMaxInterval = 1000;
|
|
80
80
|
#retryMaxAttempts = undefined;
|
|
81
|
-
#
|
|
81
|
+
#redisConnection = undefined;
|
|
82
|
+
#redisClientID;
|
|
82
83
|
#serverInfo = {};
|
|
83
84
|
#serverFeatures = {};
|
|
84
85
|
#connectionObservers = [];
|
|
@@ -106,6 +107,17 @@ class RedisClient {
|
|
|
106
107
|
return this.#clientIdentifier;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Used to return the Redis client ID.
|
|
112
|
+
*
|
|
113
|
+
* @property
|
|
114
|
+
* @returns {number}
|
|
115
|
+
* @public
|
|
116
|
+
*/
|
|
117
|
+
get clientID() {
|
|
118
|
+
return this.#redisClientID;
|
|
119
|
+
}
|
|
120
|
+
|
|
109
121
|
/**
|
|
110
122
|
* Used to return the Redis server version.
|
|
111
123
|
*
|
|
@@ -144,73 +156,27 @@ class RedisClient {
|
|
|
144
156
|
*/
|
|
145
157
|
initialize( host, port, authKey, user, defaultDB, retryMaxIntervalMs = 1000, retryMaxAttempts = undefined ) {
|
|
146
158
|
return new Promise( ( resolve, reject ) => {
|
|
147
|
-
if ( this.#
|
|
159
|
+
if ( this.#redisConnection ) {
|
|
148
160
|
resolve();
|
|
149
161
|
} else {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.#
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return result;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
let reconnectOnError = ( error ) => {
|
|
166
|
-
logger.log( `In Redis reconnect on error strategy: ${ error.message }`, logger.logSeverity.ERROR, error );
|
|
167
|
-
return !!error.message.includes( "READONLY" );
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
let options = {
|
|
171
|
-
port: port,
|
|
172
|
-
host: host,
|
|
173
|
-
username: user,
|
|
174
|
-
password: authKey,
|
|
175
|
-
db: defaultDB,
|
|
176
|
-
autoResendUnfulfilledCommands: true,
|
|
177
|
-
maxRetriesPerRequest: null,
|
|
178
|
-
retryStrategy: retryStrategy,
|
|
179
|
-
reconnectOnError: reconnectOnError
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
/** @type Redis */
|
|
183
|
-
this.#redisClient = new Redis( options );
|
|
184
|
-
|
|
185
|
-
this.#redisClient.on( "ready", () => {
|
|
186
|
-
logger.log( `Connection to Redis server ${ host }:${ port } (re)established by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
187
|
-
|
|
188
|
-
// Notify all connection observers about this event:
|
|
189
|
-
_.forEach( this.#connectionObservers, ( connectionObservers ) => {
|
|
190
|
-
connectionObservers.onConnectionRecovered( this.#clientIdentifier );
|
|
191
|
-
} );
|
|
192
|
-
|
|
193
|
-
// Fetch the server information and store it:
|
|
194
|
-
this.#fetchServerInfo();
|
|
195
|
-
|
|
196
|
-
resolve();
|
|
162
|
+
this.#setupClient( host, port, authKey, user, defaultDB, retryMaxIntervalMs, retryMaxAttempts ).then( () => {
|
|
163
|
+
// Fetch the server information and store it:
|
|
164
|
+
return this.#fetchServerInfo();
|
|
165
|
+
} ).then( () => {
|
|
166
|
+
return this.#getClientId();
|
|
167
|
+
} ).then( ( clientID ) => {
|
|
168
|
+
// Store the client ID:
|
|
169
|
+
this.#redisClientID = clientID;
|
|
170
|
+
|
|
171
|
+
// Notify all connection observers about the initialization success:
|
|
172
|
+
_.forEach( this.#connectionObservers, ( connectionObservers ) => {
|
|
173
|
+
connectionObservers.onConnectionRecovered( this.#clientIdentifier );
|
|
197
174
|
} );
|
|
198
|
-
this.#redisClient.on( "error", ( error ) => {
|
|
199
|
-
logger.log( `Error received in Redis client '${ this.identifier }'.`, logger.logSeverity.ERROR, error );
|
|
200
175
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
connectionObservers.onConnectionDisrupted( this.#clientIdentifier );
|
|
204
|
-
} );
|
|
205
|
-
} );
|
|
206
|
-
this.#redisClient.on( "reconnecting", ( info ) => {
|
|
207
|
-
if ( info.attempt > 1 ) {
|
|
208
|
-
logger.log( `Client '${ this.identifier }' reconnecting to Redis server after ${ info.delay } ms. This is attempt ${ info.attempt }.`, logger.logSeverity.DEBUG );
|
|
209
|
-
}
|
|
210
|
-
} );
|
|
211
|
-
} catch ( error ) {
|
|
176
|
+
resolve();
|
|
177
|
+
} ).catch( ( error ) => {
|
|
212
178
|
reject( exceptions.raise( error ) );
|
|
213
|
-
}
|
|
179
|
+
} );
|
|
214
180
|
}
|
|
215
181
|
} );
|
|
216
182
|
}
|
|
@@ -240,7 +206,7 @@ class RedisClient {
|
|
|
240
206
|
*/
|
|
241
207
|
executeCommands( commands ) {
|
|
242
208
|
return new Promise( ( resolve, reject ) => {
|
|
243
|
-
this.#
|
|
209
|
+
this.#redisConnection.multi( commands ).exec().then( ( results ) => {
|
|
244
210
|
resolve( results );
|
|
245
211
|
} ).catch( ( error ) => {
|
|
246
212
|
reject( exceptions.raise( error ) );
|
|
@@ -261,7 +227,7 @@ class RedisClient {
|
|
|
261
227
|
*/
|
|
262
228
|
blockingCommand( command, commandArguments ) {
|
|
263
229
|
return new Promise( ( resolve, reject ) => {
|
|
264
|
-
this.#
|
|
230
|
+
this.#redisConnection[ command ].apply( this.#redisConnection, commandArguments ).then( ( results ) => {
|
|
265
231
|
resolve( results );
|
|
266
232
|
} ).catch( ( error ) => {
|
|
267
233
|
reject( exceptions.raise( error ) );
|
|
@@ -280,7 +246,7 @@ class RedisClient {
|
|
|
280
246
|
*/
|
|
281
247
|
publishCommand( channel, message ) {
|
|
282
248
|
return new Promise( ( resolve, reject ) => {
|
|
283
|
-
this.#
|
|
249
|
+
this.#redisConnection.publish( channel, tools.stringifyJSON( message ) ).then( ( receivedBy ) => {
|
|
284
250
|
resolve( receivedBy );
|
|
285
251
|
} ).catch( ( error ) => {
|
|
286
252
|
reject( exceptions.raise( error ) );
|
|
@@ -301,7 +267,7 @@ class RedisClient {
|
|
|
301
267
|
*/
|
|
302
268
|
subscribeCommand( channel, messageHandler ) {
|
|
303
269
|
return new Promise( ( resolve, reject ) => {
|
|
304
|
-
// Avoid attaching multiple listeners
|
|
270
|
+
// Avoid attaching multiple listeners to the same channel:
|
|
305
271
|
if ( this.#messageHandlersByChannel.has( channel ) ) {
|
|
306
272
|
logger.log( "Attempting to subscribe to message channel '" + channel + "' while already subscribed to it.", logger.logSeverity.WARNING );
|
|
307
273
|
resolve();
|
|
@@ -312,21 +278,21 @@ class RedisClient {
|
|
|
312
278
|
}
|
|
313
279
|
};
|
|
314
280
|
|
|
315
|
-
this.#
|
|
281
|
+
this.#redisConnection.once( "subscribe", ( subscribedChannel ) => {
|
|
316
282
|
if ( subscribedChannel === channel ) {
|
|
317
283
|
logger.log( "Subscription to message channel '" + channel + "' successful.", logger.logSeverity.DEBUG );
|
|
318
284
|
resolve();
|
|
319
285
|
}
|
|
320
286
|
} );
|
|
321
287
|
|
|
322
|
-
this.#
|
|
288
|
+
this.#redisConnection.on( "message", onMessage );
|
|
323
289
|
this.#messageHandlersByChannel.set( channel, onMessage );
|
|
324
290
|
|
|
325
|
-
this.#
|
|
291
|
+
this.#redisConnection.subscribe( channel ).catch( ( error ) => {
|
|
326
292
|
// Cleanup partial state if subscribe fails:
|
|
327
293
|
const handler = this.#messageHandlersByChannel.get( channel );
|
|
328
294
|
if ( handler ) {
|
|
329
|
-
this.#
|
|
295
|
+
this.#redisConnection.off( "message", handler );
|
|
330
296
|
this.#messageHandlersByChannel.delete( channel );
|
|
331
297
|
}
|
|
332
298
|
reject( exceptions.raise( error ) );
|
|
@@ -347,10 +313,11 @@ class RedisClient {
|
|
|
347
313
|
return new Promise( ( resolve, reject ) => {
|
|
348
314
|
const handler = this.#messageHandlersByChannel.get( channel );
|
|
349
315
|
if ( handler ) {
|
|
350
|
-
this.#
|
|
316
|
+
this.#redisConnection.off( "message", handler );
|
|
351
317
|
this.#messageHandlersByChannel.delete( channel );
|
|
352
318
|
}
|
|
353
|
-
|
|
319
|
+
|
|
320
|
+
this.#redisConnection.unsubscribe( channel ).then( () => {
|
|
354
321
|
resolve();
|
|
355
322
|
} ).catch( ( error ) => {
|
|
356
323
|
reject( exceptions.raise( error ) );
|
|
@@ -372,7 +339,7 @@ class RedisClient {
|
|
|
372
339
|
*/
|
|
373
340
|
callCommand( commandArguments ) {
|
|
374
341
|
return new Promise( ( resolve, reject ) => {
|
|
375
|
-
this.#
|
|
342
|
+
this.#redisConnection[ "call" ].apply( this.#redisConnection, commandArguments ).then( ( result ) => {
|
|
376
343
|
resolve( result );
|
|
377
344
|
} ).catch( ( error ) => {
|
|
378
345
|
reject( exceptions.raise( error ) );
|
|
@@ -386,7 +353,7 @@ class RedisClient {
|
|
|
386
353
|
*
|
|
387
354
|
* @method
|
|
388
355
|
* @param {number} [timeoutMs=1000]
|
|
389
|
-
* @returns {Promise
|
|
356
|
+
* @returns {Promise}
|
|
390
357
|
* @public
|
|
391
358
|
*/
|
|
392
359
|
shutDown( timeoutMs = 1000 ) {
|
|
@@ -401,19 +368,19 @@ class RedisClient {
|
|
|
401
368
|
|
|
402
369
|
const timeout = setTimeout( () => {
|
|
403
370
|
try {
|
|
404
|
-
this.#
|
|
371
|
+
this.#redisConnection.disconnect();
|
|
405
372
|
} catch ( error ) {
|
|
406
373
|
}
|
|
407
374
|
done();
|
|
408
375
|
}, timeoutMs );
|
|
409
376
|
|
|
410
|
-
this.#
|
|
377
|
+
this.#redisConnection.quit().then( () => {
|
|
411
378
|
clearTimeout( timeout );
|
|
412
379
|
done();
|
|
413
380
|
} ).catch( () => {
|
|
414
381
|
clearTimeout( timeout );
|
|
415
382
|
try {
|
|
416
|
-
this.#
|
|
383
|
+
this.#redisConnection.disconnect();
|
|
417
384
|
} catch ( error ) {
|
|
418
385
|
}
|
|
419
386
|
done();
|
|
@@ -424,40 +391,131 @@ class RedisClient {
|
|
|
424
391
|
/* Private interface */
|
|
425
392
|
|
|
426
393
|
/**
|
|
427
|
-
* Used to
|
|
394
|
+
* Used to set up the connection to Redis server.
|
|
395
|
+
* <br/>
|
|
396
|
+
* NOTE: This method will only resolve once the server sends a 'ready' event.
|
|
428
397
|
*
|
|
429
398
|
* @method
|
|
430
|
-
* @
|
|
399
|
+
* @param {string} host
|
|
400
|
+
* @param {number} port
|
|
401
|
+
* @param {string} authKey
|
|
402
|
+
* @param {string} user
|
|
403
|
+
* @param {number} defaultDB
|
|
404
|
+
* @param {number} [retryMaxIntervalMs=1000] Optional max backoff interval.
|
|
405
|
+
* @param {number|undefined} [retryMaxAttempts=undefined] Optional max (re)connection attempts before abort.
|
|
406
|
+
* @public
|
|
431
407
|
*/
|
|
432
|
-
#
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
}
|
|
408
|
+
#setupClient( host, port, authKey, user, defaultDB, retryMaxIntervalMs, retryMaxAttempts ) {
|
|
409
|
+
return new Promise( ( resolve, reject ) => {
|
|
410
|
+
try {
|
|
411
|
+
this.#retryMaxInterval = retryMaxIntervalMs;
|
|
412
|
+
this.#retryMaxAttempts = retryMaxAttempts;
|
|
413
|
+
|
|
414
|
+
let retryStrategy = ( attempt ) => {
|
|
415
|
+
let result = Math.min( attempt * 50, this.#retryMaxInterval );
|
|
416
|
+
|
|
417
|
+
if ( this.#retryMaxAttempts != null && attempt > this.#retryMaxAttempts ) {
|
|
418
|
+
logger.log( "In Redis retry strategy: reached max attempts for command retry. Aborting...", logger.logSeverity.WARNING, { attempts: attempt } );
|
|
419
|
+
result = exceptions.raise( exceptions.exceptionCode.E_COM_RETRY_ATTEMPTS_EXCEEDED );
|
|
445
420
|
}
|
|
421
|
+
|
|
422
|
+
return result;
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
let reconnectOnError = ( error ) => {
|
|
426
|
+
logger.log( `In Redis reconnect on error strategy: ${ error.message }`, logger.logSeverity.ERROR, error );
|
|
427
|
+
return !!error.message.includes( "READONLY" );
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
let options = {
|
|
431
|
+
port: port,
|
|
432
|
+
host: host,
|
|
433
|
+
username: user,
|
|
434
|
+
password: authKey,
|
|
435
|
+
db: defaultDB,
|
|
436
|
+
autoResendUnfulfilledCommands: true,
|
|
437
|
+
maxRetriesPerRequest: null,
|
|
438
|
+
retryStrategy: retryStrategy,
|
|
439
|
+
reconnectOnError: reconnectOnError
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/** @type Redis */
|
|
443
|
+
this.#redisConnection = new Redis( options );
|
|
444
|
+
|
|
445
|
+
this.#redisConnection.on( "ready", () => {
|
|
446
|
+
logger.log( `Connection to Redis server ${ host }:${ port } (re)established by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
447
|
+
resolve();
|
|
446
448
|
} );
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
449
|
+
this.#redisConnection.on( "error", ( error ) => {
|
|
450
|
+
logger.log( `Error received in Redis client '${ this.identifier }'.`, logger.logSeverity.ERROR, error );
|
|
451
|
+
|
|
452
|
+
// Notify all connection observers about this event:
|
|
453
|
+
_.forEach( this.#connectionObservers, ( connectionObservers ) => {
|
|
454
|
+
connectionObservers.onConnectionDisrupted( this.#clientIdentifier );
|
|
455
|
+
} );
|
|
456
|
+
} );
|
|
457
|
+
this.#redisConnection.on( "reconnecting", ( info ) => {
|
|
458
|
+
if ( info.attempt > 1 ) {
|
|
459
|
+
logger.log( `Client '${ this.identifier }' reconnecting to Redis server after ${ info.delay } ms. This is attempt ${ info.attempt }.`, logger.logSeverity.DEBUG );
|
|
460
|
+
}
|
|
454
461
|
} );
|
|
462
|
+
} catch ( error ) {
|
|
463
|
+
reject( exceptions.raise( error ) );
|
|
455
464
|
}
|
|
456
|
-
} ).catch( ( error ) => {
|
|
457
|
-
logger.log( `Failed to fetch server information by client '${ this.identifier }'!`, logger.logSeverity.WARNING, error );
|
|
458
465
|
} );
|
|
459
466
|
}
|
|
460
467
|
|
|
468
|
+
/**
|
|
469
|
+
* Used to fetch and store Redis server information.
|
|
470
|
+
*
|
|
471
|
+
* @method
|
|
472
|
+
* @private
|
|
473
|
+
*/
|
|
474
|
+
#fetchServerInfo() {
|
|
475
|
+
return new Promise( ( resolve, reject ) => {
|
|
476
|
+
this.#redisConnection.info().then( ( result ) => {
|
|
477
|
+
this.#serverInfo = {};
|
|
478
|
+
if ( _.isString( result ) ) {
|
|
479
|
+
let rawData = _.split( result, "\r\n" );
|
|
480
|
+
_.forEach( rawData, ( entry ) => {
|
|
481
|
+
let details = _.split( entry, ":" );
|
|
482
|
+
if ( !_.startsWith( details[ 0 ], "#" ) && details[ 0 ] !== "" && details[ 0 ] ) {
|
|
483
|
+
if ( _.isNaN( _.toNumber( details[ 1 ] ) ) ) {
|
|
484
|
+
this.#serverInfo[ details[ 0 ] ] = details[ 1 ];
|
|
485
|
+
} else {
|
|
486
|
+
this.#serverInfo[ details[ 0 ] ] = _.toNumber( details[ 1 ] );
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
} );
|
|
490
|
+
}
|
|
491
|
+
return this.#redisConnection.module( "LIST" );
|
|
492
|
+
} ).then( ( result ) => {
|
|
493
|
+
this.#serverFeatures = {};
|
|
494
|
+
if ( _.isArray( result ) ) {
|
|
495
|
+
_.forEach( result, ( entry ) => {
|
|
496
|
+
this.#serverFeatures[ entry[ 1 ] ] = entry[ 3 ];
|
|
497
|
+
} );
|
|
498
|
+
}
|
|
499
|
+
resolve();
|
|
500
|
+
} ).catch( ( error ) => {
|
|
501
|
+
logger.log( `Failed to fetch Redis server information by client '${ this.identifier }'!`, logger.logSeverity.WARNING, error );
|
|
502
|
+
reject( exceptions.raise( error ) );
|
|
503
|
+
} );
|
|
504
|
+
} );
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Used to fetch and store the Redis client ID.
|
|
509
|
+
*
|
|
510
|
+
* @method
|
|
511
|
+
* @returns {Promise<number>}
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
#getClientId() {
|
|
515
|
+
let commandArguments = [ "client", "id" ];
|
|
516
|
+
return this.callCommand( commandArguments ).then( ( clientID ) => Number( clientID ) );
|
|
517
|
+
}
|
|
518
|
+
|
|
461
519
|
}
|
|
462
520
|
|
|
463
521
|
/**
|
package/package.json
CHANGED
|
@@ -1,64 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "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.",
|
|
5
|
-
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
|
-
"license": "GPL-3.0-or-later",
|
|
7
|
-
"exports": {
|
|
8
|
-
"
|
|
9
|
-
"./
|
|
10
|
-
"./
|
|
11
|
-
"./
|
|
12
|
-
"./service-
|
|
13
|
-
"./service-
|
|
14
|
-
"./
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"#
|
|
19
|
-
"#
|
|
20
|
-
"#
|
|
21
|
-
"#
|
|
22
|
-
"#default-message-
|
|
23
|
-
"#default-message-
|
|
24
|
-
"#
|
|
25
|
-
"#
|
|
26
|
-
"#
|
|
27
|
-
"#
|
|
28
|
-
"#
|
|
29
|
-
"#
|
|
30
|
-
"#message-
|
|
31
|
-
"#message-
|
|
32
|
-
"#message-
|
|
33
|
-
"#message-
|
|
34
|
-
"#message-
|
|
35
|
-
"#message-
|
|
36
|
-
"#
|
|
37
|
-
"#
|
|
38
|
-
"#
|
|
39
|
-
"#service-
|
|
40
|
-
"#service-
|
|
41
|
-
"#service-
|
|
42
|
-
"#
|
|
43
|
-
"#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@ti-engine/core",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "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.",
|
|
5
|
+
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
|
+
"license": "GPL-3.0-or-later",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./bin/start-instance.js",
|
|
9
|
+
"./exceptions": "./utils/exceptions.js",
|
|
10
|
+
"./localization": "./utils/localization.js",
|
|
11
|
+
"./logger": "./utils/logger.js",
|
|
12
|
+
"./service-consumer": "./components/service-consumer.js",
|
|
13
|
+
"./service-instance": "./components/service-instance.js",
|
|
14
|
+
"./service-provider": "./components/service-provider.js",
|
|
15
|
+
"./tools": "./utils/tools.js"
|
|
16
|
+
},
|
|
17
|
+
"imports": {
|
|
18
|
+
"#auditing": "./components/auditing.js",
|
|
19
|
+
"#cache": "./utils/cache.js",
|
|
20
|
+
"#config": "./utils/config.js",
|
|
21
|
+
"#connection-observer": "./components/connection-observer.js",
|
|
22
|
+
"#default-message-exchange": "./components/exchange/default/default-message-exchange.js",
|
|
23
|
+
"#default-message-receiver": "./components/exchange/default/default-message-receiver.js",
|
|
24
|
+
"#default-message-sender": "./components/exchange/default/default-message-sender.js",
|
|
25
|
+
"#exceptions": "./utils/exceptions.js",
|
|
26
|
+
"#gcloud-integration": "./integrations/gcloud-integration.js",
|
|
27
|
+
"#labels": "./bin/localization/labels.json",
|
|
28
|
+
"#localization": "./utils/localization.js",
|
|
29
|
+
"#logger": "./utils/logger.js",
|
|
30
|
+
"#message-dispatcher": "./components/exchange/message-dispatcher.js",
|
|
31
|
+
"#message-exchange": "./components/exchange/message-exchange.js",
|
|
32
|
+
"#message-handler": "./components/exchange/message-handler.js",
|
|
33
|
+
"#message-memory-cache": "./components/exchange/message-memory-cache.js",
|
|
34
|
+
"#message-observer": "./components/exchange/message-observer.js",
|
|
35
|
+
"#message-receiver": "./components/exchange/message-receiver.js",
|
|
36
|
+
"#message-sender": "./components/exchange/message-sender.js",
|
|
37
|
+
"#message-tracer": "./components/exchange/message-tracer.js",
|
|
38
|
+
"#redis-integration": "./integrations/redis-integration.js",
|
|
39
|
+
"#service-caller": "./components/service-caller.js",
|
|
40
|
+
"#service-consumer": "./components/service-consumer.js",
|
|
41
|
+
"#service-executor": "./components/service-executor.js",
|
|
42
|
+
"#service-instance": "./components/service-instance.js",
|
|
43
|
+
"#service-provider": "./components/service-provider.js",
|
|
44
|
+
"#settings": "./bin/settings.json",
|
|
45
|
+
"#tools": "./utils/tools.js"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"blake2": "^5.0.0",
|
|
49
|
+
"dotenv": "^17.2.1",
|
|
50
|
+
"fs-extra": "^11.3.1",
|
|
51
|
+
"lodash": "^4.17.21",
|
|
52
|
+
"node-schedule": "^2.1.1",
|
|
53
|
+
"ioredis": "^5.7.0"
|
|
54
|
+
},
|
|
55
|
+
"optionalDependencies": {
|
|
56
|
+
"@google-cloud/error-reporting": "^3.0.5",
|
|
57
|
+
"zeromq": "^6.5.0"
|
|
58
|
+
},
|
|
59
|
+
"repository": {
|
|
60
|
+
"type": "git",
|
|
61
|
+
"url": "git+https://github.com/Belleal/ti-engine.git"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=14.17.0"
|
|
65
|
+
}
|
|
64
66
|
}
|
package/utils/config.js
CHANGED
|
@@ -72,7 +72,7 @@ const tools = require( "#tools" );
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* @typedef {Object} SettingsLocalization
|
|
75
|
-
* @property {string} labelsPath
|
|
75
|
+
* @property {Array<string>} labelsPath
|
|
76
76
|
* @property {string} language
|
|
77
77
|
*/
|
|
78
78
|
|
|
@@ -200,4 +200,4 @@ Object.freeze( settings );
|
|
|
200
200
|
*/
|
|
201
201
|
module.exports.getSetting = ( setting, defaultValue ) => {
|
|
202
202
|
return _.get( settings, setting, defaultValue );
|
|
203
|
-
};
|
|
203
|
+
};
|
package/utils/exceptions.js
CHANGED
|
@@ -37,6 +37,7 @@ let exceptionCodeEnum = tools.enum( {
|
|
|
37
37
|
E_COM_SERVICE_NOT_REGISTERED: [ 3003, "service not registered", "The specified service is not found in the service registry." ],
|
|
38
38
|
E_COM_SERVICE_NOT_FOUND: [ 3004, "service not found", "The specified service is not found in the service definition interface." ],
|
|
39
39
|
E_COM_SERVICE_HANDLER_NOT_FOUND: [ 3005, "service handler not found", "No handler found in the interface for the specified service or service version." ],
|
|
40
|
+
E_COM_MESSAGE_RECEIVER_UNAVAILABLE: [ 3006, "message receiver unavailable", "The message receiver instance is currently unavailable." ],
|
|
40
41
|
// E_COM_UNRECOGNIZED_API_URL: [ 301, "unrecognized api url", "Attempt to access unrecognized or invalid API URL." ],
|
|
41
42
|
// E_COM_MISSING_REQUIRED_ARGUMENTS: [ 302, "missing required arguments", "Attempt to execute operation without all required arguments." ],
|
|
42
43
|
// E_COM_UNRECOGNIZED_RESPONSE_STRUCTURE: [ 303, "unrecognized response structure", "The received response has unrecognized structure and cannot be parsed or examined." ],
|
package/utils/localization.js
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
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-2025 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 _ = require( "lodash" );
|
|
10
|
-
const path = require( "path" );
|
|
11
|
-
const config = require( "#config" );
|
|
12
|
-
|
|
13
|
-
const labelsPath = path.normalize( path.join( process.cwd(), config.getSetting( config.setting.LOCALIZATION_LABELS_PATH ) ) );
|
|
14
|
-
const labels = require( labelsPath );
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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-2025 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 _ = require( "lodash" );
|
|
10
|
+
const path = require( "path" );
|
|
11
|
+
const config = require( "#config" );
|
|
12
|
+
|
|
13
|
+
// const labelsPath = path.normalize( path.join( process.cwd(), config.getSetting( config.setting.LOCALIZATION_LABELS_PATH ) ) );
|
|
14
|
+
// const labels = require( labelsPath );
|
|
15
|
+
const labels = require( "#labels" );
|
|
16
|
+
const defaultEmptyLabel = "!!! label not found !!!";
|
|
17
|
+
|
|
18
|
+
// TODO: Add functionality to import additional custom labels.
|
|
19
|
+
|
|
20
|
+
// prevent further modifications to the labels object:
|
|
21
|
+
Object.freeze( labels );
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Used to return the textual value for a label based on the current system language.
|
|
25
|
+
*
|
|
26
|
+
* @method
|
|
27
|
+
* @param {string} label This should be a dot-separated JSON path string.
|
|
28
|
+
* @returns {string}
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
module.exports.getLabel = ( label ) => {
|
|
32
|
+
return _.get( labels, label + "." + config.getSetting( config.setting.LOCALIZATION_LANGUAGE ), defaultEmptyLabel );
|
|
30
33
|
};
|
package/testRedis.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import Redis from "ioredis";
|
|
2
|
-
|
|
3
|
-
const redisClient = new Redis( {
|
|
4
|
-
port: 17467,
|
|
5
|
-
host: "redis-17467.c300.eu-central-1-1.ec2.redns.redis-cloud.com",
|
|
6
|
-
username: "default",
|
|
7
|
-
password: "o49Iyj2JYnmD7NSFWa32x2iYqulWkIM1",
|
|
8
|
-
db: 0,
|
|
9
|
-
autoResendUnfulfilledCommands: true,
|
|
10
|
-
maxRetriesPerRequest: null,
|
|
11
|
-
retryStrategy: ( attempt ) => {
|
|
12
|
-
let result = Math.min( attempt * 50, 1000 );
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
redisClient.on('error', err => console.log('Redis Client Error', err));
|
|
17
|
-
|
|
18
|
-
//await redisClient.connect();
|
|
19
|
-
|
|
20
|
-
await redisClient.set('foo', 'bar');
|
|
21
|
-
const result = await redisClient.get('foo');
|
|
22
|
-
console.log(result);
|