Skip to content

Commit 205f5cb

Browse files
authored
Merge pull request #151 from scalecube/config-conflict
Throw exception if some configs was not loaded successfully. On first…
2 parents e1d0e6c + c955b7d commit 205f5cb

File tree

3 files changed

+62
-46
lines changed

3 files changed

+62
-46
lines changed

config-vault/src/test/java/io/scalecube/config/vault/VaultConfigSourceTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ void shouldWorkWhenRegistryIsReloadedAndVaultIsRunning() throws InterruptedExcep
149149
.config(vaultConfig -> vaultConfig.address(address).token(rootToken))
150150
.secretsPath(VAULT_SECRETS_PATH1)
151151
.build())
152+
.jmxEnabled(false)
152153
.reloadIntervalSec(1)
153154
.build();
154155
ConfigRegistry configRegistry = ConfigRegistry.create(settings);
@@ -182,6 +183,7 @@ void shouldWorkWhenRegistryIsReloadedAndVaultIsDown() {
182183
.config(vaultConfig -> vaultConfig.address(address).token(rootToken))
183184
.secretsPath(VAULT_SECRETS_PATH1)
184185
.build())
186+
.jmxEnabled(false)
185187
.reloadIntervalSec(1)
186188
.build();
187189
ConfigRegistry configRegistry = ConfigRegistry.create(settings);
@@ -240,6 +242,7 @@ void shouldWorkWhenRegistryIsReloadedAndVaultIsUnSealed() throws InterruptedExce
240242
.config(vaultConfig -> vaultConfig.address(address).token(rootToken))
241243
.secretsPath(VAULT_SECRETS_PATH1)
242244
.build())
245+
.jmxEnabled(false)
243246
.reloadIntervalSec(1)
244247
.build();
245248

