Skip to content

Commit

Permalink
Fixed the invalidation of the configuration when path changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Sep 1, 2016
1 parent 6f2614e commit aeacf14
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 18 deletions.
Expand Up @@ -59,6 +59,8 @@ public interface Config extends BasicConfig {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void update(Map<String, ?> entries, boolean overridenByEnv); void update(Map<String, ?> entries, boolean overridenByEnv);


void setNested(String key, Object value);

Config root(); Config root();


Config parent(); Config parent();
Expand All @@ -85,5 +87,10 @@ public interface Config extends BasicConfig {


void reset(); void reset();


void invalidate();

boolean useBuiltInDefaults(); boolean useBuiltInDefaults();

void updateNested(Map<String, Object> properties);

} }
44 changes: 40 additions & 4 deletions rapidoid-commons/src/main/java/org/rapidoid/config/ConfigBase.java
Expand Up @@ -39,6 +39,10 @@ public class ConfigBase extends RapidoidThing {


final Map<String, Object> properties = Coll.synchronizedMap(); final Map<String, Object> properties = Coll.synchronizedMap();


final Map<String, Object> args = Coll.synchronizedMap();

volatile boolean initializing;

volatile boolean initialized; volatile boolean initialized;


volatile String path = ""; volatile String path = "";
Expand All @@ -53,24 +57,48 @@ public ConfigBase(String defaultFilenameBase, boolean useBuiltInDefaults) {


synchronized void reset() { synchronized void reset() {
this.properties.clear(); this.properties.clear();
this.args.clear();

this.filenameBase = this.defaultFilenameBase; this.filenameBase = this.defaultFilenameBase;
this.path = "";

this.initialized = false;
this.initializing = false;
}

synchronized void invalidate() {
this.properties.clear();

this.initialized = false; this.initialized = false;
this.initializing = false;
} }


String getFilenameBase() { String getFilenameBase() {
return filenameBase; return filenameBase;
} }


synchronized void setFilenameBase(String filenameBase) { synchronized boolean setFilenameBase(String filenameBase) {

if (U.neq(this.filenameBase, filenameBase)) { if (U.neq(this.filenameBase, filenameBase)) {
Log.info("Changing configuration filename base", "!from", this.filenameBase, "!to", filenameBase); Log.info("Changing configuration filename base", "!from", this.filenameBase, "!to", filenameBase);

this.filenameBase = filenameBase;
return true;
} }


this.filenameBase = filenameBase; return false;
} }


void setPath(String path) { boolean setPath(String path) {
this.path = path;
if (U.neq(this.path, path)) {
Log.info("Changing configuration path", "!from", this.path, "!to", path);

this.path = path;
return true;
}

return false;
} }


String getPath() { String getPath() {
Expand All @@ -81,4 +109,12 @@ public boolean useBuiltInDefaults() {
return useBuiltInDefaults; return useBuiltInDefaults;
} }


void putArg(String name, Object value) {
args.put(name, value);
}

void applyArgsTo(Config config) {
config.updateNested(args);
}

} }
55 changes: 44 additions & 11 deletions rapidoid-commons/src/main/java/org/rapidoid/config/ConfigImpl.java
Expand Up @@ -75,6 +75,12 @@ public synchronized void reset() {
base.reset(); base.reset();
} }


@Override
public void invalidate() {
clear();
base.invalidate();
}

@Override @Override
public Value<Object> entry(String key) { public Value<Object> entry(String key) {
return Values.wrap(new ConfigValueStore<Object>(this, key)); return Values.wrap(new ConfigValueStore<Object>(this, key));
Expand Down Expand Up @@ -316,6 +322,7 @@ public String toString() {


@Override @Override
public void args(List<String> args) { public void args(List<String> args) {
mustBeRoot();
makeSureIsInitialized(); makeSureIsInitialized();


if (U.notEmpty(args)) { if (U.notEmpty(args)) {
Expand All @@ -331,16 +338,21 @@ public void args(List<String> args) {
setFilenameBase(value); setFilenameBase(value);
} }


setNested(name, value); base.putArg(name, value);
} else { } else {
setNested(name, true); base.putArg(name, true);
} }
} }
} }
} }
} }


