diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml
index ad6a83d4..299ff474 100644
--- a/spring-cloud-netflix-core/pom.xml
+++ b/spring-cloud-netflix-core/pom.xml
@@ -1,6 +1,6 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.cloud
@@ -29,6 +29,7 @@
org.springframework.boot
spring-boot-autoconfigure
+
org.springframework.cloud
spring-cloud-commons
@@ -158,5 +159,15 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ test
+
+
+ com.h2database
+ h2
+ test
+
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 72d2fde1..36ca5ef8 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
@@ -17,6 +17,7 @@
package org.springframework.cloud.netflix.archaius;
import java.lang.reflect.Field;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PreDestroy;
@@ -28,6 +29,13 @@ 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 com.netflix.config.ConcurrentCompositeConfiguration;
+import com.netflix.config.ConfigurationManager;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.config.DynamicURLConfiguration;
+import com.netflix.config.DeploymentContext;
+import com.netflix.config.AggregatedConfiguration;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -40,12 +48,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.ReflectionUtils;
-import com.netflix.config.ConcurrentCompositeConfiguration;
-import com.netflix.config.ConfigurationManager;
-import com.netflix.config.DynamicPropertyFactory;
-import com.netflix.config.DynamicURLConfiguration;
-
-import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
@@ -66,6 +68,9 @@ public class ArchaiusAutoConfiguration {
@Autowired
private ConfigurableEnvironment env;
+ @Autowired
+ private List externalConfigurations;
+
@PreDestroy
public void close() {
setStatic(ConfigurationManager.class, "instance", null);
@@ -85,7 +90,7 @@ public class ArchaiusAutoConfiguration {
@Configuration
@ConditionalOnClass(Endpoint.class)
- protected static class ArchaiusEndpointConfuguration {
+ protected static class ArchaiusEndpointConfiguration {
@Bean
protected ArchaiusEndpoint archaiusEndpoint() {
return new ArchaiusEndpoint();
@@ -95,7 +100,8 @@ public class ArchaiusAutoConfiguration {
@Configuration
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
@ConditionalOnClass(EnvironmentChangeEvent.class)
- protected static class PropagateEventsConfiguration implements ApplicationListener {
+ protected static class PropagateEventsConfiguration implements
+ ApplicationListener {
@Autowired
private Environment env;
@@ -109,14 +115,13 @@ public class ArchaiusAutoConfiguration {
int type = AbstractConfiguration.EVENT_SET_PROPERTY;
String value = env.getProperty(key);
boolean beforeUpdate = false;
- listener.configurationChanged(new ConfigurationEvent(source,
- type, key, value, beforeUpdate));
+ listener.configurationChanged(new ConfigurationEvent(source, type,
+ key, value, beforeUpdate));
}
}
}
}
- @SuppressWarnings("deprecation")
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
if (initialized.compareAndSet(false, true)) {
String appName = this.env.getProperty("spring.application.name");
@@ -124,20 +129,17 @@ public class ArchaiusAutoConfiguration {
appName = "application";
log.warn("No spring.application.name found, defaulting to 'application'");
}
- // this is deprecated, but currently it seams the only way to set it initially
- System.setProperty(DEPLOYMENT_APPLICATION_ID_PROPERTY, appName);
-
- // TODO: support for other DeploymentContexts
+ System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName);
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
// support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds,
// etc...)
- /*
- * if (factories != null && !factories.isEmpty()) { for
- * (PropertiesSourceFactory factory: factories) {
- * config.addConfiguration(factory.getConfiguration(), factory.getName()); } }
- */
+ if (externalConfigurations != null) {
+ for (AbstractConfiguration externalConfig : externalConfigurations) {
+ config.addConfiguration(externalConfig);
+ }
+ }
config.addConfiguration(envConfig,
ConfigurableEnvironmentConfiguration.class.getSimpleName());
@@ -165,7 +167,7 @@ public class ArchaiusAutoConfiguration {
config.setContainerConfigurationIndex(config
.getIndexOfConfiguration(appOverrideConfig));
- ConfigurationManager.install(config);
+ addArchaiusConfiguration(config);
}
else {
// TODO: reinstall ConfigurationManager
@@ -173,6 +175,26 @@ public class ArchaiusAutoConfiguration {
}
}
+ private void addArchaiusConfiguration(ConcurrentCompositeConfiguration config) {
+ if (ConfigurationManager.isConfigurationInstalled()) {
+ AbstractConfiguration installedConfiguration = ConfigurationManager
+ .getConfigInstance();
+ if (installedConfiguration instanceof ConcurrentCompositeConfiguration) {
+ ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration;
+ configInstance.addConfiguration(config);
+ }
+ else {
+ installedConfiguration.append(config);
+ if (!(installedConfiguration instanceof AggregatedConfiguration)) {
+ log.warn("Appending a configuration to an existing non-aggregated installed configuration will have no effect");
+ }
+ }
+ }
+ else {
+ ConfigurationManager.install(config);
+ }
+ }
+
private static void setStatic(Class> type, String name, Object value) {
// Hack a private static field
Field field = ReflectionUtils.findField(type, name);
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 2f269cca..6f896ee2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2014 the original author or authors.
+ * Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,14 +23,17 @@ import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.junit.After;
import org.junit.Test;
+import com.netflix.config.ConfigurationManager;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.config.DynamicStringProperty;
+
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import com.netflix.config.ConfigurationManager;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
/**
* @author Dave Syer
@@ -76,4 +79,37 @@ public class ArchaiusAutoConfigurationTests {
assertEquals("my.newval", this.propertyValue);
}
+ @Test
+ public void configurationWithoutExternalConfigurations() throws Exception {
+ this.context = new AnnotationConfigApplicationContext(
+ ArchaiusAutoConfiguration.class);
+ DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance()
+ .getStringProperty("db.property", null);
+ DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance()
+ .getStringProperty("archaius.file.property", null);
+
+ assertNull(dbProperty.getValue());
+ assertNotNull(staticProperty.getValue());
+ assertEquals("Static config file property", staticProperty.getValue());
+ }
+
+ @Test
+ public void configurationWithInjectedDbConfiguration() throws Exception {
+ this.context = new AnnotationConfigApplicationContext(
+ ArchaiusAutoConfiguration.class, ArchaiusExternalConfiguration.class);
+ DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance()
+ .getStringProperty("db.property", null);
+ DynamicStringProperty secondDbProperty = DynamicPropertyFactory.getInstance()
+ .getStringProperty("db.second.property", null);
+ DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance()
+ .getStringProperty("archaius.file.property", null);
+
+ assertNotNull(dbProperty.getValue());
+ assertNotNull(secondDbProperty.getValue());
+ assertNotNull(staticProperty.getValue());
+ assertEquals("this is a db property", dbProperty.getValue());
+ assertEquals("this is another db property", secondDbProperty.getValue());
+ assertEquals("Static config file property", staticProperty.getValue());
+ }
+
}
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusExternalConfiguration.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusExternalConfiguration.java
new file mode 100644
index 00000000..6aec364d
--- /dev/null
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusExternalConfiguration.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2013-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.netflix.archaius;
+
+import com.netflix.config.DynamicConfiguration;
+import com.netflix.config.FixedDelayPollingScheduler;
+import com.netflix.config.PolledConfigurationSource;
+import com.netflix.config.sources.JDBCConfigurationSource;
+import org.apache.commons.configuration.AbstractConfiguration;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.SingleConnectionDataSource;
+
+/**
+ * @author Alexandru-George Burghelea
+ */
+@Configuration
+public class ArchaiusExternalConfiguration {
+
+ @Bean
+ @Qualifier("dynamicConfiguration")
+ public AbstractConfiguration createDynamicConfiguration() {
+ PolledConfigurationSource source = new JDBCConfigurationSource(initDataSource(),
+ "select distinct property_key, property_value from properties",
+ "property_key", "property_value");
+ return new DynamicConfiguration(source, new FixedDelayPollingScheduler(0, 1000, false));
+ }
+
+ @Bean
+ @Qualifier("dataSource")
+ public SingleConnectionDataSource initDataSource() {
+ SingleConnectionDataSource dataSource = new SingleConnectionDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource
+ .setUrl("jdbc:h2:mem:test_archaius;AUTOCOMMIT=ON;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;INIT=RUNSCRIPT FROM 'classpath:archaius_db_store.sql'");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ dataSource.setSuppressClose(true);
+ return dataSource;
+ }
+
+}
diff --git a/spring-cloud-netflix-core/src/test/resources/archaius_db_store.sql b/spring-cloud-netflix-core/src/test/resources/archaius_db_store.sql
new file mode 100644
index 00000000..6b914cb5
--- /dev/null
+++ b/spring-cloud-netflix-core/src/test/resources/archaius_db_store.sql
@@ -0,0 +1,8 @@
+create table if not exists properties (
+ property_key VARCHAR(40) NOT NULL PRIMARY KEY,
+ property_value VARCHAR(255) NOT NULL,
+);
+
+insert into properties(property_key, property_value) values ('db.property','this is a db property');
+insert into properties(property_key, property_value) values ('db.second.property','this is another db property');
+
diff --git a/spring-cloud-netflix-core/src/test/resources/config.properties b/spring-cloud-netflix-core/src/test/resources/config.properties
new file mode 100644
index 00000000..1e9c021f
--- /dev/null
+++ b/spring-cloud-netflix-core/src/test/resources/config.properties
@@ -0,0 +1,2 @@
+archaius.file.property=Static config file property
+db.second.property=It should be overridden