@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
package/utils/cache.js
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
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 config = require( "#config" );
|
|
9
|
+
const tools = require( "#tools" );
|
|
10
|
+
const redis = require( "#redis-integration" );
|
|
11
|
+
const exceptions = require( "#exceptions" );
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Used to create and/or return a Common Memory Cache singleton instance.
|
|
15
|
+
*
|
|
16
|
+
* @class CommonMemoryCache
|
|
17
|
+
* @extends ConnectionObserver
|
|
18
|
+
* @singleton
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
class CommonMemoryCache extends ConnectionObserver {
|
|
22
|
+
|
|
23
|
+
static #instance = null;
|
|
24
|
+
#redisClient = null;
|
|
25
|
+
#isOperational = false;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @constructor
|
|
29
|
+
* @return {CommonMemoryCache}
|
|
30
|
+
*/
|
|
31
|
+
constructor() {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
if ( !CommonMemoryCache.#instance ) {
|
|
35
|
+
let host = config.getSetting( config.setting.MEMORY_CACHE_REDIS_HOST );
|
|
36
|
+
let port = config.getSetting( config.setting.MEMORY_CACHE_REDIS_PORT );
|
|
37
|
+
let db = config.getSetting( config.setting.MEMORY_CACHE_REDIS_DB );
|
|
38
|
+
let authKey = config.getSetting( config.setting.MEMORY_CACHE_AUTH_KEY );
|
|
39
|
+
this.#redisClient = redis.createRedisClient( "system", host, port, authKey, db );
|
|
40
|
+
this.#redisClient.addConnectionObserver( this );
|
|
41
|
+
CommonMemoryCache.#instance = this;
|
|
42
|
+
}
|
|
43
|
+
return CommonMemoryCache.#instance;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Public interface */
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Property returning the operational state of the cache.
|
|
50
|
+
*
|
|
51
|
+
* @property
|
|
52
|
+
* @returns {boolean}
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
get isOperational() { return this.#isOperational; }
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Needs to be invoked by the connection handler when the connection is disrupted.
|
|
59
|
+
*
|
|
60
|
+
* @method
|
|
61
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
62
|
+
* @override
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
onConnectionDisrupted( identifier ) {
|
|
66
|
+
this.#isOperational = false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Needs to be invoked by the connection handler when the connection is recovered.
|
|
71
|
+
*
|
|
72
|
+
* @method
|
|
73
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
74
|
+
* @override
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
onConnectionRecovered( identifier ) {
|
|
78
|
+
this.#isOperational = true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Used to register a new {@link ConnectionObserver} for events related to the underlying Redis connection state.
|
|
83
|
+
*
|
|
84
|
+
* @method
|
|
85
|
+
* @param {ConnectionObserver} connectionObserver The {@link ConnectionObserver} that will be notified of any changes.
|
|
86
|
+
* @public
|
|
87
|
+
*/
|
|
88
|
+
addConnectionObserver( connectionObserver ) {
|
|
89
|
+
this.#redisClient.addConnectionObserver( connectionObserver );
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Used to search for keys by given pattern.
|
|
94
|
+
*
|
|
95
|
+
* @method
|
|
96
|
+
* @param {string} pattern
|
|
97
|
+
* @returns {Promise<Array>}
|
|
98
|
+
* @public
|
|
99
|
+
*/
|
|
100
|
+
matchKeys( pattern ) {
|
|
101
|
+
return new Promise( ( resolve, reject ) => {
|
|
102
|
+
if ( this.#isOperational === true ) {
|
|
103
|
+
let commandKeys = [ redis.cacheCommands.KEYS, pattern ];
|
|
104
|
+
this.#redisClient.executeCommands( [ commandKeys ] ).then( ( results ) => {
|
|
105
|
+
results = results[ 0 ];
|
|
106
|
+
resolve( ( results && results.length > 1 ) ? results[ 1 ] : [] );
|
|
107
|
+
} ).catch( ( error ) => {
|
|
108
|
+
reject( error );
|
|
109
|
+
} );
|
|
110
|
+
} else {
|
|
111
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
112
|
+
}
|
|
113
|
+
} );
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Used to set a specific string value.
|
|
118
|
+
*
|
|
119
|
+
* @method
|
|
120
|
+
* @param {string} key
|
|
121
|
+
* @param {string} value
|
|
122
|
+
* @param {number} [expiration] Expiration value is in seconds.
|
|
123
|
+
* @return {Promise<string>}
|
|
124
|
+
* @public
|
|
125
|
+
*/
|
|
126
|
+
setValue( key, value, expiration ) {
|
|
127
|
+
return new Promise( ( resolve, reject ) => {
|
|
128
|
+
if ( this.#isOperational === true ) {
|
|
129
|
+
if ( value ) {
|
|
130
|
+
let commandSetValue = [ redis.cacheCommands.SET_VALUE, key, tools.stringifyJSON( value ) ];
|
|
131
|
+
if ( expiration ) {
|
|
132
|
+
commandSetValue.push( "EX" );
|
|
133
|
+
commandSetValue.push( expiration );
|
|
134
|
+
}
|
|
135
|
+
this.#redisClient.executeCommands( [ commandSetValue ] ).then( () => {
|
|
136
|
+
resolve( value );
|
|
137
|
+
} ).catch( ( error ) => {
|
|
138
|
+
reject( error );
|
|
139
|
+
} );
|
|
140
|
+
} else {
|
|
141
|
+
resolve( value );
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
145
|
+
}
|
|
146
|
+
} );
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Used to set multiple string values.
|
|
151
|
+
*
|
|
152
|
+
* @method
|
|
153
|
+
* @param {Object} keyValues
|
|
154
|
+
* @param {string} [prefix]
|
|
155
|
+
* @param {number} [expiration]
|
|
156
|
+
* @return {Promise}
|
|
157
|
+
* @public
|
|
158
|
+
*/
|
|
159
|
+
setValues( keyValues, prefix, expiration ) {
|
|
160
|
+
return new Promise( ( resolve, reject ) => {
|
|
161
|
+
if ( this.#isOperational === true ) {
|
|
162
|
+
if ( keyValues ) {
|
|
163
|
+
let commands = [];
|
|
164
|
+
_.forEach( keyValues, ( value, key ) => {
|
|
165
|
+
let commandSetValue = [ redis.cacheCommands.SET_VALUE, ( ( prefix ) ? prefix : "" ) + key, tools.stringifyJSON( value ) ];
|
|
166
|
+
if ( expiration ) {
|
|
167
|
+
commandSetValue.push( "EX" );
|
|
168
|
+
commandSetValue.push( expiration );
|
|
169
|
+
}
|
|
170
|
+
commands.push( commandSetValue );
|
|
171
|
+
} );
|
|
172
|
+
|
|
173
|
+
this.#redisClient.executeCommands( commands ).then( () => {
|
|
174
|
+
resolve( keyValues );
|
|
175
|
+
} ).catch( ( error ) => {
|
|
176
|
+
reject( error );
|
|
177
|
+
} );
|
|
178
|
+
} else {
|
|
179
|
+
resolve( keyValues );
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
183
|
+
}
|
|
184
|
+
} );
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Used to get a string value.
|
|
189
|
+
*
|
|
190
|
+
* @method
|
|
191
|
+
* @param {string} key
|
|
192
|
+
* @return {Promise}
|
|
193
|
+
* @public
|
|
194
|
+
*/
|
|
195
|
+
getValue( key ) {
|
|
196
|
+
return new Promise( ( resolve, reject ) => {
|
|
197
|
+
if ( this.#isOperational === true ) {
|
|
198
|
+
let commandGetValue = [ redis.cacheCommands.GET_VALUE, key ];
|
|
199
|
+
this.#redisClient.executeCommands( [ commandGetValue ] ).then( ( results ) => {
|
|
200
|
+
results = results[ 0 ];
|
|
201
|
+
resolve( ( results && results.length > 1 && _.isString( results[ 1 ] ) ) ? tools.parseJSON( results[ 1 ] ) : undefined );
|
|
202
|
+
} ).catch( ( error ) => {
|
|
203
|
+
reject( error );
|
|
204
|
+
} );
|
|
205
|
+
} else {
|
|
206
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
207
|
+
}
|
|
208
|
+
} );
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Used to get multiple string values.
|
|
213
|
+
*
|
|
214
|
+
* @method
|
|
215
|
+
* @param {string[]} keys
|
|
216
|
+
* @param {string} [prefix]
|
|
217
|
+
* @return {Promise}
|
|
218
|
+
* @public
|
|
219
|
+
*/
|
|
220
|
+
getValues( keys, prefix ) {
|
|
221
|
+
return new Promise( ( resolve, reject ) => {
|
|
222
|
+
if ( this.#isOperational === true ) {
|
|
223
|
+
let commands = [];
|
|
224
|
+
_.forEach( keys, ( key ) => {
|
|
225
|
+
commands.push( [ redis.cacheCommands.GET_VALUE, ( ( prefix ) ? prefix : "" ) + key ] );
|
|
226
|
+
} );
|
|
227
|
+
this.#redisClient.executeCommands( commands ).then( ( rawResults ) => {
|
|
228
|
+
let results = {};
|
|
229
|
+
_.forEach( rawResults, ( result, idx ) => {
|
|
230
|
+
results[ keys[ idx ] ] = ( results && results.length > 1 && _.isString( results[ 1 ] ) ) ? tools.parseJSON( results[ 1 ] ) : null;
|
|
231
|
+
} );
|
|
232
|
+
resolve( results );
|
|
233
|
+
} ).catch( ( error ) => {
|
|
234
|
+
reject( error );
|
|
235
|
+
} );
|
|
236
|
+
} else {
|
|
237
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
238
|
+
}
|
|
239
|
+
} );
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Used to delete a value / item.
|
|
244
|
+
*
|
|
245
|
+
* @method
|
|
246
|
+
* @param {string} key
|
|
247
|
+
* @returns {Promise<boolean>}
|
|
248
|
+
* @public
|
|
249
|
+
*/
|
|
250
|
+
deleteValue( key ) {
|
|
251
|
+
return new Promise( ( resolve, reject ) => {
|
|
252
|
+
if ( this.#isOperational === true ) {
|
|
253
|
+
let commandDeleteValue = [ redis.cacheCommands.DELETE_VALUE, key ];
|
|
254
|
+
this.#redisClient.executeCommands( [ commandDeleteValue ] ).then( ( results ) => {
|
|
255
|
+
results = results[ 0 ];
|
|
256
|
+
resolve( ( results && results.length > 1 ) ? results[ 1 ] : undefined );
|
|
257
|
+
} ).catch( ( error ) => {
|
|
258
|
+
reject( error );
|
|
259
|
+
} );
|
|
260
|
+
} else {
|
|
261
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
262
|
+
}
|
|
263
|
+
} );
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Used to add the specified values to a list.
|
|
268
|
+
*
|
|
269
|
+
* @method
|
|
270
|
+
* @param {string} listName
|
|
271
|
+
* @param {Object[]} values
|
|
272
|
+
* @returns {Promise<number>}
|
|
273
|
+
* @public
|
|
274
|
+
*/
|
|
275
|
+
listPushValue( listName, values ) {
|
|
276
|
+
return new Promise( ( resolve, reject ) => {
|
|
277
|
+
if ( this.#isOperational === true ) {
|
|
278
|
+
let commandPushValues = [ redis.cacheCommands.LIST_PUSH, listName ];
|
|
279
|
+
_.forEach( values, ( value ) => {
|
|
280
|
+
if ( value ) {
|
|
281
|
+
commandPushValues.push( tools.stringifyJSON( value ) );
|
|
282
|
+
}
|
|
283
|
+
} );
|
|
284
|
+
this.#redisClient.executeCommands( [ commandPushValues ] ).then( ( results ) => {
|
|
285
|
+
results = results[ 0 ];
|
|
286
|
+
resolve( ( results && results.length > 1 ) ? results[ 1 ] : undefined );
|
|
287
|
+
} ).catch( ( error ) => {
|
|
288
|
+
reject( error );
|
|
289
|
+
} );
|
|
290
|
+
} else {
|
|
291
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
292
|
+
}
|
|
293
|
+
} );
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Used to add the specified value to a set.
|
|
298
|
+
*
|
|
299
|
+
* @method
|
|
300
|
+
* @param {string} key
|
|
301
|
+
* @param {string} value
|
|
302
|
+
* @returns {Promise}
|
|
303
|
+
* @public
|
|
304
|
+
*/
|
|
305
|
+
addToSet( key, value ) {
|
|
306
|
+
return new Promise( ( resolve, reject ) => {
|
|
307
|
+
if ( this.#isOperational === true ) {
|
|
308
|
+
let commandAddToSet = [ redis.cacheCommands.ADD_TO_SET, key, tools.stringifyJSON( value ) ];
|
|
309
|
+
this.#redisClient.executeCommands( [ commandAddToSet ] ).then( () => {
|
|
310
|
+
resolve();
|
|
311
|
+
} ).catch( ( error ) => {
|
|
312
|
+
reject( error );
|
|
313
|
+
} );
|
|
314
|
+
} else {
|
|
315
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
316
|
+
}
|
|
317
|
+
} );
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Used to add multiple values to multiple sets in one transactional request.
|
|
322
|
+
* <br/>
|
|
323
|
+
* NOTE: The two arrays of keys and values must have correct index relations (i.e. first pair on keys[0] and values[0] and so on)!
|
|
324
|
+
*
|
|
325
|
+
* @method
|
|
326
|
+
* @param {string[]} keys
|
|
327
|
+
* @param {string[]} values
|
|
328
|
+
* @returns {Promise}
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
331
|
+
addToSetMulti( keys, values ) {
|
|
332
|
+
return new Promise( ( resolve, reject ) => {
|
|
333
|
+
if ( this.#isOperational === true ) {
|
|
334
|
+
let commands = [];
|
|
335
|
+
_.forEach( keys, ( key, idx ) => {
|
|
336
|
+
commands.push( [ redis.cacheCommands.ADD_TO_SET, key, tools.stringifyJSON( values[ idx ] ) ] );
|
|
337
|
+
} );
|
|
338
|
+
this.#redisClient.executeCommands( commands ).then( () => {
|
|
339
|
+
resolve();
|
|
340
|
+
} ).catch( ( error ) => {
|
|
341
|
+
reject( error );
|
|
342
|
+
} );
|
|
343
|
+
} else {
|
|
344
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
345
|
+
}
|
|
346
|
+
} );
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Used to check if the provided value is member of the specified set.
|
|
351
|
+
*
|
|
352
|
+
* @method
|
|
353
|
+
* @param {string} setName
|
|
354
|
+
* @param {string} value
|
|
355
|
+
* @returns {Promise<boolean>}
|
|
356
|
+
* @public
|
|
357
|
+
*/
|
|
358
|
+
isSetMember( setName, value ) {
|
|
359
|
+
return new Promise( ( resolve, reject ) => {
|
|
360
|
+
if ( this.#isOperational === true ) {
|
|
361
|
+
let commandIsSetMember = [ redis.cacheCommands.IS_SET_MEMBER, setName, value ];
|
|
362
|
+
this.#redisClient.executeCommands( [ commandIsSetMember ] ).then( ( results ) => {
|
|
363
|
+
results = results[ 0 ];
|
|
364
|
+
let result = !!( results && results.length > 1 && results[ 1 ] === 1 );
|
|
365
|
+
resolve( result );
|
|
366
|
+
} ).catch( ( error ) => {
|
|
367
|
+
reject( error );
|
|
368
|
+
} );
|
|
369
|
+
} else {
|
|
370
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
371
|
+
}
|
|
372
|
+
} );
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Used to get all elements of a set.
|
|
377
|
+
*
|
|
378
|
+
* @method
|
|
379
|
+
* @param {string} key
|
|
380
|
+
* @returns {Promise<Object[]>}
|
|
381
|
+
* @public
|
|
382
|
+
*/
|
|
383
|
+
membersOfSet( key ) {
|
|
384
|
+
return new Promise( ( resolve, reject ) => {
|
|
385
|
+
if ( this.#isOperational === true ) {
|
|
386
|
+
let commandMembersOfSet = [ redis.cacheCommands.GET_ALL_FROM_SET, key ];
|
|
387
|
+
this.#redisClient.executeCommands( [ commandMembersOfSet ] ).then( ( results ) => {
|
|
388
|
+
results = results[ 0 ];
|
|
389
|
+
let parsedResults = ( results && results.length > 1 && results[ 1 ] ) ? results[ 1 ] : [];
|
|
390
|
+
resolve( parsedResults );
|
|
391
|
+
} ).catch( ( error ) => {
|
|
392
|
+
reject( error );
|
|
393
|
+
} );
|
|
394
|
+
} else {
|
|
395
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
396
|
+
}
|
|
397
|
+
} );
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Used to get a union of all elements in the list of sets.
|
|
402
|
+
*
|
|
403
|
+
* @method
|
|
404
|
+
* @param {string[]} keys
|
|
405
|
+
* @returns {Promise<Object[]>}
|
|
406
|
+
* @public
|
|
407
|
+
*/
|
|
408
|
+
unionOfSets( keys ) {
|
|
409
|
+
return new Promise( ( resolve, reject ) => {
|
|
410
|
+
if ( this.#isOperational === true ) {
|
|
411
|
+
let commandUnionOfSets = _.concat( [ redis.cacheCommands.UNION_OF_SETS ], keys );
|
|
412
|
+
this.#redisClient.executeCommands( [ commandUnionOfSets ] ).then( ( results ) => {
|
|
413
|
+
results = results[ 0 ];
|
|
414
|
+
let parsedResults = ( results && results.length > 1 && results[ 1 ] ) ? results[ 1 ] : [];
|
|
415
|
+
resolve( parsedResults );
|
|
416
|
+
} ).catch( ( error ) => {
|
|
417
|
+
reject( error );
|
|
418
|
+
} );
|
|
419
|
+
} else {
|
|
420
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
421
|
+
}
|
|
422
|
+
} );
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Used to set a single hash field.
|
|
427
|
+
*
|
|
428
|
+
* @method
|
|
429
|
+
* @param {string} key
|
|
430
|
+
* @param {string} name
|
|
431
|
+
* @param {*} value
|
|
432
|
+
* @returns {Promise}
|
|
433
|
+
* @public
|
|
434
|
+
*/
|
|
435
|
+
hashSetField( key, name, value ) {
|
|
436
|
+
return new Promise( ( resolve, reject ) => {
|
|
437
|
+
if ( this.#isOperational === true ) {
|
|
438
|
+
let commandHashSetField = [ redis.cacheCommands.HASH_SET_MANY, key, name, tools.stringifyJSON( value ) ];
|
|
439
|
+
this.#redisClient.executeCommands( [ commandHashSetField ] ).then( () => {
|
|
440
|
+
resolve();
|
|
441
|
+
} ).catch( ( error ) => {
|
|
442
|
+
reject( error );
|
|
443
|
+
} );
|
|
444
|
+
} else {
|
|
445
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
446
|
+
}
|
|
447
|
+
} );
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Used to set multiple hash fields.
|
|
452
|
+
*
|
|
453
|
+
* @method
|
|
454
|
+
* @param {string} key
|
|
455
|
+
* @param {Object[]} fields
|
|
456
|
+
* @param {string} fields[].name
|
|
457
|
+
* @param {*} fields[].value
|
|
458
|
+
* @returns {Promise}
|
|
459
|
+
* @public
|
|
460
|
+
*/
|
|
461
|
+
hashSetFields( key, fields ) {
|
|
462
|
+
return new Promise( ( resolve, reject ) => {
|
|
463
|
+
if ( this.#isOperational === true ) {
|
|
464
|
+
let commandHashSetFields = [ redis.cacheCommands.HASH_SET_MANY, key ];
|
|
465
|
+
_.forEach( fields, ( field ) => {
|
|
466
|
+
commandHashSetFields.push( field.name );
|
|
467
|
+
commandHashSetFields.push( _.isObjectLike( field.value ) ? tools.stringifyJSON( field.value ) : field.value );
|
|
468
|
+
} );
|
|
469
|
+
this.#redisClient.executeCommands( [ commandHashSetFields ] ).then( () => {
|
|
470
|
+
resolve();
|
|
471
|
+
} ).catch( ( error ) => {
|
|
472
|
+
reject( error );
|
|
473
|
+
} );
|
|
474
|
+
} else {
|
|
475
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
476
|
+
}
|
|
477
|
+
} );
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Used to get a single field from a hash.
|
|
482
|
+
*
|
|
483
|
+
* @method
|
|
484
|
+
* @param {string} key
|
|
485
|
+
* @param {string} field
|
|
486
|
+
* @return {Promise}
|
|
487
|
+
* @public
|
|
488
|
+
*/
|
|
489
|
+
hashGetField( key, field ) {
|
|
490
|
+
return new Promise( ( resolve, reject ) => {
|
|
491
|
+
if ( this.#isOperational === true ) {
|
|
492
|
+
let commandHashGetField = [ redis.cacheCommands.HASH_GET, key, field ];
|
|
493
|
+
this.#redisClient.executeCommands( [ commandHashGetField ] ).then( ( results ) => {
|
|
494
|
+
results = results[ 0 ];
|
|
495
|
+
resolve( ( results && results.length > 1 && _.isString( results[ 1 ] ) ) ? tools.parseJSON( results[ 1 ] ) : null );
|
|
496
|
+
} ).catch( ( error ) => {
|
|
497
|
+
reject( error );
|
|
498
|
+
} );
|
|
499
|
+
} else {
|
|
500
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_GEN_SYSTEM_CACHE_UNAVAILABLE ) );
|
|
501
|
+
}
|
|
502
|
+
} );
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const instance = new CommonMemoryCache();
|
|
507
|
+
module.exports = Object.freeze( instance );
|
package/utils/config.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
3
|
+
* SPDX-License-Identifier: ICU
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const _ = require( "lodash" );
|
|
7
|
+
const tools = require( "#tools" );
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {string} EnvironmentVariable
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {NodeJS.Process} Environment
|
|
15
|
+
* @property {ProcessEnv} env
|
|
16
|
+
* @property {EnvironmentVariable} env.TI_GCLOUD_API_KEY
|
|
17
|
+
* @property {EnvironmentVariable} env.TI_GCLOUD_ENABLED
|
|
18
|
+
* @property {EnvironmentVariable} env.TI_GCLOUD_PROJECT_ID
|
|
19
|
+
* @property {EnvironmentVariable} env.TI_INSTANCE_CLASS
|
|
20
|
+
* @property {EnvironmentVariable} env.TI_INSTANCE_CONFIG
|
|
21
|
+
* @property {EnvironmentVariable} env.TI_INSTANCE_ID
|
|
22
|
+
* @property {EnvironmentVariable} env.TI_INSTANCE_NAME
|
|
23
|
+
* @property {EnvironmentVariable} env.TI_LOG_CONSOLE_ENABLED
|
|
24
|
+
* @property {EnvironmentVariable} env.TI_LOG_MIN_LEVEL
|
|
25
|
+
* @property {EnvironmentVariable} env.TI_LOG_USED_JSON
|
|
26
|
+
* @property {EnvironmentVariable} env.TI_OPERATION_MODE
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {string} CronString
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {Object} SettingsMain
|
|
35
|
+
* @property {SettingsAuditing} auditing
|
|
36
|
+
* @property {SettingsGcloudIntegration} gcloudIntegration
|
|
37
|
+
* @property {SettingsMemoryCache} memoryCache
|
|
38
|
+
* @property {SettingsMessageExchange} messageExchange
|
|
39
|
+
* @property {SettingsServiceConfig} serviceConfig
|
|
40
|
+
* @property {string} operationMode
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {Object} SettingsAuditing
|
|
45
|
+
* @property {boolean} logConsoleEnabled
|
|
46
|
+
* @property {boolean} logDetails
|
|
47
|
+
* @property {TiLogSeverity} logMinLevel
|
|
48
|
+
* @property {boolean} logUsesJSON
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {Object} SettingsGcloudIntegration
|
|
53
|
+
* @property {string} apiKey
|
|
54
|
+
* @property {string} projectID
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {Object} SettingsMemoryCache
|
|
59
|
+
* @property {string} authKey
|
|
60
|
+
* @property {number} redisDB
|
|
61
|
+
* @property {string} redisHost
|
|
62
|
+
* @property {number} redisPort
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {Object} SettingsMessageExchange
|
|
67
|
+
* @property {string} messageQueuePrefix
|
|
68
|
+
* @property {string} messageStore
|
|
69
|
+
* @property {boolean} traceLogEnabled
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @typedef {Object} SettingsServiceConfig
|
|
74
|
+
* @property {number} executionTimeout
|
|
75
|
+
* @property {string} healthCheckAddress
|
|
76
|
+
* @property {CronString} healthCheckInterval
|
|
77
|
+
* @property {number} healthCheckTimeout
|
|
78
|
+
* @property {string} serviceRegistryAddress
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Enum for listing all system settings.
|
|
83
|
+
*
|
|
84
|
+
* @readonly
|
|
85
|
+
* @enum {string} Keys of this ENUM are strings.
|
|
86
|
+
*/
|
|
87
|
+
let settingsEnum = tools.enum( {
|
|
88
|
+
AUDITING_LOG_CONSOLE_ENABLED: [ "auditing.logConsoleEnabled", "logConsoleEnabled", "" ],
|
|
89
|
+
AUDITING_LOG_DETAILS: [ "auditing.logDetails", "logDetails", "" ],
|
|
90
|
+
AUDITING_LOG_MIN_LEVEL: [ "auditing.logMinLevel", "logMinLevel", "" ],
|
|
91
|
+
AUDITING_LOG_USES_JSON: [ "auditing.logUsesJSON", "logUsesJSON", "" ],
|
|
92
|
+
GCLOUD_API_KEY: [ "gcloudIntegration.apiKey", "apiKey", "" ],
|
|
93
|
+
GCLOUD_PROJECT_ID: [ "gcloudIntegration.projectID", "projectID", "" ],
|
|
94
|
+
MEMORY_CACHE_AUTH_KEY: [ "memoryCache.authKey", "authKey", "" ],
|
|
95
|
+
MEMORY_CACHE_REDIS_DB: [ "memoryCache.redisDB", "redisDB", "" ],
|
|
96
|
+
MEMORY_CACHE_REDIS_HOST: [ "memoryCache.redisHost", "redisHost", "" ],
|
|
97
|
+
MEMORY_CACHE_REDIS_PORT: [ "memoryCache.redisPort", "redisPort", "" ],
|
|
98
|
+
MESSAGE_EXCHANGE_QUEUE_PREFIX: [ "messageExchange.messageQueuePrefix", "messageQueuePrefix", "" ],
|
|
99
|
+
MESSAGE_EXCHANGE_STORE: [ "messageExchange.messageStore", "messageStore", "" ],
|
|
100
|
+
MESSAGE_EXCHANGE_TRACE_LOG_ENABLED: [ "messageExchange.traceLogEnabled", "traceLogEnabled", "" ],
|
|
101
|
+
SERVICE_EXECUTION_TIMEOUT: [ "serviceConfig.executionTimeout", "executionTimeout", "" ],
|
|
102
|
+
SERVICE_HEALTH_CHECK_ADDRESS: [ "serviceConfig.healthCheckAddress", "healthCheckAddress", "" ],
|
|
103
|
+
SERVICE_HEALTH_CHECK_INTERVAL: [ "serviceConfig.healthCheckInterval", "healthCheckInterval", "" ],
|
|
104
|
+
SERVICE_HEALTH_CHECK_TIMEOUT: [ "serviceConfig.healthCheckTimeout", "healthCheckTimeout", "" ],
|
|
105
|
+
SERVICE_REGISTRY_ADDRESS: [ "serviceConfig.serviceRegistryAddress", "serviceRegistryAddress", "" ],
|
|
106
|
+
OPERATION_MODE: [ "operationMode", "operationMode", "" ]
|
|
107
|
+
} );
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @typedef {string} TiSetting
|
|
111
|
+
*/
|
|
112
|
+
module.exports.setting = settingsEnum;
|
|
113
|
+
|
|
114
|
+
/** @type {SettingsMain} */
|
|
115
|
+
const settings = require( "#settings" );
|
|
116
|
+
|
|
117
|
+
// override remaining settings with ENV variables (if provided):
|
|
118
|
+
if ( settings.auditing ) {
|
|
119
|
+
settings.auditing.logMinLevel = ( process.env.TI_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_LOG_CONSOLE_ENABLED : settings.auditing.logMinLevel;
|
|
120
|
+
settings.auditing.logConsoleEnabled = ( process.env.TI_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
|
|
121
|
+
settings.auditing.logUsesJSON = ( process.env.TI_LOG_USED_JSON !== undefined ) ? tools.toBool( process.env.TI_LOG_USED_JSON ) : settings.auditing.logUsesJSON;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// make sure GCloud is enabled before trying to setup it:
|
|
125
|
+
if ( process.env.TI_GCLOUD_ENABLED === true && settings.gcloudIntegration ) {
|
|
126
|
+
settings.gcloudIntegration.apiKey = ( process.env.TI_GCLOUD_API_KEY !== undefined ) ? process.env.TI_GCLOUD_API_KEY : settings.gcloudIntegration.apiKey;
|
|
127
|
+
settings.gcloudIntegration.projectID = ( process.env.TI_GCLOUD_PROJECT_ID !== undefined ) ? process.env.TI_GCLOUD_PROJECT_ID : settings.gcloudIntegration.projectID;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
settings.operationMode = process.env.TI_OPERATION_MODE || settings.operationMode;
|
|
131
|
+
|
|
132
|
+
// prevent further modifications to the settings object:
|
|
133
|
+
Object.freeze( settings );
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A standard getter method for fetching a setting.
|
|
137
|
+
*
|
|
138
|
+
* @method
|
|
139
|
+
* @param {string|TiSetting} setting Specifies either a dot-separated JSON path of the setting, or is a Setting from the settings enum.
|
|
140
|
+
* @param {*} [defaultValue] The default value to be returned if the setting is not found in the current configuration.
|
|
141
|
+
* @returns {*}
|
|
142
|
+
* @public
|
|
143
|
+
*/
|
|
144
|
+
module.exports.getSetting = ( setting, defaultValue ) => {
|
|
145
|
+
return _.get( settings, setting, defaultValue );
|
|
146
|
+
};
|