Read configuration from application.yml in spring

Updated: Jul 26, 2021

In spring we generally keep application configuration data and values which are static in the application.properties file. Then when needed we read those values from the application.properties file. In this file the parameter and their values are stored as a key value pair. Similarly we can also use an application.yml file to store configuration related data. The parameters and values are stored in this file in YAML format. The advantage of using an application.yml is we can store key values in a nested format. Today I will show how we can read parameters and their corresponding values from an application.yml file. This file is kept in the same place where we store the application.properties file, that is under the resources folder.


A sample application.yml

Let's assume we want to connect to another service or application and we would like to build its full path. As in different deployments the domain is different. We need to keep a list of those domains and at run time we need to determine which deployment services or applications are running. The caller application needs to determine this during runtime or deployment time when the application is started. Depending on the deployment the corresponding URL needs to be used to build the fully qualified path of the caller application. An example structure can be like this, but we can put any structure. The example has three levels. The first level we have BACKEND_URLS then in the second level we have STAGING_DEV, PRODUCTION1 etc and at the leaf we have URL.

BACKEND_URLS:
  STAGING_DEV:
    URL: "urls.for.staging.and.dev"
  PRODUCTION1:
    URL:  "urls.for.production1"
  PRODUCTION2:
    URL:  "urls.for.production2"
  PRODUCTION3:
    URL:  "urls.for.production3"

The code to parse the yml file

The code to read the file is written as a spring configuration file so the file will be read and information will be extracted when the application starts. The getYmlObject() method reads the file and the content of the file is saved as a map, the key of the map element here will be the first level elements and the value will be the content of the first level element. The init() method is executed when the application is started, this method calls the getYmlObject() method. Here in the example file we have only one first level element that is “BACKEND_URLS”. Hence the key is BACKEND_URLS . Then we call the getBaseObject() method to extract the value of the first level element. The returned value is again a map with a key value pair. This time the keys are STAGING_DEV, PRODUCTION1 etc. Here next the application needs to know which deployment it is running and needs to extract the URL for that particular deployment. Here for simplicity I have hardcoded the name of the deployment as PRODUCTION2. So next what we do is give this key and extract the value which is the third level element in the structure. In this example, this is the URL parameter and its value. We extract that by calling the getUrlMapForProd() method. The returned value is again a map where the key is “URL” and the value is "urls.for.production2". Finally we use the getUrlFromMap() method to get the value.

import java.util.LinkedHashMap;
import java.util.Map;  
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;  
import org.springframework.context.support.PropertySourcePlaceHolderConfigurer;  
import org.springframework.core.io.ClasspathResource ;

  @Configuration
  public class YmlConfig {
 
  @PostConstruct
  public void init() {
    initURL():
  }
 
  @Bean
  public static 
   PropertySourcePlaceHolderConfigurer  propertySourcePlaceHolderConfigurer() {
    return new  PropertySourcePlaceHolderConfigurer();
  }
 
  private void  initURL() {
    try {
      Map<String,Object> mapObject = getYmlObject();
      Map<String,Object> urlMap = null;
      Map<String,Object> prodToUrl = getBaseObject(mapObject);  
      if( prodToUrl  == null) {
        throw new Exception("some error message");
      }
      urlMap = getUrlMapForProd( prodToUrl, "PRODUCTION2");
      if( urlMap  == null) {
        throw new Exception("some error message");
      }
      String url = getUrlFromMap(urlMap);
      if(url == null || url.eqal("") ) {
        throw new Exception("some error message"); 
      }
    } catch(Exception e) {
       throw new Exception("some error message"); 
    }
  }
 
  Map<String,Object> getYmlObject() {
     YamlMapFactoryBean fBean = new  YamlMapFactoryBean();
     fBean.setResource(new ClasspathResource("application.yml"));
     fBean.setSingleton(true);
     return  fBean.getObject();
  }
 
  LinkedHashMap<String,Object> getBaseObject(Map<String,Object> mapObject) {
    return  (LinkedHashMap<String,Object>)  mapObject.get("BACKEND_URLS");
   } 
 
  LinkedHashMap<String,Object> getUrlMapForProd (Map<String,Object> prodToUrl, 
         String prod) {
    return  (LinkedHashMap<String,Object>) prodToUrl.get(prod);
  }  
 
  String  getUrlFromMap( Map<String,Object> urlMap) {
    return (String) urlMap.get("URL");
  }
}

In this blog post, I have shown how we can read and extract a nested structure from an application.yml file in spring.


81 views0 comments

Recent Posts

See All