CURATOR-236: TreeCache throws IllegalArgumentException when node is a substring of the requested path
Better path walking algorithm. Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/a63bb03e Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/a63bb03e Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/a63bb03e Branch: refs/heads/CURATOR-3.0 Commit: a63bb03e590460985b729cb2fd1a4a5e7ed345ba Parents: e71da8f Author: Scott Blum <[email protected]> Authored: Thu Jul 16 17:50:32 2015 -0400 Committer: Scott Blum <[email protected]> Committed: Thu Jul 16 17:50:32 2015 -0400 ---------------------------------------------------------------------- .../framework/recipes/cache/TreeCache.java | 45 +++++++++++--------- .../framework/recipes/cache/TestTreeCache.java | 5 +++ 2 files changed, 30 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/a63bb03e/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java index 71efd28..7cf2267 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java @@ -33,6 +33,7 @@ import org.apache.curator.framework.listen.ListenerContainer; import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.utils.CloseableExecutorService; +import org.apache.curator.utils.PathUtils; import org.apache.curator.utils.ThreadUtils; import org.apache.curator.utils.ZKPaths; import org.apache.zookeeper.KeeperException; @@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentMap; @@ -601,33 +603,36 @@ public class TreeCache implements Closeable return errorListeners; } - private TreeNode find(String fullPath) + private TreeNode find(String findPath) { - if ( !fullPath.startsWith(root.path) ) - { - return null; + PathUtils.validatePath(findPath); + LinkedList<String> rootElements = new LinkedList<String>(ZKPaths.split(root.path)); + LinkedList<String> findElements = new LinkedList<String>(ZKPaths.split(findPath)); + while (!rootElements.isEmpty()) { + if (findElements.isEmpty()) { + // Target path shorter than root path + return null; + } + String nextRoot = rootElements.removeFirst(); + String nextFind = findElements.removeFirst(); + if (!nextFind.equals(nextRoot)) { + // Initial root path does not match + return null; + } } TreeNode current = root; - if ( fullPath.length() > root.path.length() ) - { - if ( root.path.length() > 1 ) + while (!findElements.isEmpty()) { + String nextFind = findElements.removeFirst(); + ConcurrentMap<String, TreeNode> map = current.children.get(); + if ( map == null ) { - fullPath = fullPath.substring(root.path.length()); + return null; } - List<String> split = ZKPaths.split(fullPath); - for ( String part : split ) + current = map.get(nextFind); + if ( current == null ) { - ConcurrentMap<String, TreeNode> map = current.children.get(); - if ( map == null ) - { - return null; - } - current = map.get(part); - if ( current == null ) - { - return null; - } + return null; } } return current; http://git-wip-us.apache.org/repos/asf/curator/blob/a63bb03e/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java index e1c61d0..0bccb54 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java @@ -395,11 +395,16 @@ public class TestTreeCache extends BaseTestTreeCache assertEvent(TreeCacheEvent.Type.NODE_ADDED, "/test"); assertEvent(TreeCacheEvent.Type.INITIALIZED); Assert.assertEquals(cache.getCurrentChildren("/test").keySet(), ImmutableSet.of()); + Assert.assertNull(cache.getCurrentChildren("/t")); + Assert.assertNull(cache.getCurrentChildren("/testing")); client.create().forPath("/test/one", "hey there".getBytes()); assertEvent(TreeCacheEvent.Type.NODE_ADDED, "/test/one"); Assert.assertEquals(cache.getCurrentChildren("/test").keySet(), ImmutableSet.of("one")); Assert.assertEquals(new String(cache.getCurrentData("/test/one").getData()), "hey there"); + Assert.assertEquals(cache.getCurrentChildren("/test/one").keySet(), ImmutableSet.of()); + Assert.assertNull(cache.getCurrentChildren("/test/o")); + Assert.assertNull(cache.getCurrentChildren("/test/onely")); client.setData().forPath("/test/one", "sup!".getBytes()); assertEvent(TreeCacheEvent.Type.NODE_UPDATED, "/test/one");
