Merge pull request #84 from gdarmont/pr-empty-and-nested-properties-handing
* pr-empty-and-nested-properties-handing: Handling of empty properties and nested properties
This commit is contained in:
@@ -43,7 +43,7 @@ public class ZookeeperPropertySource extends AbstractZookeeperPropertySource {
|
||||
|
||||
public ZookeeperPropertySource(String context, CuratorFramework source) {
|
||||
super(context, source);
|
||||
findProperties(this.getContext());
|
||||
findProperties(this.getContext(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,8 +56,7 @@ public class ZookeeperPropertySource extends AbstractZookeeperPropertySource {
|
||||
byte[] bytes = null;
|
||||
try {
|
||||
bytes = this.getSource().getData().forPath(fullPath);
|
||||
}
|
||||
catch (KeeperException e) {
|
||||
} catch (KeeperException e) {
|
||||
if (e.code() != KeeperException.Code.NONODE) { // not found
|
||||
throw e;
|
||||
}
|
||||
@@ -75,31 +74,30 @@ public class ZookeeperPropertySource extends AbstractZookeeperPropertySource {
|
||||
return strings.toArray(new String[strings.size()]);
|
||||
}
|
||||
|
||||
private void findProperties(String path) {
|
||||
private void findProperties(String path, List<String> children) {
|
||||
try {
|
||||
log.trace("entering findProperties for path: " + path);
|
||||
List<String> children = null;
|
||||
try {
|
||||
children = this.getSource().getChildren().forPath(path);
|
||||
}
|
||||
catch (KeeperException e) {
|
||||
if (e.code() != KeeperException.Code.NONODE) { // not found
|
||||
throw e;
|
||||
}
|
||||
if (children == null) {
|
||||
children = getChildren(path);
|
||||
}
|
||||
if (children == null || children.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String child : children) {
|
||||
String childPath = path + "/" + child;
|
||||
List<String> childPathChildren = getChildren(childPath);
|
||||
|
||||
byte[] bytes = getPropertyBytes(childPath);
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
findProperties(childPath);
|
||||
}
|
||||
else {
|
||||
String key = sanitizeKey(childPath);
|
||||
this.properties.put(key, new String(bytes, Charset.forName("UTF-8")));
|
||||
if (childPathChildren == null || childPathChildren.isEmpty()) {
|
||||
registerKeyValue(childPath, "");
|
||||
}
|
||||
} else {
|
||||
registerKeyValue(childPath, new String(bytes, Charset.forName("UTF-8")));
|
||||
}
|
||||
|
||||
// Check children even if we have found a value for the current znode
|
||||
findProperties(childPath, childPathChildren);
|
||||
}
|
||||
log.trace("leaving findProperties for path: " + path);
|
||||
} catch (Exception exception) {
|
||||
@@ -107,4 +105,21 @@ public class ZookeeperPropertySource extends AbstractZookeeperPropertySource {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerKeyValue(String path, String value) {
|
||||
String key = sanitizeKey(path);
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
private List<String> getChildren(String path) throws Exception {
|
||||
List<String> children = null;
|
||||
try {
|
||||
children = this.getSource().getChildren().forPath(path);
|
||||
} catch (KeeperException e) {
|
||||
if (e.code() != KeeperException.Code.NONODE) { // not found
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScope;
|
||||
import org.springframework.cloud.endpoint.RefreshEndpoint;
|
||||
import org.springframework.cloud.zookeeper.ZookeeperProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -43,6 +42,7 @@ import org.springframework.util.SocketUtils;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isEmptyString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,23 @@ public class ZookeeperPropertySourceLocatorTests {
|
||||
public static final String PREFIX = "test__config__";
|
||||
public static final String ROOT = "/" + PREFIX + UUID.randomUUID();
|
||||
private ConfigurableApplicationContext context;
|
||||
public static final String KEY = ROOT + "/application/testProp";
|
||||
public static final String CONTEXT = ROOT + "/application/";
|
||||
|
||||
public static final String KEY_BASIC = "testProp";
|
||||
public static final String KEY_BASIC_PATH = CONTEXT + KEY_BASIC;
|
||||
public static final String VAL_BASIC = "testPropVal";
|
||||
|
||||
public static final String KEY_WITH_DOT = "testProp.dot";
|
||||
public static final String KEY_WITH_DOT_PATH = CONTEXT + KEY_WITH_DOT;
|
||||
public static final String VAL_WITH_DOT = "withDotVal";
|
||||
|
||||
public static final String KEY_NESTED = "testProp.nested";
|
||||
public static final String KEY_NESTED_PATH = CONTEXT + KEY_NESTED.replace('.','/');
|
||||
public static final String VAL_NESTED = "nestedVal";
|
||||
|
||||
public static final String KEY_WITHOUT_VALUE = "testProp.novalue";
|
||||
public static final String KEY_WITHOUT_VALUE_PATH = CONTEXT + KEY_WITHOUT_VALUE;
|
||||
|
||||
private TestingServer testingServer;
|
||||
|
||||
@Configuration
|
||||
@@ -110,7 +126,18 @@ public class ZookeeperPropertySourceLocatorTests {
|
||||
}
|
||||
}
|
||||
|
||||
String create = this.curator.create().creatingParentsIfNeeded().forPath(KEY, "testPropVal".getBytes());
|
||||
StringBuilder create = new StringBuilder(1024);
|
||||
create.append(
|
||||
this.curator.create().creatingParentsIfNeeded().forPath(KEY_BASIC_PATH, VAL_BASIC.getBytes())).append(
|
||||
'\n');
|
||||
create.append(this.curator.create().creatingParentsIfNeeded().forPath(KEY_WITH_DOT_PATH,
|
||||
VAL_WITH_DOT.getBytes())).append('\n');
|
||||
create.append(
|
||||
this.curator.create().creatingParentsIfNeeded().forPath(KEY_NESTED_PATH, VAL_NESTED.getBytes()))
|
||||
.append(
|
||||
'\n');
|
||||
create.append(this.curator.create().creatingParentsIfNeeded().forPath(KEY_WITHOUT_VALUE_PATH, null)).append(
|
||||
'\n');
|
||||
this.curator.close();
|
||||
System.out.println(create);
|
||||
|
||||
@@ -145,17 +172,32 @@ public class ZookeeperPropertySourceLocatorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyLoadedAndUpdated() throws Exception {
|
||||
String testProp = this.environment.getProperty("testProp");
|
||||
assertThat("testProp was wrong", testProp, is(equalTo("testPropVal")));
|
||||
public void checkKeyValues() throws Exception {
|
||||
String propValue = this.environment.getProperty(KEY_BASIC);
|
||||
assertThat(KEY_BASIC + " was wrong", propValue, is(equalTo(VAL_BASIC)));
|
||||
|
||||
this.curator.setData().forPath(KEY, "testPropValUpdate".getBytes());
|
||||
propValue = this.environment.getProperty(KEY_NESTED);
|
||||
assertThat(KEY_NESTED + " was wrong", propValue, is(equalTo(VAL_NESTED)));
|
||||
|
||||
propValue = this.environment.getProperty(KEY_WITH_DOT);
|
||||
assertThat(KEY_BASIC + " was wrong", propValue, is(equalTo(VAL_WITH_DOT)));
|
||||
|
||||
propValue = this.environment.getProperty(KEY_WITHOUT_VALUE);
|
||||
assertThat(KEY_BASIC + " was wrong", propValue, is(isEmptyString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyLoadedAndUpdated() throws Exception {
|
||||
String testProp = this.environment.getProperty(KEY_BASIC);
|
||||
assertThat("testProp was wrong", testProp, is(equalTo(VAL_BASIC)));
|
||||
|
||||
this.curator.setData().forPath(KEY_BASIC_PATH, "testPropValUpdate".getBytes());
|
||||
|
||||
CountDownLatch latch = this.context.getBean(CountDownLatch.class);
|
||||
boolean receivedEvent = latch.await(15, TimeUnit.SECONDS);
|
||||
assertThat("listener didn't receive event", receivedEvent, is(true));
|
||||
|
||||
testProp = this.environment.getProperty("testProp");
|
||||
testProp = this.environment.getProperty(KEY_BASIC);
|
||||
assertThat("testProp was wrong after update", testProp, is(equalTo("testPropValUpdate")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user