Table of Contents
- Quick start
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.
You may want to read the following (a bit lengthy) article about configuration management using cfg4j to get better understanding of the core configuration management concepts.
Add cfg4j-core and cfg4j-git dependencies to your project (see previous paragraph for detail).
Use the following code in your application to connect to the sample configuration source (git repository). Also see this sample app.
- Optional steps
- Fork the sample configuration repository.
- Add your configuration to the “application.properties” file and commit the changes.
- Update the code above to point to your fork.
Using cfg4j is quite simple. It boils down to the following steps:
- Point to the
ConfigurationSourcethat stores your configs (e.g. Consul K-V store, git repository, local files, classpath resources).
ConfigurationProviderbacked by your configuration source.
- Access your configuration in one of the two ways:
- Directly through ConfigurationProvider methods (e.g.
- 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.
- Directly through ConfigurationProvider methods (e.g.
- (optional) If you want you can customize the ConfigurationProvider behavior by using:
ReloadStrategy- those allow configuration to be automatically reloaded. There’s
PeriodicalReloadStrategyprovided 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.
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.
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)
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).
- Get collections directly from Provider
- Utilize object binding (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:
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.
- Read configuration from multiple files located in classpath. Also see this sample app.
- Read configuration from multiple files located in a given path. Also see this sample app.
- 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.
- 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).