Chaining Profiles and Additional Documents

Just recently I have been playing around with multiple active profiles. This is apart from having the main application config, plus the profile that matches the environment on which the application is running. That is quite commonplace. Instead I’m talking more of an additional profile that gets activated aside from the environment profile based on another criteria. And like environment variables are defined depending on where the application is ran, that additional criteria also needs to be set somewhere so that it can be picked up when the software starts up.

Say I have the application.yml, usually the default one, where all the properties are crammed together. Then there are the dev, test and prod profiles, where properties of say the database connection are specifically defined for each environment. But then I need an additional layer of properties that only gets activated off of a condition, like for example, based on the season. Thus I may have spring, summer, fall and winter YAML documents defined.

It’s gonna be defined as such:

--spring.profiles.active=dev,summer

Now the thing is, I also need to define properties by season based on the environment. For obvious reasons, I can’t have those in my environment profiles. A property value will be different by season. Some properties may be common for that season. Then others can be different on non-prod and prod environments.

I’ve thought about chaining it using multi-documents, putting in spring.config.activate.on-profile conditions. Then lastly pull in some additional configuration through spring.config.import.

It might get complicated and hard to understand later on, which is what I would like to avoid.

Here is what I thought about doing. Starting with the application-dev.yml.

spring:    
  datasource:
    url: jdbc:mysql://localhost:3306/store?useSSL=false   

Sample contents for application-summer.yml:

spring:
  config:
    activate:
      on-profile: summer
      
hello: world
foo: bar
folder: /summer-common
checklist:
  - water bottle

---
spring:
  config:
    activate:
      on-profile: prod
  import: summer-prod.yml

This additional document gets loaded based on the season variable that gets passed when the application starts. Since summer was the other activated profile, application-fall.yml, application-winter.yml and so on will be ignored.

I’ve made the summer config a multi-document. The common properties for summer are there. The second logical document separated by --- only activates when the on-profile condition is met. Here it’s set to prod environment. Then it imports the additional YAML document when that happens.

Sample contents for summer-prod.yml:

folder: /summer
checklist:
  - water bottle
  - field hat
  - sunglasses

All of these documents are ordered top-down. So any property that was defined last has the final value. Imports are additional documents inserted after the declaring document. Documentation says it gets only loaded once even if declared several times at different points. So the placement where it’s called matters I suppose?

There is spring.profiles.include that is similar to import. But I read somewhere it is/will no longer be supported in future Spring versions.

Additionally there is another feature called Proflile Groups. I haven’t really considered using that, but it is an option and good to know.

Similar Posts: