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); + } + } }