config/src/main/java/io/scalecube/config/ConfigRegistryImpl.java

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.scalecube.config.source.ConfigSource;
66
import io.scalecube.config.source.ConfigSourceInfo;
77
import io.scalecube.config.source.LoadedConfigProperty;
8+
import io.scalecube.config.utils.ThrowableUtil;
89
import java.lang.management.ManagementFactory;
910
import java.lang.reflect.Field;
1011
import java.time.Duration;
@@ -29,7 +30,6 @@
2930
import java.util.function.Function;
3031
import java.util.stream.Collectors;
3132
import java.util.stream.Stream;
32-
import javax.management.MBeanInfo;
3333
import javax.management.MBeanServer;
3434
import javax.management.ObjectName;
3535
import org.slf4j.Logger;
@@ -55,7 +55,7 @@ final class ConfigRegistryImpl implements ConfigRegistry {
5555
r -> {
5656
Thread thread = new Thread(r);
5757
thread.setDaemon(true);
58-
thread.setName("config-reloader");
58+
thread.setName("config-registry");
5959
thread.setUncaughtExceptionHandler((t, e) -> LOGGER.error("Exception occurred: " + e, e));
6060
return thread;
6161
};
@@ -70,6 +70,7 @@ final class ConfigRegistryImpl implements ConfigRegistry {
7070

7171
private volatile Map<String, LoadedConfigProperty> propertyMap; // being reset on reload
7272

73+
@SuppressWarnings("rawtypes")
7374
private final Map<String, Map<Class, PropertyCallback>> propertyCallbackMap =
7475
new ConcurrentHashMap<>();
7576

@@ -94,7 +95,7 @@ void init() {
9495
try {
9596
loadAndNotify();
9697
} catch (Exception e) {
97-
LOGGER.error("Exception on config reload, cause: {}", e, e);
98+
LOGGER.error("[loadAndNotify] Exception occurred, cause: " + e);
9899
}
99100
},
100101
settings.getReloadIntervalSec(),
@@ -111,10 +112,8 @@ private void registerJmxMBean() {
111112
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
112113
ObjectName objectName = new ObjectName(settings.getJmxMBeanName());
113114
mbeanServer.registerMBean(new JmxConfigRegistry(this), objectName);
114-
MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(objectName);
115-
LOGGER.info("Registered JMX MBean: {}", mbeanInfo);
116115
} catch (Exception e) {
117-
LOGGER.warn("Failed to register JMX MBean '{}', cause: {}", settings.getJmxMBeanName(), e);
116+
throw ThrowableUtil.propagate(e);
118117
}
119118
}
120119

@@ -377,26 +376,26 @@ private void loadAndNotify() {
377376

378377
// load config from sources
379378
Map<String, ConfigSource> sources = settings.getSources();
380-
for (String name : sources.keySet()) {
381-
ConfigSource source = sources.get(name);
379+
for (String sourceName : sources.keySet()) {
380+
ConfigSource source = sources.get(sourceName);
382381

383-
Throwable loadException = null;
384-
Map<String, ConfigProperty> configMap = null;
382+
final Map<String, ConfigProperty> configMap;
383+
Throwable error = null;
385384
try {
386385
configMap = source.loadConfig();
387386
} catch (Exception e) {
388-
loadException = e; // save error occurrence
387+
error = e;
388+
throw ThrowableUtil.propagate(e);
389+
} finally {
390+
computeConfigLoadStatus(sourceName, error);
389391
}
390392

391-
computeConfigLoadStatus(name, source, loadException);
392-
393-
if (loadException == null) {
394-
// populate loaded properties with new field 'source'
395-
configMap.forEach(
396-
(key, configProperty) ->
397-
loadedPropertyMap.putIfAbsent(
398-
key, LoadedConfigProperty.withCopyFrom(configProperty).source(name).build()));
399-
}
393+
// populate loaded properties with new field 'source'
394+
configMap.forEach(
395+
(key, configProperty) ->
396+
loadedPropertyMap.putIfAbsent(
397+
key,
398+
LoadedConfigProperty.withCopyFrom(configProperty).source(sourceName).build()));
400399
}
401400

402401
List<ConfigEvent> detectedChanges = new ArrayList<>();
@@ -488,15 +487,15 @@ private void reportChanges(Collection<ConfigEvent> events) {
488487
});
489488
}
490489

491-
private void computeConfigLoadStatus(String name, ConfigSource source, Throwable throwable) {
490+
private void computeConfigLoadStatus(String sourceName, Throwable throwable) {
492491
int status = throwable != null ? 1 : 0;
493-
Integer status0 = configSourceStatusMap.put(name, status);
492+
Integer status0 = configSourceStatusMap.put(sourceName, status);
494493
if (status0 == null || (status0 ^ status) == 1) {
495494
if (status == 1) {
496495
LOGGER.error(
497-
"Exception at loadConfig on {}, source: {}, cause: {}", source, name, throwable);
496+
"[loadConfig][{}] Exception occurred, cause: {}", sourceName, throwable.toString());
498497
} else {
499-
LOGGER.debug("Loaded config properties from {}, source: {}", source, name);
498+
LOGGER.debug("[loadConfig][{}] Loaded config properties", sourceName);
500499
}
501500
}
502501
}

config/src/main/java/io/scalecube/config/audit/Slf4JConfigEventListener.java

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ public void onEvents(Collection<ConfigEvent> events) {
1919
.forEach(
2020
event -> {
2121
sb.append("\n");
22-
sb.append(event.getName()).append("=");
22+
sb.append(event.getName()).append("=[");
2323
sb.append(propValueAsString(event));
24-
sb.append(",\t");
24+
sb.append("], ");
2525
sb.append("source=");
2626
sb.append(sourceAsString(event));
27-
sb.append(",\t");
27+
sb.append(", ");
2828
sb.append("origin=");
2929
sb.append(originAsString(event));
3030
});
@@ -33,31 +33,45 @@ public void onEvents(Collection<ConfigEvent> events) {
3333
}
3434
}
3535

36-
private String originAsString(ConfigEvent event) {
37-
if (Objects.equals(event.getOldOrigin(), event.getNewOrigin())) {
38-
return event.getNewOrigin();
39-
} else {
40-
return event.getOldOrigin() + "->" + event.getNewOrigin();
36+
private static String originAsString(ConfigEvent event) {
37+
final String oldValue = event.getOldOrigin();
38+
final String newValue = event.getNewOrigin();
39+
40+
if (Objects.equals(oldValue, newValue)) {
41+
return newValue;
4142
}
43+
return (oldValue == null || oldValue.isEmpty()) ? newValue : oldValue + "->" + newValue;
4244
}
4345

44-
private String sourceAsString(ConfigEvent event) {
45-
if (Objects.equals(event.getOldSource(), event.getNewSource())) {
46-
return event.getNewSource();
47-
} else {
48-
return event.getOldSource() + "->" + event.getNewSource();
46+
private static String sourceAsString(ConfigEvent event) {
47+
final String oldValue = event.getOldSource();
48+
final String newValue = event.getNewSource();
49+
50+
if (Objects.equals(oldValue, newValue)) {
51+
return newValue;
4952
}
53+
return (oldValue == null || oldValue.isEmpty()) ? newValue : oldValue + "->" + newValue;
5054
}
5155

52-
private String propValueAsString(ConfigEvent event) {
53-
if (event.getOldValue() != null && event.getNewValue() != null) {
54-
return "***->***";
55-
} else if (event.getOldValue() != null) {
56-
return "***->null";
57-
} else if (event.getNewValue() != null) {
58-
return "null->***";
59-
} else {
60-
return null;
56+
private static String propValueAsString(ConfigEvent event) {
57+
final String oldValue = event.getOldValue();
58+
final String newValue = event.getNewValue();
59+
60+
if (Objects.equals(oldValue, newValue)) {
61+
return newValue;
62+
}
63+
return (oldValue == null || oldValue.isEmpty())
64+
? mask(newValue)
65+
: mask(oldValue) + "->" + mask(newValue);
66+
}
67+
68+
private static String mask(String value) {
69+
if (value == null || value.isEmpty()) {
70+
return "null";
71+
}
72+
if (value.length() < 5) {
73+
return "***";
6174
}
75+
return value.replace(value.substring(2, value.length() - 2), "***");
6276
}
6377
}

0 commit comments

Comments
 (0)