This feature is useful mainly for server applications. This type of applications usually integrate with external systems and the data to connect to them is different depending on the environment in which the application is running. For example, there may be a local development environment, an integration environment, a preproduction environment and of course a production environment.
EasyConf supports having different properties for each environment. In fact it does so using the features you already know:
Let's assume a component called moduleABC. We want to support two environments: development and production. The base configuration properties of this component will be searched for in a file called moduleABC.properties. Some of the properties in this file will have a value which depends on the environment. In the base file default values will be provided. The values specific to the environment will be in other two files:
The values of the properties of the included file will override the values of the same properties of the base file (moduleABC.properties). Next, let's do a little change in the previous sentence. Instead of hardcoding the word development, we'll use a variable:
The last step is to give a value to this property using a system property. So in the development environment you have to execute the application using:
java -Dmy-environment=development ...
In this case the file moduleABC.development.properties will be included and the properties for the development environment will override the default ones. To load the file with the properties for production all you have to do is to execute the application using:
java -Dmy-environment=production ...
And that's all. You can deploy the same application in all the environments and then choose the configuration using a single system property. To add more environments just create more files of the form moduleABC.ENVIRONMENT.properties. Note that the name of the system property is an example, you are free to choose any name you want.
The following image shows this process:
Note that if the system property my-environment is given a value which does not correspond to a supported environment no file will be included. The reason is that in this case include-and-override will try to include a file which does not exist, and in that case it will just silently ignore it.
A more complex case occurs when you have a product which is used for several projects and then each projects has several environments. This situation is also supported by EasyConf. All you have to do is to include in the base properties file another file whose name depends on the project name. So if we have two projects, projectA and projectB and two environments 6 files may be used:
There are several ways to achieve this, but a good one would be using a second system property which contains the name of the project. For example, we'll give this second property the name my-project. In the moduleABC.properties file we write:
The first file to be included is the one with properties specific for a project. Next the file with the properties specific for one environment of that project will be loaded overriding any previous property values.
To use the configuration, for example, for the production environment of projectB execute the application with the following command line arguments:
java -Dmy-project=projectB -Dmy-environment=production ...
Another complex environment happens when several components are aggregated and the values of its properties must have different values in different environments. In this case the solution is very similar to the above cases, but the base files must not be changed. For this reason, the inclusion of the files with the properties specific for an environment is done in the global-configuration.properties file. For example:
And then all the property values specific for one of environments will be set in global-configuration.development.properties, global-configuration.production.properties, etc.