Repository: curator
Updated Branches:
  refs/heads/CURATOR-426 46ce6b7ae -> 31d7f9a20


initial work on ZooKeeper 3.4.x compatibility mode


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

Branch: refs/heads/CURATOR-426
Commit: 0641243f75d25a92a9ceb811e8e2611a1e95869e
Parents: 7e611bd
Author: randgalt <randg...@apache.org>
Authored: Wed Jul 19 12:36:24 2017 -0500
Committer: randgalt <randg...@apache.org>
Committed: Wed Jul 19 12:36:24 2017 -0500

----------------------------------------------------------------------
 .../main/java/org/apache/curator/RetryLoop.java |   2 +-
 .../curator/framework/CuratorFramework.java     |   7 +
 .../framework/CuratorFrameworkFactory.java      |  50 +++++++-
 .../apache/curator/framework/SafeIsTtlMode.java |  43 +++++++
 .../imps/CompatibleCreateCallback.java          |  26 ++++
 .../framework/imps/CreateBuilderImpl.java       | 125 ++++++++++++------
 .../curator/framework/imps/CreateZK35.java      |  47 +++++++
 .../framework/imps/CuratorFrameworkImpl.java    |  21 ++-
 .../framework/imps/WatcherRemovalManager.java   |   2 +-
 .../framework/imps/TestFrameworkEdges.java      |   5 +-
 curator-recipes/pom.xml                         |  16 +++
 .../framework/recipes/nodes/PersistentNode.java |   3 +-
 curator-test-zk34/pom.xml                       | 127 +++++++++++++++++++
 .../curator/framework/imps/TestCleanState.java  |  25 ++++
 .../src/test/resources/log4j.properties         |  27 ++++
 pom.xml                                         |   8 ++
 16 files changed, 483 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-client/src/main/java/org/apache/curator/RetryLoop.java
----------------------------------------------------------------------
diff --git a/curator-client/src/main/java/org/apache/curator/RetryLoop.java 
b/curator-client/src/main/java/org/apache/curator/RetryLoop.java
index 2ea6f97..51df662 100644
--- a/curator-client/src/main/java/org/apache/curator/RetryLoop.java
+++ b/curator-client/src/main/java/org/apache/curator/RetryLoop.java
@@ -136,7 +136,7 @@ public class RetryLoop
             (rc == KeeperException.Code.OPERATIONTIMEOUT.intValue()) ||
             (rc == KeeperException.Code.SESSIONMOVED.intValue()) ||
             (rc == KeeperException.Code.SESSIONEXPIRED.intValue()) ||
-            (rc == KeeperException.Code.NEWCONFIGNOQUORUM.intValue());
+            (rc == -13); // KeeperException.Code.NEWCONFIGNOQUORUM.intValue()) 
- using hard coded value for ZK 3.4.x compatibility
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
index 4135e82..bf6167c 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
@@ -324,4 +324,11 @@ public interface CuratorFramework extends Closeable
      * @return schema set
      */
     SchemaSet getSchemaSet();
+
+    /**
+     * Return true if this instance is running in ZK 3.4.x compatibility mode
+     *
+     * @return true/false
+     */
+    boolean isZk34CompatibilityMode();
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/CuratorFrameworkFactory.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFrameworkFactory.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFrameworkFactory.java
index 915aee1..5ce7762 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFrameworkFactory.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFrameworkFactory.java
@@ -35,15 +35,16 @@ import 
org.apache.curator.framework.imps.CuratorTempFrameworkImpl;
 import org.apache.curator.framework.imps.DefaultACLProvider;
 import org.apache.curator.framework.imps.GzipCompressionProvider;
 import org.apache.curator.framework.schema.SchemaSet;
+import org.apache.curator.framework.state.ConnectionState;
 import org.apache.curator.framework.state.ConnectionStateErrorPolicy;
 import org.apache.curator.framework.state.StandardConnectionStateErrorPolicy;
-import org.apache.curator.framework.state.ConnectionState;
 import org.apache.curator.utils.DefaultZookeeperFactory;
 import org.apache.curator.utils.ZookeeperFactory;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.ZooKeeper;
+import org.slf4j.LoggerFactory;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Arrays;
@@ -67,6 +68,33 @@ public class CuratorFrameworkFactory
     private static final long DEFAULT_INACTIVE_THRESHOLD_MS = 
(int)TimeUnit.MINUTES.toMillis(3);
     private static final int DEFAULT_CLOSE_WAIT_MS = 
(int)TimeUnit.SECONDS.toMillis(1);
 
+    private static final boolean hasZooKeeperAdmin;
+    static
+    {
+        boolean hasIt;
+        try
+        {
+            Class.forName("org.apache.zookeeper.admin.ZooKeeperAdmin");
+            hasIt = true;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            hasIt = false;
+            
LoggerFactory.getLogger(CuratorFrameworkFactory.class).info("Running in 
ZooKeeper 3.4.x compatibility mode");
+        }
+        hasZooKeeperAdmin = hasIt;
+    }
+
+    /**
+     * Return true if the classpath ZooKeeper library is 3.4.x
+     *
+     * @return true/false
+     */
+    public static boolean isZK34()
+    {
+        return !hasZooKeeperAdmin;
+    }
+
     /**
      * Return a new builder that builds a CuratorFramework
      *
@@ -145,6 +173,7 @@ public class CuratorFrameworkFactory
         private ConnectionStateErrorPolicy connectionStateErrorPolicy = new 
StandardConnectionStateErrorPolicy();
         private ConnectionHandlingPolicy connectionHandlingPolicy = 
Boolean.getBoolean("curator-use-classic-connection-handling") ? new 
ClassicConnectionHandlingPolicy() : new StandardConnectionHandlingPolicy();
         private SchemaSet schemaSet = SchemaSet.getDefaultSchemaSet();
+        private boolean zk34CompatibilityMode = isZK34();
 
         /**
          * Apply the current values and build a new CuratorFramework
@@ -386,6 +415,20 @@ public class CuratorFrameworkFactory
         }
 
         /**
+         * If mode is true, create a ZooKeeper 3.4.x compatible client. 
IMPORTANT: If the client
+         * library used is ZooKeeper 3.4.x <code>zk34CompatibilityMode</code> 
is enabled by default.
+         *
+         * @since 3.5.0
+         * @param mode true/false
+         * @return this
+         */
+        public Builder zk34CompatibilityMode(boolean mode)
+        {
+            this.zk34CompatibilityMode = mode;
+            return this;
+        }
+
+        /**
          * <p>
          *     Change the connection handling policy. The default policy is 
{@link StandardConnectionHandlingPolicy}.
          * </p>
@@ -515,6 +558,11 @@ public class CuratorFrameworkFactory
             return schemaSet;
         }
 
+        public boolean isZk34CompatibilityMode()
+        {
+            return zk34CompatibilityMode;
+        }
+
         @Deprecated
         public String getAuthScheme()
         {

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/SafeIsTtlMode.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/SafeIsTtlMode.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/SafeIsTtlMode.java
new file mode 100644
index 0000000..3c4b9e6
--- /dev/null
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/SafeIsTtlMode.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework;
+
+import org.apache.zookeeper.CreateMode;
+
+public class SafeIsTtlMode
+{
+    private static class Internal
+    {
+        private static final Internal instance = new Internal();
+
+        public boolean isTtl(CreateMode mode)
+        {
+            return mode.isTTL();
+        }
+    }
+
+    public static boolean isTtl(CreateMode mode)
+    {
+        return !CuratorFrameworkFactory.isZK34() && 
Internal.instance.isTtl(mode);
+    }
+
+    private SafeIsTtlMode()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/imps/CompatibleCreateCallback.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CompatibleCreateCallback.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CompatibleCreateCallback.java
new file mode 100644
index 0000000..30ca391
--- /dev/null
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CompatibleCreateCallback.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework.imps;
+
+import org.apache.zookeeper.data.Stat;
+
+interface CompatibleCreateCallback
+{
+    void processResult(int rc, String path, Object ctx, String name, Stat 
stat);
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
index 416485a..b58084f 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
@@ -623,49 +623,76 @@ public class CreateBuilderImpl implements CreateBuilder, 
CreateBuilder2, Backgro
             final OperationTrace trace = 
client.getZookeeperClient().startAdvancedTracer("CreateBuilderImpl-Background");
             final byte[] data = operationAndData.getData().getData();
 
-            client.getZooKeeper().create
-            (
-                operationAndData.getData().getPath(),
-                data,
-                acling.getAclList(operationAndData.getData().getPath()),
-                createMode,
-                new AsyncCallback.Create2Callback() {
-                    @Override
-                    public void processResult(int rc, String path, Object ctx, 
String name, Stat stat) {
-                        
trace.setReturnCode(rc).setRequestBytesLength(data).setPath(path).commit();
+            final CompatibleCreateCallback mainCallback = new 
CompatibleCreateCallback()
+            {
+                @Override
+                public void processResult(int rc, String path, Object ctx, 
String name, Stat stat) {
+                    
trace.setReturnCode(rc).setRequestBytesLength(data).setPath(path).commit();
 
-                        if ( (stat != null) && (storingStat != null) )
-                        {
-                            storingStat.setAversion(stat.getAversion());
-                            storingStat.setCtime(stat.getCtime());
-                            storingStat.setCversion(stat.getCversion());
-                            storingStat.setCzxid(stat.getCzxid());
-                            storingStat.setDataLength(stat.getDataLength());
-                            
storingStat.setEphemeralOwner(stat.getEphemeralOwner());
-                            storingStat.setMtime(stat.getMtime());
-                            storingStat.setMzxid(stat.getMzxid());
-                            storingStat.setNumChildren(stat.getNumChildren());
-                            storingStat.setPzxid(stat.getPzxid());
-                            storingStat.setVersion(stat.getVersion());
-                        }
+                    if ( (stat != null) && (storingStat != null) )
+                    {
+                        storingStat.setAversion(stat.getAversion());
+                        storingStat.setCtime(stat.getCtime());
+                        storingStat.setCversion(stat.getCversion());
+                        storingStat.setCzxid(stat.getCzxid());
+                        storingStat.setDataLength(stat.getDataLength());
+                        
storingStat.setEphemeralOwner(stat.getEphemeralOwner());
+                        storingStat.setMtime(stat.getMtime());
+                        storingStat.setMzxid(stat.getMzxid());
+                        storingStat.setNumChildren(stat.getNumChildren());
+                        storingStat.setPzxid(stat.getPzxid());
+                        storingStat.setVersion(stat.getVersion());
+                    }
 
-                        if ( (rc == KeeperException.Code.NONODE.intValue()) && 
createParentsIfNeeded )
-                        {
-                            backgroundCreateParentsThenNode(client, 
operationAndData, operationAndData.getData().getPath(), backgrounding, 
acling.getACLProviderForParents(), createParentsAsContainers);
-                        }
-                        else if ( (rc == 
KeeperException.Code.NODEEXISTS.intValue()) && setDataIfExists )
-                        {
-                            backgroundSetData(client, operationAndData, 
operationAndData.getData().getPath(), backgrounding);
-                        }
-                        else
-                        {
-                            sendBackgroundResponse(rc, path, ctx, name, stat, 
operationAndData);
-                        }
+                    if ( (rc == KeeperException.Code.NONODE.intValue()) && 
createParentsIfNeeded )
+                    {
+                        backgroundCreateParentsThenNode(client, 
operationAndData, operationAndData.getData().getPath(), backgrounding, 
acling.getACLProviderForParents(), createParentsAsContainers);
                     }
-                },
-                backgrounding.getContext(),
-                ttl
-            );
+                    else if ( (rc == 
KeeperException.Code.NODEEXISTS.intValue()) && setDataIfExists )
+                    {
+                        backgroundSetData(client, operationAndData, 
operationAndData.getData().getPath(), backgrounding);
+                    }
+                    else
+                    {
+                        sendBackgroundResponse(rc, path, ctx, name, stat, 
operationAndData);
+                    }
+                }
+            };
+
+            if ( client.isZk34CompatibilityMode() )
+            {
+                AsyncCallback.StringCallback stringCallback = new 
AsyncCallback.StringCallback()
+                {
+                    @Override
+                    public void processResult(int rc, String path, Object ctx, 
String name)
+                    {
+                        mainCallback.processResult(rc, path, ctx, name, null);
+                    }
+                };
+                client.getZooKeeper().create
+                    (
+                        operationAndData.getData().getPath(),
+                        data,
+                        
acling.getAclList(operationAndData.getData().getPath()),
+                        createMode,
+                        stringCallback,
+                        backgrounding.getContext()
+                    );
+            }
+            else
+            {
+                CreateZK35.create
+                (
+                    client.getZooKeeper(),
+                    operationAndData.getData().getPath(),
+                    data,
+                    acling.getAclList(operationAndData.getData().getPath()),
+                    createMode,
+                    mainCallback,
+                    backgrounding.getContext(),
+                    ttl
+                );
+            }
         }
         catch ( Throwable e )
         {
@@ -1144,14 +1171,28 @@ public class CreateBuilderImpl implements 
CreateBuilder, CreateBuilder2, Backgro
                         {
                             try
                             {
-                                createdPath = 
client.getZooKeeper().create(path, data, aclList, createMode, storingStat, ttl);
+                                if ( client.isZk34CompatibilityMode() )
+                                {
+                                    createdPath = 
client.getZooKeeper().create(path, data, aclList, createMode);
+                                }
+                                else
+                                {
+                                    createdPath = 
client.getZooKeeper().create(path, data, aclList, createMode, storingStat, ttl);
+                                }
                             }
                             catch ( KeeperException.NoNodeException e )
                             {
                                 if ( createParentsIfNeeded )
                                 {
                                     ZKPaths.mkdirs(client.getZooKeeper(), 
path, false, acling.getACLProviderForParents(), createParentsAsContainers);
-                                    createdPath = 
client.getZooKeeper().create(path, data, acling.getAclList(path), createMode, 
storingStat, ttl);
+                                    if ( client.isZk34CompatibilityMode() )
+                                    {
+                                        createdPath = 
client.getZooKeeper().create(path, data, acling.getAclList(path), createMode);
+                                    }
+                                    else
+                                    {
+                                        createdPath = 
client.getZooKeeper().create(path, data, acling.getAclList(path), createMode, 
storingStat, ttl);
+                                    }
                                 }
                                 else
                                 {

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateZK35.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateZK35.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateZK35.java
new file mode 100644
index 0000000..a32e614
--- /dev/null
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateZK35.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework.imps;
+
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import java.util.List;
+
+// keep reference to AsyncCallback.Create2Callback in separate class for ZK 
3.4 compatibility
+class CreateZK35
+{
+    static void create(ZooKeeper zooKeeper, String path, byte data[], 
List<ACL> acl, CreateMode createMode, final CompatibleCreateCallback 
compatibleCallback, Object ctx, long ttl)
+    {
+        AsyncCallback.Create2Callback callback = new 
AsyncCallback.Create2Callback()
+        {
+            @Override
+            public void processResult(int rc, String path, Object ctx, String 
name, Stat stat)
+            {
+                compatibleCallback.processResult(rc, path, ctx, name, stat);
+            }
+        };
+        zooKeeper.create(path, data, acl, createMode, callback, ctx, ttl);
+    }
+
+    private CreateZK35()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
index 7b620d3..00adb3e 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
@@ -91,6 +91,7 @@ public class CuratorFrameworkImpl implements CuratorFramework
     private final InternalConnectionHandler internalConnectionHandler;
     private final EnsembleTracker ensembleTracker;
     private final SchemaSet schemaSet;
+    private final boolean zk34CompatibilityMode;
 
     private volatile ExecutorService executorService;
     private final AtomicBoolean logAsErrorConnectionErrors = new 
AtomicBoolean(false);
@@ -146,6 +147,7 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
         useContainerParentsIfAvailable = 
builder.useContainerParentsIfAvailable();
         connectionStateErrorPolicy = 
Preconditions.checkNotNull(builder.getConnectionStateErrorPolicy(), 
"errorPolicy cannot be null");
         schemaSet = Preconditions.checkNotNull(builder.getSchemaSet(), 
"schemaSet cannot be null");
+        zk34CompatibilityMode = builder.isZk34CompatibilityMode();
 
         byte[] builderDefaultData = builder.getDefaultData();
         defaultData = (builderDefaultData != null) ? 
Arrays.copyOf(builderDefaultData, builderDefaultData.length) : new byte[0];
@@ -155,7 +157,7 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
         failedRemoveWatcherManager = new FailedRemoveWatchManager(this);
         namespaceFacadeCache = new NamespaceFacadeCache(this);
 
-        ensembleTracker = new EnsembleTracker(this, 
builder.getEnsembleProvider());
+        ensembleTracker = zk34CompatibilityMode ? null : new 
EnsembleTracker(this, builder.getEnsembleProvider());
     }
 
     private List<AuthInfo> buildAuths(CuratorFrameworkFactory.Builder builder)
@@ -230,6 +232,7 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
         connectionStateErrorPolicy = parent.connectionStateErrorPolicy;
         internalConnectionHandler = parent.internalConnectionHandler;
         schemaSet = parent.schemaSet;
+        zk34CompatibilityMode = parent.zk34CompatibilityMode;
         ensembleTracker = null;
     }
 
@@ -316,7 +319,10 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
                 }
             });
 
-            ensembleTracker.start();
+            if ( ensembleTracker != null )
+            {
+                ensembleTracker.start();
+            }
 
             log.info(schemaSet.toDocumentation());
         }
@@ -366,7 +372,10 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
                 }
             }
 
-            ensembleTracker.close();
+            if ( ensembleTracker != null )
+            {
+                ensembleTracker.close();
+            }
             listeners.clear();
             unhandledErrorListeners.clear();
             connectionStateManager.close();
@@ -782,6 +791,12 @@ public class CuratorFrameworkImpl implements 
CuratorFramework
         connectionStateManager.addStateChange(newConnectionState);
     }
 
+    @Override
+    public boolean isZk34CompatibilityMode()
+    {
+        return zk34CompatibilityMode;
+    }
+
     EnsembleTracker getEnsembleTracker()
     {
         return ensembleTracker;

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/main/java/org/apache/curator/framework/imps/WatcherRemovalManager.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/WatcherRemovalManager.java
 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/WatcherRemovalManager.java
index b9c9044..b85675b 100644
--- 
a/curator-framework/src/main/java/org/apache/curator/framework/imps/WatcherRemovalManager.java
+++ 
b/curator-framework/src/main/java/org/apache/curator/framework/imps/WatcherRemovalManager.java
@@ -57,7 +57,7 @@ public class WatcherRemovalManager
         while ( localEntries.size() > 0 )
         {
             NamespaceWatcher watcher = localEntries.remove(0);
-            if ( entries.remove(watcher) )
+            if ( entries.remove(watcher) && !client.isZk34CompatibilityMode() )
             {
                 try
                 {

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java
----------------------------------------------------------------------
diff --git 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java
 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java
index 887f236..8fee2d3 100644
--- 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java
+++ 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java
@@ -23,6 +23,7 @@ import org.apache.curator.RetryPolicy;
 import org.apache.curator.RetrySleeper;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.SafeIsTtlMode;
 import org.apache.curator.framework.api.BackgroundCallback;
 import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
@@ -180,7 +181,7 @@ public class TestFrameworkEdges extends BaseClassForTests
             final String TEST_PATH = "/a/b/c/test-";
             long ttl = timing.forWaiting().milliseconds()*1000;
             CreateBuilder firstCreateBuilder = client.create();
-            if(mode.isTTL()) {
+            if( SafeIsTtlMode.isTtl(mode) ) {
                 firstCreateBuilder.withTtl(ttl);
             }
             
firstCreateBuilder.withMode(mode).inBackground(callback).forPath(TEST_PATH);
@@ -195,7 +196,7 @@ public class TestFrameworkEdges extends BaseClassForTests
             
             CreateBuilderImpl createBuilder = 
(CreateBuilderImpl)client.create();
             createBuilder.withProtection();
-            if(mode.isTTL()) {
+            if(SafeIsTtlMode.isTtl(mode)) {
                 createBuilder.withTtl(ttl);
             }
 

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-recipes/pom.xml
----------------------------------------------------------------------
diff --git a/curator-recipes/pom.xml b/curator-recipes/pom.xml
index 77f2a51..1ed413c 100644
--- a/curator-recipes/pom.xml
+++ b/curator-recipes/pom.xml
@@ -87,4 +87,20 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
----------------------------------------------------------------------
diff --git 
a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
 
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
index af74695..bdf607c 100644
--- 
a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
+++ 
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
@@ -23,6 +23,7 @@ import com.google.common.base.Function;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.SafeIsTtlMode;
 import org.apache.curator.framework.WatcherRemoveCuratorFramework;
 import org.apache.curator.framework.api.ACLBackgroundPathAndBytesable;
 import org.apache.curator.framework.api.BackgroundCallback;
@@ -449,7 +450,7 @@ public class PersistentNode implements Closeable
             CreateModable<ACLBackgroundPathAndBytesable<String>> 
localCreateMethod = createMethod.get();
             if ( localCreateMethod == null )
             {
-                CreateBuilderMain createBuilder = mode.isTTL() ? 
client.create().withTtl(ttl) : client.create();
+                CreateBuilderMain createBuilder = SafeIsTtlMode.isTtl(mode) ? 
client.create().withTtl(ttl) : client.create();
                 CreateModable<ACLBackgroundPathAndBytesable<String>> 
tempCreateMethod = useProtection ? 
createBuilder.creatingParentContainersIfNeeded().withProtection() : 
createBuilder.creatingParentContainersIfNeeded();
                 createMethod.compareAndSet(null, tempCreateMethod);
                 localCreateMethod = createMethod.get();

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-test-zk34/pom.xml
----------------------------------------------------------------------
diff --git a/curator-test-zk34/pom.xml b/curator-test-zk34/pom.xml
new file mode 100644
index 0000000..fe5e216
--- /dev/null
+++ b/curator-test-zk34/pom.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>apache-curator</artifactId>
+        <groupId>org.apache.curator</groupId>
+        <version>3.3.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>curator-test-zk34</artifactId>
+
+    <properties>
+        <zookeeper-34-version>3.4.8</zookeeper-34-version>
+        <curator-2-version>2.12.0</curator-2-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>${zookeeper-34-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.sun.jmx</groupId>
+                    <artifactId>jmxri</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.jdmk</groupId>
+                    <artifactId>jmxtools</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>javax.jms</groupId>
+                    <artifactId>jms</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <version>${curator-2-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>zookeeper</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>zookeeper</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>zookeeper</artifactId>
+                </exclusion>
+            </exclusions>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>deploy</phase>
+                        <configuration>
+                            <skip>true</skip>
+                        </configuration>
+                        <goals>
+                            <goal>deploy</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <dependenciesToScan>
+                        
<dependency>org.apache.curator:curator-framework</dependency>
+                        
<dependency>org.apache.curator:curator-recipes</dependency>
+                    </dependenciesToScan>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-test-zk34/src/test/java/org/apache/curator/framework/imps/TestCleanState.java
----------------------------------------------------------------------
diff --git 
a/curator-test-zk34/src/test/java/org/apache/curator/framework/imps/TestCleanState.java
 
b/curator-test-zk34/src/test/java/org/apache/curator/framework/imps/TestCleanState.java
new file mode 100644
index 0000000..9efeb90
--- /dev/null
+++ 
b/curator-test-zk34/src/test/java/org/apache/curator/framework/imps/TestCleanState.java
@@ -0,0 +1,25 @@
+package org.apache.curator.framework.imps;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.utils.CloseableUtils;
+import java.util.concurrent.Callable;
+
+public class TestCleanState
+{
+    public static void closeAndTestClean(CuratorFramework client)
+    {
+        CloseableUtils.closeQuietly(client);
+    }
+
+    public static void test(CuratorFramework client, Callable<Void> proc) 
throws Exception
+    {
+        try
+        {
+            proc.call();
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(client);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/curator-test-zk34/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/curator-test-zk34/src/test/resources/log4j.properties 
b/curator-test-zk34/src/test/resources/log4j.properties
new file mode 100644
index 0000000..2a85e0d
--- /dev/null
+++ b/curator-test-zk34/src/test/resources/log4j.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+log4j.rootLogger=ERROR, console
+
+log4j.logger.org.apache.curator=DEBUG, console
+log4j.additivity.org.apache.curator=false
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-5p %c %x %m [%t]%n

http://git-wip-us.apache.org/repos/asf/curator/blob/0641243f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index aa8fd86..b816d36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -298,6 +298,7 @@
         <module>curator-x-discovery-server</module>
         <module>curator-x-rpc</module>
         <module>curator-x-async</module>
+        <module>curator-test-zk34</module>
     </modules>
 
     <dependencyManagement>
@@ -347,6 +348,13 @@
 
             <dependency>
                 <groupId>org.apache.curator</groupId>
+                <artifactId>curator-recipes</artifactId>
+                <version>${project.version}</version>
+                <type>test-jar</type>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.curator</groupId>
                 <artifactId>curator-test</artifactId>
                 <version>${project.version}</version>
             </dependency>

Reply via email to