@ti-engine/core 1.0.14 → 1.1.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.
package/utils/cache.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
2
+ * SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
3
3
  * SPDX-License-Identifier: ICU
4
4
  */
5
5
 
@@ -278,6 +278,32 @@ class CommonMemoryCache extends ConnectionObserver {
278
278
  } );
279
279
  }
280
280
 
281
+ /**
282
+ * Used to set expiration in seconds to an existing key.
283
+ * <br/>
284
+ * NOTE: For performance optimization reasons, only use this only if the Redis command does not itself support the 'EX' argument.
285
+ *
286
+ * @method
287
+ * @param {string} key
288
+ * @param {number} seconds
289
+ * @returns {Promise<number>} This will resolve with the seconds as provided initially by the caller.
290
+ * @public
291
+ */
292
+ expireValue( key, seconds ) {
293
+ return new Promise( ( resolve, reject ) => {
294
+ if ( this.#isOperational === true ) {
295
+ let commandExpire = [ redis.cacheCommands.EXPIRE, key, seconds ];
296
+ this.#redisClient.executeCommands( [ commandExpire ] ).then( () => {
297
+ resolve( seconds );
298
+ } ).catch( ( error ) => {
299
+ reject( error );
300
+ } );
301
+ } else {
302
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
303
+ }
304
+ } );
305
+ }
306
+
281
307
  /**
282
308
  * Used to add the specified values to a list.
283
309
  *
@@ -313,7 +339,7 @@ class CommonMemoryCache extends ConnectionObserver {
313
339
  *
314
340
  * @method
315
341
  * @param {string} key
316
- * @param {string} value
342
+ * @param {string|Object} value
317
343
  * @returns {Promise}
318
344
  * @public
319
345
  */
@@ -516,6 +542,104 @@ class CommonMemoryCache extends ConnectionObserver {
516
542
  }
517
543
  } );
518
544
  }
545
+
546
+ /**
547
+ * Used to store a JSON variable.
548
+ * <br/>
549
+ * NOTE: Requires ReJSON module installed on server to work.
550
+ *
551
+ * @method
552
+ * @param {string} key
553
+ * @param {Object} value
554
+ * @param {string} [path='&']
555
+ * @param {number} [overrideMode=0] By default this allows full override for existing keys.
556
+ * Option 1 will set the key only if it doesn't already exist. Option 2 will set it only if it already exists.
557
+ * @returns {Promise}
558
+ * @public
559
+ */
560
+ setJSON( key, value, path = "$", overrideMode = 0 ) {
561
+ return new Promise( ( resolve, reject ) => {
562
+ if ( this.#isOperational === true ) {
563
+ if ( this.#redisClient.isJSONSupported ) {
564
+ let commandArguments = [ redis.cacheCommands.JSON_SET, key, path, tools.stringifyJSON( value ) ];
565
+ if ( overrideMode !== 0 ) {
566
+ commandArguments.push( overrideMode === 1 ? redis.cacheOverrideMode.NX : redis.cacheOverrideMode.XX );
567
+ }
568
+ this.#redisClient.callCommand( commandArguments ).then( () => {
569
+ resolve();
570
+ } ).catch( ( error ) => {
571
+ reject( error );
572
+ } );
573
+ } else {
574
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_FEATURE_UNSUPPORTED ), { details: "No RedisJSON module installed on server." } );
575
+ }
576
+ } else {
577
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
578
+ }
579
+ } );
580
+ }
581
+
582
+ /**
583
+ * Used to fetch a JSON variable.
584
+ * <br/>
585
+ * NOTE: Requires ReJSON module installed on server to work.
586
+ *
587
+ * @method
588
+ * @param {string} key
589
+ * @param {string} path
590
+ * @returns {Promise<Object>}
591
+ * @public
592
+ */
593
+ getJSON( key, path = "$" ) {
594
+ return new Promise( ( resolve, reject ) => {
595
+ if ( this.#isOperational === true ) {
596
+ if ( this.#redisClient.isJSONSupported ) {
597
+ let commandArguments = [ redis.cacheCommands.JSON_GET, key, path ];
598
+ this.#redisClient.callCommand( commandArguments ).then( ( result ) => {
599
+ resolve( tools.parseJSON( result ) );
600
+ } ).catch( ( error ) => {
601
+ reject( error );
602
+ } );
603
+ } else {
604
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_FEATURE_UNSUPPORTED ), { details: "No RedisJSON module installed on server." } );
605
+ }
606
+ } else {
607
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
608
+ }
609
+ } );
610
+ }
611
+
612
+ /**
613
+ * Used to add an item to a JSON array. That array needs to exist already.
614
+ * <br/>
615
+ * NOTE: Requires ReJSON module installed on server to work.
616
+ *
617
+ * @method
618
+ * @param {string} key
619
+ * @param {Object} value
620
+ * @param {string} path
621
+ * @returns {Promise}
622
+ * @public
623
+ */
624
+ arrayAppendJSON( key, value, path = "$" ) {
625
+ return new Promise( ( resolve, reject ) => {
626
+ if ( this.#isOperational === true ) {
627
+ if ( this.#redisClient.isJSONSupported ) {
628
+ let commandArguments = [ redis.cacheCommands.JSON_ARRAY_APPEND, key, path, tools.stringifyJSON( value ) ];
629
+ this.#redisClient.callCommand( commandArguments ).then( () => {
630
+ resolve();
631
+ } ).catch( ( error ) => {
632
+ reject( error );
633
+ } );
634
+ } else {
635
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_FEATURE_UNSUPPORTED ), { details: "No RedisJSON module installed on server." } );
636
+ }
637
+ } else {
638
+ reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
639
+ }
640
+ } );
641
+ }
642
+
519
643
  }
