You can start using cfg4j in your app by simply including it as a dependency. It consists of cfg4j-core module (required) and a number of plugins (e.g. cfg4j-consul, cfg4j-git) which add support for additional configuration sources. Below is the configuration for Gradle and Maven that will get you started quickly. Once you add cfg4j dependency proceed to the usage section.
Add your configuration to the “application.properties” file and commit the changes.
Update the code above to point to your fork.
Tutorial
Introduction
Using cfg4j is quite simple. It boils down to the following steps:
Point to the ConfigurationSource that stores your configs (e.g. Consul K-V store, git repository, local files, classpath resources).
Create ConfigurationProvider backed by your configuration source.
Access your configuration in one of the two ways:
Directly through ConfigurationProvider methods (e.g. getProperty("my.property", Integer.class))
Through a binding mechanism. Simply create an interface with methods representing your configuration variables and ask ConfigurationProvider to create a configuration object implementing your interface (i.e. calling bind("my.configuration.set", MyInterface.class)). Every time the configuration changes your object will be automatically updated with new values.
(optional) If you want you can customize the ConfigurationProvider behavior by using:
ReloadStrategy - those allow configuration to be automatically reloaded. There’s PeriodicalReloadStrategy provided that can reload configuration after every specified time period. You can also implement your own strategy.
Environment - Use it to specify where your configuration is located inside ConfigurationSource. It’s especially useful when you have multiple configuration sets (e.g. multi-tenant) in one source (e.g. under different paths, on different git branches, etc.). Read more below.
Configuration source
Obviously, you need your configuration to be stored somewhere before you can access it. You can store it in a K-V store (e.g. Consul K-V), files (remote git repository, local files, classpath resources) or a relational database. If you’re unsure what the best practices are, you can consult this article.
Once you have your configuration in place, create a ```ConfigurationSource`` object that will fetch it. Here’s an example using Consul K-V.
To learn more about supported configuration sources and their capabilities head to the PLUGINS section.
Configuration provider
Once we have ConfigurationSource in place, we need ConfigurationProvider that will provide your app with a uniform interface for reading configs.
You can obtain ConfigurationProvider using builder:
You can also use DI container (like Spring)
Accessing configuration
Once you have ConfigurationProvider in hand you can use it for accessing configuration. Here’s a bunch of examples (values that you need to put in your configuration source are listed in comments next to examples).
Get primitive (and boxed) types directly from Provider (also see this sample app).
Being able to change your configuration without bringing the service down is extremely important for web apps. CFG4J provides runtime configuration reloading which can be configured using ReloadStrategy. When configuration gets reloaded all bound configuration objects (see “Accessing configuration” above) will be updated.
Reload configuration periodically (also see this sample app).
Reload on-demand (e.g. triggered by push mechanism)
Multi-tenant support (a.k.a. environment selection)
You may want to store multiple configuration sets in a single configuration store (e.g. to support different environments [dev, test, prod] in your app or simplify because you want to maintain one store for multiple tenants).
To support this use case cfg4j introduces Environments. Environment is simply a way to tell the provider where in the store is your configuration set located. Because each source may support environments differently (e.g. in git you could use separate branches or directories, in K-V store you could use different paths, etc.).
For now we’re keeping it simple. Environment has a name that is interpreted by the source. It’s up to the source what interpretation to use. Consult documentation for each of the sources (plugins) for more detail.
You can provide Environment to the provider in the following way:
Different file types support (YAML, properties)
When reading from ConfigurationSource that is backed by files (e.g. git repository) you have an option of using either plain properties files or YAML files. Cfg4j will automatically recognize the file by its extension (.properties or .yaml).
Merging configurations from multiple sources
You can merge configs from multiple configuration sources. To do that use MergeConfigurationSource as seen below:
Fallback in case of failure
When working in a distributed environment failure happen all the time. You may consider using multiple sources. When one fails another one will be used as a fallback. You can use FallbackConfigurationSource in the following way:
Metrics
Most of the cfg4j components are instrumented. Metrics are exposed with support from Dropwizard’s Metrics library. You can see the number of invocations (e.g. how many times your configuration was reloaded) and execution time (e.g. how long does it take to fetch configuration from external configuration source - git repository or Consul). To enable instrumentation you have to provide ConfigurationProvider with Metric’s MetricRegistry. To easily differentiate between metrics for different provided you can specify prefix prepended to all metric names constructed for the given provider.
Extensions
Classpath
Read configuration from multiple files located in classpath. Also see this sample app.
Files
Read configuration from multiple files located in a given path. Also see this sample app.
Git
Use remote or local git repository that reloads configuration every 5 seconds. Also see this sample app.
Read configuration from a given files (defaults to application.properties). Also see this sample app.
Multi-tenant support (multiple configuration sets per source)
Read configuration from a given branch (defaults to master). Also see this sample app.
Read configuration from files (see examples above to change list of files) at a given path.
Consul
Connect to local Consul agent and reload configuration every 5 seconds. Also see this sample app.
Connect to remote Consul agent and reload configuration every 5 seconds.
Multi-tenant support (multiple configuration sets per repository)
Read configuration from a given prefix (defaults to no prefix).