Reading yaml files to get environment variables | Spring Boot, Hibernate, MicroServices and Cloud Forum
S
srikanth Posted on 15/09/2021

Hi 

we have yaml files which have values-dev1.yaml, values-QA1.yaml, values-QA2.yaml....files under "src/main/resources", values have environment related info like db connection, other services...etc. 

They use these environment variables it in src/main/java....using springboot @configuration.

Can use the same in src/test/java for Integration Tests?. Please let me know.

 

Thanks

Sri


Y
Yogesh Chawla Replied on 16/09/2021

Sorry for the late reply:

Yes, We can have as many configuration files as we want.

Just need to configure which one to pick according to env where our app is deployed.

It's done via flag 'spring.profiles.active' which we set in application.properties file

like
spring.profiles.active=prod

Spring actually help enable Spring Applications to define different properties for different environments.

Using the below code, you can check which configurations are picked by your app. Here we are using YAMLConfig class object to fetch the details.
Remember functions called to fetch the details are actually based on the flags present in the configuration file.

@SpringBootApplication
public class MyApplication implements CommandLineRunner {

    @Autowired
    private YAMLConfig myConfig;

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MyApplication.class);
        app.run();
    }

    public void run(String... args) throws Exception {
        System.out.println("using environment: " + myConfig.getEnvironment());
        System.out.println("name: " + myConfig.getName());
        System.out.println("enabled:" + myConfig.isEnabled());
        System.out.println("servers: " + myConfig.getServers());
    }
}

Please do let me know in case you couldn't figure out which configurations are picked by your app.


S
srikanth Replied on 26/01/2022

Thanks Yogesh.

I want to use the properties in "src/test/java" but these properties are from yaml files which are in "src/main/resourcs". can I do that?.

 

Thanks

Sri


Y
Yogesh Chawla Replied on 26/01/2022

Yes. You can do that.

Like this:

????spring-boot-main-test-application-yaml
    ????pom.xml
    ????src
        ????main
        ?   ????java
        ?   ????resources
        ?       ????application.yml
        ?   
        ????test
            ????java
            ????resources
                ???? application.yml

Do "mvn clean package" and see which version ends inside the jar in your .m2 folder.

Now the question is how to pick the java or test folder yaml file:

Based on the scope of the jar file mentioned in your pom, that yaml file will be picked up.

Scope can be set to compile,test, runtime or system (default is runtime) for any dependency in pom

NOTE: Set it to test to read the test folder yaml file or runtime to read java folder yaml file.

While making the build with pom, make sure correct file is picked up.

Just a sample part how we build including both. Your pom will be different for sure:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
      <execution>
        <phase>process-test-resources</phase>
        <goals>
          <goal>run</goal>
        </goals>
        <configuration>
          <target>
            <!-- Include environment-invariant content from src/main/java -->
            <copy overwrite="true" todir="${project.build.testOutputDirectory}" verbose="true">
              <fileset dir="${project.basedir}/src/main/java" includes="*">
                <type type="file"/>
                <!-- don't include subfolders -->
              </fileset>
            </copy>

            <!-- Include environment-variant content from src/main/test/${test.config.profile}, including subfolders -->
            <copy overwrite="true" todir="${project.build.testOutputDirectory}" verbose="true">
              <fileset dir="${project.basedir}/src/main/test/${test.config.profile}" includes="**/*"/>
            </copy>
          </target>
        </configuration>
      </execution>
    </executions>
  </plugin>

 

Few facts about yaml file:

Compared to XML and JSON, YAML has a minimum syntax with more emphasis on human readability. YAML uses indentation to indicate nesting. This is perhaps the biggest difference between YAML and other data formats.

Yaml is often referred as the superset of JSON. Meaning, JSON is contained within YAML. In fact, we could directly embed JSON objects within YAML.

YAML documents usually start with three dashes and optionally end with three dots. Sometimes the dots are omitted if there's only one document.

If there are multiple configurations/documents inside a single file, then each should be separated with the common three dashes.

YAML basic data types are signed integers, floats, strings, Booleans or nulls. String values in YAML are sometimes left unquoted but you can quote them too.

The objects in YAML are in key value pairs. The key and value are separated by colon.

The lists in YAML could be represented either with square brackets or with the same indentation and a dash in front of the list item.

The map could be represented by curly brackets or nested with the same indentation.

Unlike JSON and XML, YAML does not use brackets or tags to represent hierarchy. It uses new lines and spaces. If two items share the same indentation, it means they're in at the same level.

YAML provides a way to incorporate comments. Comments in YAML are proceeded by the hash symbol.

Please let me know in case you face any issues.


S
srikanth Replied on 01/02/2022

Thanks, Yogesh. will try it.