CURATOR-161 - Added support for quietly() call that will suppress
NoWatcherException exceptions.


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

Branch: refs/heads/CURATOR-3.0
Commit: 4c2ba3744d90f2af12d815e8aa0747fd0d1a1c67
Parents: a83090b
Author: Cameron McKenzie <came...@unico.com.au>
Authored: Mon May 11 09:19:45 2015 +1000
Committer: Cameron McKenzie <came...@unico.com.au>
Committed: Mon May 11 09:19:45 2015 +1000

----------------------------------------------------------------------
 .../api/BackgroundPathableQuietly.java          |  5 ++
 .../apache/curator/framework/api/Quietly.java   |  6 ++
 .../framework/api/RemoveWatchesLocal.java       |  4 +-
 .../imps/RemoveWatchesBuilderImpl.java          | 38 +++++++++---
 .../framework/imps/TestRemoveWatches.java       | 64 ++++++++++++++++++++
 5 files changed, 107 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/4c2ba374/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundPathableQuietly.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundPathableQuietly.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundPathableQuietly.java
new file mode 100644
index 0000000..1174067
--- /dev/null
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundPathableQuietly.java
@@ -0,0 +1,5 @@
+package org.apache.curator.framework.api;
+
+public interface BackgroundPathableQuietly<T> extends BackgroundPathable<T>, 
Quietly<BackgroundPathable<T>>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/4c2ba374/curator-framework/src/main/java/org/apache/curator/framework/api/Quietly.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/api/Quietly.java 
b/curator-framework/src/main/java/org/apache/curator/framework/api/Quietly.java
new file mode 100644
index 0000000..cf4edc8
--- /dev/null
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/api/Quietly.java
@@ -0,0 +1,6 @@
+package org.apache.curator.framework.api;
+
+public interface Quietly<T>
+{
+    public T quietly();
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/4c2ba374/curator-framework/src/main/java/org/apache/curator/framework/api/RemoveWatchesLocal.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/api/RemoveWatchesLocal.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/api/RemoveWatchesLocal.java
index 2e9816b..d183a6a 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/api/RemoveWatchesLocal.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/api/RemoveWatchesLocal.java
@@ -4,7 +4,7 @@ package org.apache.curator.framework.api;
  * Builder to allow the specification of whether it is acceptable to remove 
client side watch information
  * in the case where ZK cannot be contacted. 
  */
-public interface RemoveWatchesLocal extends BackgroundPathable<Void>
+public interface RemoveWatchesLocal extends BackgroundPathableQuietly<Void>
 {
    
     /**
@@ -12,6 +12,6 @@ public interface RemoveWatchesLocal extends 
BackgroundPathable<Void>
      * is not available.
      * @return
      */
-    public BackgroundPathable<Void> local();
+    public BackgroundPathableQuietly<Void> local();
     
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/4c2ba374/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java
index 5d1f945..1e4fb88 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java
@@ -7,6 +7,7 @@ import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
 import org.apache.curator.framework.api.BackgroundCallback;
 import org.apache.curator.framework.api.BackgroundPathable;
+import org.apache.curator.framework.api.BackgroundPathableQuietly;
 import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.framework.api.CuratorWatcher;
@@ -15,6 +16,7 @@ import org.apache.curator.framework.api.RemoveWatchesLocal;
 import org.apache.curator.framework.api.RemoveWatchesBuilder;
 import org.apache.curator.framework.api.RemoveWatchesType;
 import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.Watcher.WatcherType;
 import org.apache.zookeeper.ZooKeeper;
@@ -25,7 +27,8 @@ public class RemoveWatchesBuilderImpl implements 
RemoveWatchesBuilder, RemoveWat
     private CuratorFrameworkImpl client;
     private Watcher watcher;
     private WatcherType watcherType;
-    private boolean local;    
+    private boolean local;
+    private boolean quietly;
     private Backgrounding backgrounding;
     
     public RemoveWatchesBuilderImpl(CuratorFrameworkImpl client)
@@ -34,6 +37,7 @@ public class RemoveWatchesBuilderImpl implements 
RemoveWatchesBuilder, RemoveWat
         this.watcher = null;
         this.watcherType = null;
         this.local = false;
+        this.quietly = false;
         this.backgrounding = new Backgrounding();
     }
     
@@ -109,13 +113,20 @@ public class RemoveWatchesBuilderImpl implements 
RemoveWatchesBuilder, RemoveWat
     }
 
     @Override
