Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring YAML profile configuration

I'm not sure if I well understand how Spring profiles works with yaml and properties files. I was trying to misc those two types of configuration (the two file do not share any configuration) but i'm having problems when reading profiles from yaml configuration.

I'm using Spring 4.1.1

Here is the code. This is the context:property-placeholder configuration:

<context:property-placeholder location="classpath:/job-config.properties" order="1" 
ignore-unresolvable="true" ignore-resource-not-found="false"/>


<context:property-placeholder properties-ref="yamlProperties" order="2"
ignore-resource-not-found="false" ignore-unresolvable="true"/>

where yamlProperties is the following bean

    <bean id="yamlProperties" 
    class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
                <property name="resources" 
value="file:${catalina.home}/properties/test.yml"/>
            </bean>

Here is the test.yml

spring:
  profiles.default: default
---
spring:
  profiles: default
db:
  url: jdbc:oracle:thin:@##hostname##:##port##:##SID##
  usr: ##USER##
  pwd: ##PWD##
---
spring:
  profiles: development
db:
  url: jdbc:oracle:thin:@##hostname##:##port##:##SID_DEVELOPMENT##
  usr: ##USER_DEVELOPMENT##
  pwd: ##PWD_DEVELOPMENT##

My problem is that when I try to configure (via xml) my datasources by doing this:

<property name="url" value="${db.url}"/>
<property name="username" value="${db.usr}"/>
<property name="password" value="${db.pwd}"/>

Spring always use the last configuration in the YAML file ignoring the profile. I tried to pass the active profile through contex-parameter in web.xml or directly to the JVM (I implemented a bean that implements EnvironmentAware interface to get the active/default profiles and it's corret) and it seems all good but, when trying to inject values the profile is ignored.

I believe that using property-placeholder context (with orders) I get one property-placeholder that is an instance of PropertySourcesPlaceholderConfigurer so with access to Environment but i cannot understand why the profile is ignored and spring gets the last yaml file configuration.

I add a reference to the documentation (spring-boot), in the section 63.6 http://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html

Thanks in advance

like image 357
Raffaele Avatar asked Sep 27 '22 07:09

Raffaele


1 Answers

Not sure if this helps at this point but here is what I did.

I used SpringProfileDocumentMatcher class [by Dave Syer from spring boot] as my base matcher and implemented EnvironmentAware to get the actives profiles and pass this bean to the YamlPropertiesFactoryBean bean. Here is the code:

applicationContext.xml

<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" value="classpath:application.yml" />
<property name="documentMatchers">
  <bean class="com.vivastream.quant.spring.SpringProfileDocumentMatcher" />
</property>

SpringProfileDocumentMatcher.java

public class SpringProfileDocumentMatcher implements DocumentMatcher, EnvironmentAware {

private static final String[] DEFAULT_PROFILES = new String[] {
        "^\\s*$"
};

private String[] activeProfiles = new String[0];

public SpringProfileDocumentMatcher() {
}

@Override
public void setEnvironment(Environment environment) {
    if (environment != null) {
        addActiveProfiles(environment.getActiveProfiles());
    }
}

public void addActiveProfiles(String... profiles) {
    LinkedHashSet<String> set = new LinkedHashSet<String>(Arrays.asList(this.activeProfiles));
    Collections.addAll(set, profiles);
    this.activeProfiles = set.toArray(new String[set.size()]);
}

@Override
public MatchStatus matches(Properties properties) {
    String[] profiles = this.activeProfiles;
    if (profiles.length == 0) {
        profiles = DEFAULT_PROFILES;
    }
    return new ArrayDocumentMatcher("spring.profiles", profiles).matches(properties);
}

}

like image 57
Gustavo Avatar answered Sep 30 '22 07:09

Gustavo