From 830278650c63143462a363e4ff10e9b0cb1ddb34 Mon Sep 17 00:00:00 2001 From: Eric Schoonover Date: Fri, 12 Jun 2015 16:31:44 -0700 Subject: [PATCH] addressing review feedback --- .../source/EtcdConfigurationSource.java | 102 ++++++++++-------- .../source/EtcdConfigurationSourceTest.java | 23 +++- 2 files changed, 77 insertions(+), 48 deletions(-) diff --git a/archaius-etcd/src/main/java/com/netflix/config/source/EtcdConfigurationSource.java b/archaius-etcd/src/main/java/com/netflix/config/source/EtcdConfigurationSource.java index beafc8e88..631bf6565 100644 --- a/archaius-etcd/src/main/java/com/netflix/config/source/EtcdConfigurationSource.java +++ b/archaius-etcd/src/main/java/com/netflix/config/source/EtcdConfigurationSource.java @@ -2,6 +2,7 @@ import com.google.common.base.Objects; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.netflix.config.WatchedConfigurationSource; @@ -18,6 +19,9 @@ import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; +import static com.google.common.collect.Maps.newHashMap; +import static com.netflix.config.WatchedUpdateResult.createIncremental; + /** * Implementation of the dynamic {@link WatchedConfigurationSource} for Etcd @@ -44,51 +48,7 @@ public class EtcdConfigurationSource implements WatchedConfigurationSource { private final Etcd etcd; private final String configPath; - private Handler updateHandler = new Handler() { - @Override - public void handle(Response updateResponse) { - if (updateResponse.wasError()) { - logger.error("Etcd failed with an error response: %s", updateResponse); - } - - final Map create = Maps.newHashMap(); - final Map set = Maps.newHashMap(); - final Map delete = Maps.newHashMap(); - - final String action = updateResponse.action().toLowerCase(); - final Node node = updateResponse.node(); - - if (node != null ) { - final String etcdKey = node.key(); - final String sourceKey = Iterables.getLast(keySplitter.split(etcdKey)); - final String value = node.getValue(); - valueCache.put(sourceKey, value); - - switch (action) { - case "create": - create.put(sourceKey, value); - break; - - case "set": - set.put(sourceKey, value); - break; - - case "delete": - delete.put(sourceKey, value); - break; - - default: - logger.warn("unrecognized action, response: %s", updateResponse); - break; - } - - final WatchedUpdateResult result = WatchedUpdateResult.createIncremental(create, set, delete); - updateConfiguration(result); - } - - etcd.waitRecursive(updateHandler, configPath); - } - }; + private Handler updateHandler = new UpdateHandler(); /** * Initialize EtcdConfigurationSource with property values @ configPath @@ -144,4 +104,56 @@ private void updateConfiguration(WatchedUpdateResult result) { } } } + + private class UpdateHandler implements Handler { + @Override + public void handle(Response updateResponse) { + if (updateResponse.wasError()) { + logger.error("Etcd failed with an error response: %s", updateResponse); + etcd.waitRecursive(updateHandler, configPath); + return; + } + + logger.debug("Etcd updateResponse: ", updateResponse); + final Node node = updateResponse.node(); + + if (node != null ) { + final String etcdKey = node.key(); + final String sourceKey = Iterables.getLast(keySplitter.split(etcdKey)); + final String value = node.getValue(); + final String action = getUpdateAction(node, updateResponse.action()); + + switch (action) { + case "create": + valueCache.put(sourceKey, value); + updateConfiguration(createIncremental(null, ImmutableMap.of(sourceKey, value), null)); + break; + + case "set": + valueCache.put(sourceKey, value); + updateConfiguration(createIncremental(ImmutableMap.of(sourceKey, value), null, null)); + break; + + case "delete": + valueCache.remove(sourceKey); + updateConfiguration(createIncremental(null, null, ImmutableMap.of(sourceKey, ""))); + break; + + default: + logger.warn("unrecognized action, response: %s", updateResponse); + break; + } + } + + etcd.waitRecursive(updateHandler, configPath); + } + + private String getUpdateAction(Node updateNode, String responseAction) { + final String value = updateNode.getValue(); + if (value == null) { + return "delete"; + } + return responseAction.toLowerCase(); + } + } } diff --git a/archaius-etcd/src/test/java/com/netflix/config/source/EtcdConfigurationSourceTest.java b/archaius-etcd/src/test/java/com/netflix/config/source/EtcdConfigurationSourceTest.java index ba3aacde7..9234b0a88 100644 --- a/archaius-etcd/src/test/java/com/netflix/config/source/EtcdConfigurationSourceTest.java +++ b/archaius-etcd/src/test/java/com/netflix/config/source/EtcdConfigurationSourceTest.java @@ -42,7 +42,8 @@ public class EtcdConfigurationSourceTest { new Node("/config", null, 1378, 1378, 0, true, Lists.newArrayList( new Node("/config/test.key1", "test.value1-etcd", 19311, 19311, 0, false, null), new Node("/config/test.key4", "test.value4-etcd", 1388, 1388, 0, false, null), - new Node("/config/test.key6", "test.value6-etcd", 1232, 1232, 0, false, null) + new Node("/config/test.key6", "test.value6-etcd", 1232, 1232, 0, false, null), + new Node("/config/test.key7", "test.value7-etcd", 1234, 1234, 0, false, null) ))); private static Handler ETCD_UPDATE_HANDLER; private static final Answer WITH_ETCD_UPDATE_HANDLER = new Answer() { @@ -72,6 +73,7 @@ public static void before() throws Exception { MAP_CONFIGURATION.addProperty("test.key2", "test.value2-map"); MAP_CONFIGURATION.addProperty("test.key3", "test.value3-map"); MAP_CONFIGURATION.addProperty("test.key4", "test.value4-map"); + MAP_CONFIGURATION.addProperty("test.key7", "test.value7-map"); compositeConfig.addConfiguration(MAP_CONFIGURATION, "map configuration"); System.setProperty("test.key4", "test.value4-system"); @@ -143,9 +145,24 @@ public void testUpdateEtcdProperty() throws Exception { final String updateValue = "test.value6-etcd-override"; final String initialValue = "test.value6-etcd"; - assertEquals(initialValue, DynamicPropertyFactory.getInstance().getStringProperty("test.key6", "default").get()); + assertEquals(initialValue, DynamicPropertyFactory.getInstance().getStringProperty(updateProperty, "default").get()); ETCD_UPDATE_HANDLER.handle(new Response("set", 200, new Node(updateKey, updateValue, 19444, 19444, 0, false, null))); - assertEquals(updateValue, DynamicPropertyFactory.getInstance().getStringProperty("test.key6", "default").get()); + assertEquals(updateValue, DynamicPropertyFactory.getInstance().getStringProperty(updateProperty, "default").get()); + } + + /** + * should delete from EtcdConfigurationSource when Etcd client handles a delete event + */ + @Test + public void testDeleteEtcdProperty() throws Exception { + final String deleteProperty = "test.key7"; + final String deleteKey = CONFIG_PATH + "/" + deleteProperty; + final String initialValue = "test.value7-etcd"; + + assertEquals(initialValue, DynamicPropertyFactory.getInstance().getStringProperty(deleteProperty, "default").get()); + + ETCD_UPDATE_HANDLER.handle(new Response("delete", 200, new Node(deleteKey, null, 12345, 12345, 0, false, null))); + assertEquals("test.value7-map", DynamicPropertyFactory.getInstance().getStringProperty(deleteProperty, "default").get()); } }