Enterprise Java

Netflix Archaius properties in a Spring project

Archaius Basics

Netflix Archaius is a library for managing configuration for an application. Consider a properties file “sample.properties” holding a property called “myprop”:
 
 
 
 
 
 
 

myprop=myprop_value_default

This is how the file is loaded up using Archaius:

ConfigurationManager
                .loadCascadedPropertiesFromResources("sample");

String myProp = DynamicPropertyFactory.getInstance().getStringProperty("myprop", "NOT FOUND").get();

assertThat(myProp, equalTo("myprop_value_default"));

Archaius can load property appropriate to an environment, consider that there is a “sample-perf.properties” with the same configuration over-ridden for perf environment:

myprop=myprop_value_perf

Now Archaius can be instructed to load the configuration in a cascaded way by adding the following in sample.properties file:

myprop=myprop_value_default

@next=sample-${@environment}.properties

And the test would look like this:

ConfigurationManager.getDeploymentContext().setDeploymentEnvironment("perf");
ConfigurationManager
        .loadCascadedPropertiesFromResources("sample");

String myProp = DynamicPropertyFactory.getInstance().getStringProperty("myprop", "NOT FOUND").get();

assertThat(myProp, equalTo("myprop_value_perf"));

Spring Property basics

Spring property basics are very well explained at the Spring Framework reference site here. In short, if there is a property file “sample.properties”, it can be loaded up and referenced the following way:

@Configuration
@PropertySource("classpath:/sample.properties")
public class AppConfig {
    @Autowired
    Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("myprop"));
        return testBean;
    }


}

Or even simpler, they can be de-referenced with placeholders this way:

@Configuration
@PropertySource("classpath:/sample.properties")
public class AppConfig {
    @Value("${myprop}")
    private String myProp;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(myProp));
        return testBean;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}

Making Archaius properties visible to Spring

So now the question is how to get the Archaius properties visible in Spring, the approach I have taken is a little quick and dirty one but can be cleaned up to suite your needs. My approach is to define a Spring PropertySource which internally delegates to Archaius:

import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicPropertyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.PropertySource;

import java.io.IOException;

public class SpringArchaiusPropertySource extends PropertySource<Void> {


    private static final Logger LOGGER = LoggerFactory.getLogger(SpringArchaiusPropertySource.class);


    public SpringArchaiusPropertySource(String name) {
        super(name);
        try {
            ConfigurationManager
                    .loadCascadedPropertiesFromResources(name);
        } catch (IOException e) {
            LOGGER.warn(
                    "Cannot find the properties specified : {}", name);
        }

    }

    @Override
    public Object getProperty(String name) {
         return DynamicPropertyFactory.getInstance().getStringProperty(name, null).get();
    }
}

The tricky part is registering this new PropertySource with Spring, this can be done using an ApplicationContextInitializer which is triggered before the application context is initialized:

import com.netflix.config.ConfigurationBasedDeploymentContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;

public class SpringProfileSettingApplicationContextInitializer
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext ctx) {
        ctx.getEnvironment()
                .getPropertySources()
                .addFirst(new SpringArchaiusPropertySource("samples"));
    }
}

And finally registering this new ApplicationContextInitializer with Spring is described here. This is essentially it, now the Netflix Archaius properties should work in a Spring application.

Reference: Netflix Archaius properties in a Spring project from our JCG partner Biju Kunjummen at the all and sundry blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Piyush Nagar
Piyush Nagar
3 years ago

What is samples here? All of the above place you have passed sample but here it is samples. Is it file name?
.addFirst(new SpringArchaiusPropertySource(“samples”));

Piyush Nagar
Piyush Nagar
3 years ago

Second Point is we have made Archaius properties visible to Spring in above code, but that will not hot reload, because context initialization will be done at startup of application. How will be reload it on change in file.

Back to top button