520
644
 
521
645
  const instance = new CommonMemoryCache();
package/utils/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
2
+ * SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
3
3
  * SPDX-License-Identifier: ICU
4
4
  */
5
5
 
@@ -21,12 +21,14 @@ const tools = require( "#tools" );
21
21
  * @property {EnvironmentVariable} env.TI_INSTANCE_ID
22
22
  * @property {EnvironmentVariable} env.TI_INSTANCE_NAME
23
23
  * @property {EnvironmentVariable} env.TI_AUDITING_LOG_CONSOLE_ENABLED
24
+ * @property {EnvironmentVariable} env.TI_AUDITING_LOG_DETAILS
24
25
  * @property {EnvironmentVariable} env.TI_AUDITING_LOG_MIN_LEVEL
25
26
  * @property {EnvironmentVariable} env.TI_AUDITING_LOG_USES_JSON
26
27
  * @property {EnvironmentVariable} env.TI_MEMORY_CACHE_AUTH_KEY
27
28
  * @property {EnvironmentVariable} env.TI_MEMORY_CACHE_REDIS_DB
28
29
  * @property {EnvironmentVariable} env.TI_MEMORY_CACHE_REDIS_HOST
29
30
  * @property {EnvironmentVariable} env.TI_MEMORY_CACHE_REDIS_PORT
31
+ * @property {EnvironmentVariable} env.TI_MEMORY_CACHE_USER
30
32
  * @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED
31
33
  * @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY
32
34
  * @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED
@@ -76,7 +78,9 @@ const tools = require( "#tools" );
76
78
  * @property {string} messageStore
77
79
  * @property {boolean} securityHashEnabled
78
80
  * @property {string} securityHashKey
81
+ * @property {number} traceExpirationTime
79
82
  * @property {boolean} traceLogEnabled
83
+ * @property {string} traceRepository
80
84
  */
81
85
 
82
86
  /**
@@ -110,7 +114,9 @@ let settingsEnum = tools.enum( {
110
114
  MESSAGE_EXCHANGE_MESSAGE_STORE: [ "messageExchange.messageStore", "messageStore", "" ],
111
115
  MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED: [ "messageExchange.securityHashEnabled", "securityHashEnabled", "" ],
112
116
  MESSAGE_EXCHANGE_SECURITY_HASH_KEY: [ "messageExchange.securityHashKey", "securityHashKey", "" ],
117
+ MESSAGE_EXCHANGE_TRACE_EXPIRATION_TIME: [ "messageExchange.traceExpirationTime", "traceExpirationTime", "" ],
113
118
  MESSAGE_EXCHANGE_TRACE_LOG_ENABLED: [ "messageExchange.traceLogEnabled", "traceLogEnabled", "" ],
119
+ MESSAGE_EXCHANGE_TRACE_REPOSITORY: [ "messageExchange.traceRepository", "traceRepository", "" ],
114
120
  SERVICE_EXECUTION_TIMEOUT: [ "serviceConfig.executionTimeout", "executionTimeout", "" ],
115
121
  SERVICE_HEALTH_CHECK_ADDRESS: [ "serviceConfig.healthCheckAddress", "healthCheckAddress", "" ],
116
122
  SERVICE_HEALTH_CHECK_INTERVAL: [ "serviceConfig.healthCheckInterval", "healthCheckInterval", "" ],
@@ -129,8 +135,9 @@ const settings = require( "#settings" );
129
135
 
130
136
  // override remaining settings with ENV variables (if provided):
131
137
  if ( settings.auditing ) {
132
- settings.auditing.logMinLevel = ( process.env.TI_AUDITING_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_AUDITING_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
133
138
  settings.auditing.logConsoleEnabled = ( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
139
+ settings.auditing.logDetails = ( process.env.TI_AUDITING_LOG_DETAILS !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_DETAILS ) : settings.auditing.logDetails;
140
+ settings.auditing.logMinLevel = ( process.env.TI_AUDITING_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_AUDITING_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
134
141
  settings.auditing.logUsesJSON = ( process.env.TI_AUDITING_LOG_USES_JSON !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_USES_JSON ) : settings.auditing.logUsesJSON;
135
142
  }
136
143
  if ( settings.memoryCache ) {
@@ -138,7 +145,7 @@ if ( settings.memoryCache ) {
138
145
  settings.memoryCache.redisDB = ( process.env.TI_MEMORY_CACHE_REDIS_DB !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_DB : settings.memoryCache.redisDB;
139
146
  settings.memoryCache.redisHost = ( process.env.TI_MEMORY_CACHE_REDIS_HOST !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_HOST : settings.memoryCache.redisHost;
140
147
  settings.memoryCache.redisPort = ( process.env.TI_MEMORY_CACHE_REDIS_PORT !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_PORT : settings.memoryCache.redisPort;
141
- settings.memoryCache.user = ( process.env.MEMORY_CACHE_USER !== undefined ) ? process.env.MEMORY_CACHE_USER : settings.memoryCache.user;
148
+ settings.memoryCache.user = ( process.env.TI_MEMORY_CACHE_USER !== undefined ) ? process.env.TI_MEMORY_CACHE_USER : settings.memoryCache.user;
142
149
  }
143
150
  if ( settings.messageExchange ) {
144
151
  settings.messageExchange.securityHashEnabled = ( process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED !== undefined ) ? tools.toBool( process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED ) : settings.messageExchange.securityHashEnabled;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
2
+ * SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
3
3
  * SPDX-License-Identifier: ICU
4
4
  */
