You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2016/12/10 14:12:52 UTC

[2/4] curator git commit: more doc and tests

more doc and tests


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/7aa5617e
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/7aa5617e
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/7aa5617e

Branch: refs/heads/CURATOR-351
Commit: 7aa5617e299a6259de3360bef307a231b426bcfb
Parents: 994778c
Author: randgalt <ra...@apache.org>
Authored: Fri Dec 9 15:35:50 2016 +0100
Committer: randgalt <ra...@apache.org>
Committed: Fri Dec 9 15:35:50 2016 +0100

----------------------------------------------------------------------
 .../src/site/confluence/index.confluence        |  2 +-
 .../persistent-ephemeral-node.confluence        | 39 --------------
 .../site/confluence/persistent-node.confluence  | 39 ++++++++++++++
 .../confluence/persistent-ttl-node.confluence   |  2 +
 .../recipes/nodes/TestPersistentTtlNode.java    | 55 ++++++++++++++++++++
 5 files changed, 97 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/7aa5617e/curator-recipes/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/curator-recipes/src/site/confluence/index.confluence b/curator-recipes/src/site/confluence/index.confluence
index 4cf2cde..08ef762 100644
--- a/curator-recipes/src/site/confluence/index.confluence
+++ b/curator-recipes/src/site/confluence/index.confluence
@@ -29,7 +29,7 @@ regarding "Curator Recipes Own Their ZNode/Paths".
 |[[Tree Cache|tree-cache.html]] \- A utility that attempts to keep all data from all children of a ZK path locally cached. This class will watch the ZK path, respond to update/create/delete events, pull down the data, etc. You can register a listener that will get notified when changes occur.|
 
 ||Nodes||
-|[[Persistent Node|persistent-ephemeral-node.html]] \- A node that attempts to stay present in ZooKeeper, even through connection and session interruptions.|
+|[[Persistent Node|persistent-node.html]] \- A node that attempts to stay present in ZooKeeper, even through connection and session interruptions.|
 |[[Persistent TTL Node|persistent-ttl-node.html]] \- Useful when you need to create a TTL node but don't want to keep it alive manually by periodically setting data.|
 |[Group Member|group-member.html]] \- Group membership management. Adds this instance into a group and keeps a cache of members in the group.|
 

http://git-wip-us.apache.org/repos/asf/curator/blob/7aa5617e/curator-recipes/src/site/confluence/persistent-ephemeral-node.confluence
----------------------------------------------------------------------
diff --git a/curator-recipes/src/site/confluence/persistent-ephemeral-node.confluence b/curator-recipes/src/site/confluence/persistent-ephemeral-node.confluence
deleted file mode 100644
index 5baca09..0000000
--- a/curator-recipes/src/site/confluence/persistent-ephemeral-node.confluence
+++ /dev/null
@@ -1,39 +0,0 @@
-h1. Persistent Node
-
-h2. Description
-A persistent node is a node that attempts to stay present in ZooKeeper, even through connection and session interruptions.
-
-h2. Participating Classes
-* PersistentNode
-
-h2. Usage
-h3. Creating a PersistentNode
-{code}
-public PersistentNode(CuratorFramework client,
-                               CreateMode mode,
-                               boolean useProtection,
-                               String basePath,
-                               byte[] data)
-Parameters:
-client - client instance
-mode - creation mode
-useProtection - if true, call CreateBuilder.withProtection()
-basePath - the base path for the node
-data - data for the node
-{code}
-
-h3. General Usage
-PersistentNodes must be started:
-{code}
-node.start();
-{code}
-
-When you are through with the PersistentNode instance, you should call close:
-{code}
-node.close();
-{code}
-
-NOTE: this will delete the node
-
-h2. Error Handling
-PersistentNode instances internally handle all error states recreating the node as necessary.

http://git-wip-us.apache.org/repos/asf/curator/blob/7aa5617e/curator-recipes/src/site/confluence/persistent-node.confluence
----------------------------------------------------------------------
diff --git a/curator-recipes/src/site/confluence/persistent-node.confluence b/curator-recipes/src/site/confluence/persistent-node.confluence
new file mode 100644
index 0000000..5baca09
--- /dev/null
+++ b/curator-recipes/src/site/confluence/persistent-node.confluence
@@ -0,0 +1,39 @@
+h1. Persistent Node
+
+h2. Description
+A persistent node is a node that attempts to stay present in ZooKeeper, even through connection and session interruptions.
+
+h2. Participating Classes
+* PersistentNode
+
+h2. Usage
+h3. Creating a PersistentNode
+{code}
+public PersistentNode(CuratorFramework client,
+                               CreateMode mode,
+                               boolean useProtection,
+                               String basePath,
+                               byte[] data)
+Parameters:
+client - client instance
+mode - creation mode
+useProtection - if true, call CreateBuilder.withProtection()
+basePath - the base path for the node
+data - data for the node
+{code}
+
+h3. General Usage
+PersistentNodes must be started:
+{code}
+node.start();
+{code}
+
+When you are through with the PersistentNode instance, you should call close:
+{code}
+node.close();
+{code}
+
+NOTE: this will delete the node
+
+h2. Error Handling
+PersistentNode instances internally handle all error states recreating the node as necessary.

http://git-wip-us.apache.org/repos/asf/curator/blob/7aa5617e/curator-recipes/src/site/confluence/persistent-ttl-node.confluence
----------------------------------------------------------------------
diff --git a/curator-recipes/src/site/confluence/persistent-ttl-node.confluence b/curator-recipes/src/site/confluence/persistent-ttl-node.confluence
index acd2d33..f123c1d 100644
--- a/curator-recipes/src/site/confluence/persistent-ttl-node.confluence
+++ b/curator-recipes/src/site/confluence/persistent-ttl-node.confluence
@@ -3,6 +3,8 @@ h1. Persistent TTL Node
 h2. Description
 PersistentTtlNode is useful when you need to create a TTL node but don't want to keep it alive manually by periodically setting data \-
 PersistentTtlNode does that for you. Further the keep\-alive is done in a way that does not generate watch triggers on the parent node.
+It also provides similar guarantees that a [[Persistent Node|persistent-node.html]] does: the node attempts to stay present in ZooKeeper,
+even through connection and session interruptions.
 
 h2. Participating Classes
 * PersistentNode

http://git-wip-us.apache.org/repos/asf/curator/blob/7aa5617e/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentTtlNode.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentTtlNode.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentTtlNode.java
index 9ae8df9..848c034 100644
--- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentTtlNode.java
+++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentTtlNode.java
@@ -2,6 +2,9 @@ package org.apache.curator.framework.recipes.nodes;
 
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.recipes.cache.PathChildrenCache;
+import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
+import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
 import org.apache.curator.retry.RetryOneTime;
 import org.apache.curator.test.BaseClassForTests;
 import org.apache.curator.test.Timing;
@@ -9,8 +12,11 @@ import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
+import static org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode.BUILD_INITIAL_CACHE;
+
 public class TestPersistentTtlNode extends BaseClassForTests
 {
     private final Timing timing = new Timing();
@@ -55,4 +61,53 @@ public class TestPersistentTtlNode extends BaseClassForTests
             Assert.assertNull(client.checkExists().forPath("/test"));
         }
     }
+
+    @Test
+    public void testEventsOnParent() throws Exception
+    {
+        try (CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)))
+        {
+            client.start();
+
+            try (PersistentTtlNode node = new PersistentTtlNode(client, "/test", 10, new byte[0]))
+            {
+                try(PathChildrenCache cache = new PathChildrenCache(client, "/", true))
+                {
+                    final Semaphore changes = new Semaphore(0);
+                    PathChildrenCacheListener listener = new PathChildrenCacheListener()
+                    {
+                        @Override
+                        public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception
+                        {
+                            if ( event.getType() == PathChildrenCacheEvent.Type.CHILD_UPDATED )
+                            {
+                                if ( event.getData().getPath().equals("/test") )
+                                {
+                                    changes.release();
+                                }
+                            }
+                        }
+                    };
+                    cache.getListenable().addListener(listener);
+
+                    node.start();
+                    node.waitForInitialCreate(timing.session(), TimeUnit.MILLISECONDS);
+                    cache.start(BUILD_INITIAL_CACHE);
+
+                    Assert.assertEquals(changes.availablePermits(), 0);
+                    timing.sleepABit();
+                    Assert.assertEquals(changes.availablePermits(), 0);
+
+                    client.setData().forPath("/test", "changed".getBytes());
+                    Assert.assertTrue(timing.acquireSemaphore(changes));
+                    timing.sleepABit();
+                    Assert.assertEquals(changes.availablePermits(), 0);
+                }
+            }
+
+            timing.sleepABit();
+
+            Assert.assertNull(client.checkExists().forPath("/test"));
+        }
+    }
 }