-    public BackgroundPathable<Void> local()
+    public BackgroundPathableQuietly<Void> local()
     {
         local = true;
         return this;
     }
     
     @Override
+    public BackgroundPathable<Void> quietly()
+    {
+        quietly = true;
+        return this;
+    }
+    
+    @Override
     public Void forPath(String path) throws Exception
     {
         final String adjustedPath = client.fixForNamespace(path);
@@ -146,16 +157,27 @@ public class RemoveWatchesBuilderImpl implements 
RemoveWatchesBuilder, RemoveWat
                     @Override
                     public Void call() throws Exception
                     {
-                        ZooKeeper zkClient = client.getZooKeeper();
-                        if(watcher == null)
+                        try
                         {
-                            zkClient.removeAllWatches(path, watcherType, 
local);    
+                            ZooKeeper zkClient = client.getZooKeeper();
+                            if(watcher == null)
+                            {
+                                zkClient.removeAllWatches(path, watcherType, 
local);    
+                            }
+                            else
+                            {
+                                zkClient.removeWatches(path, watcher, 
watcherType, local);
+                            }
                         }
-                        else
+                        catch(KeeperException.NoWatcherException e)
                         {
-                            zkClient.removeWatches(path, watcher, watcherType, 
local);
+                            //Swallow this exception if the quietly flag is 
set, otherwise rethrow.
+                            if(!quietly)
+                            {
+                                throw e;
+                            }
                         }
-                        
+                     
                         return null;
                     }
                 });

http://git-wip-us.apache.org/repos/asf/curator/blob/4c2ba374/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java
 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java
index b740286..28799f7 100644
--- 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java
+++ 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java
@@ -14,6 +14,7 @@ import org.apache.curator.retry.RetryOneTime;
 import org.apache.curator.test.BaseClassForTests;
 import org.apache.curator.test.Timing;
 import org.apache.curator.utils.CloseableUtils;
+import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.Watcher.Event.EventType;
@@ -331,4 +332,67 @@ public class TestRemoveWatches extends BaseClassForTests
             CloseableUtils.closeQuietly(client);
         }
     }
+    
+    /**
+     * Test the case where we try and remove an unregistered watcher. In this 
case we expect a NoWatcherException to
+     * be thrown. 
+     * @throws Exception
+     */
+    @Test(expectedExceptions=KeeperException.NoWatcherException.class)
+    public void testRemoveUnregisteredWatcher() throws Exception
+    {
+        CuratorFramework client = CuratorFrameworkFactory.builder().
+                connectString(server.getConnectString()).
+                retryPolicy(new RetryOneTime(1)).
+                build();
+        try
+        {
+            client.start();
+            
+            final String path = "/";            
+            Watcher watcher = new Watcher() {
+                @Override
+                public void process(WatchedEvent event)
+                {
+                }                
+            };
+            
+            
client.watches().remove(watcher).ofType(WatcherType.Data).forPath(path);
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(client);
+        }
+    }
+    
+    /**
+     * Test the case where we try and remove an unregistered watcher but have 
the quietly flag set. In this case we expect success. 
+     * @throws Exception
+     */
+    @Test
+    public void testRemoveUnregisteredWatcherQuietly() throws Exception
+    {
+        CuratorFramework client = CuratorFrameworkFactory.builder().
+                connectString(server.getConnectString()).
+                retryPolicy(new RetryOneTime(1)).
+                build();
+        try
+        {
+            client.start();
+            
+            final String path = "/";            
+            Watcher watcher = new Watcher() {
+                @Override
+                public void process(WatchedEvent event)
+                {
+                }                
+            };
+            
+            
client.watches().remove(watcher).ofType(WatcherType.Data).quietly().forPath(path);
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(client);
+        }
+    }    
 }

Reply via email to