Browse Source

Added posibility to append archaius configuration to existing installed configurations

pull/6/head
Alexandru Burghelea 10 years ago committed by Spencer Gibb
parent
commit
611c0b5c1c
  1. 13
      spring-cloud-netflix-core/pom.xml
  2. 64
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java
  3. 42
      spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java
  4. 58
      spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusExternalConfiguration.java
  5. 8
      spring-cloud-netflix-core/src/test/resources/archaius_db_store.sql
  6. 2
      spring-cloud-netflix-core/src/test/resources/config.properties

13
spring-cloud-netflix-core/pom.xml

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
@ -158,5 +159,15 @@ @@ -158,5 +159,15 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

64
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java

@ -17,6 +17,7 @@ @@ -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; @@ -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; @@ -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 { @@ -66,6 +68,9 @@ public class ArchaiusAutoConfiguration {
@Autowired
private ConfigurableEnvironment env;
@Autowired
private List<AbstractConfiguration> externalConfigurations;
@PreDestroy
public void close() {
setStatic(ConfigurationManager.class, "instance", null);
@ -85,7 +90,7 @@ public class ArchaiusAutoConfiguration { @@ -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 { @@ -95,7 +100,8 @@ public class ArchaiusAutoConfiguration {
@Configuration
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
@ConditionalOnClass(EnvironmentChangeEvent.class)
protected static class PropagateEventsConfiguration implements ApplicationListener<EnvironmentChangeEvent> {
protected static class PropagateEventsConfiguration implements
ApplicationListener<EnvironmentChangeEvent> {
@Autowired
private Environment env;
@ -109,14 +115,13 @@ public class ArchaiusAutoConfiguration { @@ -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 { @@ -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 { @@ -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 { @@ -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);

42
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 { @@ -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());
}
}

58
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusExternalConfiguration.java

@ -0,0 +1,58 @@ @@ -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;
}
}

8
spring-cloud-netflix-core/src/test/resources/archaius_db_store.sql

@ -0,0 +1,8 @@ @@ -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');

2
spring-cloud-netflix-core/src/test/resources/config.properties

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
archaius.file.property=Static config file property
db.second.property=It should be overridden
Loading…
Cancel
Save