Configuration API
Configuration API in J-Framework is an easy-to-use, flexible, and sophisticated config API that enables an efficient approach to managing the configuration of software systems on all scales. It could allow configurations on the component level, and system level, with support of classpath configurations, local directory, git, and others.
Configuration of software systems is not an easy task, since new trends, practices, and technologies are demanding a higher level of operation automation through proper DevOps and agile practices, where, for example, changing the data-source password for different environments, (dev, test, staging, and prod) shouldn’t be that hard and time-consuming, and should happen in an efficient approach and shall take near-immediate effect on the systems with zero-downtime.
Use-Cases
Below are some use cases to use the config API:
Dev Environment:
-
For a simple web application Development environment: Add
config.properties
to yoursrc/main/resources
folder. -
For simple standalone applications: Add
smartcloud.config
to your current working directory. -
For Multi-module applications such as microservices and micro-fronts:
-
Create a
git
repository with thedev
branch and create asystem.config.properties
file which shall contain the common config for all your systems, in addition, create APP_NAME.config.properties which shall contain the config of specific apps. -
Create and place the
pre.config.properties
file in the commons-library of your system, which shall contain the config needed to access thegit
repository. -
In each project, add
src/main/resources/app.config.properties
which shall contain only keyapp.name=YOUR_APP_NAME
.
That’s it. Now, all the configurations are managed in a git repository, and the config can be reloaded instantly by hitting a/util/config
endpoint of your component using thepost
method.
-
Tests, Staging, and Prod Environments:
-
Follow the same approach above.
-
In the CI/CD process, replace the config files with the new one that contains the target environment configurations.
-
For security and operational purposes, you could place the critical configurations such as passwords and encryption keys as environment variables on the target host machine and reference it using the
env:
prefix likeyour-config-key= ${env:YOUR-CONFIG-KEY}
.
Basic Usage
In your Maven project, create a src/main/resources/config.properties
file, with the following sample contents:
app.name = J-Framework Demo
hibernate.connection.url = jdbc:h2:file:./h2db.data
hibernate.connection.username = sa
hibernate.connection.password = sa
db-entities-packages=com.app
Properties can be retrieved with:
JKConfig.get().getProperty(propertyName);
or with
JK.getProperty(propertyName);
As a shortcut.
Config Initialization
In most cases, the configuration will be auto-unidolized and loaded during the application
startups using listeners. However, if for some reason you want to initialize it yourself,
the first call to JKConfig.getDefaultInstance()
will autoconfigure it.
To read a value from the configuration, use the following code:
String property = JKConfig.get().getProperty("your-variable-name", "default value);
When a password starts with three underscores "___", the password will be considered encrypted, the decryption algorithm will remove the three hashes and then decrypt the password. |
Configuration Order
In J-Framework, the configuration is loaded from the following config sources based on the priorities-order:
-
Load
jk.config
file if exists from the current working directory and override any configuration from the following config sources (useful for standalone deployments). -
Load the
test.config.properties
file if exists from the classpath and override any configuration from the following config sources (useful for test automation). -
Process
pre.config.properties
which shall contain a local path for the config and/or Git repository settings and overrider and properties configured in the later config sources (useful for Microservices and Multi-components systems). In this approach:-
Look for the app.name property, if not found, look for it in the config sources.
-
If config.local.path is available, read
system.config.properties
and${app.name}.config.properties
from it. -
If Git-URL is there, the repository will be cloned to the local folder config.local.path value if configured.
-
Read
system.config.properties
andYOUR_APP_NAME.config.properties
from the cloned repository. -
If the git-keep-local property is false (default), the cloned local folder will be deleted once loaded.
-
-
Load the JKFRAMEWORK_ENV key from the system environment variable if exists, where the value is CSV key-value format of the configuration, and override any of the following configurations (useful for apps with simple configurations which require host operator ownership).
-
Load configuration from
config.properties
and override any of the following configurations. -
Load configuration from
app.config.properties
and override any of the following configurations. -
Load configuration from
system.config.properties
and override any of the following configurations. -
Load configuration from
default.config.properties
(not recommended to use, since it’s loaded from the framework Data APIs).
Load Configuration from Local Folder or Git Repository
For advanced configurations, you can specify a Git repository to host your configurations per system, per app, or even per environment.
You can do it by adding a pre.config.properties to the src/main/resources folder of your project.
app.name=....
config.local.path=....
git-url=....
git-username=....
#git-password=.....
git-password-plain=.....
In your repository, you can have the system.config.properties
file as the default configuration
for all the apps in your applications, also you can specify the configuration per module by
having a file named APP_NAME.config.properties
where APP_NAME is the value of
your app.name property in the pre.config.properties
.
mentioned above.
For profiles, you can use git branches as profiles, for example, you can create dev, test, staging, and prod branches.
J-Framework configuration is based on Apache Commons Config, so you can use the system, constants, or environment variables as follows:
user.file = ${sys:user.home}/settings.xml
action.key = ${const:yourclass.CONSTANT_NAME}
java.home = ${env:JAVA_HOME}
Available Configuration Properties
This section shows a list of available configuration properties used by J-Framework.
Generic Config
Header Name |
Default |
Description |
app.name |
app |
Your application name |
jk.security.enc-key |
SetMeIneEnvVaria |
Encryption key used in encryption and decryption |
Data Configurations
Below are the configuration and their defaults of the Data project, including database, NoSQL, and connection pool settings.
Detailed configuration of the c3p0 connection pool available at C3p0 Official Documentation. |
Config Name | Default Value | Description |
---|---|---|
nosql.url |
mongodb://localhost:27017/ |
- |
nosql.db.name |
app |
Default Database name. |
nosql.db.user |
- |
Default Database user. |
nosql.db.password |
Default Database password. |
|
db-entities-packages (deprecated) |
com.app |
The package names to scan for JPA entities. CSV value is allowed for multiple packages |
jk.data.jpa.entities-packages |
com.app |
Starting from 7.0.0-M6, The package names to scan for JPA entities. CSV value is allowed for multiple packages |
jk.data.connection.set_client_info |
false |
Set client information on the JDBC connection, helpful for DBA’s and troubleshooting |
hibernate.connection.url |
jdbc:h2:file:~/.jk/h2-db/h2db2.data; IGNORECASE=TRUE; CASE_INSENSITIVE_IDENTIFIERS=TRUE; DATABASE_TO_UPPER=FALSE; |
Database URL |
hibernate.connection.username |
sa |
Database username. |
hibernate.connection.password |
sa |
Database password. |
hibernate.connection.driver_class |
- |
Database driver, most likely you will not need to set it+, it will be automatically detected by the framework. |
hibernate.dialect |
- |
Hibernate database dialect, most likely you will not need to set |
hibernate.c3p0.max_size |
100 |
Maximum number of database connections in the pool. |
hibernate.c3p0.min_size |
1 |
Minimum number of database connections that the pool keeps |
hibernate.physical_naming_strategy |
- |
Naming strategy to be used for mapping with database |
hibernate.id.new_generator_mappings |
false |
important to to avoid AUTO id error in JPA |
hibernate.globally_quoted_identifiers |
true |
this will ensure escaping all fields that are keywords |
hibernate.use_sql_comments |
- |
- |
hibernate.format_sql |
true |
Format the generated SQL statement. |
hibernate.show_sql |
true |
Show Generated SQL statement. |
hibernate.connection.autocommit |
true |
Default to Auto Commit. |
hibernate.hbm2ddl.auto |
update |
Create tables of not exists. |
hibernate.c3p0. debugUnreturnedConnectionStackTraces |
true |
- |
hibernate.c3p0. unreturnedConnectionTimeout |
10 |
Defines a limit (in seconds) to how long a connection may remain checked out. |
hibernate.c3p0.acquireRetryDelay |
10000 |
Millis |
hibernate.c3p0.acquireRetryAttempts |
1 |
- |
hibernate.c3p0.idleConnectionTestPeriod |
30 |
Seconds |
hibernate.c3p0.preferredTestQuery |
- |
- |
hibernate.c3p0.testConnectionOnCheckout |
false |
- |
hibernate.c3p0.maxConnectionAge |
18000 |
seconds, refresh the connection after this timeout |
hibernate.c3p0.timeout |
600 |
Release un-needed connections above the min-size (seconds) |
hibernate.c3p0.acquire_increment |
1 |
- |
hibernate.c3p0.privilegeSpawnedThreads |
true |
For hot un/deployment |
hibernate.c3p0.contextClassLoaderSource |
library |
For hot un/deployment |
hibernate.c3p0.checkoutTimeout |
20000 |
millis, this time could be needed in the init phase of the pool, need verification |
hibernate.c3p0.maxStatements |
0 |
Unlimited |
hibernate.c3p0.maxStatementsPerConnection |
10 |
- |
hibernate.c3p0.numHelperThreads |
10 |
- |
jk.data.datasource.impl |
hibernate |
Options are "hibernate" and "plain", other implementation shall be added future releases |
jk.data.orm.results.max |
1000 |
- |
Multi-Database Support
In the config file, you can add a prefix to the same configuration used in normal database setup. Then you can call the
mydb.hibernate.connection.url =jdbc:oracle:thin:@0.0.0.0:1521:DB
mydb.hibernate.connection.username =user
mydb.hibernate.connection.password = pass
Git Config
Config Name | Default Value | Description |
---|---|---|
git-url |
- |
Repository URL of config repository. |
git-keep-local |
false |
Keep/Remove cloned repository folder. |
git-branch |
master |
Target git branch. |
git-password-plain |
- |
Plain password or token of the repository (Not recommended) |
git-password |
- |
Encrypted password of your git account. |
git-username |
- |
Username of you git repository. |
git-local-path |
- |
The path where your repository should be cloned. |
Microservices Config
Config Name | Default | Description |
---|---|---|
jk.service.url.visibleOnError |
true |
Shall the framework show the remote microservice URL on error (recommended to be off on production) |
jk.service.allowed.ip |
true |
CSV List of IPs that are allowed to call a microservice. |
jk.service.connect_timeout |
10 |
Allowed timeout in seconds to connect to a microservice |
jk.service.read_timeout |
20 |
Allowed timeout in seconds to wait response from microservice |
jk.services.headers.enabled |
true |
Allow showing request header on a microservice (Recommended to be false on production) |
jk.config.allowReload |
true |
Allows to reload config on runtime for a microservice or micro-frontend |
jk.services.info.enabled |
true |
Allow showing microservice info (Swagger like) of microservice (Recommended to be off on production) |
jk.logs.allowReadFile |
false |
Allow reading microservice log file remotely. Even though passwords will be masked, it is recommended to be turned off on production. |
jk.config.allowReadConfig |
true |
Allow reload configuration at runtime. |
jk.service.crosscutting.logservice.enabled |
false |
Check whether crosscutting remote calls should be logged to the unified logging microservice |
jk.service.crosscutting.logservice.base |
- |
The base url for the unified logging service |
jk.service.crosscutting.logservice.async |
true |
Shall the unified loggging be called async or sync |
jk.services.workflow.url |
- |
The base url of the workflow engine. |
Web Config
Header Name | Default | Description |
---|---|---|
jk.security.enabled |
false |
Enable security, the default is based on Spring Security. |
jk.web.security.public_url |
/services/, /index.xhtml, /error/, /login/, /public/, /resources/ , .css, .js, /jakarta.faces.resource/, /javax.faces.resource/, /util/ |
List of URLs the considered public by default. |
jk.web.session.username |
- |
If managed by the application, the name of session attribute variable that holds the username. |
jk.web.config.reset |
true |
Servlet URL that allows reset config |
jk.web.versions |
true |
Servlet URL that shows the versions of the framework components |
jk.web.mvc.models.package |
com.app |
(an MVC framework, in Progress) |