@ti-engine/core 1.1.1 → 1.1.3
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 +19 -0
- package/README.md +131 -7
- package/bin/localization/labels.json +65 -0
- package/bin/settings.json +4 -0
- package/bin/start-instance.js +6 -4
- package/components/service-instance.js +2 -1
- package/components/service-provider.js +1 -1
- package/package.json +5 -3
- package/utils/config.js +16 -2
- package/utils/localization.js +27 -0
- package/utils/logger.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# ti-engine changelog
|
|
2
2
|
|
|
3
|
+
## Version 1.1.3
|
|
4
|
+
|
|
5
|
+
* feat(config)!: removed ENV variable `TI_OPERATION_MODE` as it was duplicating the practical purpose of `NODE_ENV`
|
|
6
|
+
* feat(config)!: setting `OPERATION_MODE` is now initialized by the `NODE_ENV` ENV variable (if provided)
|
|
7
|
+
* feat(service instance): show application operation mode in log at successful startup
|
|
8
|
+
* docs: add more sections and information in `README.md`
|
|
9
|
+
|
|
10
|
+
## Version 1.1.2
|
|
11
|
+
|
|
12
|
+
* feat(localization): add new functionality for localization based on labels and system language. It is currently utilized by the `exceptions` module for localizing the exception descriptions. The new `localization` module can also be accessed externally in the implementing application's files via standard import
|
|
13
|
+
* feat(config): add new setting `localization.labelsPath` that specifies the file path for the localization labels
|
|
14
|
+
* feat(config): add new setting `localization.language` that specifies the language to be used for the labels
|
|
15
|
+
* feat(config): add new ENV variable `TI_LOCALIZATION_LABELS_PATH` that controls the `localization.labelsPath` setting
|
|
16
|
+
* feat(config): add new ENV variable `TI_LOCALIZATION_LANGUAGE` that controls the `localization.language` setting
|
|
17
|
+
* feat(logger): log exception label instead of system-level description
|
|
18
|
+
* fix(start instance): fix the order of ENV loading in the `start-instance.js` script. It will now properly load the `.env` file first and then proceed with any configuration overrides in `config` module
|
|
19
|
+
* fix(service provider): normalize service file paths on dynamic service handler loading
|
|
20
|
+
* build(npm): update npm dependencies to their latest versions
|
|
21
|
+
|
|
3
22
|
## Version 1.1.1
|
|
4
23
|
|
|
5
24
|
* feat(config): add new ENV variable `TI_AUDITING_LOG_DETAILS` that controls the `auditing.logDetails` setting
|
package/README.md
CHANGED
|
@@ -6,10 +6,6 @@ Flexible framework for the creation of microservices with [node.js](https://node
|
|
|
6
6
|
|
|
7
7
|
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**. The architectural concept of the framework is based on a standard _messaging system_ that allows for certain customization but also provides predictability and traceability of its behavior.
|
|
8
8
|
|
|
9
|
-
Being a messaging system, the **ti-engine** relies on a message broker for the actual exchange of messages between microservice instances. The default implementation of the framework uses [Redis](https://redis.io/) cache, however, you could create your own implementation using something like [Rabbit MQ](https://www.rabbitmq.com/). See the [Advanced topics](#advanced-topics) section of this documentation for guides on how to do this.
|
|
10
|
-
|
|
11
|
-
Please be aware, that this framework is under active development and will expand in the near future. Also, this documentation is still in the process of being created and refined. Make sure to keep an eye on the changes in case you want to use it in the meantime.
|
|
12
|
-
|
|
13
9
|
## Why ti-engine?
|
|
14
10
|
|
|
15
11
|
The framework is created based on a decade of professional experience with the utilized technologies and architectural approach. It's primary goal is to provide you with a lightweight and flexible solution that can help you build quickly a microservice ecosystem with any degree of size and complexity.
|
|
@@ -27,12 +23,19 @@ These are just some benefits **ti-engine** offers. Get to know it better to find
|
|
|
27
23
|
|
|
28
24
|
## Prerequisites & installation
|
|
29
25
|
|
|
26
|
+
Being a messaging system, the **ti-engine** relies on a message broker for the actual exchange of messages between microservice instances. The default implementation of the framework uses [Redis](https://redis.io/) cache, however, you could create your own implementation using something like [Rabbit MQ](https://www.rabbitmq.com/). See the [Advanced topics](#advanced-topics) section of this documentation for guides on how to do this. For now let's focus on the default setup.
|
|
27
|
+
|
|
30
28
|
In order to run the basic ti-engine framework you will need a couple of things:
|
|
31
29
|
|
|
32
30
|
* A local [node.js installation](https://nodejs.org/en/download/) with a minimum version of **14.17.0**
|
|
33
31
|
* A local or remote [Redis cache installation](https://redis.io/download) with a minimum version of **5.0.14**
|
|
34
32
|
|
|
35
|
-
If you are working under Windows 10+ OS and you need to install Redis, take a look at this [guide](https://redis.com/blog/redis-on-windows-10/). You could also use [Redis Cloud](https://app.redislabs.com/) for development purposes as it offers free basic account.
|
|
33
|
+
If you are working under Windows 10+ OS and you need to install Redis, take a look at this [guide](https://redis.com/blog/redis-on-windows-10/). You could also use [Redis Cloud](https://app.redislabs.com/) for development purposes as it offers free basic account. You can configure your connection to remote Redis server using the following ENV variables:
|
|
34
|
+
|
|
35
|
+
* `TI_MEMORY_CACHE_AUTH_KEY` can be used to provide the Redis password if there is any at all.
|
|
36
|
+
* `TI_MEMORY_CACHE_REDIS_DB` can be used to specify the Redis DB you want to use. Make sure to set the correct number as for example Redis Cloud only uses DB `0`.
|
|
37
|
+
* `TI_MEMORY_CACHE_REDIS_HOST` can be used to provide the remote host. This can be an IP or URL depending on your setup.
|
|
38
|
+
* `TI_MEMORY_CACHE_REDIS_PORT` can be used to provide the remote port. By default, Redis uses `6379` however many implementations might use a custom port that needs to be specified in the connection settings.
|
|
36
39
|
|
|
37
40
|
To get the framework itself, use the command `npm install @ti-engine/core`. And to include it directly in your package.json dependencies execute `npm install @ti-engine/core --save-prod`.
|
|
38
41
|
|
|
@@ -330,11 +333,132 @@ Now without exiting this node process let's start the original tester microservi
|
|
|
330
333
|
|
|
331
334
|
This means the service call processing was successful and result was returned to `my-service`. Because we made the receiving of the result blocking and part of the initialization sequence, the new microservice did not report successful startup until it received that response from `ti-tester-service`.
|
|
332
335
|
|
|
333
|
-
And with this we are
|
|
336
|
+
And with this step we are done. The new microservice is now operational. You can continue to tweak and play with it in order to understand better how it all works. For more details on the **ti-engine** inner working please see the following sections.
|
|
334
337
|
|
|
335
338
|
## Using the framework
|
|
336
339
|
|
|
337
|
-
|
|
340
|
+
### Framework settings
|
|
341
|
+
|
|
342
|
+
Here you can find all settings used by **ti-engine** together with information on what they do. They are defined inside the `config` module and the full list can be accessed through the public `setting` enum. To get the current value of a setting, you can use the public method `getSetting` from the same module. Some settings can be overridden by providing ENV variables as specified below at node application start up.
|
|
343
|
+
|
|
344
|
+
AUDITING_LOG_CONSOLE_ENABLED
|
|
345
|
+
: JSON path `auditing.logConsoleEnabled`, type `boolean`, default `true`
|
|
346
|
+
: ENV variable `TI_AUDITING_LOG_CONSOLE_ENABLED`
|
|
347
|
+
: This setting controls whether the `auditing` module will send the log entries to the OS console or not. In some cases, like Cloud environments, you might want to disable this, especially if the OS console is not made available. This functions independently of other logging outputs like for example GCloud error reporting.
|
|
348
|
+
|
|
349
|
+
AUDITING_LOG_DETAILS
|
|
350
|
+
: JSON path `auditing.logDetails`, type `boolean`, default `true`
|
|
351
|
+
: ENV variable `TI_AUDITING_LOG_DETAILS`
|
|
352
|
+
: This setting controls whether the `auditing` module will include the log entry details (located in the `data` property) in the final log output. You might want to disable this if you want a leaner log output or the log entry details are not something you plan to use for analysis later.
|
|
353
|
+
|
|
354
|
+
AUDITING_LOG_MIN_LEVEL
|
|
355
|
+
: JSON path `auditing.logMinLevel`, type `number`, default `0`
|
|
356
|
+
: ENV variable `TI_AUDITING_LOG_MIN_LEVEL`
|
|
357
|
+
: This setting controls the minimum log severity level that the framework will log in the log output. You can and should set this to `200` (INFO) for production environments in order to filter out the DEBUG and the low-level DEFAULT entries.
|
|
358
|
+
|
|
359
|
+
AUDITING_LOG_USES_JSON
|
|
360
|
+
: JSON path `auditing.logUsesJSON`, type `boolean`, default `false`
|
|
361
|
+
: ENV variable `TI_AUDITING_LOG_USES_JSON`
|
|
362
|
+
: This setting controls whether the log entries would be sent to output formatted as JSONs or not. By default, the framework outputs log entries as prettified text. In some cases however you might want to have the entire entry as a JSON for further processing (for example if you're sending all logs to Elasticsearch).
|
|
363
|
+
|
|
364
|
+
GCLOUD_API_KEY (Alpha)
|
|
365
|
+
: JSON path `gcloudIntegration.apiKey`
|
|
366
|
+
: This setting holds the API key for the GCloud integration module.
|
|
367
|
+
|
|
368
|
+
GCLOUD_PROJECT_ID (Alpha)
|
|
369
|
+
: JSON path `gcloudIntegration.projectID`
|
|
370
|
+
: This setting holds the project ID for the GCloud integration module.
|
|
371
|
+
|
|
372
|
+
LOCALIZATION_LABELS_PATH
|
|
373
|
+
: JSON path `localization.labelsPath`, type `string`, default `../core/bin/localization/labels.json`
|
|
374
|
+
: ENV variable `TI_LOCALIZATION_LABELS_PATH`
|
|
375
|
+
: This setting holds the file system path to the `.json` file containing the localization information. By default, the framework provides such a file with english texts that can be customized further. Alternatively, you can provide your own file from a different location, but it still has to follow the rules of the `localization` module.
|
|
376
|
+
|
|
377
|
+
LOCALIZATION_LANGUAGE
|
|
378
|
+
: JSON path `localization.language`, type `string`, default `en`
|
|
379
|
+
: ENV variable `TI_LOCALIZATION_LANGUAGE`
|
|
380
|
+
: This setting specifies the default framework language. It will be used when translating labels into a localized text.
|
|
381
|
+
|
|
382
|
+
MEMORY_CACHE_AUTH_KEY
|
|
383
|
+
: JSON path `memoryCache.authKey`, type `string`, default `undefined`
|
|
384
|
+
: ENV variable `TI_MEMORY_CACHE_AUTH_KEY`
|
|
385
|
+
: This setting holds the Redis password for accessing the Redis server if such password is required.
|
|
386
|
+
|
|
387
|
+
MEMORY_CACHE_REDIS_DB
|
|
388
|
+
: JSON path `memoryCache.redisDB`, type `number`, default `0`
|
|
389
|
+
: ENV variable `TI_MEMORY_CACHE_REDIS_DB`
|
|
390
|
+
: This setting specifies the Redis DB to be used for all operations. When setting this make sure that the Redis server actually supports multiple DBs (for example Redis Cloud has only one DB with ID `0`).
|
|
391
|
+
|
|
392
|
+
MEMORY_CACHE_REDIS_HOST
|
|
393
|
+
: JSON path `memoryCache.redisHost`, type `string`, default `127.0.0.1`
|
|
394
|
+
: ENV variable `TI_MEMORY_CACHE_REDIS_HOST`
|
|
395
|
+
: This setting holds the Redis server hostname. It can be an IP or URL depending on your configuration.
|
|
396
|
+
|
|
397
|
+
MEMORY_CACHE_REDIS_PORT
|
|
398
|
+
: JSON path `memoryCache.redisPort`, type `number`, default `6379`
|
|
399
|
+
: ENV variable `TI_MEMORY_CACHE_REDIS_PORT`
|
|
400
|
+
: This setting holds the Redis server port.
|
|
401
|
+
|
|
402
|
+
MEMORY_CACHE_USER
|
|
403
|
+
: JSON path `memoryCache.user`, type `string`, default `default`
|
|
404
|
+
: ENV variable `TI_MEMORY_CACHE_USER`
|
|
405
|
+
: This setting holds the Redis username for accessing the Redis server if this is supported by the Redis version (it will be ignored otherwise).
|
|
406
|
+
|
|
407
|
+
MESSAGE_EXCHANGE_QUEUE_PREFIX (Advanced)
|
|
408
|
+
: JSON path `messageExchange.messageQueuePrefix`, type `string`, default `ti:messages:`
|
|
409
|
+
: This setting holds the Redis key prefix for the queues that will hold the messages of the message exchange. This is not something you should modify unless you are making a customized implementation of the tier 1 architectural layer.
|
|
410
|
+
|
|
411
|
+
MESSAGE_EXCHANGE_MESSAGE_STORE (Advanced)
|
|
412
|
+
: JSON path `messageExchange.messageStore`, type `string`, default `ti:messages:store`
|
|
413
|
+
: This setting holds the Redis key name of the hash table that will hold the message payloads of the message exchange. This is not something you should modify unless you are making a customized implementation of the tier 1 architectural layer.
|
|
414
|
+
|
|
415
|
+
MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED (Advanced)
|
|
416
|
+
: JSON path `messageExchange.securityHashEnabled`, type `boolean`, default `true`
|
|
417
|
+
: ENV variable `TI_MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED`
|
|
418
|
+
: This setting controls whether the message exchange will use a control hash mechanism to ensure there is no tampering with the messages in between service calls. In most cases you would want to keep this enabled since it ensures the integrity of your data. If you are concerned about performance (hashing with `blake2` is very fast, but it still eats some milliseconds) you might want to try and disable this to see if it makes any notable difference.
|
|
419
|
+
|
|
420
|
+
MESSAGE_EXCHANGE_SECURITY_HASH_KEY (Advanced)
|
|
421
|
+
: JSON path `messageExchange.securityHashKey`, type `string`, default `random uuid`
|
|
422
|
+
: ENV variable `TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY`
|
|
423
|
+
: This setting holds the encryption key used by the message exchange control hash mechanism. By default, this has a random uuid value that can be used for development purposes only. For production environments you absolutely must provide your own encryption key via the ENV variable. Depending on your configuration and infrastructure it might come from a secure storage, HSM, key vault, etc.
|
|
424
|
+
|
|
425
|
+
MESSAGE_EXCHANGE_TRACE_EXPIRATION_TIME
|
|
426
|
+
: JSON path `messageExchange.traceExpirationTime`, type `number`, default `3600`
|
|
427
|
+
: This setting specifies the expiration time in seconds of the Redis key that will hold the message trace entries. Set this to `0` to disable expiration altogether.
|
|
428
|
+
|
|
429
|
+
MESSAGE_EXCHANGE_TRACE_LOG_ENABLED
|
|
430
|
+
: JSON path `messageExchange.traceLogEnabled`, type `boolean`, default `false`
|
|
431
|
+
: ENV variable `TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED`
|
|
432
|
+
: This setting controls whether the `auditing` module should output all trace messages as normal log entries or not. Normally, you don't want that since it will clutter the standard log quite a lot. All traces go their own storage and can be reviewed and processed separately from the log entries. In some cases, however, as in debugging, enabling this can help you identify hard to track problem.
|
|
433
|
+
|
|
434
|
+
MESSAGE_EXCHANGE_TRACE_REPOSITORY (Advanced)
|
|
435
|
+
: JSON path `messageExchange.traceRepository`, type `string`, default `ti:messages:trace`
|
|
436
|
+
: This setting holds the Redis key name for the message trace cache storage. This is not something you should modify unless you are making a customized implementation of the tier 1 architectural layer.
|
|
437
|
+
|
|
438
|
+
SERVICE_EXECUTION_TIMEOUT
|
|
439
|
+
: JSON path `serviceConfig.executionTimeout`, type `number`, default `180000`
|
|
440
|
+
: This setting specifies the timeout in milliseconds of the service call executions at tier 2 of the architecture. Any service call that hasn't received response within this time will interrupt the wait and raise an `E_COM_SERVICE_EXEC_TIMEOUT` exception. Please keep in mind that reaching the timeout does not mean the remote service did not process the request. You might want to tweak this setting if you have many time-consuming operations in business services, or you plan to integrate with slow APIs.
|
|
441
|
+
|
|
442
|
+
SERVICE_HEALTH_CHECK_ADDRESS (Advanced)
|
|
443
|
+
: JSON path `serviceConfig.healthCheckAddress`, type `string`, default `ti:services:registry:health:`
|
|
444
|
+
: This setting specifies the address of the health check report endpoint for the microservice. In the default implementation this is a prefix for a Redis key that gets updated once at every `SERVICE_HEALTH_CHECK_INTERVAL`. If you override the `reportHealthy` method of the microservice, this setting can contain a URL or another type of destination that can be used by your custom implementation.
|
|
445
|
+
|
|
446
|
+
SERVICE_HEALTH_CHECK_INTERVAL (Advanced)
|
|
447
|
+
: JSON path `serviceConfig.healthCheckInterval`, type `CRON string`, default `*/1 * * * * *`
|
|
448
|
+
: This setting specifies the health check report interval at which the endpoint in `SERVICE_HEALTH_CHECK_ADDRESS` is notified.
|
|
449
|
+
|
|
450
|
+
SERVICE_HEALTH_CHECK_TIMEOUT (Advanced)
|
|
451
|
+
: JSON path `serviceConfig.healthCheckTimeout`, type `number`, default `3`
|
|
452
|
+
: This setting specifies the timeout in seconds after which a microservice is no longer considered healthy. In the default implementation this represents an expiration parameter to the Redis key defined in `SERVICE_HEALTH_CHECK_ADDRESS`. Essentially, if the microservice does not update the Redis key within this time interval, it will expire and the monitoring application will lose the healthy status of the microservice. If you override the `reportHealthy` method of the microservice, this setting can be used for your custom implementation as needed.
|
|
453
|
+
|
|
454
|
+
SERVICE_REGISTRY_ADDRESS (Advanced)
|
|
455
|
+
: JSON path `serviceConfig.serviceRegistryAddress`, type `string`, default `ti:services:registry:catalog:`
|
|
456
|
+
: This setting holds the prefix of the Redis key name used as business service registry. If the microservice is a `ServiceProvider`, on start up it will register its business service portfolio in that Redis set. Also, on each service call that same registry will be searched for the existence of the called business service. This is not something you should modify unless you are making a customized implementation of the tier 1 architectural layer.
|
|
457
|
+
|
|
458
|
+
OPERATION_MODE
|
|
459
|
+
: JSON path `operationMode`, type `string`, default `production`
|
|
460
|
+
: ENV variable `NODE_ENV`
|
|
461
|
+
: This setting holds the current operation mode of the node application. It will inherit the value from the `NODE_ENV` variable if it exists, otherwise will use its default.
|
|
338
462
|
|
|
339
463
|
## Advanced topics
|
|
340
464
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"labels": {
|
|
3
|
+
"general": {
|
|
4
|
+
"exceptions": {
|
|
5
|
+
"0": {
|
|
6
|
+
"en": "Unidentified error encountered or unrecognized exception code provided."
|
|
7
|
+
},
|
|
8
|
+
"1000": {
|
|
9
|
+
"en": "Error thrown by internal JS source."
|
|
10
|
+
},
|
|
11
|
+
"1001": {
|
|
12
|
+
"en": "Attempt to construct an abstract class detected."
|
|
13
|
+
},
|
|
14
|
+
"1002": {
|
|
15
|
+
"en": "Attempt to call an abstract method detected."
|
|
16
|
+
},
|
|
17
|
+
"1003": {
|
|
18
|
+
"en": "Invalid or no service domain name provided at microservice startup."
|
|
19
|
+
},
|
|
20
|
+
"1004": {
|
|
21
|
+
"en": "The system cache required for proper engine operation is unavailable."
|
|
22
|
+
},
|
|
23
|
+
"1005": {
|
|
24
|
+
"en": "The provided service handler is not a proper function."
|
|
25
|
+
},
|
|
26
|
+
"1006": {
|
|
27
|
+
"en": "The requested feature is not supported by current configuration or version."
|
|
28
|
+
},
|
|
29
|
+
"2000": {
|
|
30
|
+
"en": "Invalid authorization token provided."
|
|
31
|
+
},
|
|
32
|
+
"2001": {
|
|
33
|
+
"en": "Invalid or expired session encountered."
|
|
34
|
+
},
|
|
35
|
+
"2002": {
|
|
36
|
+
"en": "Attempt for unauthorized access detected."
|
|
37
|
+
},
|
|
38
|
+
"2003": {
|
|
39
|
+
"en": "The system detected tampering with the message received via message exchange."
|
|
40
|
+
},
|
|
41
|
+
"3000": {
|
|
42
|
+
"en": "General error during cross-application communication."
|
|
43
|
+
},
|
|
44
|
+
"3001": {
|
|
45
|
+
"en": "The message sender instance is currently unavailable."
|
|
46
|
+
},
|
|
47
|
+
"3002": {
|
|
48
|
+
"en": "The execution of a service could not complete within the allowed timeout."
|
|
49
|
+
},
|
|
50
|
+
"3003": {
|
|
51
|
+
"en": "The specified service is not found in the service registry."
|
|
52
|
+
},
|
|
53
|
+
"3004": {
|
|
54
|
+
"en": "The specified service is not found in the service definition interface."
|
|
55
|
+
},
|
|
56
|
+
"3005": {
|
|
57
|
+
"en": "No handler found in the interface for the specified service or service version."
|
|
58
|
+
},
|
|
59
|
+
"3010": {
|
|
60
|
+
"en": "Connection retry attempts exceeded the configured limit."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/bin/settings.json
CHANGED
package/bin/start-instance.js
CHANGED
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
const _ = require( "lodash" );
|
|
9
9
|
const path = require( "path" );
|
|
10
|
-
const tools = require( "#tools" );
|
|
11
|
-
const logger = require( "#logger" );
|
|
12
10
|
|
|
13
|
-
// load any ENV variables defined in a .env file:
|
|
11
|
+
// load any ENV variables defined in a .env file - before including any framework files:
|
|
14
12
|
require( "dotenv" ).config( { path: path.join( process.cwd(), ".env" ) } );
|
|
15
13
|
|
|
14
|
+
const tools = require( "#tools" );
|
|
15
|
+
const logger = require( "#logger" );
|
|
16
|
+
|
|
16
17
|
// configure the current instance variables before requiring any platform modules and store the necessary ones in memory cache:
|
|
17
18
|
process.env.TI_INSTANCE_ID = "ti-" + tools.getUUID();
|
|
18
19
|
process.env.TI_INSTANCE_CLASS = process.env.TI_INSTANCE_CLASS || "";
|
|
@@ -74,13 +75,14 @@ process.on( "uncaughtException", ( error ) => {
|
|
|
74
75
|
try {
|
|
75
76
|
logger.log( `Starting new instance of type '${ process.env.TI_INSTANCE_NAME }' with instance ID '${ process.env.TI_INSTANCE_ID }'.`, logger.logSeverity.NOTICE );
|
|
76
77
|
|
|
77
|
-
/** @type ServiceInstance */
|
|
78
78
|
const serviceConstructor = require( path.join( process.cwd(), process.env.TI_INSTANCE_CLASS ) );
|
|
79
79
|
const serviceConfigPath = process.env.TI_INSTANCE_CONFIG;
|
|
80
|
+
/** @type ServiceConfiguration */
|
|
80
81
|
let serviceConfig = {};
|
|
81
82
|
if ( serviceConfigPath ) {
|
|
82
83
|
serviceConfig = require( path.join( process.cwd(), process.env.TI_INSTANCE_CONFIG ) );
|
|
83
84
|
}
|
|
85
|
+
/** @type ServiceInstance */
|
|
84
86
|
const mainInstance = new serviceConstructor( process.env.TI_INSTANCE_NAME, serviceConfig );
|
|
85
87
|
|
|
86
88
|
/** @override */
|
|
@@ -225,7 +225,8 @@ class ServiceInstance {
|
|
|
225
225
|
} );
|
|
226
226
|
|
|
227
227
|
logger.log( `Instance '${ ServiceInstance.instanceID }' started successfully.`, logger.logSeverity.NOTICE, {
|
|
228
|
-
nodeVersion: process.version
|
|
228
|
+
nodeVersion: process.version,
|
|
229
|
+
operationMode: config.getSetting( config.setting.OPERATION_MODE )
|
|
229
230
|
} );
|
|
230
231
|
|
|
231
232
|
resolve();
|
|
@@ -138,7 +138,7 @@ class ServiceProvider extends ServiceConsumer {
|
|
|
138
138
|
/** @type {ServiceHandlerMethod} */
|
|
139
139
|
let serviceHandler = null;
|
|
140
140
|
if ( serviceDefinition.serviceFile ) {
|
|
141
|
-
let serviceFilePath = path.join( process.cwd(), serviceDefinition.serviceFile );
|
|
141
|
+
let serviceFilePath = path.normalize( path.join( process.cwd(), serviceDefinition.serviceFile ) );
|
|
142
142
|
try {
|
|
143
143
|
serviceHandler = require( serviceFilePath ).service;
|
|
144
144
|
} catch ( error ) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
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
5
|
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
6
|
"license": "ISC",
|
|
7
7
|
"exports": {
|
|
8
8
|
"./exceptions": "./utils/exceptions.js",
|
|
9
|
+
"./localization": "./utils/localization.js",
|
|
9
10
|
"./logger": "./utils/logger.js",
|
|
10
11
|
"./service-consumer": "./components/service-consumer.js",
|
|
11
12
|
"./service-instance": "./components/service-instance.js",
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
"#default-message-sender": "./components/exchange/default/default-message-sender.js",
|
|
23
24
|
"#exceptions": "./utils/exceptions.js",
|
|
24
25
|
"#gcloud-integration": "./integrations/gcloud-integration.js",
|
|
26
|
+
"#localization": "./utils/localization.js",
|
|
25
27
|
"#logger": "./utils/logger.js",
|
|
26
28
|
"#message-dispatcher": "./components/exchange/message-dispatcher.js",
|
|
27
29
|
"#message-exchange": "./components/exchange/message-exchange.js",
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
"dependencies": {
|
|
44
46
|
"blake2": "^5.0.0",
|
|
45
47
|
"dotenv": "^16.3.1",
|
|
46
|
-
"fs-extra": "^11.
|
|
48
|
+
"fs-extra": "^11.2.0",
|
|
47
49
|
"lodash": "^4.17.21",
|
|
48
50
|
"node-schedule": "^2.1.1",
|
|
49
51
|
"ioredis": "^5.3.2"
|
|
@@ -54,7 +56,7 @@
|
|
|
54
56
|
},
|
|
55
57
|
"repository": {
|
|
56
58
|
"type": "git",
|
|
57
|
-
"url": "https://github.com/Belleal/ti-engine.git"
|
|
59
|
+
"url": "git+https://github.com/Belleal/ti-engine.git"
|
|
58
60
|
},
|
|
59
61
|
"engines": {
|
|
60
62
|
"node": ">=14.17.0"
|
package/utils/config.js
CHANGED
|
@@ -24,6 +24,8 @@ const tools = require( "#tools" );
|
|
|
24
24
|
* @property {EnvironmentVariable} env.TI_AUDITING_LOG_DETAILS
|
|
25
25
|
* @property {EnvironmentVariable} env.TI_AUDITING_LOG_MIN_LEVEL
|
|
26
26
|
* @property {EnvironmentVariable} env.TI_AUDITING_LOG_USES_JSON
|
|
27
|
+
* @property {EnvironmentVariable} env.TI_LOCALIZATION_LABELS_PATH
|
|
28
|
+
* @property {EnvironmentVariable} env.TI_LOCALIZATION_LANGUAGE
|
|
27
29
|
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_AUTH_KEY
|
|
28
30
|
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_REDIS_DB
|
|
29
31
|
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_REDIS_HOST
|
|
@@ -32,7 +34,6 @@ const tools = require( "#tools" );
|
|
|
32
34
|
* @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_ENABLED
|
|
33
35
|
* @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_SECURITY_HASH_KEY
|
|
34
36
|
* @property {EnvironmentVariable} env.TI_MESSAGE_EXCHANGE_TRACE_LOG_ENABLED
|
|
35
|
-
* @property {EnvironmentVariable} env.TI_OPERATION_MODE
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
39
|
/**
|
|
@@ -43,6 +44,7 @@ const tools = require( "#tools" );
|
|
|
43
44
|
* @typedef {Object} SettingsMain
|
|
44
45
|
* @property {SettingsAuditing} auditing
|
|
45
46
|
* @property {SettingsGcloudIntegration} gcloudIntegration
|
|
47
|
+
* @property {SettingsLocalization} localization
|
|
46
48
|
* @property {SettingsMemoryCache} memoryCache
|
|
47
49
|
* @property {SettingsMessageExchange} messageExchange
|
|
48
50
|
* @property {SettingsServiceConfig} serviceConfig
|
|
@@ -63,6 +65,12 @@ const tools = require( "#tools" );
|
|
|
63
65
|
* @property {string} projectID
|
|
64
66
|
*/
|
|
65
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @typedef {Object} SettingsLocalization
|
|
70
|
+
* @property {string} labelsPath
|
|
71
|
+
* @property {string} language
|
|
72
|
+
*/
|
|
73
|
+
|
|
66
74
|
/**
|
|
67
75
|
* @typedef {Object} SettingsMemoryCache
|
|
68
76
|
* @property {string} authKey
|
|
@@ -105,6 +113,8 @@ let settingsEnum = tools.enum( {
|
|
|
105
113
|
AUDITING_LOG_USES_JSON: [ "auditing.logUsesJSON", "logUsesJSON", "" ],
|
|
106
114
|
GCLOUD_API_KEY: [ "gcloudIntegration.apiKey", "apiKey", "" ],
|
|
107
115
|
GCLOUD_PROJECT_ID: [ "gcloudIntegration.projectID", "projectID", "" ],
|
|
116
|
+
LOCALIZATION_LABELS_PATH: [ "localization.labelsPath", "labelsPath", "" ],
|
|
117
|
+
LOCALIZATION_LANGUAGE: [ "localization.language", "language", "" ],
|
|
108
118
|
MEMORY_CACHE_AUTH_KEY: [ "memoryCache.authKey", "authKey", "" ],
|
|
109
119
|
MEMORY_CACHE_REDIS_DB: [ "memoryCache.redisDB", "redisDB", "" ],
|
|
110
120
|
MEMORY_CACHE_REDIS_HOST: [ "memoryCache.redisHost", "redisHost", "" ],
|
|
@@ -140,6 +150,10 @@ if ( settings.auditing ) {
|
|
|
140
150
|
settings.auditing.logMinLevel = ( process.env.TI_AUDITING_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_AUDITING_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
|
|
141
151
|
settings.auditing.logUsesJSON = ( process.env.TI_AUDITING_LOG_USES_JSON !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_USES_JSON ) : settings.auditing.logUsesJSON;
|
|
142
152
|
}
|
|
153
|
+
if ( settings.localization ) {
|
|
154
|
+
settings.localization.labelsPath = ( process.env.TI_LOCALIZATION_LABELS_PATH !== undefined ) ? process.env.TI_LOCALIZATION_LABELS_PATH : settings.localization.labelsPath;
|
|
155
|
+
settings.localization.language = ( process.env.TI_LOCALIZATION_LANGUAGE !== undefined ) ? process.env.TI_LOCALIZATION_LANGUAGE : settings.localization.language;
|
|
156
|
+
}
|
|
143
157
|
if ( settings.memoryCache ) {
|
|
144
158
|
settings.memoryCache.authKey = ( process.env.TI_MEMORY_CACHE_AUTH_KEY !== undefined ) ? process.env.TI_MEMORY_CACHE_AUTH_KEY : settings.memoryCache.authKey;
|
|
145
159
|
settings.memoryCache.redisDB = ( process.env.TI_MEMORY_CACHE_REDIS_DB !== undefined ) ? process.env.TI_MEMORY_CACHE_REDIS_DB : settings.memoryCache.redisDB;
|
|
@@ -159,7 +173,7 @@ if ( process.env.TI_GCLOUD_ENABLED === true && settings.gcloudIntegration ) {
|
|
|
159
173
|
settings.gcloudIntegration.projectID = ( process.env.TI_GCLOUD_PROJECT_ID !== undefined ) ? process.env.TI_GCLOUD_PROJECT_ID : settings.gcloudIntegration.projectID;
|
|
160
174
|
}
|
|
161
175
|
|
|
162
|
-
settings.operationMode = process.env.
|
|
176
|
+
settings.operationMode = process.env.NODE_ENV || settings.operationMode;
|
|
163
177
|
|
|
164
178
|
// prevent further modifications to the settings object:
|
|
165
179
|
Object.freeze( settings );
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: © 2021-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
3
|
+
* SPDX-License-Identifier: ICU
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const _ = require( "lodash" );
|
|
7
|
+
const path = require( "path" );
|
|
8
|
+
const config = require( "#config" );
|
|
9
|
+
|
|
10
|
+
const labelsPath = path.normalize( path.join( process.cwd(), config.getSetting( config.setting.LOCALIZATION_LABELS_PATH ) ) );
|
|
11
|
+
const labels = require( labelsPath );
|
|
12
|
+
const defaultEmptyLabel = "!!! label not found !!!";
|
|
13
|
+
|
|
14
|
+
// prevent further modifications to the labels object:
|
|
15
|
+
Object.freeze( labels );
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Used to return the textual value for a label based on the current system language.
|
|
19
|
+
*
|
|
20
|
+
* @method
|
|
21
|
+
* @param {string} label This should be a dot-separated JSON path string.
|
|
22
|
+
* @returns {string}
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
module.exports.getLabel = ( label ) => {
|
|
26
|
+
return _.get( labels, label + "." + config.getSetting( config.setting.LOCALIZATION_LANGUAGE ), defaultEmptyLabel );
|
|
27
|
+
};
|
package/utils/logger.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const _ = require( "lodash" );
|
|
7
7
|
const tools = require( "#tools" );
|
|
8
8
|
const exceptions = require( "#exceptions" );
|
|
9
|
+
const localization = require( "#localization" );
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Enum for specifying the log entry severity. This is based on the Google Stackdriver severity levels.
|
|
@@ -52,7 +53,7 @@ module.exports.getSeverityName = ( severity ) => {
|
|
|
52
53
|
const exceptionToLog = ( exception ) => {
|
|
53
54
|
return {
|
|
54
55
|
exceptionID: exception.id,
|
|
55
|
-
description: exception.
|
|
56
|
+
description: localization.getLabel( exception.label ),
|
|
56
57
|
details: !_.isEmpty( exception.data ) ? exception.data : undefined
|
|
57
58
|
};
|
|
58
59
|
};
|