5
5
 
@@ -21,6 +21,7 @@ let exceptionCodeEnum = tools.enum( {
21
21
  E_GEN_INVALID_SERVICE_DOMAIN_NAME: [ 1003, "invalid service domain name", "Invalid or no service domain name provided at microservice startup." ],
22
22
  E_GEN_SYSTEM_CACHE_UNAVAILABLE: [ 1004, "system cache unavailable", "The system cache required for proper engine operation is unavailable." ],
23
23
  E_GEN_BAD_SERVICE_HANDLER: [ 1005, "bad service handler", "The provided service handler is not a proper function." ],
24
+ E_GEN_FEATURE_UNSUPPORTED: [ 1006, "feature unsupported", "The requested feature is not supported by current configuration or version." ],
24
25
  /** Security & Administration related exceptions - codes under 2xxx */
25
26
  E_SEC_INVALID_AUTH_TOKEN: [ 2000, "invalid auth token", "Invalid authorization token provided." ],
26
27
  E_SEC_INVALID_EXPIRED_SESSION: [ 2001, "invalid or expired session", "Invalid or expired session encountered." ],
package/utils/logger.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
2
+ * SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
3
3
  * SPDX-License-Identifier: ICU
4
4
  */
5
5
 
@@ -41,6 +41,22 @@ module.exports.getSeverityName = ( severity ) => {
41
41
  return tools.getEnumName( logSeverityEnum, severity, "unknown" );
42
42
  };
43
43
 
44
+ /**
45
+ * Used to extract information from an Exception and convert it to loggable data object.
46
+ *
47
+ * @method
48
+ * @param {Exception} exception
49
+ * @returns {{description, details: (*|undefined), exceptionID}}
50
+ * @private
51
+ */
52
+ const exceptionToLog = ( exception ) => {
53
+ return {
54
+ exceptionID: exception.id,
55
+ description: exception.description,
56
+ details: !_.isEmpty( exception.data ) ? exception.data : undefined
57
+ };
58
+ };
59
+
44
60
  /**
45
61
  * Used to generate and store a log entry in the active cache.
46
62
  *
@@ -58,11 +74,9 @@ module.exports.log = ( message, level = logSeverityEnum.DEFAULT, data = {}, thre
58
74
  if ( data instanceof Error ) {
59
75
  data = tools.errorToJSON( data );
60
76
  } else if ( exceptions.isException( data ) ) {
61
- data = {
62
- id: data.id,
63
- description: data.description,
64
- details: !_.isEmpty( data.data ) ? data.data : undefined
65
- };
77
+ data = exceptionToLog( data );
78
+ } else if ( data.exception !== undefined && exceptions.isException( data.exception ) ) {
79
+ data.exception = exceptionToLog( data.exception );
66
80
  }
67
81
 
68
82
  auditing.log( message, level, thread, data );
package/utils/tools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
2
+ * SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
3
3
  * SPDX-License-Identifier: ICU
4
4
  */
5
5