@ti-engine/core 1.3.12 → 1.4.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/CHANGELOG.md +36 -1
- package/bin/localization/labels.json +12 -0
- package/bin/start-instance.js +1 -1
- package/components/auditing.js +47 -22
- package/components/connection-observer.js +2 -2
- package/components/definitions.types.js +248 -0
- package/components/exchange/message-dispatcher.js +1 -1
- package/components/exchange/message-exchange.js +6 -30
- package/components/exchange/message-handler.js +2 -2
- package/components/exchange/message-memory-cache.js +1 -1
- package/components/exchange/message-observer.js +2 -2
- package/components/exchange/message-receiver.js +2 -2
- package/components/exchange/message-sender.js +2 -2
- package/components/exchange/message-tracer.js +4 -27
- package/components/service-caller.js +1 -40
- package/components/service-consumer.js +1 -1
- package/components/service-executor.js +1 -16
- package/components/service-instance.js +4 -9
- package/components/service-provider.js +9 -8
- package/integrations/redis-integration.js +8 -13
- package/package.json +8 -10
- package/utils/cache.js +57 -12
- package/utils/config.js +103 -200
- package/utils/exceptions.js +37 -20
- package/utils/localization.js +2 -17
- package/utils/logger.js +5 -8
- package/utils/tools.js +5 -20
- package/integrations/gcloud-integration.js +0 -65
package/utils/config.js
CHANGED
|
@@ -1,201 +1,104 @@
|
|
|
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-
|
|
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 tools = require( "#tools" );
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* @typedef {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* @
|
|
97
|
-
* @
|
|
98
|
-
* @
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* @property {string} healthCheckAddress
|
|
105
|
-
* @property {CronString} healthCheckInterval
|
|
106
|
-
* @property {number} healthCheckTimeout
|
|
107
|
-
* @property {string} serviceRegistryAddress
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Enum for listing all system settings.
|
|
112
|
-
*
|
|
113
|
-
* @readonly
|
|
114
|
-
* @enum {string} Keys of this ENUM are strings.
|
|
115
|
-
* @typedef {string} TiSetting
|
|
116
|
-
*/
|
|
117
|
-
const settingsEnum = tools.enum( {
|
|
118
|
-
AUDITING_LOG_CONSOLE_ENABLED: [ "auditing.logConsoleEnabled", "logConsoleEnabled", "" ],
|
|
119
|
-
AUDITING_LOG_DETAILS: [ "auditing.logDetails", "logDetails", "" ],
|
|
120
|
-
AUDITING_LOG_MIN_LEVEL: [ "auditing.logMinLevel", "logMinLevel", "" ],
|
|
121
|
-
AUDITING_LOG_USES_JSON: [ "auditing.logUsesJSON", "logUsesJSON", "" ],
|
|
122
|
-
GCLOUD_API_KEY: [ "gcloudIntegration.apiKey", "apiKey", "" ],
|
|
123
|
-
GCLOUD_PROJECT_ID: [ "gcloudIntegration.projectID", "projectID", "" ],
|
|
124
|
-
LOCALIZATION_LABELS_PATH: [ "localization.labelsPath", "labelsPath", "" ],
|
|
125
|
-
LOCALIZATION_LANGUAGE: [ "localization.language", "language", "" ],
|
|
126
|
-
MEMORY_CACHE_AUTH_KEY: [ "memoryCache.authKey", "authKey", "" ],
|
|
127
|
-
MEMORY_CACHE_REDIS_DB: [ "memoryCache.redisDB", "redisDB", "" ],
|
|
128
|
-
MEMORY_CACHE_REDIS_HOST: [ "memoryCache.redisHost", "redisHost", "" ],
|
|
129
|
-
MEMORY_CACHE_REDIS_PORT: [ "memoryCache.redisPort", "redisPort", "" ],
|
|
130
|
-
MEMORY_CACHE_RETRY_MAX_ATTEMPTS: [ "memoryCache.retryMaxAttempts", "retryMaxAttempts", "" ],
|
|
131
|
-
MEMORY_CACHE_RETRY_MAX_INTERVAL: [ "memoryCache.retryMaxInterval", "retryMaxInterval", "" ],
|
|
132
|
-
MEMORY_CACHE_USER: [ "memoryCache.user", "user", "" ],
|
|
133
|
-
MESSAGE_EXCHANGE_QUEUE_PREFIX: [ "messageExchange.messageQueuePrefix", "messageQueuePrefix", "" ],
|
|
134
|
-
MESSAGE_EXCHANGE_MESSAGE_STORE: [ "messageExchange.messageStore", "messageStore", "" ],
|
|
135
|
-
MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED: [ "messageExchange.securityHashEnabled", "securityHashEnabled", "" ],
|
|
136
|
-
MESSAGE_EXCHANGE_SECURITY_HASH_KEY: [ "messageExchange.securityHashKey", "securityHashKey", "" ],
|
|
137
|
-
MESSAGE_EXCHANGE_TRACE_EXPIRATION_TIME: [ "messageExchange.traceExpirationTime", "traceExpirationTime", "" ],
|
|
138
|
-
MESSAGE_EXCHANGE_TRACE_LOG_ENABLED: [ "messageExchange.traceLogEnabled", "traceLogEnabled", "" ],
|
|
139
|
-
MESSAGE_EXCHANGE_TRACE_REPOSITORY: [ "messageExchange.traceRepository", "traceRepository", "" ],
|
|
140
|
-
SERVICE_EXECUTION_TIMEOUT: [ "serviceConfig.executionTimeout", "executionTimeout", "" ],
|
|
141
|
-
SERVICE_HEALTH_CHECK_ADDRESS: [ "serviceConfig.healthCheckAddress", "healthCheckAddress", "" ],
|
|
142
|
-
SERVICE_HEALTH_CHECK_INTERVAL: [ "serviceConfig.healthCheckInterval", "healthCheckInterval", "" ],
|
|
143
|
-
SERVICE_HEALTH_CHECK_TIMEOUT: [ "serviceConfig.healthCheckTimeout", "healthCheckTimeout", "" ],
|
|
144
|
-
SERVICE_REGISTRY_ADDRESS: [ "serviceConfig.serviceRegistryAddress", "serviceRegistryAddress", "" ],
|
|
145
|
-
OPERATION_MODE: [ "operationMode", "operationMode", "" ]
|
|
146
|
-
} );
|
|
147
|
-
|
|
148
|
-
module.exports.setting = settingsEnum;
|
|
149
|
-
|
|
150
|
-
/** @type {SettingsMain} */
|
|
151
|
-
const settings = require( "#settings" );
|
|
152
|
-
|
|
153
|
-
// Override the remaining settings with ENV variables (if provided):
|
|
154
|
-
if ( settings.auditing ) {
|
|
155
|
-
settings.auditing.logConsoleEnabled = ( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
|
|
156
|
-
settings.auditing.logDetails = ( process.env.TI_AUDITING_LOG_DETAILS !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_DETAILS ) : settings.auditing.logDetails;
|
|
157
|
-
settings.auditing.logMinLevel = ( process.env.TI_AUDITING_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_AUDITING_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
|
|
158
|
-
settings.auditing.logUsesJSON = ( process.env.TI_AUDITING_LOG_USES_JSON !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_USES_JSON ) : settings.auditing.logUsesJSON;
|
|
159
|
-
}
|
|
160
|
-
if ( settings.localization ) {
|
|
161
|
-
settings.localization.labelsPath = ( process.env.TI_LOCALIZATION_LABELS_PATH !== undefined ) ? [ process.env.TI_LOCALIZATION_LABELS_PATH ] : settings.localization.labelsPath;
|
|
162
|
-
settings.localization.language = ( process.env.TI_LOCALIZATION_LANGUAGE !== undefined ) ? process.env.TI_LOCALIZATION_LANGUAGE : settings.localization.language;
|
|
163
|
-
}
|
|
164
|
-
if ( settings.memoryCache ) {
|
|
165
|
-
settings.memoryCache.authKey = ( process.env.TI_MEMORY_CACHE_AUTH_KEY !== undefined ) ? process.env.TI_MEMORY_CACHE_AUTH_KEY : settings.memoryCache.authKey;
|
|
166
|
-
settings.memoryCache.redisDB = ( process.env.TI_MEMORY_CACHE_REDIS_DB !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_REDIS_DB ) : settings.memoryCache.redisDB;
|
|
167
|
-
settings.memoryCache.redisHost = ( process.env.TI_MEMORY_CACHE_REDIS_HOST !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_HOST : settings.memoryCache.redisHost;
|
|
168
|
-
settings.memoryCache.redisPort = ( process.env.TI_MEMORY_CACHE_REDIS_PORT !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_REDIS_PORT ) : settings.memoryCache.redisPort;
|
|
169
|
-
settings.memoryCache.retryMaxAttempts = ( process.env.TI_MEMORY_CACHE_RETRY_MAX_ATTEMPTS !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_RETRY_MAX_ATTEMPTS ) : settings.memoryCache.retryMaxAttempts;
|
|
170
|
-
settings.memoryCache.retryMaxInterval = ( process.env.TI_MEMORY_CACHE_RETRY_MAX_INTERVAL !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_RETRY_MAX_INTERVAL ) : settings.memoryCache.retryMaxInterval;
|
|
171
|
-
settings.memoryCache.user = ( process.env.TI_MEMORY_CACHE_USER !== undefined ) ? process.env.TI_MEMORY_CACHE_USER : settings.memoryCache.user;
|
|
172
|
-
}
|
|
173
|
-
if ( settings.messageExchange ) {
|
|
174
|
-
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;
|
|
175
|
-
settings.messageExchange.securityHashKey = ( process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY !== undefined ) ? process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY : settings.messageExchange.securityHashKey;
|
|
176
|
-
settings.messageExchange.traceLogEnabled = ( process.env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED !== undefined ) ? tools.toBool( process.env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED ) : settings.messageExchange.traceLogEnabled;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Make sure GCloud is enabled before trying to set it up:
|
|
180
|
-
if ( tools.toBool( process.env.TI_GCLOUD_ENABLED ) === true && settings.gcloudIntegration ) {
|
|
181
|
-
settings.gcloudIntegration.apiKey = ( process.env.TI_GCLOUD_API_KEY !== undefined ) ? process.env.TI_GCLOUD_API_KEY : settings.gcloudIntegration.apiKey;
|
|
182
|
-
settings.gcloudIntegration.projectID = ( process.env.TI_GCLOUD_PROJECT_ID !== undefined ) ? process.env.TI_GCLOUD_PROJECT_ID : settings.gcloudIntegration.projectID;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
settings.operationMode = process.env.NODE_ENV || settings.operationMode;
|
|
186
|
-
|
|
187
|
-
// Prevent further modifications to the settings object:
|
|
188
|
-
tools.deepFreeze( settings );
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* A standard getter method for fetching a setting.
|
|
192
|
-
*
|
|
193
|
-
* @method
|
|
194
|
-
* @param {string|TiSetting} setting Specifies either a dot-separated JSON path of the setting, or is a Setting from the settings enum.
|
|
195
|
-
* @param {*} [defaultValue] The default value to be returned if the setting is not found in the current configuration.
|
|
196
|
-
* @returns {*}
|
|
197
|
-
* @public
|
|
198
|
-
*/
|
|
199
|
-
module.exports.getSetting = ( setting, defaultValue ) => {
|
|
200
|
-
return _.get( settings, setting, defaultValue );
|
|
1
|
+
/*
|
|
2
|
+
* The ti-engine is an open source, free to use—both for personal and commercial projects—framework for the creation of microservice-based solutions using node.js.
|
|
3
|
+
* Copyright © 2021-2026 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
5
|
+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
6
|
+
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const _ = require( "lodash" );
|
|
10
|
+
const tools = require( "#tools" );
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Enum for listing all system settings.
|
|
14
|
+
*
|
|
15
|
+
* @readonly
|
|
16
|
+
* @enum {string} Keys of this ENUM are strings.
|
|
17
|
+
* @typedef {string} TiSetting
|
|
18
|
+
*/
|
|
19
|
+
const settingsEnum = tools.enum( {
|
|
20
|
+
AUDITING_LOG_CONSOLE_ENABLED: [ "auditing.logConsoleEnabled", "logConsoleEnabled", "" ],
|
|
21
|
+
AUDITING_LOG_DETAILS: [ "auditing.logDetails", "logDetails", "" ],
|
|
22
|
+
AUDITING_LOG_MIN_LEVEL: [ "auditing.logMinLevel", "logMinLevel", "" ],
|
|
23
|
+
AUDITING_LOG_USES_JSON: [ "auditing.logUsesJSON", "logUsesJSON", "" ],
|
|
24
|
+
GCLOUD_API_KEY: [ "gcloudIntegration.apiKey", "apiKey", "" ],
|
|
25
|
+
GCLOUD_PROJECT_ID: [ "gcloudIntegration.projectID", "projectID", "" ],
|
|
26
|
+
LOCALIZATION_LABELS_PATH: [ "localization.labelsPath", "labelsPath", "" ],
|
|
27
|
+
LOCALIZATION_LANGUAGE: [ "localization.language", "language", "" ],
|
|
28
|
+
MEMORY_CACHE_AUTH_KEY: [ "memoryCache.authKey", "authKey", "" ],
|
|
29
|
+
MEMORY_CACHE_REDIS_DB: [ "memoryCache.redisDB", "redisDB", "" ],
|
|
30
|
+
MEMORY_CACHE_REDIS_HOST: [ "memoryCache.redisHost", "redisHost", "" ],
|
|
31
|
+
MEMORY_CACHE_REDIS_PORT: [ "memoryCache.redisPort", "redisPort", "" ],
|
|
32
|
+
MEMORY_CACHE_RETRY_MAX_ATTEMPTS: [ "memoryCache.retryMaxAttempts", "retryMaxAttempts", "" ],
|
|
33
|
+
MEMORY_CACHE_RETRY_MAX_INTERVAL: [ "memoryCache.retryMaxInterval", "retryMaxInterval", "" ],
|
|
34
|
+
MEMORY_CACHE_USER: [ "memoryCache.user", "user", "" ],
|
|
35
|
+
MESSAGE_EXCHANGE_QUEUE_PREFIX: [ "messageExchange.messageQueuePrefix", "messageQueuePrefix", "" ],
|
|
36
|
+
MESSAGE_EXCHANGE_MESSAGE_STORE: [ "messageExchange.messageStore", "messageStore", "" ],
|
|
37
|
+
MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED: [ "messageExchange.securityHashEnabled", "securityHashEnabled", "" ],
|
|
38
|
+
MESSAGE_EXCHANGE_SECURITY_HASH_KEY: [ "messageExchange.securityHashKey", "securityHashKey", "" ],
|
|
39
|
+
MESSAGE_EXCHANGE_TRACE_EXPIRATION_TIME: [ "messageExchange.traceExpirationTime", "traceExpirationTime", "" ],
|
|
40
|
+
MESSAGE_EXCHANGE_TRACE_LOG_ENABLED: [ "messageExchange.traceLogEnabled", "traceLogEnabled", "" ],
|
|
41
|
+
MESSAGE_EXCHANGE_TRACE_REPOSITORY: [ "messageExchange.traceRepository", "traceRepository", "" ],
|
|
42
|
+
SERVICE_EXECUTION_TIMEOUT: [ "serviceConfig.executionTimeout", "executionTimeout", "" ],
|
|
43
|
+
SERVICE_HEALTH_CHECK_ADDRESS: [ "serviceConfig.healthCheckAddress", "healthCheckAddress", "" ],
|
|
44
|
+
SERVICE_HEALTH_CHECK_INTERVAL: [ "serviceConfig.healthCheckInterval", "healthCheckInterval", "" ],
|
|
45
|
+
SERVICE_HEALTH_CHECK_TIMEOUT: [ "serviceConfig.healthCheckTimeout", "healthCheckTimeout", "" ],
|
|
46
|
+
SERVICE_REGISTRY_ADDRESS: [ "serviceConfig.serviceRegistryAddress", "serviceRegistryAddress", "" ],
|
|
47
|
+
OPERATION_MODE: [ "operationMode", "operationMode", "" ]
|
|
48
|
+
} );
|
|
49
|
+
module.exports.setting = settingsEnum;
|
|
50
|
+
|
|
51
|
+
/** @type {SettingsMain} */
|
|
52
|
+
const settings = require( "#settings" );
|
|
53
|
+
|
|
54
|
+
// Override the remaining settings with ENV variables (if provided):
|
|
55
|
+
if ( settings.auditing ) {
|
|
56
|
+
settings.auditing.logConsoleEnabled = ( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
|
|
57
|
+
settings.auditing.logDetails = ( process.env.TI_AUDITING_LOG_DETAILS !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_DETAILS ) : settings.auditing.logDetails;
|
|
58
|
+
settings.auditing.logMinLevel = ( process.env.TI_AUDITING_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_AUDITING_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
|
|
59
|
+
settings.auditing.logUsesJSON = ( process.env.TI_AUDITING_LOG_USES_JSON !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_USES_JSON ) : settings.auditing.logUsesJSON;
|
|
60
|
+
}
|
|
61
|
+
if ( settings.localization ) {
|
|
62
|
+
settings.localization.labelsPath = ( process.env.TI_LOCALIZATION_LABELS_PATH !== undefined )
|
|
63
|
+
? process.env.TI_LOCALIZATION_LABELS_PATH.split( "," ).map( ( p ) => p.trim() ).filter( Boolean )
|
|
64
|
+
: settings.localization.labelsPath;
|
|
65
|
+
settings.localization.language = ( process.env.TI_LOCALIZATION_LANGUAGE !== undefined ) ? process.env.TI_LOCALIZATION_LANGUAGE : settings.localization.language;
|
|
66
|
+
}
|
|
67
|
+
if ( settings.memoryCache ) {
|
|
68
|
+
settings.memoryCache.authKey = ( process.env.TI_MEMORY_CACHE_AUTH_KEY !== undefined ) ? process.env.TI_MEMORY_CACHE_AUTH_KEY : settings.memoryCache.authKey;
|
|
69
|
+
settings.memoryCache.redisDB = ( process.env.TI_MEMORY_CACHE_REDIS_DB !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_REDIS_DB ) : settings.memoryCache.redisDB;
|
|
70
|
+
settings.memoryCache.redisHost = ( process.env.TI_MEMORY_CACHE_REDIS_HOST !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_HOST : settings.memoryCache.redisHost;
|
|
71
|
+
settings.memoryCache.redisPort = ( process.env.TI_MEMORY_CACHE_REDIS_PORT !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_REDIS_PORT ) : settings.memoryCache.redisPort;
|
|
72
|
+
settings.memoryCache.retryMaxAttempts = ( process.env.TI_MEMORY_CACHE_RETRY_MAX_ATTEMPTS !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_RETRY_MAX_ATTEMPTS ) : settings.memoryCache.retryMaxAttempts;
|
|
73
|
+
settings.memoryCache.retryMaxInterval = ( process.env.TI_MEMORY_CACHE_RETRY_MAX_INTERVAL !== undefined ) ? Number( process.env.TI_MEMORY_CACHE_RETRY_MAX_INTERVAL ) : settings.memoryCache.retryMaxInterval;
|
|
74
|
+
settings.memoryCache.user = ( process.env.TI_MEMORY_CACHE_USER !== undefined ) ? process.env.TI_MEMORY_CACHE_USER : settings.memoryCache.user;
|
|
75
|
+
}
|
|
76
|
+
if ( settings.messageExchange ) {
|
|
77
|
+
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;
|
|
78
|
+
settings.messageExchange.securityHashKey = ( process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY !== undefined ) ? process.env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY : settings.messageExchange.securityHashKey;
|
|
79
|
+
settings.messageExchange.traceLogEnabled = ( process.env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED !== undefined ) ? tools.toBool( process.env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED ) : settings.messageExchange.traceLogEnabled;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Make sure GCloud is enabled before trying to set it up:
|
|
83
|
+
if ( tools.toBool( process.env.TI_GCLOUD_ENABLED ) === true && settings.gcloudIntegration ) {
|
|
84
|
+
settings.gcloudIntegration.apiKey = ( process.env.TI_GCLOUD_API_KEY !== undefined ) ? process.env.TI_GCLOUD_API_KEY : settings.gcloudIntegration.apiKey;
|
|
85
|
+
settings.gcloudIntegration.projectID = ( process.env.TI_GCLOUD_PROJECT_ID !== undefined ) ? process.env.TI_GCLOUD_PROJECT_ID : settings.gcloudIntegration.projectID;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
settings.operationMode = process.env.NODE_ENV || settings.operationMode;
|
|
89
|
+
|
|
90
|
+
// Prevent further modifications to the settings object:
|
|
91
|
+
tools.deepFreeze( settings );
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A standard getter method for fetching a setting.
|
|
95
|
+
*
|
|
96
|
+
* @method
|
|
97
|
+
* @param {string|TiSetting} setting Specifies either a dot-separated JSON path of the setting, or is a Setting from the settings enum.
|
|
98
|
+
* @param {*} [defaultValue] The default value to be returned if the setting is not found in the current configuration.
|
|
99
|
+
* @returns {*}
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
module.exports.getSetting = ( setting, defaultValue ) => {
|
|
103
|
+
return _.get( settings, setting, defaultValue );
|
|
201
104
|
};
|
package/utils/exceptions.js
CHANGED
|
@@ -28,6 +28,8 @@ const exceptionCodeEnum = tools.enum( {
|
|
|
28
28
|
E_GEN_FEATURE_UNSUPPORTED: [ 1006, "feature unsupported", "The requested feature is not supported by current configuration or version." ],
|
|
29
29
|
E_GEN_INVALID_ARGUMENT_TYPE: [ 1007, "invalid argument type", "The provided argument is not of the expected type." ],
|
|
30
30
|
E_GEN_NOT_INITIALIZED: [ 1008, "not initialized", "The invoked framework component is not initialized." ],
|
|
31
|
+
E_GEN_UNALLOWED_OVERRIDE: [ 1009, "unallowed override", "Attempt to override a protected or private method or property detected." ],
|
|
32
|
+
E_GEN_NOT_IMPLEMENTED: [ 1010, "not implemented", "The requested functionality is not yet implemented." ],
|
|
31
33
|
/** Security & Administration exceptions - codes under 2xxx */
|
|
32
34
|
E_SEC_INVALID_AUTH_TOKEN: [ 2000, "invalid auth token", "Invalid authorization token provided." ],
|
|
33
35
|
E_SEC_INVALID_EXPIRED_SESSION: [ 2001, "invalid or expired session", "Invalid or expired session encountered." ],
|
|
@@ -55,9 +57,11 @@ const exceptionCodeEnum = tools.enum( {
|
|
|
55
57
|
E_WEB_INVALID_REQUEST_FORMAT: [ 4006, "invalid request format", "The request format is not recognized or not supported." ],
|
|
56
58
|
E_WEB_INVALID_REQUEST_CONTENT_TYPE: [ 4007, "invalid request content type", "The request content type is not recognized or not supported." ],
|
|
57
59
|
E_WEB_INVALID_REQUEST_CONTENT_LENGTH: [ 4008, "invalid request content length", "The request content length is not recognized or not supported." ],
|
|
58
|
-
E_WEB_INVALID_REQUEST_CONTENT_ENCODING: [ 4009, "invalid request content encoding", "The request content encoding is not recognized or not supported." ]
|
|
60
|
+
E_WEB_INVALID_REQUEST_CONTENT_ENCODING: [ 4009, "invalid request content encoding", "The request content encoding is not recognized or not supported." ],
|
|
61
|
+
/** Application exceptions - codes under 5xxx */
|
|
62
|
+
E_APP_RESOURCE_NOT_FOUND: [ 5004, "resource not found", "The requested resource cannot be found. See details for more information." ],
|
|
63
|
+
E_APP_SERVICE_ERROR: [ 5005, "app service error", "The application service encountered an error. See details for more information." ]
|
|
59
64
|
} );
|
|
60
|
-
|
|
61
65
|
module.exports.exceptionCode = exceptionCodeEnum;
|
|
62
66
|
|
|
63
67
|
/**
|
|
@@ -133,18 +137,17 @@ const httpCodeEnum = tools.enum( {
|
|
|
133
137
|
C_510: [ 510, "Not Extended", "Further extensions to the request are required for the server to fulfil it." ],
|
|
134
138
|
C_511: [ 511, "Network Authentication Required", "The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network." ]
|
|
135
139
|
} );
|
|
136
|
-
|
|
137
140
|
module.exports.httpCode = httpCodeEnum;
|
|
138
141
|
|
|
139
142
|
const labelPath = "system.exceptions.";
|
|
140
143
|
|
|
141
144
|
/**
|
|
142
|
-
* Represents an exception.
|
|
145
|
+
* Represents an any-purpose exception.
|
|
143
146
|
*
|
|
144
|
-
* @class
|
|
147
|
+
* @class TiException
|
|
145
148
|
* @public
|
|
146
149
|
*/
|
|
147
|
-
class
|
|
150
|
+
class TiException {
|
|
148
151
|
|
|
149
152
|
#id;
|
|
150
153
|
#code;
|
|
@@ -265,7 +268,7 @@ class Exception {
|
|
|
265
268
|
}
|
|
266
269
|
|
|
267
270
|
/**
|
|
268
|
-
* Extracts the essential information about the
|
|
271
|
+
* Extracts the essential information about the {@link TiException} and returns it as JSON.
|
|
269
272
|
*
|
|
270
273
|
* @method
|
|
271
274
|
* @param {boolean} [includeData=true] Whether to include the data property in the output.
|
|
@@ -291,38 +294,48 @@ class Exception {
|
|
|
291
294
|
|
|
292
295
|
/**
|
|
293
296
|
* Used to raise an exception from the provided source.
|
|
297
|
+
* <br/>
|
|
298
|
+
* NOTE: Custom numeric exception IDs are not supported when 'httpCode' is omitted!
|
|
294
299
|
*
|
|
295
300
|
* @method
|
|
296
|
-
* @param {Error|TiExceptionCode|
|
|
301
|
+
* @param {Error|TiExceptionCode|TiException} source Could be a standard JS Error, an ExceptionCode, or another TiException (in which case it will be raised further).
|
|
297
302
|
* @param {Object} [data] Additional JSON data that can go with the exception. If more data is added on later Raise calls, it will be merged with the existing one.
|
|
298
|
-
* @param {string} [exceptionID] Should be used only in cases when we have a recognizable exception ID beforehand. Should not be entered otherwise!
|
|
299
|
-
* @
|
|
303
|
+
* @param {string} [exceptionID=undefined] Should be used only in cases when we have a recognizable exception ID beforehand. Should not be entered otherwise!
|
|
304
|
+
* @param {TiHttpCode} [httpCode=undefined] An optional HTTP code in case this exception needs to be propagated to a web-application frontend. If provided, this will
|
|
305
|
+
* override any preexisting HTTP code in 'source'!
|
|
306
|
+
* @returns {TiException}
|
|
300
307
|
* @public
|
|
301
308
|
*/
|
|
302
|
-
module.exports.raise = ( source, data, exceptionID ) => {
|
|
303
|
-
/** @type
|
|
309
|
+
module.exports.raise = ( source, data, exceptionID = undefined, httpCode = undefined ) => {
|
|
310
|
+
/** @type TiException */
|
|
304
311
|
let exception;
|
|
305
312
|
|
|
313
|
+
// Support flexible argument passing: if exceptionID is a number (likely an HTTP code) and httpCode is missing, swap them:
|
|
314
|
+
if ( typeof exceptionID === "number" && httpCode === undefined ) {
|
|
315
|
+
httpCode = exceptionID;
|
|
316
|
+
exceptionID = undefined;
|
|
317
|
+
}
|
|
318
|
+
|
|
306
319
|
if ( source instanceof Error ) {
|
|
307
|
-
exception = new
|
|
308
|
-
} else if ( source instanceof
|
|
320
|
+
exception = new TiException( exceptionID || tools.getUUID(), exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR, tools.errorToJSON( source ) );
|
|
321
|
+
} else if ( source instanceof TiException ) {
|
|
309
322
|
exception = source;
|
|
310
323
|
} else if ( _.isString( source ) ) {
|
|
311
|
-
exception = new
|
|
324
|
+
exception = new TiException( exceptionID || tools.getUUID(), exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR, {
|
|
312
325
|
message: source
|
|
313
326
|
} );
|
|
314
327
|
} else if ( _.isObjectLike( source ) ) {
|
|
315
|
-
exception = new
|
|
328
|
+
exception = new TiException(
|
|
316
329
|
exceptionID || ( source.id || tools.getUUID() ),
|
|
317
330
|
source.code || exceptionCodeEnum.E_GEN_JS_INTERNAL_ERROR,
|
|
318
331
|
source.data,
|
|
319
332
|
source.description
|
|
320
333
|
);
|
|
321
|
-
if ( httpCodeEnum.contains( source.httpCode ) ) {
|
|
334
|
+
if ( source.httpCode && httpCodeEnum.contains( source.httpCode ) ) {
|
|
322
335
|
exception.httpCode = source.httpCode;
|
|
323
336
|
}
|
|
324
337
|
} else {
|
|
325
|
-
exception = new
|
|
338
|
+
exception = new TiException( exceptionID || tools.getUUID(), ( exceptionCodeEnum.contains( source ) ) ? source : exceptionCodeEnum.E_UNKNOWN_ERROR );
|
|
326
339
|
}
|
|
327
340
|
|
|
328
341
|
// Merge the default exception data with the additional one if it's provided:
|
|
@@ -335,11 +348,15 @@ module.exports.raise = ( source, data, exceptionID ) => {
|
|
|
335
348
|
exception.data = tools.decycle( exception.data );
|
|
336
349
|
}
|
|
337
350
|
|
|
351
|
+
if ( httpCode && httpCodeEnum.contains( httpCode ) ) {
|
|
352
|
+
exception.httpCode = httpCode;
|
|
353
|
+
}
|
|
354
|
+
|
|
338
355
|
return exception;
|
|
339
356
|
};
|
|
340
357
|
|
|
341
358
|
/**
|
|
342
|
-
* Verifies if the passed object is
|
|
359
|
+
* Verifies if the passed object is a {@link TiException}.
|
|
343
360
|
*
|
|
344
361
|
* @method
|
|
345
362
|
* @param {*} object
|
|
@@ -347,5 +364,5 @@ module.exports.raise = ( source, data, exceptionID ) => {
|
|
|
347
364
|
* @public
|
|
348
365
|
*/
|
|
349
366
|
module.exports.isException = ( object ) => {
|
|
350
|
-
return ( object instanceof
|
|
367
|
+
return ( object instanceof TiException );
|
|
351
368
|
};
|
package/utils/localization.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
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-
|
|
3
|
+
* Copyright © 2021-2026 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
4
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
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
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/>.
|
|
@@ -18,6 +18,7 @@ const defaultEmptyLabel = "!!! label not found !!!";
|
|
|
18
18
|
*
|
|
19
19
|
* @readonly
|
|
20
20
|
* @enum {string}
|
|
21
|
+
* @typedef {string} TiLocalizationLanguage
|
|
21
22
|
*/
|
|
22
23
|
const localizationLanguageEnum = tools.enum( {
|
|
23
24
|
// A:
|
|
@@ -227,24 +228,8 @@ const localizationLanguageEnum = tools.enum( {
|
|
|
227
228
|
ZHUANG: [ "za", "Zhuang", "Zhuang" ],
|
|
228
229
|
ZULU: [ "zu", "Zulu", "Zulu" ]
|
|
229
230
|
} );
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* @typedef {string} TiLocalizationLanguage
|
|
233
|
-
*/
|
|
234
231
|
module.exports.localizationLanguage = localizationLanguageEnum;
|
|
235
232
|
|
|
236
|
-
/**
|
|
237
|
-
* The key of this object is the language code, and the value is the textual representation of the label.
|
|
238
|
-
*
|
|
239
|
-
* @typedef {Object<TiLocalizationLanguage, string>} TiLocalizedLabel
|
|
240
|
-
*/
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* A nested labels tree where intermediate nodes are objects and leaf nodes are language-to-text maps.
|
|
244
|
-
*
|
|
245
|
-
* @typedef {Object<string, TiLocalizedLabel | TiLabelsTree>} TiLabelsTree
|
|
246
|
-
*/
|
|
247
|
-
|
|
248
233
|
/** @type {TiLabelsTree} */
|
|
249
234
|
const labels = require( "#labels" );
|
|
250
235
|
|
package/utils/logger.js
CHANGED
|
@@ -16,6 +16,7 @@ const localization = require( "#localization" );
|
|
|
16
16
|
*
|
|
17
17
|
* @readonly
|
|
18
18
|
* @enum {number}
|
|
19
|
+
* @typedef {number} TiLogSeverity
|
|
19
20
|
*/
|
|
20
21
|
const logSeverityEnum = tools.enum( {
|
|
21
22
|
DEFAULT: [ 0, "default", "The log entry has no assigned severity level." ],
|
|
@@ -28,10 +29,6 @@ const logSeverityEnum = tools.enum( {
|
|
|
28
29
|
ALERT: [ 700, "alert", "A person must take an action immediately." ],
|
|
29
30
|
EMERGENCY: [ 800, "emergency", "One or more systems are unusable." ]
|
|
30
31
|
} );
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @typedef {number} TiLogSeverity
|
|
34
|
-
*/
|
|
35
32
|
module.exports.logSeverity = logSeverityEnum;
|
|
36
33
|
|
|
37
34
|
/**
|
|
@@ -46,10 +43,10 @@ module.exports.getSeverityName = ( severity ) => {
|
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
/**
|
|
49
|
-
* Used to extract information from
|
|
46
|
+
* Used to extract information from a {@link TiException} and convert it to a loggable data object.
|
|
50
47
|
*
|
|
51
48
|
* @method
|
|
52
|
-
* @param {
|
|
49
|
+
* @param {TiException} exception
|
|
53
50
|
* @returns {{description, details: (*|undefined), exceptionID}}
|
|
54
51
|
* @private
|
|
55
52
|
*/
|
|
@@ -66,8 +63,8 @@ const exceptionToLog = ( exception ) => {
|
|
|
66
63
|
*
|
|
67
64
|
* @method
|
|
68
65
|
* @param {string} message The primary log message.
|
|
69
|
-
* @param {TiLogSeverity} [level=DEFAULT] The log severity level. If the current log filtering setting is higher than this then the log entry will be ignored.
|
|
70
|
-
* @param {Object|Error|
|
|
66
|
+
* @param {TiLogSeverity} [level=DEFAULT] The log severity level. If the current log filtering setting is higher than this, then the log entry will be ignored.
|
|
67
|
+
* @param {Object|Error|TiException} [data={}] Optional JSON data containing details of the log entry.
|
|
71
68
|
* @param {string} [thread='main'] The logging thread to which the log entry belongs.
|
|
72
69
|
* @public
|
|
73
70
|
*/
|
package/utils/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
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-
|
|
3
|
+
* Copyright © 2021-2026 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
4
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
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
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/>.
|
|
@@ -9,21 +9,6 @@
|
|
|
9
9
|
const _ = require( "lodash" );
|
|
10
10
|
const crypto = require( "node:crypto" );
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* @typedef {Object} TiEnumValue
|
|
14
|
-
* @property {number|string} value
|
|
15
|
-
* @property {string} name
|
|
16
|
-
* @property {string} [description]
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @typedef {Object} TiEnum
|
|
21
|
-
* @property {Object.<number|string,TiEnumValue>} properties
|
|
22
|
-
* @property {function( (number|string), [string] ): (string|undefined)} name
|
|
23
|
-
* @property {function( (number|string), [string] ): (string|undefined)} description
|
|
24
|
-
* @property {function( (number|string) ): boolean} contains
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
12
|
/**
|
|
28
13
|
* Used to generate and return new UUID.
|
|
29
14
|
*
|
|
@@ -41,7 +26,7 @@ module.exports.getUUID = () => {
|
|
|
41
26
|
* @method
|
|
42
27
|
* @param {Object} object
|
|
43
28
|
* @param {WeakSet} [seen]
|
|
44
|
-
* @
|
|
29
|
+
* @returns {Object}
|
|
45
30
|
* @public
|
|
46
31
|
*/
|
|
47
32
|
module.exports.deepFreeze = ( object, seen = new WeakSet() ) => {
|
|
@@ -367,7 +352,7 @@ module.exports.decycle = ( object, replacer ) => {
|
|
|
367
352
|
* replaced with references to the value found by the PATH. This will restore cycles. The object will be mutated.
|
|
368
353
|
*
|
|
369
354
|
* The eval function is used to locate the values described by a PATH. The root object is kept in a $ variable. A
|
|
370
|
-
* regular expression is used to
|
|
355
|
+
* regular expression is used to ensure that the PATH is extremely well-formed. The regexp contains nested quantifiers.
|
|
371
356
|
* That has been known to have extremely bad performance problems on some browsers for very long strings. A PATH is
|
|
372
357
|
* expected to be reasonably short. A PATH is allowed to belong to a very restricted subset of Goessner's JSONPath.
|
|
373
358
|
*
|
|
@@ -455,7 +440,7 @@ module.exports.isJsonString = ( string ) => {
|
|
|
455
440
|
};
|
|
456
441
|
|
|
457
442
|
/**
|
|
458
|
-
* Use this to parse any JSON string into JSON object for internal system purposes as it ensures to restore any
|
|
443
|
+
* Use this to parse any JSON string into a JSON object for internal system purposes as it ensures to restore any
|
|
459
444
|
* circular dependencies obscured with 'stringifyJSON'.
|
|
460
445
|
*
|
|
461
446
|
* @method
|
|
@@ -474,7 +459,7 @@ module.exports.parseJSON = ( value ) => {
|
|
|
474
459
|
|
|
475
460
|
/**
|
|
476
461
|
* Use this to decompose a JSON object into a sorted string. The values will be ordered alphabetically and combined with
|
|
477
|
-
* their keys, where applicable, starting from the bottom and moving up. Null or undefined values will be ignored and
|
|
462
|
+
* their keys, where applicable, starting from the bottom and moving up. Null or undefined values will be ignored, and
|
|
478
463
|
* their keys will not be included in the final string.
|
|
479
464
|
*
|
|
480
465
|
* @param {Object} input
|