From 01c5b44a18ca735b19da2370eb46d1383dafbe53 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Mon, 26 Jan 2015 22:16:09 -0700 Subject: [PATCH] propagate EnvironmentChangeEvents to archaius dynamic property listenters fixes gh-144 --- .../archaius/ArchaiusAutoConfiguration.java | 31 +++++++++++++++++++ .../ArchaiusAutoConfigurationTests.java | 25 +++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java index 7a769cb8..72d2fde1 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java @@ -22,15 +22,22 @@ import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.PreDestroy; import lombok.extern.apachecommons.CommonsLog; +import org.apache.commons.configuration.AbstractConfiguration; import org.apache.commons.configuration.ConfigurationBuilder; import org.apache.commons.configuration.EnvironmentConfiguration; import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration.event.ConfigurationEvent; +import org.apache.commons.configuration.event.ConfigurationListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; import org.springframework.util.ReflectionUtils; import com.netflix.config.ConcurrentCompositeConfiguration; @@ -85,6 +92,30 @@ public class ArchaiusAutoConfiguration { } } + @Configuration + @ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true) + @ConditionalOnClass(EnvironmentChangeEvent.class) + protected static class PropagateEventsConfiguration implements ApplicationListener { + @Autowired + private Environment env; + + @Override + public void onApplicationEvent(EnvironmentChangeEvent event) { + AbstractConfiguration manager = ConfigurationManager.getConfigInstance(); + for (String key : event.getKeys()) { + for (ConfigurationListener listener : manager.getConfigurationListeners()) { + Object source = event.getSource(); + // TODO: Handle add vs set vs delete? + int type = AbstractConfiguration.EVENT_SET_PROPERTY; + String value = env.getProperty(key); + boolean beforeUpdate = false; + listener.configurationChanged(new ConfigurationEvent(source, + type, key, value, beforeUpdate)); + } + } + } + } + @SuppressWarnings("deprecation") protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) { if (initialized.compareAndSet(false, true)) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java index a6759087..65e89e99 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java @@ -16,11 +16,18 @@ package org.springframework.cloud.netflix.archaius; +import com.google.common.collect.Sets; +import com.netflix.config.ConfigurationManager; import org.apache.commons.configuration.AbstractConfiguration; +import org.apache.commons.configuration.event.ConfigurationEvent; +import org.apache.commons.configuration.event.ConfigurationListener; import org.junit.After; import org.junit.Test; +import org.springframework.boot.test.EnvironmentTestUtils; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** @@ -29,6 +36,7 @@ import static org.junit.Assert.assertNotNull; public class ArchaiusAutoConfigurationTests { private AnnotationConfigApplicationContext context; + private Object propertyValue; @After public void close() { @@ -46,4 +54,21 @@ public class ArchaiusAutoConfigurationTests { assertNotNull(config.getString("java.io.tmpdir")); } + @Test + public void environmentChangeEventPropagated() { + this.context = new AnnotationConfigApplicationContext( + ArchaiusAutoConfiguration.class); + ConfigurationManager.getConfigInstance().addConfigurationListener(new ConfigurationListener() { + @Override + public void configurationChanged(ConfigurationEvent event) { + if (event.getPropertyName().equals("my.prop")) { + propertyValue = event.getPropertyValue(); + } + } + }); + EnvironmentTestUtils.addEnvironment(context, "my.prop=my.newval"); + context.publishEvent(new EnvironmentChangeEvent(Sets.newHashSet("my.prop"))); + assertEquals("my.newval", propertyValue); + } + }