Archaius Basics
Netflix Archaius is a library for managing configuration for an application. Consider a properties file "sample.properties" holding a property called "myprop":
1 | myprop=myprop_value_default |
This is how the file is loaded up using Archaius:
1 2 3 4 5 6 | 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:
1 | 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:
1 2 3 | myprop=myprop_value_default @next =sample-${ @environment }.properties |
And the test would look like this:
1 2 3 4 5 6 7 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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.
Great stuff. This exactly what I was looking for.
ReplyDelete