Like other applications, my main project runs through several quality gates before being deployed on the production stage. For example, there is a developer stage, which simply is the locally running version on every developer machine, and a test stage. This test stage is similar to the production setup and can be used to test features before they are merged into the main branch of your version control system. Many projects use an additional quality stage which runs the latest stable build so the customer can test, too. The deployed system behaves differently for every stage. The simplest difference is the database used. You don’t want to use the same database for your production and test system, so the deployed code has to decide which database to use. This article describes, how we use Spring to setup different stages.
Because the deployed code is the same in every stage, we need a system property to set the stage. In this example, there are only two instances, using the following system properties:
developer stage: no system property set (to keep the costs for setting up a new developer machine as low as possible)
test stage: spring.profiles.active = test
As mentioned above, other stages can easily be added to this setup.
This system property has to be used by Java code. To implement clean code, the first step is to have an enum for the system properties used:
Depending on the stage the application is running on, there are different configurations to use. These are listed in properties files. For each stage, there is one property file. They have the same attributes, but different values. To keep this example simple, there are just two attributes in the files. One for the name of the application (which is the same regardless of the stage) and one string that represents the stage itself. This is the properties file for the local development stage:
This is the properties for the test stage:
Using Java configuration, these configuration files can be mapped to a Java class:
There are two things happening in this class. First, the annotation of the class decides which property file to map. If there is a system property “spring.profiles.active”, it is used. If there is no property, the default “developer” is used. The path of the property file is “[stage]/client.properties”.
Second, each attribute of the property file is mapped into the Java class to be used by the application.
Of course, this setup has to be tested. Here’s the test for the locally running developer stage:
Here’s the slightly more complicated version for the test stage. ProvideSystemProperty is used to set the system property “spring.profiles.active” to “test”: