Skip to content

Commit

Permalink
Support for DynamicPropertyFactory backed by archaius2
Browse files Browse the repository at this point in the history
Fix order of cascading config for application layer
Fix NPE in configuration mapping/binding guice listener
  • Loading branch information
elandau committed May 28, 2015
1 parent 5ec75aa commit b928029
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@
import com.netflix.archaius.Config;
import com.netflix.archaius.commons.CommonsToConfig;
import com.netflix.archaius.config.CompositeConfig;
import com.netflix.archaius.config.DefaultConfigListener;
import com.netflix.archaius.config.SettableConfig;
import com.netflix.archaius.exceptions.ConfigAlreadyExistsException;
import com.netflix.archaius.exceptions.ConfigException;
import com.netflix.archaius.inject.LibrariesLayer;
import com.netflix.archaius.inject.RuntimeLayer;
import com.netflix.config.AggregatedConfiguration;
import com.netflix.config.DeploymentContext;
import com.netflix.config.DynamicPropertySupport;
import com.netflix.config.PropertyListener;

/**
* @see StaticArchaiusBridgeModule
* @author elandau
*/
@Singleton
class AbstractConfigurationBridge extends AbstractConfiguration implements AggregatedConfiguration {
class AbstractConfigurationBridge extends AbstractConfiguration implements AggregatedConfiguration, DynamicPropertySupport {

private final Config config;
private final SettableConfig settable;
Expand All @@ -37,7 +41,7 @@ class AbstractConfigurationBridge extends AbstractConfiguration implements Aggre

@Inject
public AbstractConfigurationBridge(
Config config,
final Config config,
@LibrariesLayer CompositeConfig libraries,
@RuntimeLayer SettableConfig settable,
DeploymentContext context) {
Expand Down Expand Up @@ -80,7 +84,11 @@ public void addConfiguration(AbstractConfiguration config) {
public void addConfiguration(AbstractConfiguration config, String name) {
try {
libraries.addConfig(name, new CommonsToConfig(config));
} catch (ConfigException e) {
}
catch (ConfigAlreadyExistsException e) {
// OK To ignore
}
catch (ConfigException e) {
throw new RuntimeException("Unable to add configuration " + name, e);
}
}
Expand Down Expand Up @@ -130,4 +138,24 @@ public boolean removeConfiguration(Configuration config) {
public Configuration removeConfigurationAt(int index) {
throw new UnsupportedOperationException();
}

@Override
public void addConfigurationListener(final PropertyListener expandedPropertyListener) {
config.addListener(new DefaultConfigListener() {
@Override
public void onConfigAdded(Config config) {
expandedPropertyListener.configSourceLoaded(config);
}

@Override
public void onConfigRemoved(Config config) {
expandedPropertyListener.configSourceLoaded(config);
}

@Override
public void onConfigUpdated(Config config) {
expandedPropertyListener.configSourceLoaded(config);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

import com.netflix.config.AggregatedConfiguration;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicPropertySupport;
import com.netflix.config.PropertyListener;

/**
* @see StaticArchaiusBridgeModule
* @author elandau
*/
public class StaticAbstractConfiguration extends AbstractConfiguration implements AggregatedConfiguration {
public class StaticAbstractConfiguration extends AbstractConfiguration implements AggregatedConfiguration, DynamicPropertySupport {
private static volatile AbstractConfigurationBridge delegate;

@Inject
Expand Down Expand Up @@ -109,4 +111,8 @@ protected void addPropertyDirect(String key, Object value) {
delegate.addPropertyDirect(key, value);
}

@Override
public void addConfigurationListener(PropertyListener expandedPropertyListener) {
delegate.addConfigurationListener(expandedPropertyListener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ public class StaticArchaiusBridgeModule extends AbstractModule {
protected void configure() {
requestStaticInjection(StaticAbstractConfiguration.class);
requestStaticInjection(StaticDeploymentContext.class);

bind(DeploymentContext.class).to(ConfigBasedDeploymentContext.class);
bind(AbstractConfigurationBridge.class).asEagerSingleton();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.netflix.archaius.bridge;

import org.junit.Assert;
import org.junit.Test;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.netflix.archaius.Property;
import com.netflix.archaius.PropertyFactory;
import com.netflix.archaius.config.SettableConfig;
import com.netflix.archaius.guice.ArchaiusModule;
import com.netflix.archaius.inject.RuntimeLayer;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;

public class DynamicPropertyTest {
@Test
public void test() {
Injector injector = Guice.createInjector(new ArchaiusModule(), new StaticArchaiusBridgeModule());

Property<String> prop2 = injector.getInstance(PropertyFactory.class).getProperty("foo").asString("default");

DynamicStringProperty prop = DynamicPropertyFactory.getInstance().getStringProperty("foo", "default");
Assert.assertEquals("default", prop.get());
Assert.assertEquals("default", prop2.get());

SettableConfig config = injector.getInstance(Key.get(SettableConfig.class, RuntimeLayer.class));
config.setProperty("foo", "newvalue");

Assert.assertEquals("newvalue", prop.get());
Assert.assertEquals("newvalue", prop2.get());

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Properties;
Expand Down Expand Up @@ -172,15 +173,18 @@ public LinkedHashMap<String, Config> load(String resourceName) throws ConfigExce
configs.put(resourceName, new MapConfig(overrides));
}

for (String permutationName : strategy.generate(resourceName, interpolator, lookup)) {
LOG.info("Attempting to load {}", permutationName);
for (ConfigReader loader : loaders) {
if (loader.canLoad(classLoader, permutationName)) {
List<String> names = strategy.generate(resourceName, interpolator, lookup);
for (String name : names) {
LOG.info("Attempting to load {}", name);
for (ConfigReader reader : loaders) {
if (reader.canLoad(classLoader, name)) {
try {
configs.put(permutationName, loader.load(classLoader, permutationName));
configs.put(name, reader.load(classLoader, name));
LOG.info("Loaded {} ", name);
failIfNotLoaded = false;
}
catch (ConfigException e) {
LOG.info("Unable to load {}, {}", name, e.getMessage());
if (failIfNotLoaded == true) {
throw new ConfigException("Failed to load configuration resource '" + resourceName + "'");
}
Expand All @@ -192,15 +196,19 @@ public LinkedHashMap<String, Config> load(String resourceName) throws ConfigExce

return configs;
}

@Override
public Config load(URL url) {
for (ConfigReader loader : loaders) {
if (loader.canLoad(classLoader, url)) {
try {
return loader.load(classLoader, url);
Config config = loader.load(classLoader, url);
LOG.info("Loaded " + url);
return config;
} catch (ConfigException e) {
LOG.debug("Unable to load file '{}'", new Object[]{url, e.getMessage()});
LOG.info("Unable to load file '{}'", new Object[]{url, e.getMessage()});
} catch (Exception e) {
LOG.info("Unable to load file '{}'", new Object[]{url, e.getMessage()});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import com.netflix.archaius.Config;
import com.netflix.archaius.ConfigListener;
import com.netflix.archaius.exceptions.ConfigAlreadyExistsException;
import com.netflix.archaius.exceptions.ConfigException;

/**
Expand Down Expand Up @@ -138,7 +139,7 @@ private synchronized void internalAddConfig(String name, Config child) throws Co
}

if (lookup.containsKey(name)) {
throw new ConfigException(String.format("Configuration with name '%s' already exists", name));
throw new ConfigAlreadyExistsException(String.format("Configuration with name '%s' already exists", name));
}

lookup.put(name, child);
Expand All @@ -152,9 +153,9 @@ private synchronized void internalAddConfig(String name, Config child) throws Co
postConfigAdded(child);
}

public void addConfigs(LinkedHashMap<String, Config> configs) throws ConfigException {
public synchronized void addConfigs(LinkedHashMap<String, Config> configs) throws ConfigException {
for (Entry<String, Config> entry : configs.entrySet()) {
addConfig(entry.getKey(), entry.getValue());
internalAddConfig(entry.getKey(), entry.getValue());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.netflix.archaius.exceptions;

public class ConfigAlreadyExistsException extends ConfigException {
public ConfigAlreadyExistsException(String message) {
super(message);
}

}
1 change: 1 addition & 0 deletions archaius2-core/src/test/resources/log4j.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
log4j.rootLogger=ERROR, console

log4j.logger.com.netflix.archaius=DEBUG, console
log4j.additivity.com.netflix.archaius=false

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
Expand Down
Loading

0 comments on commit b928029

Please sign in to comment.