Support for multiple environments

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:

  • Inclusion of files
  • Access to system properties
Let's see an example which shows how to use this features to support multiple environments.

An example

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:

  • moduleABC.development.properties
  • moduleABC.production.properties
We could include, for example, the first of this files in the moduleABC.properties file using the include-and-override special property:

include-and-override=moduleABC.development.properties
         

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:

include-and-override=moduleABC.${my-environment}.properties
         

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.

Multiple projects and multiple environments

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:

  • moduleABC.projectA.properties: will contain the properties whose value has been changed for the projectA.
  • moduleABC.projectA.development.properties: will contain the properties whose value has been changed for the development environment of projectA.
  • moduleABC.projectA.production.properties: will contain the properties whose value has been changed for the production environment of projectA.
  • moduleABC.projectB.properties: will contain the properties whose value has been changed for the projectB.
  • moduleABC.projectB.development.properties: will contain the properties whose value has been changed for the development environment of projectB.
  • moduleABC.projectB.production.properties: will contain the properties whose value has been changed for the production environment of projectB.

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:

include-and-override=moduleABC.${my-project}.properties
include-and-override=moduleABC.${my-project}.${my-environment}.properties
         

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 ...
			

Multiple components and multiple environments

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:

include-and-override=global-configuration.${my-environment}.properties
         

And then all the property values specific for one of environments will be set in global-configuration.development.properties, global-configuration.production.properties, etc.