In an earlier post, we discussed how to externalize application properties in Spring Boot applications.

That would work well for single, standalone applications. However, when we have more than one application, say in a microservice architecture, a better alternative would be to manage the configurations centrally. That can be easily done using Spring Cloud Config. We can have a centralized configuration service just by creating a Spring Boot application with a spring-cloud-config-server dependency, annotating the auto-generated main class with @EnableConfigServer, and then having the following in src/main/resources/application.yml:

          uri: https://path/to/config-repo
          username: xxxxxxxxxx
          password: yyyyyyyyyy
  port: 8888

The URI above points to a git repository where your properties or yml files would be lying. For example -- if you have two services, say service1 and service2 -- you could have the following files in the config-repo:

  1. application.yml: all the common configurations
  2. service1.yml: configurations for service1
  3. service2.yml: configurations for service2
  4. application-dev.yml: common configurations for the dev profile
  5. application-test.yml: common configurations for the test profile
  6. application-prod.yml: common configurations for the prod profile
  7. service1-dev.yml: configurations for service1 for the dev profile
  8. … and so on.

If a property is defined in multiple files, the last one in the above order will take precedence. Spring Cloud Config provides us many options and alternatives, which can be found in its documentation.

So, our services can now have just a single file at src/main/resources, bootstrap.yml, looking as below:

    name: service1
    active: dev
      uri: http://localhost:8888
      label: branch1,branch2,...

The above should work, but we now have an interesting problem – how to maintain different configurations for different feature branches?

How to maintain different configurations for different feature branches

If you noticed in the bootstrap.yml above, we have label: branch1,branch2,.... Consequently, configurations will be fetched from branch1 of the config-repo. In the absence of branch1, branch2 would be looked for, and so on. If you omit that line above, the master branch would be used.

With the above knowledge, we can set the label appropriately to point to the correct configuration branch. For example, when working on a feature branch, have label: feature1,develop, and when you merge your code to another branch, remember to change the label accordingly.

Obviously, it’s cumbersome to keep changing the labels manually when merging branches. So, here’s a way to automate it:

1) Generate a file

Let your build process generate a file. Googling will get you many ways, and I’d recommend following the Spring Boot Documentation.

2) Use the git.branch variable in the label

For example, assuming your code is branched in the following structure:

  |- develop
       |- feature1
       |- feature2
       |- ...

You can set label in bootstrap.yml as below:

label: ${git.branch},develop

3) Inject git.branch in the variable above

This is the most tricky part. A normal way to do this would be to annotate some configuration class with @PropertySource(""), as below:

@PropertySource("") // won't work!
public class Service1Application

But, this won’t work, because the label property in bootstrap.yml would be used before is read!

So, a solution for this would be to customize Spring Cloud bootstrap configuration. Specifically, we can create a class as below:

public class GitPropertySourceLocator {}

And then, add a src/main/resources/META-INF/spring.factories file, containing

We’ll not need the above GitPropertySourceLocator class in our main application context; so, better to have it in a package that’s not @ComponentScanned.

If you know of any other pattern for maintaining configuration branch, please share a comment! By the way, if you are new to microservices or Spring Cloud, Ken has a beautiful course on it at Udemy. Click here to know more about it.