private void setNested(String key, Object value) { private void mustBeRoot() {
U.must(isRoot, "Must be Config's root!");
}

@Override
public void setNested(String key, Object value) {
String[] keys = key.split("\\."); String[] keys = key.split("\\.");
Config cfg = keys.length > 1 ? sub(Arr.sub(keys, 0, -1)) : this; Config cfg = keys.length > 1 ? sub(Arr.sub(keys, 0, -1)) : this;
cfg.set(U.last(keys), value); cfg.set(U.last(keys), value);
Expand Down Expand Up @@ -412,8 +424,9 @@ public String getFilenameBase() {
@Override @Override
public Config setFilenameBase(String filenameBase) { public Config setFilenameBase(String filenameBase) {


base.setFilenameBase(filenameBase); if (base.setFilenameBase(filenameBase)) {
reset(); // reset to apply changes invalidate(); // clear to apply changes
}


return this; return this;
} }
Expand All @@ -426,8 +439,9 @@ public String getPath() {
@Override @Override
public Config setPath(String path) { public Config setPath(String path) {


base.setPath(path); if (base.setPath(path)) {
reset(); // reset to apply changes invalidate(); // clear to apply changes
}


return this; return this;
} }
Expand All @@ -439,26 +453,38 @@ public void applyTo(Object target) {
} }


private void makeSureIsInitialized() { private void makeSureIsInitialized() {
if (base.initializing) {
return;
}

if (!base.initialized) { if (!base.initialized) {
synchronized (this) { synchronized (this) {
if (!base.initialized) { if (!base.initialized) {
base.initialized = true; base.initializing = true;
root.initialize(); root.initialize();
base.initialized = true;
} }
} }
} }
} }


protected synchronized void initialize() { protected synchronized void initialize() {
List<List<String>> detached = ConfigUtil.untrack(); mustBeRoot();


List<List<String>> detached = ConfigUtil.untrack();
List<String> loaded = U.list(); List<String> loaded = U.list();


args(Env.args());
base.applyArgsTo(this);

if (useBuiltInDefaults()) {
ConfigLoaderUtil.loadBuiltInConfig(this, loaded);
}

ConfigLoaderUtil.loadDefaultConfig(this, loaded); ConfigLoaderUtil.loadDefaultConfig(this, loaded);
ConfigLoaderUtil.loadConfig(this, detached, loaded); ConfigLoaderUtil.loadConfig(this, detached, loaded);


args(Env.args()); base.applyArgsTo(this);

Conf.applyConfig(this); Conf.applyConfig(this);


if (!loaded.isEmpty()) { if (!loaded.isEmpty()) {
Expand All @@ -473,4 +499,11 @@ public boolean useBuiltInDefaults() {
return base.useBuiltInDefaults(); return base.useBuiltInDefaults();
} }


@Override
public void updateNested(Map<String, Object> properties) {
for (Map.Entry<String, Object> prop : properties.entrySet()) {
setNested(prop.getKey(), prop.getValue());
}
}

} }
Expand Up @@ -52,21 +52,35 @@ public static void loadConfig(Config config, List<List<String>> detached, List<S
} }
} }


static void loadBuiltInConfig(Config config, List<String> loaded) {
String nameBase = config.getFilenameBase();

if (U.notEmpty(nameBase)) {

ConfigUtil.load("default-config.yml", config, true, loaded);

for (String profile : Env.profiles()) {
String filename = U.frmt("default-config-%s.yml", profile);
ConfigUtil.load(filename, config, true, loaded);
}
}
}

static void loadDefaultConfig(Config config, List<String> loaded) { static void loadDefaultConfig(Config config, List<String> loaded) {
String nameBase = config.getFilenameBase(); String nameBase = config.getFilenameBase();


if (U.notEmpty(nameBase)) { if (U.notEmpty(nameBase)) {
String name = "default-" + nameBase; String name = "default-" + nameBase;


String filename = name + ".yml"; String filename = name + ".yml";
if (!config.useBuiltInDefaults()) filename = Msc.path(config.getPath(), filename); filename = Msc.path(config.getPath(), filename);


ConfigUtil.load(filename, config, true, loaded); ConfigUtil.load(filename, config, true, loaded);


for (String profile : Env.profiles()) { for (String profile : Env.profiles()) {


filename = U.frmt(name + "-%s.yml", profile); filename = U.frmt(name + "-%s.yml", profile);
if (!config.useBuiltInDefaults()) filename = Msc.path(config.getPath(), filename); filename = Msc.path(config.getPath(), filename);


ConfigUtil.load(filename, config, true, loaded); ConfigUtil.load(filename, config, true, loaded);
} }
Expand Down
Expand Up @@ -48,7 +48,7 @@ public void testCustomFileConfig() {
eq(config.toMap(), U.map("x", 1, "y", 2, "z", "foo", "k", "hey")); eq(config.toMap(), U.map("x", 1, "y", 2, "z", "foo", "k", "hey"));


Env.setProfiles("prof1", "prof2"); Env.setProfiles("prof1", "prof2");
config.reset(); config.invalidate();


eq(config.toMap(), U.map("x", 1, "y", 100, "z", "bar", "m", "moo", "k", "hey")); eq(config.toMap(), U.map("x", 1, "y", 100, "z", "bar", "m", "moo", "k", "hey"));
} }
Expand Down
Expand Up @@ -88,4 +88,25 @@ public void testDefaultProfiles() {
eq(Env.profiles(), U.set("test", "default")); eq(Env.profiles(), U.set("test", "default"));
} }


@Test
public void testPathChange() {
Env.setArgs("config=myconfig");

checkDefaults();
}

@Test
public void testUsersConfigWithArgs() {
String pswd = "m-i_h?1f~@121";
Env.setArgs("users.admin.password=abc123", "users.nick.password=" + pswd, "users.nick.roles=moderator");

checkDefaults();

eq(Conf.USERS.toMap().keySet(), U.set("admin", "nick"));

eq(Conf.USERS.sub("admin").toMap(), U.map("roles", "administrator", "password", "abc123"));

eq(Conf.USERS.sub("nick").toMap(), U.map("roles", "moderator", "password", pswd));
}

} }

0 comments on commit aeacf14

Please sign in to comment.