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 2015/10/09 02:09:55 UTC

[01/10] curator git commit: interim work - updated APIs make sure old tests work

Repository: curator
Updated Branches:
  refs/heads/CURATOR-3.0 df949e7a2 -> 0fe4d969f


interim work - updated APIs make sure old tests work


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

Branch: refs/heads/CURATOR-3.0
Commit: 2c0fca86ca3c25c9777e1b5c3bb3eea6cb0be8da
Parents: ea36769
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 19:14:53 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 19:14:53 2015 -0500

----------------------------------------------------------------------
 .../api/AddStatConfigEnsembleable.java          |   5 +-
 .../framework/api/BackgroundEnsembleable.java   |   7 +
 .../framework/api/BackgroundStatable.java       |  24 -
 .../curator/framework/api/Configurable.java     |  31 --
 .../framework/api/ConfigureEnsembleable.java    |  32 ++
 .../curator/framework/api/GetConfigBuilder.java |   9 +-
 .../api/JoinAddStatConfigEnsembleable.java      |   3 +-
 .../api/JoinLeaveStatConfigEnsembleable.java    |   3 +-
 .../api/JoinStatConfigEnsembleable.java         |   5 +-
 .../framework/api/JoinStatConfigurable.java     |   2 +-
 .../api/LeaveAddStatConfigEnsembleable.java     |   3 +-
 .../api/LeaveStatConfigEnsembleable.java        |   5 +-
 .../curator/framework/api/ReconfigBuilder.java  |   4 +-
 .../framework/api/StatConfigEnsembleable.java   |  26 -
 .../curator/framework/api/StatEnsembleable.java |  26 -
 .../api/WatchBackgroundEnsembleable.java        |   7 +
 .../framework/imps/GetConfigBuilderImpl.java    | 125 ++++-
 .../framework/imps/ReconfigBuilderImpl.java     | 110 +++--
 .../framework/imps/TestReconfiguration.java     | 474 +++++--------------
 .../framework/imps/TestReconfigurationX.java    | 418 ++++++++++++++++
 20 files changed, 798 insertions(+), 521 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
index 16f78a2..c60f617 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
@@ -25,8 +25,9 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface AddStatConfigEnsembleable extends
-    Addable<StatConfigEnsembleable>,
-    StatConfigEnsembleable
+    Addable<Statable<ConfigureEnsembleable>>,
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
new file mode 100644
index 0000000..ae2b226
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
@@ -0,0 +1,7 @@
+package org.apache.curator.framework.api;
+
+public interface BackgroundEnsembleable<T> extends
+    Backgroundable<Ensembleable<T>>,
+    Ensembleable<T>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatable.java
deleted file mode 100644
index 77c4e96..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatable.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * 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.api;
-
-public interface BackgroundStatable<T> extends
-    Backgroundable<T>,
-    Statable<T> {
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
deleted file mode 100644
index 2bc0494..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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.api;
-
-public interface Configurable
-{
-
-    /**
-     * Sets the configuration version to use.
-     * @param config The version of the configuration.
-     * @throws Exception
-     */
-    StatEnsembleable<byte[]> fromConfig(long config) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/ConfigureEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ConfigureEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ConfigureEnsembleable.java
new file mode 100644
index 0000000..8c739bc
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/ConfigureEnsembleable.java
@@ -0,0 +1,32 @@
+/**
+ * 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.api;
+
+public interface ConfigureEnsembleable extends
+    Ensembleable<byte[]>
+{
+
+    /**
+     * Sets the configuration version to use.
+     * @param config The version of the configuration.
+     * @throws Exception
+     */
+    Ensembleable<byte[]> fromConfig(long config) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/GetConfigBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/GetConfigBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/GetConfigBuilder.java
index c42e4cb..d137f28 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/GetConfigBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/GetConfigBuilder.java
@@ -20,10 +20,9 @@
 package org.apache.curator.framework.api;
 
 public interface GetConfigBuilder extends
-    Watchable<BackgroundStatable<Ensembleable<byte[]>>>,
-    BackgroundStatable<Ensembleable<byte[]>>,
-    Ensembleable<byte[]>
+    Ensembleable<byte[]>,
+    Backgroundable<Ensembleable<byte[]>>,
+    Watchable<BackgroundEnsembleable<byte[]>>,
+    Statable<WatchBackgroundEnsembleable<byte[]>>
 {
 }
-
-

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
index a905dd1..4356ba7 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
@@ -27,7 +27,8 @@ package org.apache.curator.framework.api;
 public interface JoinAddStatConfigEnsembleable extends
     Joinable<AddStatConfigEnsembleable>,
     Addable<JoinStatConfigurable>,
-    StatConfigEnsembleable
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
index 9642297..fac16a9 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
@@ -27,7 +27,8 @@ package org.apache.curator.framework.api;
 public interface JoinLeaveStatConfigEnsembleable extends
     Joinable<LeaveStatConfigEnsembleable>,
     Leaveable<JoinStatConfigEnsembleable>,
-    StatConfigEnsembleable
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
index 5fe7a8c..7ab51e2 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
@@ -25,8 +25,9 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface JoinStatConfigEnsembleable extends
-    Joinable<StatConfigEnsembleable>,
-    StatConfigEnsembleable
+    Joinable<ConfigureEnsembleable>,
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
index ef17ef4..18713e4 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
@@ -25,6 +25,6 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface JoinStatConfigurable extends
-    Joinable<Configurable>
+    Joinable<ConfigureEnsembleable>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
index 7912d45..b5125dc 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
@@ -27,6 +27,7 @@ package org.apache.curator.framework.api;
 public interface LeaveAddStatConfigEnsembleable extends
     Leaveable<AddStatConfigEnsembleable>,
     Addable<LeaveStatConfigEnsembleable>,
-    StatConfigEnsembleable
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
index ddad854..1464d26 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
@@ -25,8 +25,9 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface LeaveStatConfigEnsembleable extends
-    Leaveable<StatConfigEnsembleable>,
-    StatConfigEnsembleable
+    Leaveable<Statable<ConfigureEnsembleable>>,
+    ConfigureEnsembleable,
+    Statable<ConfigureEnsembleable>
 {
 
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
index 438abcf..d8a2cc2 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
@@ -20,9 +20,7 @@
 package org.apache.curator.framework.api;
 
 public interface ReconfigBuilder extends
-    Joinable<LeaveAddStatConfigEnsembleable>,
-    Leaveable<JoinAddStatConfigEnsembleable>,
-    Addable<JoinLeaveStatConfigEnsembleable>,
+    ReconfigBuilderMain,
     Backgroundable<ReconfigBuilderMain>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
deleted file mode 100644
index 4700c8c..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.api;
-
-public interface StatConfigEnsembleable extends
-    Configurable,
-    StatEnsembleable<byte[]>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
deleted file mode 100644
index 0993b50..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.api;
-
-public interface StatEnsembleable<T> extends
-    Statable<Ensembleable<T>>,
-    Ensembleable<T>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
new file mode 100644
index 0000000..073cfe3
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
@@ -0,0 +1,7 @@
+package org.apache.curator.framework.api;
+
+public interface WatchBackgroundEnsembleable<T> extends
+    Watchable<BackgroundEnsembleable<T>>,
+    BackgroundEnsembleable<T>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
index 5468bd4..09cb0ab 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
@@ -22,12 +22,13 @@ package org.apache.curator.framework.imps;
 import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
 import org.apache.curator.framework.api.BackgroundCallback;
-import org.apache.curator.framework.api.BackgroundStatable;
+import org.apache.curator.framework.api.BackgroundEnsembleable;
 import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.framework.api.CuratorWatcher;
 import org.apache.curator.framework.api.Ensembleable;
 import org.apache.curator.framework.api.GetConfigBuilder;
+import org.apache.curator.framework.api.WatchBackgroundEnsembleable;
 import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.ZooDefs;
@@ -51,31 +52,92 @@ public class GetConfigBuilderImpl implements GetConfigBuilder, BackgroundOperati
     }
 
     @Override
-    public Ensembleable<byte[]> storingStatIn(Stat stat)
+    public WatchBackgroundEnsembleable<byte[]> storingStatIn(Stat stat)
     {
         this.stat = stat;
-        return this;
+        return new WatchBackgroundEnsembleable<byte[]>()
+        {
+            @Override
+            public Ensembleable<byte[]> inBackground()
+            {
+                return GetConfigBuilderImpl.this.inBackground();
+            }
+
+            @Override
+            public Ensembleable<byte[]> inBackground(Object context)
+            {
+                return GetConfigBuilderImpl.this.inBackground(context);
+            }
+
+            @Override
+            public Ensembleable<byte[]> inBackground(BackgroundCallback callback)
+            {
+                return GetConfigBuilderImpl.this.inBackground(callback);
+            }
+
+            @Override
+            public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context)
+            {
+                return GetConfigBuilderImpl.this.inBackground(callback, context);
+            }
+
+            @Override
+            public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Executor executor)
+            {
+                return GetConfigBuilderImpl.this.inBackground(callback, executor);
+            }
+
+            @Override
+            public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context, Executor executor)
+            {
+                return GetConfigBuilderImpl.this.inBackground(callback, context, executor);
+            }
+
+            @Override
+            public byte[] forEnsemble() throws Exception
+            {
+                return GetConfigBuilderImpl.this.forEnsemble();
+            }
+
+            @Override
+            public BackgroundEnsembleable<byte[]> watched()
+            {
+                return GetConfigBuilderImpl.this.watched();
+            }
+
+            @Override
+            public BackgroundEnsembleable<byte[]> usingWatcher(Watcher watcher)
+            {
+                return GetConfigBuilderImpl.this.usingWatcher(watcher);
+            }
+
+            @Override
+            public BackgroundEnsembleable<byte[]> usingWatcher(CuratorWatcher watcher)
+            {
+                return GetConfigBuilderImpl.this.usingWatcher(watcher);
+            }
+        };
     }
 
     @Override
-    public BackgroundStatable<Ensembleable<byte[]>> watched()
+    public BackgroundEnsembleable<byte[]> watched()
     {
         watching = new Watching(true);
-        return this;
+        return new InternalBackgroundEnsembleable();
     }
 
     @Override
-    public GetConfigBuilder usingWatcher(Watcher watcher)
+    public BackgroundEnsembleable<byte[]> usingWatcher(Watcher watcher)
     {
         watching = new Watching(client, watcher);
-        return this;
+        return new InternalBackgroundEnsembleable();
     }
 
     @Override
-    public GetConfigBuilder usingWatcher(final CuratorWatcher watcher)
+    public BackgroundEnsembleable<byte[]> usingWatcher(CuratorWatcher watcher)
     {
         watching = new Watching(client, watcher);
-        return this;
+        return new InternalBackgroundEnsembleable();
     }
 
     @Override
@@ -185,4 +247,49 @@ public class GetConfigBuilderImpl implements GetConfigBuilder, BackgroundOperati
             trace.commit();
         }
     }
+
+    private class InternalBackgroundEnsembleable implements BackgroundEnsembleable<byte[]>
+    {
+        @Override
+        public Ensembleable<byte[]> inBackground()
+        {
+            return GetConfigBuilderImpl.this.inBackground();
+        }
+
+        @Override
+        public Ensembleable<byte[]> inBackground(Object context)
+        {
+            return GetConfigBuilderImpl.this.inBackground(context);
+        }
+
+        @Override
+        public Ensembleable<byte[]> inBackground(BackgroundCallback callback)
+        {
+            return GetConfigBuilderImpl.this.inBackground(callback);
+        }
+
+        @Override
+        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context)
+        {
+            return GetConfigBuilderImpl.this.inBackground(callback, context);
+        }
+
+        @Override
+        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Executor executor)
+        {
+            return GetConfigBuilderImpl.this.inBackground(callback, executor);
+        }
+
+        @Override
+        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context, Executor executor)
+        {
+            return GetConfigBuilderImpl.this.inBackground(callback, context, executor);
+        }
+
+        @Override
+        public byte[] forEnsemble() throws Exception
+        {
+            return GetConfigBuilderImpl.this.forEnsemble();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
index 0efa481..832272b 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
@@ -34,10 +34,8 @@ import java.util.concurrent.Executor;
 public class ReconfigBuilderImpl implements
     ReconfigBuilder,
     ReconfigBuilderMain,
-    StatEnsembleable<byte[]>,
-    Configurable,
-    StatConfigEnsembleable,
-    BackgroundOperation<Void>
+    ConfigureEnsembleable,
+    BackgroundOperation<Void>,Statable<Ensembleable<byte[]>>,Ensembleable<byte[]>
 {
     private final CuratorFrameworkImpl client;
 
@@ -75,7 +73,7 @@ public class ReconfigBuilderImpl implements
     }
 
     @Override
-    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+    public Ensembleable<byte[]> fromConfig(long config) throws Exception
     {
         fromConfig = config;
         return this;
@@ -101,13 +99,26 @@ public class ReconfigBuilderImpl implements
             }
 
             @Override
-            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return ReconfigBuilderImpl.this.storingStatIn(stat);
+                return new ConfigureEnsembleable()
+                {
+                    @Override
+                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
+
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
+                };
             }
 
             @Override
-            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            public Ensembleable<byte[]> fromConfig(long config) throws Exception
             {
                 return ReconfigBuilderImpl.this.fromConfig(config);
             }
@@ -130,25 +141,25 @@ public class ReconfigBuilderImpl implements
                     }
 
                     @Override
-                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    public ConfigureEnsembleable storingStatIn(Stat stat)
                     {
-                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
                     {
                         return ReconfigBuilderImpl.this.fromConfig(config);
                     }
 
                     @Override
-                    public StatConfigEnsembleable leaving(List<String> servers)
+                    public Statable<ConfigureEnsembleable> leaving(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.leaving(servers);
                     }
 
                     @Override
-                    public StatConfigEnsembleable leaving(String... server)
+                    public Statable<ConfigureEnsembleable> leaving(String... server)
                     {
                         return ReconfigBuilderImpl.this.leaving(server);
                     }
@@ -173,25 +184,25 @@ public class ReconfigBuilderImpl implements
                     }
 
                     @Override
-                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    public ConfigureEnsembleable storingStatIn(Stat stat)
                     {
-                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
                     {
                         return ReconfigBuilderImpl.this.fromConfig(config);
                     }
 
                     @Override
-                    public StatConfigEnsembleable joining(List<String> servers)
+                    public ConfigureEnsembleable joining(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.joining(servers);
                     }
 
                     @Override
-                    public StatConfigEnsembleable joining(String... server)
+                    public ConfigureEnsembleable joining(String... server)
                     {
                         return ReconfigBuilderImpl.this.joining(server);
                     }
@@ -262,13 +273,13 @@ public class ReconfigBuilderImpl implements
             }
 
             @Override
-            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return ReconfigBuilderImpl.this.storingStatIn(stat);
+                return new InternalConfigureEnsembleable();
             }
 
             @Override
-            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            public Ensembleable<byte[]> fromConfig(long config) throws Exception
             {
                 return ReconfigBuilderImpl.this.fromConfig(config);
             }
@@ -291,25 +302,25 @@ public class ReconfigBuilderImpl implements
                     }
 
                     @Override
-                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    public ConfigureEnsembleable storingStatIn(Stat stat)
                     {
-                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
                     {
                         return ReconfigBuilderImpl.this.fromConfig(config);
                     }
 
                     @Override
-                    public StatConfigEnsembleable leaving(List<String> servers)
+                    public Statable<ConfigureEnsembleable> leaving(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.leaving(servers);
                     }
 
                     @Override
-                    public StatConfigEnsembleable leaving(String... server)
+                    public Statable<ConfigureEnsembleable> leaving(String... server)
                     {
                         return ReconfigBuilderImpl.this.leaving(server);
                     }
@@ -334,25 +345,25 @@ public class ReconfigBuilderImpl implements
                     }
 
                     @Override
-                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    public ConfigureEnsembleable storingStatIn(Stat stat)
                     {
-                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    public ConfigureEnsembleable fromConfig(long config) throws Exception
                     {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatConfigEnsembleable adding(List<String> servers)
+                    public Statable<ConfigureEnsembleable> adding(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.adding(servers);
                     }
 
                     @Override
-                    public StatConfigEnsembleable adding(String... server)
+                    public Statable<ConfigureEnsembleable> adding(String... server)
                     {
                         return ReconfigBuilderImpl.this.adding(server);
                     }
@@ -381,13 +392,13 @@ public class ReconfigBuilderImpl implements
             }
 
             @Override
-            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return ReconfigBuilderImpl.this.storingStatIn(stat);
+                return new InternalConfigureEnsembleable();
             }
 
             @Override
-            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            public Ensembleable<byte[]> fromConfig(long config) throws Exception
             {
                 return ReconfigBuilderImpl.this.fromConfig(config);
             }
@@ -404,13 +415,13 @@ public class ReconfigBuilderImpl implements
                 return new JoinStatConfigurable()
                 {
                     @Override
-                    public Configurable joining(List<String> servers)
+                    public ConfigureEnsembleable joining(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.joining(servers);
                     }
 
                     @Override
-                    public Configurable joining(String... server)
+                    public ConfigureEnsembleable joining(String... server)
                     {
                         return ReconfigBuilderImpl.this.joining(server);
                     }
@@ -435,25 +446,25 @@ public class ReconfigBuilderImpl implements
                     }
 
                     @Override
-                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    public ConfigureEnsembleable storingStatIn(Stat stat)
                     {
-                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                        return new InternalConfigureEnsembleable();
                     }
 
                     @Override
-                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
                     {
                         return ReconfigBuilderImpl.this.fromConfig(config);
                     }
 
                     @Override
-                    public StatConfigEnsembleable adding(List<String> servers)
+                    public Statable<ConfigureEnsembleable> adding(List<String> servers)
                     {
                         return ReconfigBuilderImpl.this.adding(servers);
                     }
 
                     @Override
-                    public StatConfigEnsembleable adding(String... server)
+                    public Statable<ConfigureEnsembleable> adding(String... server)
                     {
                         return ReconfigBuilderImpl.this.adding(server);
                     }
@@ -501,4 +512,19 @@ public class ReconfigBuilderImpl implements
         trace.commit();
         return responseData;
     }
+
+    private class InternalConfigureEnsembleable implements ConfigureEnsembleable
+    {
+        @Override
+        public Ensembleable<byte[]> fromConfig(long config) throws Exception
+        {
+            return ReconfigBuilderImpl.this.fromConfig(config);
+        }
+
+        @Override
+        public byte[] forEnsemble() throws Exception
+        {
+            return ReconfigBuilderImpl.this.forEnsemble();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
index 2438ef8..d4c89be 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
@@ -19,400 +19,184 @@
 
 package org.apache.curator.framework.imps;
 
-import org.apache.curator.ensemble.EnsembleListener;
-import org.apache.curator.ensemble.dynamic.DynamicEnsembleProvider;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.api.BackgroundCallback;
-import org.apache.curator.framework.api.CuratorEvent;
-import org.apache.curator.framework.ensemble.EnsembleTracker;
 import org.apache.curator.retry.RetryOneTime;
+import org.apache.curator.test.BaseClassForTests;
 import org.apache.curator.test.InstanceSpec;
 import org.apache.curator.test.TestingCluster;
-import org.apache.curator.test.Timing;
 import org.apache.curator.utils.CloseableUtils;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
 import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
 import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.ByteArrayInputStream;
 import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
 
-public class TestReconfiguration
+public class TestReconfiguration extends BaseClassForTests
 {
-    private static final Timing timing = new Timing();
     private TestingCluster cluster;
-    private DynamicEnsembleProvider dynamicEnsembleProvider;
-    private WaitOnDelegateListener waitOnDelegateListener;
-    private EnsembleTracker ensembleTracker;
-    private CuratorFramework client;
-
-    private String connectionString1to5;
-    private String connectionString2to5;
-    private String connectionString3to5;
 
     @BeforeMethod
+    @Override
     public void setup() throws Exception
     {
-        cluster = new TestingCluster(5);
-        cluster.start();
-
-        connectionString1to5 = cluster.getConnectString();
-        connectionString2to5 = getConnectionString(cluster, 2, 3, 4, 5);
-        connectionString3to5 = getConnectionString(cluster, 3, 4, 5);
+        super.setup();
 
-        dynamicEnsembleProvider = new DynamicEnsembleProvider(connectionString1to5);
-        client = CuratorFrameworkFactory.builder()
-            .ensembleProvider(dynamicEnsembleProvider)
-            .retryPolicy(new RetryOneTime(1))
-            .build();
-        client.start();
-        client.blockUntilConnected();
-
-        //Wrap around the dynamic ensemble provider, so that we can wait until it has received the event.
-        waitOnDelegateListener = new WaitOnDelegateListener(dynamicEnsembleProvider);
-        ensembleTracker = new EnsembleTracker(client);
-        ensembleTracker.getListenable().addListener(waitOnDelegateListener);
-        ensembleTracker.start();
-        //Wait for the initial event.
-        waitOnDelegateListener.waitForEvent();
+        CloseableUtils.closeQuietly(server);
+        server = null;
+        cluster = new TestingCluster(3);
+        cluster.start();
     }
 
     @AfterMethod
-    public void tearDown() throws IOException
+    @Override
+    public void teardown() throws Exception
     {
-        CloseableUtils.closeQuietly(ensembleTracker);
-        CloseableUtils.closeQuietly(client);
         CloseableUtils.closeQuietly(cluster);
-    }
-
-    @Test
-    public void testSyncIncremental() throws Exception
-    {
-        Stat stat = new Stat();
-        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
-        Assert.assertNotNull(bytes);
-        QuorumVerifier qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-
-        //Remove Servers
-        bytes = client.reconfig().leaving("1").fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
 
-        bytes = client.reconfig().leaving("2").fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-
-        //Add Servers
-        bytes = client.reconfig().joining("server.2=" + server2).fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig().joining("server.1=" + server1).fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+        super.teardown();
     }
 
-    @Test
-    public void testAsyncIncremental() throws Exception
+    @SuppressWarnings("ConstantConditions")
+    public void testApiPermutations() throws Exception
     {
-        final AtomicReference<byte[]> bytes = new AtomicReference<>();
-        final BackgroundCallback callback = new BackgroundCallback()
-        {
-            @Override
-            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
-            {
-                bytes.set(event.getData());
-                //We only need the latch on getConfig.
-                if ( event.getContext() != null )
-                {
-                    ((CountDownLatch)event.getContext()).countDown();
-                }
-            }
-
-        };
-
-        CountDownLatch latch = new CountDownLatch(1);
-        client.getConfig().inBackground(callback, latch).forEnsemble();
-        Assert.assertTrue(timing.awaitLatch(latch));
-        Assert.assertNotNull(bytes.get());
-        QuorumVerifier qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-
-        //Remove Servers
-        client.reconfig().inBackground(callback).leaving("1").fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch).leaving("2").fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        //Add Servers
-        client.reconfig().inBackground(callback, latch).joining("server.2=" + server2).fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch).joining("server.1=" + server1).fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-    }
-
-    @Test
-    public void testSyncNonIncremental() throws Exception
-    {
-        Stat stat = new Stat();
-        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
-        Assert.assertNotNull(bytes);
-        QuorumVerifier qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-        String server3 = getServerString(qv, cluster, 3L);
-        String server4 = getServerString(qv, cluster, 4L);
-        String server5 = getServerString(qv, cluster, 5L);
-
-        //Remove Servers
-        bytes = client.reconfig()
-            .adding("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig()
-            .adding("server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-
-        //Add Servers
-        bytes = client.reconfig()
-            .adding("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig()
-            .adding("server.1=" + server1,
-                "server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).storingStatIn(stat).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+        // not an actual test. Specifies all possible API possibilities
+
+        Watcher watcher = null;
+        Stat stat = null;
+        CuratorFramework client = null;
+
+        client.getConfig().forEnsemble();
+        client.getConfig().inBackground().forEnsemble();
+        client.getConfig().usingWatcher(watcher).forEnsemble();
+        client.getConfig().usingWatcher(watcher).inBackground().forEnsemble();
+        client.getConfig().storingStatIn(stat).forEnsemble();
+        client.getConfig().storingStatIn(stat).inBackground().forEnsemble();
+        client.getConfig().storingStatIn(stat).usingWatcher(watcher).forEnsemble();
+        client.getConfig().storingStatIn(stat).usingWatcher(watcher).inBackground().forEnsemble();
+
+        // ---------
+
+        client.reconfig().adding().forEnsemble();
+        client.reconfig().leaving().forEnsemble();
+        client.reconfig().joining().forEnsemble();
+        client.reconfig().adding().leaving().forEnsemble();
+        client.reconfig().adding().joining().forEnsemble();
+        client.reconfig().leaving().joining().forEnsemble();
+
+        client.reconfig().adding().fromConfig(0).forEnsemble();
+        client.reconfig().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().joining().fromConfig(0).forEnsemble();
+        client.reconfig().adding().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().adding().joining().fromConfig(0).forEnsemble();
+        client.reconfig().leaving().joining().fromConfig(0).forEnsemble();
+
+        client.reconfig().adding().fromConfig(0).forEnsemble();
+        client.reconfig().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().joining().fromConfig(0).forEnsemble();
+        client.reconfig().adding().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().adding().joining().fromConfig(0).forEnsemble();
+        client.reconfig().leaving().joining().fromConfig(0).forEnsemble();
+
+        client.reconfig().adding().storingStatIn(stat).forEnsemble();
+        client.reconfig().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().adding().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().adding().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().leaving().joining().storingStatIn(stat).forEnsemble();
+
+        client.reconfig().adding().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().adding().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().adding().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+
+        client.reconfig().inBackground().adding().forEnsemble();
+        client.reconfig().inBackground().leaving().forEnsemble();
+        client.reconfig().inBackground().joining().forEnsemble();
+        client.reconfig().inBackground().adding().leaving().forEnsemble();
+        client.reconfig().inBackground().adding().joining().forEnsemble();
+        client.reconfig().inBackground().leaving().joining().forEnsemble();
+
+        client.reconfig().inBackground().adding().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().joining().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().joining().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().joining().fromConfig(0).forEnsemble();
+
+        client.reconfig().inBackground().adding().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().joining().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().joining().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().joining().fromConfig(0).forEnsemble();
+
+        client.reconfig().inBackground().adding().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().adding().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().adding().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().leaving().joining().storingStatIn(stat).forEnsemble();
+
+        client.reconfig().inBackground().adding().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().adding().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
     }
 
     @Test
-    public void testAsyncNonIncremental() throws Exception
+    public void testBasicGetConfig() throws Exception
     {
-        final AtomicReference<byte[]> bytes = new AtomicReference<>();
-        final BackgroundCallback callback = new BackgroundCallback()
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
         {
-            @Override
-            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
-            {
-                bytes.set(event.getData());
-                ((CountDownLatch)event.getContext()).countDown();
-            }
+            client.start();
+            QuorumVerifier quorumVerifier = toQuorumVerifier(client.getConfig().forEnsemble());
+            System.out.println(quorumVerifier);
 
-        };
-
-        CountDownLatch latch = new CountDownLatch(1);
-        client.getConfig().inBackground(callback, latch).forEnsemble();
-        Assert.assertTrue(timing.awaitLatch(latch));
-        Assert.assertNotNull(bytes.get());
-        QuorumVerifier qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-        String server3 = getServerString(qv, cluster, 3L);
-        String server4 = getServerString(qv, cluster, 4L);
-        String server5 = getServerString(qv, cluster, 5L);
-
-        //Remove Servers
-        client.reconfig().inBackground(callback, latch)
-            .adding("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch)
-            .adding("server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        //Add Servers
-        client.reconfig().inBackground(callback, latch)
-            .adding("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch)
-            .adding("server.1=" + server1,
-                "server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-    }
-
-    static QuorumVerifier getQuorumVerifier(byte[] bytes) throws Exception
-    {
-        Properties properties = new Properties();
-        properties.load(new StringReader(new String(bytes)));
-        return new QuorumMaj(properties);
-    }
-
-    static InstanceSpec getInstance(TestingCluster cluster, int id)
-    {
-        for ( InstanceSpec spec : cluster.getInstances() )
-        {
-            if ( spec.getServerId() == id )
+            for ( InstanceSpec instance : cluster.getInstances() )
             {
-                return spec;
+                QuorumPeer.QuorumServer quorumServer = quorumVerifier.getAllMembers().get((long)instance.getServerId());
+                Assert.assertNotNull(quorumServer);
+                Assert.assertEquals(quorumServer.clientAddr.getPort(), instance.getPort());
             }
         }
-        throw new IllegalStateException("InstanceSpec with id:" + id + " not found");
     }
 
-    static String getServerString(QuorumVerifier qv, TestingCluster cluster, long id) throws Exception
+    @Test
+    public void testAdd1Sync() throws Exception
     {
-        String str = qv.getAllMembers().get(id).toString();
-        //check if connection string is already there.
-        if ( str.contains(";") )
-        {
-            return str;
-        }
-        else
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
         {
-            return str + ";" + getInstance(cluster, (int)id).getConnectString();
-        }
-    }
+            client.start();
 
-    static String getConnectionString(TestingCluster cluster, long... ids) throws Exception
-    {
-        StringBuilder sb = new StringBuilder();
-        Map<Long, InstanceSpec> specs = new HashMap<>();
-        for ( InstanceSpec spec : cluster.getInstances() )
-        {
-            specs.put((long)spec.getServerId(), spec);
-        }
-        for ( long id : ids )
-        {
-            if ( sb.length() != 0 )
+            Watcher watcher = new Watcher()
             {
-                sb.append(",");
-            }
-            sb.append(specs.get(id).getConnectString());
+                @Override
+                public void process(WatchedEvent event)
+                {
+
+                }
+            };
+            client.getConfig().usingWatcher(watcher).forEnsemble();
         }
-        return sb.toString();
     }
 
-    //Simple EnsembleListener that can wait until the delegate handles the event.
-    private static class WaitOnDelegateListener implements EnsembleListener
+    private static QuorumVerifier toQuorumVerifier(byte[] bytes) throws Exception
     {
-        private CountDownLatch latch = new CountDownLatch(1);
-
-        private final EnsembleListener delegate;
-
-        private WaitOnDelegateListener(EnsembleListener delegate)
-        {
-            this.delegate = delegate;
-        }
-
-        @Override
-        public void connectionStringUpdated(String connectionString)
-        {
-            delegate.connectionStringUpdated(connectionString);
-            latch.countDown();
-        }
-
-        public void waitForEvent() throws InterruptedException, TimeoutException
-        {
-            if ( timing.awaitLatch(latch) )
-            {
-                latch = new CountDownLatch(1);
-            }
-            else
-            {
-                throw new TimeoutException("Failed to receive event in time.");
-            }
-        }
+        Assert.assertNotNull(bytes);
+        Properties properties = new Properties();
+        properties.load(new ByteArrayInputStream(bytes));
+        return new QuorumMaj(properties);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/curator/blob/2c0fca86/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
new file mode 100644
index 0000000..2268055
--- /dev/null
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
@@ -0,0 +1,418 @@
+/**
+ * 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.curator.ensemble.EnsembleListener;
+import org.apache.curator.ensemble.dynamic.DynamicEnsembleProvider;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.api.BackgroundCallback;
+import org.apache.curator.framework.api.CuratorEvent;
+import org.apache.curator.framework.ensemble.EnsembleTracker;
+import org.apache.curator.retry.RetryOneTime;
+import org.apache.curator.test.InstanceSpec;
+import org.apache.curator.test.TestingCluster;
+import org.apache.curator.test.Timing;
+import org.apache.curator.utils.CloseableUtils;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
+import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class TestReconfigurationX
+{
+    private static final Timing timing = new Timing();
+    private TestingCluster cluster;
+    private DynamicEnsembleProvider dynamicEnsembleProvider;
+    private WaitOnDelegateListener waitOnDelegateListener;
+    private EnsembleTracker ensembleTracker;
+    private CuratorFramework client;
+
+    private String connectionString1to5;
+    private String connectionString2to5;
+    private String connectionString3to5;
+
+    @BeforeMethod
+    public void setup() throws Exception
+    {
+        cluster = new TestingCluster(5);
+        cluster.start();
+
+        connectionString1to5 = cluster.getConnectString();
+        connectionString2to5 = getConnectionString(cluster, 2, 3, 4, 5);
+        connectionString3to5 = getConnectionString(cluster, 3, 4, 5);
+
+        dynamicEnsembleProvider = new DynamicEnsembleProvider(connectionString1to5);
+        client = CuratorFrameworkFactory.builder()
+            .ensembleProvider(dynamicEnsembleProvider)
+            .retryPolicy(new RetryOneTime(1))
+            .build();
+        client.start();
+        client.blockUntilConnected();
+
+        //Wrap around the dynamic ensemble provider, so that we can wait until it has received the event.
+        waitOnDelegateListener = new WaitOnDelegateListener(dynamicEnsembleProvider);
+        ensembleTracker = new EnsembleTracker(client);
+        ensembleTracker.getListenable().addListener(waitOnDelegateListener);
+        ensembleTracker.start();
+        //Wait for the initial event.
+        waitOnDelegateListener.waitForEvent();
+    }
+
+    @AfterMethod
+    public void tearDown() throws IOException
+    {
+        CloseableUtils.closeQuietly(ensembleTracker);
+        CloseableUtils.closeQuietly(client);
+        CloseableUtils.closeQuietly(cluster);
+    }
+
+    @Test
+    public void testSyncIncremental() throws Exception
+    {
+        Stat stat = new Stat();
+        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
+        Assert.assertNotNull(bytes);
+        QuorumVerifier qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+        String server1 = getServerString(qv, cluster, 1L);
+        String server2 = getServerString(qv, cluster, 2L);
+
+        //Remove Servers
+        bytes = client.reconfig().leaving("1").storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+
+        bytes = client.reconfig().leaving("2").storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 3);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
+
+        //Add Servers
+        bytes = client.reconfig().joining("server.2=" + server2).storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+
+        bytes = client.reconfig().joining("server.1=" + server1).storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+    }
+
+    @Test
+    public void testAsyncIncremental() throws Exception
+    {
+        final AtomicReference<byte[]> bytes = new AtomicReference<>();
+        final BackgroundCallback callback = new BackgroundCallback()
+        {
+            @Override
+            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
+            {
+                bytes.set(event.getData());
+                //We only need the latch on getConfig.
+                if ( event.getContext() != null )
+                {
+                    ((CountDownLatch)event.getContext()).countDown();
+                }
+            }
+
+        };
+
+        CountDownLatch latch = new CountDownLatch(1);
+        client.getConfig().inBackground(callback, latch).forEnsemble();
+        Assert.assertTrue(timing.awaitLatch(latch));
+        Assert.assertNotNull(bytes.get());
+        QuorumVerifier qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+        String server1 = getServerString(qv, cluster, 1L);
+        String server2 = getServerString(qv, cluster, 2L);
+
+        //Remove Servers
+        client.reconfig().inBackground(callback).leaving("1").fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        client.reconfig().inBackground(callback, latch).leaving("2").fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 3);
+
+        //Add Servers
+        client.reconfig().inBackground(callback, latch).joining("server.2=" + server2).fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        client.reconfig().inBackground(callback, latch).joining("server.1=" + server1).fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+    }
+
+    @Test
+    public void testSyncNonIncremental() throws Exception
+    {
+        Stat stat = new Stat();
+        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
+        Assert.assertNotNull(bytes);
+        QuorumVerifier qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+        String server1 = getServerString(qv, cluster, 1L);
+        String server2 = getServerString(qv, cluster, 2L);
+        String server3 = getServerString(qv, cluster, 3L);
+        String server4 = getServerString(qv, cluster, 4L);
+        String server5 = getServerString(qv, cluster, 5L);
+
+        //Remove Servers
+        bytes = client.reconfig()
+            .adding("server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+
+        bytes = client.reconfig()
+            .adding("server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 3);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
+
+        //Add Servers
+        bytes = client.reconfig()
+            .adding("server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+
+        bytes = client.reconfig()
+            .adding("server.1=" + server1,
+                "server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
+        qv = getQuorumVerifier(bytes);
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+    }
+
+    @Test
+    public void testAsyncNonIncremental() throws Exception
+    {
+        final AtomicReference<byte[]> bytes = new AtomicReference<>();
+        final BackgroundCallback callback = new BackgroundCallback()
+        {
+            @Override
+            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
+            {
+                bytes.set(event.getData());
+                ((CountDownLatch)event.getContext()).countDown();
+            }
+
+        };
+
+        CountDownLatch latch = new CountDownLatch(1);
+        client.getConfig().inBackground(callback, latch).forEnsemble();
+        Assert.assertTrue(timing.awaitLatch(latch));
+        Assert.assertNotNull(bytes.get());
+        QuorumVerifier qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+        String server1 = getServerString(qv, cluster, 1L);
+        String server2 = getServerString(qv, cluster, 2L);
+        String server3 = getServerString(qv, cluster, 3L);
+        String server4 = getServerString(qv, cluster, 4L);
+        String server5 = getServerString(qv, cluster, 5L);
+
+        //Remove Servers
+        client.reconfig().inBackground(callback, latch)
+            .adding("server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        client.reconfig().inBackground(callback, latch)
+            .adding("server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 3);
+
+        //Add Servers
+        client.reconfig().inBackground(callback, latch)
+            .adding("server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 4);
+
+        client.reconfig().inBackground(callback, latch)
+            .adding("server.1=" + server1,
+                "server.2=" + server2,
+                "server.3=" + server3,
+                "server.4=" + server4,
+                "server.5=" + server5)
+            .fromConfig(qv.getVersion()).forEnsemble();
+        waitOnDelegateListener.waitForEvent();
+        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
+        qv = getQuorumVerifier(bytes.get());
+        Assert.assertEquals(qv.getAllMembers().size(), 5);
+    }
+
+    static QuorumVerifier getQuorumVerifier(byte[] bytes) throws Exception
+    {
+        Properties properties = new Properties();
+        properties.load(new StringReader(new String(bytes)));
+        return new QuorumMaj(properties);
+    }
+
+    static InstanceSpec getInstance(TestingCluster cluster, int id)
+    {
+        for ( InstanceSpec spec : cluster.getInstances() )
+        {
+            if ( spec.getServerId() == id )
+            {
+                return spec;
+            }
+        }
+        throw new IllegalStateException("InstanceSpec with id:" + id + " not found");
+    }
+
+    static String getServerString(QuorumVerifier qv, TestingCluster cluster, long id) throws Exception
+    {
+        String str = qv.getAllMembers().get(id).toString();
+        //check if connection string is already there.
+        if ( str.contains(";") )
+        {
+            return str;
+        }
+        else
+        {
+            return str + ";" + getInstance(cluster, (int)id).getConnectString();
+        }
+    }
+
+    static String getConnectionString(TestingCluster cluster, long... ids) throws Exception
+    {
+        StringBuilder sb = new StringBuilder();
+        Map<Long, InstanceSpec> specs = new HashMap<>();
+        for ( InstanceSpec spec : cluster.getInstances() )
+        {
+            specs.put((long)spec.getServerId(), spec);
+        }
+        for ( long id : ids )
+        {
+            if ( sb.length() != 0 )
+            {
+                sb.append(",");
+            }
+            sb.append(specs.get(id).getConnectString());
+        }
+        return sb.toString();
+    }
+
+    //Simple EnsembleListener that can wait until the delegate handles the event.
+    private static class WaitOnDelegateListener implements EnsembleListener
+    {
+        private CountDownLatch latch = new CountDownLatch(1);
+
+        private final EnsembleListener delegate;
+
+        private WaitOnDelegateListener(EnsembleListener delegate)
+        {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void connectionStringUpdated(String connectionString)
+        {
+            delegate.connectionStringUpdated(connectionString);
+            latch.countDown();
+        }
+
+        public void waitForEvent() throws InterruptedException, TimeoutException
+        {
+            if ( timing.awaitLatch(latch) )
+            {
+                latch = new CountDownLatch(1);
+            }
+            else
+            {
+                throw new TimeoutException("Failed to receive event in time.");
+            }
+        }
+    }
+}
\ No newline at end of file


[03/10] curator git commit: wip - adding() API was misnamed. Also, it's mutually exclusive with join/leave

Posted by ra...@apache.org.
wip - adding() API was misnamed. Also, it's mutually exclusive with join/leave


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

Branch: refs/heads/CURATOR-3.0
Commit: d42ef172e57af17ed42d7c2c4e2d9a7a0c520f3c
Parents: 4c3c837
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 21:07:44 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 21:07:44 2015 -0500

----------------------------------------------------------------------
 .../api/JoinStatConfigEnsembleable.java         |   2 +-
 .../api/LeaveStatConfigEnsembleable.java        |   2 +-
 .../curator/framework/api/Membersable.java      |  43 +++
 .../framework/api/ReconfigBuilderMain.java      |   6 +-
 .../api/StatConfigureEnsembleable.java          |  26 ++
 .../framework/imps/ReconfigBuilderImpl.java     | 370 +++----------------
 .../framework/imps/TestReconfiguration.java     | 205 +++++++---
 .../framework/imps/TestReconfigurationX.java    |  33 +-
 .../org/apache/curator/test/TestingCluster.java |  40 +-
 9 files changed, 337 insertions(+), 390 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
index 7ab51e2..c20387c 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
@@ -25,7 +25,7 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface JoinStatConfigEnsembleable extends
-    Joinable<ConfigureEnsembleable>,
+    Joinable<LeaveStatConfigEnsembleable>,
     ConfigureEnsembleable,
     Statable<ConfigureEnsembleable>
 {

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
index 1464d26..b80bd00 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
@@ -25,7 +25,7 @@ package org.apache.curator.framework.api;
  * mixing concepts that can't be used together.
  */
 public interface LeaveStatConfigEnsembleable extends
-    Leaveable<Statable<ConfigureEnsembleable>>,
+    Leaveable<JoinStatConfigEnsembleable>,
     ConfigureEnsembleable,
     Statable<ConfigureEnsembleable>
 {

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/api/Membersable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Membersable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Membersable.java
new file mode 100644
index 0000000..e1f8d9e
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/Membersable.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.api;
+
+import java.util.List;
+
+public interface Membersable<T>
+{
+    /**
+     * Sets one or more members that are meant to be the ensemble.
+     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
+     *
+     * @param server The server joining.
+     * @return this
+     */
+    T withNewMembers(String... server);
+
+    /**
+     * Sets one or more members that are meant to be the ensemble.
+     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
+     *
+     * @param servers The servers joining.
+     * @return this
+     */
+    T withNewMembers(List<String> servers);
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
index b86af2d..b9d1be3 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
@@ -20,8 +20,8 @@
 package org.apache.curator.framework.api;
 
 public interface ReconfigBuilderMain extends
-    Joinable<LeaveAddStatConfigEnsembleable>,
-    Leaveable<JoinAddStatConfigEnsembleable>,
-    Addable<JoinLeaveStatConfigEnsembleable>
+    Joinable<LeaveStatConfigEnsembleable>,
+    Leaveable<JoinStatConfigEnsembleable>,
+    Membersable<StatConfigureEnsembleable>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigureEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigureEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigureEnsembleable.java
new file mode 100644
index 0000000..8b61ab9
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigureEnsembleable.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.api;
+
+public interface StatConfigureEnsembleable extends
+    Statable<ConfigureEnsembleable>,
+    ConfigureEnsembleable
+{
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
index 832272b..e786883 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
@@ -31,18 +31,14 @@ import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
 
-public class ReconfigBuilderImpl implements
-    ReconfigBuilder,
-    ReconfigBuilderMain,
-    ConfigureEnsembleable,
-    BackgroundOperation<Void>,Statable<Ensembleable<byte[]>>,Ensembleable<byte[]>
+public class ReconfigBuilderImpl implements ReconfigBuilder, BackgroundOperation<Void>
 {
     private final CuratorFrameworkImpl client;
 
     private Backgrounding backgrounding = new Backgrounding();
     private Stat responseStat;
     private long fromConfig = -1;
-    private List<String> adding;
+    private List<String> newMembers;
     private List<String> joining;
     private List<String> leaving;
 
@@ -51,8 +47,7 @@ public class ReconfigBuilderImpl implements
         this.client = client;
     }
 
-    @Override
-    public byte[] forEnsemble() throws Exception
+    private byte[] forEnsemble() throws Exception
     {
         if ( backgrounding.inBackground() )
         {
@@ -66,152 +61,6 @@ public class ReconfigBuilderImpl implements
     }
 
     @Override
-    public Ensembleable<byte[]> storingStatIn(Stat stat)
-    {
-        responseStat = stat;
-        return this;
-    }
-
-    @Override
-    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-    {
-        fromConfig = config;
-        return this;
-    }
-
-    @Override
-    public JoinLeaveStatConfigEnsembleable adding(String... server)
-    {
-        return adding((server != null) ? Arrays.asList(server) : null);
-    }
-
-    @Override
-    public JoinLeaveStatConfigEnsembleable adding(List<String> servers)
-    {
-        this.adding = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
-
-        return new JoinLeaveStatConfigEnsembleable()
-        {
-            @Override
-            public byte[] forEnsemble() throws Exception
-            {
-                return ReconfigBuilderImpl.this.forEnsemble();
-            }
-
-            @Override
-            public ConfigureEnsembleable storingStatIn(Stat stat)
-            {
-                return new ConfigureEnsembleable()
-                {
-                    @Override
-                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
-                    }
-
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-                };
-            }
-
-            @Override
-            public Ensembleable<byte[]> fromConfig(long config) throws Exception
-            {
-                return ReconfigBuilderImpl.this.fromConfig(config);
-            }
-
-            @Override
-            public LeaveStatConfigEnsembleable joining(String... server)
-            {
-                return joining((server != null) ? Arrays.asList(server) : null);
-            }
-
-            @Override
-            public LeaveStatConfigEnsembleable joining(List<String> servers)
-            {
-                return new LeaveStatConfigEnsembleable()
-                {
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable storingStatIn(Stat stat)
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> leaving(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.leaving(servers);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> leaving(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.leaving(server);
-                    }
-                };
-            }
-
-            @Override
-            public JoinStatConfigEnsembleable leaving(String... server)
-            {
-                return leaving((server != null) ? Arrays.asList(server) : null);
-            }
-
-            @Override
-            public JoinStatConfigEnsembleable leaving(List<String> servers)
-            {
-                return new JoinStatConfigEnsembleable()
-                {
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable storingStatIn(Stat stat)
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable joining(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.joining(servers);
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable joining(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.joining(server);
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
     public ReconfigBuilderMain inBackground()
     {
         backgrounding = new Backgrounding(true);
@@ -254,19 +103,25 @@ public class ReconfigBuilderImpl implements
     }
 
     @Override
-    public LeaveAddStatConfigEnsembleable joining(String... server)
+    public StatConfigureEnsembleable withNewMembers(String... server)
     {
-        return joining((server != null) ? Arrays.asList(server) : null);
+        return withNewMembers((server != null) ? Arrays.asList(server) : null);
     }
 
     @Override
-    public LeaveAddStatConfigEnsembleable joining(List<String> servers)
+    public StatConfigureEnsembleable withNewMembers(List<String> servers)
     {
-        joining = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
-
-        return new LeaveAddStatConfigEnsembleable()
+        newMembers = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
+        return new StatConfigureEnsembleable()
         {
             @Override
+            public Ensembleable<byte[]> fromConfig(long config) throws Exception
+            {
+                fromConfig = config;
+                return this;
+            }
+
+            @Override
             public byte[] forEnsemble() throws Exception
             {
                 return ReconfigBuilderImpl.this.forEnsemble();
@@ -275,115 +130,71 @@ public class ReconfigBuilderImpl implements
             @Override
             public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return new InternalConfigureEnsembleable();
+                responseStat = stat;
+                return this;
             }
+        };
+    }
+
+    @Override
+    public LeaveStatConfigEnsembleable joining(String... server)
+    {
+        return joining((server != null) ? Arrays.asList(server) : null);
+    }
+
+    @Override
+    public LeaveStatConfigEnsembleable joining(List<String> servers)
+    {
+        joining = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
 
+        return new LeaveStatConfigEnsembleable()
+        {
             @Override
-            public Ensembleable<byte[]> fromConfig(long config) throws Exception
+            public byte[] forEnsemble() throws Exception
             {
-                return ReconfigBuilderImpl.this.fromConfig(config);
+                return ReconfigBuilderImpl.this.forEnsemble();
             }
 
             @Override
-            public LeaveStatConfigEnsembleable adding(String... server)
+            public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return adding((server != null) ? Arrays.asList(server) : null);
+                responseStat = stat;
+                return this;
             }
 
             @Override
-            public LeaveStatConfigEnsembleable adding(List<String> servers)
+            public Ensembleable<byte[]> fromConfig(long config) throws Exception
             {
-                return new LeaveStatConfigEnsembleable()
-                {
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable storingStatIn(Stat stat)
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> leaving(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.leaving(servers);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> leaving(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.leaving(server);
-                    }
-                };
+                fromConfig = config;
+                return this;
             }
 
             @Override
-            public AddStatConfigEnsembleable leaving(String... server)
+            public JoinStatConfigEnsembleable leaving(String... server)
             {
-                return leaving((server != null) ? Arrays.asList(server) : null);
+                return ReconfigBuilderImpl.this.leaving(server);
             }
 
             @Override
-            public AddStatConfigEnsembleable leaving(List<String> servers)
+            public JoinStatConfigEnsembleable leaving(List<String> servers)
             {
-                return new AddStatConfigEnsembleable()
-                {
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable storingStatIn(Stat stat)
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable fromConfig(long config) throws Exception
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> adding(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.adding(servers);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> adding(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.adding(server);
-                    }
-                };
+                return ReconfigBuilderImpl.this.leaving(servers);
             }
         };
     }
 
     @Override
-    public JoinAddStatConfigEnsembleable leaving(String... server)
+    public JoinStatConfigEnsembleable leaving(String... server)
     {
         return leaving((server != null) ? Arrays.asList(server) : null);
     }
 
     @Override
-    public JoinAddStatConfigEnsembleable leaving(List<String> servers)
+    public JoinStatConfigEnsembleable leaving(List<String> servers)
     {
         leaving = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
 
-        return new JoinAddStatConfigEnsembleable()
+        return new JoinStatConfigEnsembleable()
         {
             @Override
             public byte[] forEnsemble() throws Exception
@@ -394,81 +205,27 @@ public class ReconfigBuilderImpl implements
             @Override
             public ConfigureEnsembleable storingStatIn(Stat stat)
             {
-                return new InternalConfigureEnsembleable();
+                responseStat = stat;
+                return this;
             }
 
             @Override
             public Ensembleable<byte[]> fromConfig(long config) throws Exception
             {
-                return ReconfigBuilderImpl.this.fromConfig(config);
+                fromConfig = config;
+                return this;
             }
 
             @Override
-            public JoinStatConfigurable adding(String... server)
-            {
-                return adding((server != null) ? Arrays.asList(server) : null);
-            }
-
-            @Override
-            public JoinStatConfigurable adding(List<String> servers)
-            {
-                return new JoinStatConfigurable()
-                {
-                    @Override
-                    public ConfigureEnsembleable joining(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.joining(servers);
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable joining(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.joining(server);
-                    }
-                };
-            }
-
-            @Override
-            public AddStatConfigEnsembleable joining(String... server)
+            public LeaveStatConfigEnsembleable joining(String... server)
             {
                 return joining((server != null) ? Arrays.asList(server) : null);
             }
 
             @Override
-            public AddStatConfigEnsembleable joining(List<String> servers)
+            public LeaveStatConfigEnsembleable joining(List<String> servers)
             {
-                return new AddStatConfigEnsembleable()
-                {
-                    @Override
-                    public byte[] forEnsemble() throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.forEnsemble();
-                    }
-
-                    @Override
-                    public ConfigureEnsembleable storingStatIn(Stat stat)
-                    {
-                        return new InternalConfigureEnsembleable();
-                    }
-
-                    @Override
-                    public Ensembleable<byte[]> fromConfig(long config) throws Exception
-                    {
-                        return ReconfigBuilderImpl.this.fromConfig(config);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> adding(List<String> servers)
-                    {
-                        return ReconfigBuilderImpl.this.adding(servers);
-                    }
-
-                    @Override
-                    public Statable<ConfigureEnsembleable> adding(String... server)
-                    {
-                        return ReconfigBuilderImpl.this.adding(server);
-                    }
-                };
+                return ReconfigBuilderImpl.this.joining(servers);
             }
         };
     }
@@ -491,7 +248,7 @@ public class ReconfigBuilderImpl implements
                 client.processBackgroundOperation(data, event);
             }
         };
-        client.getZooKeeper().reconfig(joining, leaving, adding, fromConfig, callback, backgrounding.getContext());
+        client.getZooKeeper().reconfig(joining, leaving, newMembers, fromConfig, callback, backgrounding.getContext());
     }
 
     private byte[] ensembleInForeground() throws Exception
@@ -505,26 +262,11 @@ public class ReconfigBuilderImpl implements
                     @Override
                     public byte[] call() throws Exception
                     {
-                        return client.getZooKeeper().reconfig(joining, leaving, adding, fromConfig, responseStat);
+                        return client.getZooKeeper().reconfig(joining, leaving, newMembers, fromConfig, responseStat);
                     }
                 }
             );
         trace.commit();
         return responseData;
     }
-
-    private class InternalConfigureEnsembleable implements ConfigureEnsembleable
-    {
-        @Override
-        public Ensembleable<byte[]> fromConfig(long config) throws Exception
-        {
-            return ReconfigBuilderImpl.this.fromConfig(config);
-        }
-
-        @Override
-        public byte[] forEnsemble() throws Exception
-        {
-            return ReconfigBuilderImpl.this.forEnsemble();
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
index d4c89be..99e5a2e 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
@@ -19,12 +19,17 @@
 
 package org.apache.curator.framework.imps;
 
+import com.google.common.collect.Lists;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.api.BackgroundCallback;
+import org.apache.curator.framework.api.CuratorEvent;
+import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.retry.RetryOneTime;
 import org.apache.curator.test.BaseClassForTests;
 import org.apache.curator.test.InstanceSpec;
 import org.apache.curator.test.TestingCluster;
+import org.apache.curator.test.Timing;
 import org.apache.curator.utils.CloseableUtils;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
@@ -37,7 +42,12 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
 
 public class TestReconfiguration extends BaseClassForTests
 {
@@ -84,75 +94,53 @@ public class TestReconfiguration extends BaseClassForTests
 
         // ---------
 
-        client.reconfig().adding().forEnsemble();
         client.reconfig().leaving().forEnsemble();
         client.reconfig().joining().forEnsemble();
-        client.reconfig().adding().leaving().forEnsemble();
-        client.reconfig().adding().joining().forEnsemble();
         client.reconfig().leaving().joining().forEnsemble();
+        client.reconfig().joining().leaving().forEnsemble();
+        client.reconfig().withNewMembers().forEnsemble();
 
-        client.reconfig().adding().fromConfig(0).forEnsemble();
         client.reconfig().leaving().fromConfig(0).forEnsemble();
         client.reconfig().joining().fromConfig(0).forEnsemble();
-        client.reconfig().adding().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().adding().joining().fromConfig(0).forEnsemble();
         client.reconfig().leaving().joining().fromConfig(0).forEnsemble();
+        client.reconfig().joining().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().withNewMembers().fromConfig(0).forEnsemble();
 
-        client.reconfig().adding().fromConfig(0).forEnsemble();
-        client.reconfig().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().joining().fromConfig(0).forEnsemble();
-        client.reconfig().adding().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().adding().joining().fromConfig(0).forEnsemble();
-        client.reconfig().leaving().joining().fromConfig(0).forEnsemble();
-
-        client.reconfig().adding().storingStatIn(stat).forEnsemble();
         client.reconfig().leaving().storingStatIn(stat).forEnsemble();
         client.reconfig().joining().storingStatIn(stat).forEnsemble();
-        client.reconfig().adding().leaving().storingStatIn(stat).forEnsemble();
-        client.reconfig().adding().joining().storingStatIn(stat).forEnsemble();
         client.reconfig().leaving().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().joining().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().withNewMembers().storingStatIn(stat).forEnsemble();
 
-        client.reconfig().adding().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().adding().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().adding().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().joining().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().withNewMembers().storingStatIn(stat).forEnsemble();
 
-        client.reconfig().inBackground().adding().forEnsemble();
         client.reconfig().inBackground().leaving().forEnsemble();
         client.reconfig().inBackground().joining().forEnsemble();
-        client.reconfig().inBackground().adding().leaving().forEnsemble();
-        client.reconfig().inBackground().adding().joining().forEnsemble();
         client.reconfig().inBackground().leaving().joining().forEnsemble();
+        client.reconfig().inBackground().joining().leaving().forEnsemble();
+        client.reconfig().inBackground().withNewMembers().forEnsemble();
 
-        client.reconfig().inBackground().adding().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().joining().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().joining().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().leaving().joining().fromConfig(0).forEnsemble();
-
-        client.reconfig().inBackground().adding().fromConfig(0).forEnsemble();
         client.reconfig().inBackground().leaving().fromConfig(0).forEnsemble();
         client.reconfig().inBackground().joining().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().leaving().fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().joining().fromConfig(0).forEnsemble();
         client.reconfig().inBackground().leaving().joining().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().joining().leaving().fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().withNewMembers().fromConfig(0).forEnsemble();
 
-        client.reconfig().inBackground().adding().storingStatIn(stat).forEnsemble();
         client.reconfig().inBackground().leaving().storingStatIn(stat).forEnsemble();
         client.reconfig().inBackground().joining().storingStatIn(stat).forEnsemble();
-        client.reconfig().inBackground().adding().leaving().storingStatIn(stat).forEnsemble();
-        client.reconfig().inBackground().adding().joining().storingStatIn(stat).forEnsemble();
         client.reconfig().inBackground().leaving().joining().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().joining().leaving().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().withNewMembers().storingStatIn(stat).forEnsemble();
 
-        client.reconfig().inBackground().adding().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().inBackground().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().inBackground().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().adding().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().inBackground().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().joining().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
+        client.reconfig().inBackground().withNewMembers().storingStatIn(stat).forEnsemble();
     }
 
     @Test
@@ -163,33 +151,154 @@ public class TestReconfiguration extends BaseClassForTests
             client.start();
             QuorumVerifier quorumVerifier = toQuorumVerifier(client.getConfig().forEnsemble());
             System.out.println(quorumVerifier);
+            assertConfig(quorumVerifier, cluster.getInstances());
+        }
+    }
+
+    @Test
+    public void testAdd() throws Exception
+    {
+        Timing timing = new Timing();
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        {
+            client.start();
+
+            QuorumVerifier oldConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            assertConfig(oldConfig, cluster.getInstances());
 
-            for ( InstanceSpec instance : cluster.getInstances() )
+            CountDownLatch latch = setChangeWaiter(client);
+            try ( TestingCluster newCluster = new TestingCluster(1, false) )
             {
-                QuorumPeer.QuorumServer quorumServer = quorumVerifier.getAllMembers().get((long)instance.getServerId());
-                Assert.assertNotNull(quorumServer);
-                Assert.assertEquals(quorumServer.clientAddr.getPort(), instance.getPort());
+                newCluster.start();
+
+                client.reconfig().joining(toReconfigSpec(newCluster.getInstances())).fromConfig(oldConfig.getVersion()).forEnsemble();
+
+                Assert.assertTrue(timing.awaitLatch(latch));
+
+                QuorumVerifier newConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+                List<InstanceSpec> newInstances = Lists.newArrayList(cluster.getInstances());
+                newInstances.addAll(newCluster.getInstances());
+                assertConfig(newConfig, newInstances);
             }
         }
     }
 
     @Test
-    public void testAdd1Sync() throws Exception
+    public void testAddAsync() throws Exception
     {
+        Timing timing = new Timing();
         try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
         {
             client.start();
 
-            Watcher watcher = new Watcher()
+            QuorumVerifier oldConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            assertConfig(oldConfig, cluster.getInstances());
+
+            CountDownLatch latch = setChangeWaiter(client);
+            try ( TestingCluster newCluster = new TestingCluster(1, false) )
             {
-                @Override
-                public void process(WatchedEvent event)
+                newCluster.start();
+
+                final CountDownLatch callbackLatch = new CountDownLatch(1);
+                BackgroundCallback callback = new BackgroundCallback()
                 {
+                    @Override
+                    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
+                    {
+                        if ( event.getType() == CuratorEventType.RECONFIG )
+                        {
+                            callbackLatch.countDown();
+                        }
+                    }
+                };
+                client.reconfig().inBackground(callback).joining(toReconfigSpec(newCluster.getInstances())).fromConfig(oldConfig.getVersion()).forEnsemble();
+
+                Assert.assertTrue(timing.awaitLatch(callbackLatch));
+                Assert.assertTrue(timing.awaitLatch(latch));
 
+                QuorumVerifier newConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+                List<InstanceSpec> newInstances = Lists.newArrayList(cluster.getInstances());
+                newInstances.addAll(newCluster.getInstances());
+                assertConfig(newConfig, newInstances);
+            }
+        }
+    }
+
+    @Test
+    public void testAddAndRemove() throws Exception
+    {
+        Timing timing = new Timing();
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        {
+            client.start();
+
+            QuorumVerifier oldConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            assertConfig(oldConfig, cluster.getInstances());
+
+            CountDownLatch latch = setChangeWaiter(client);
+
+            try ( TestingCluster newCluster = new TestingCluster(1, false) )
+            {
+                newCluster.start();
+
+                Collection<InstanceSpec> oldInstances = cluster.getInstances();
+                InstanceSpec us = cluster.findConnectionInstance(client.getZookeeperClient().getZooKeeper());
+                InstanceSpec removeSpec = oldInstances.iterator().next();
+                if ( us.equals(removeSpec) ) {
+                    Iterator<InstanceSpec> iterator = oldInstances.iterator();
+                    iterator.next();
+                    removeSpec = iterator.next();
                 }
-            };
-            client.getConfig().usingWatcher(watcher).forEnsemble();
+
+                Collection<InstanceSpec> instances = newCluster.getInstances();
+                client.reconfig().leaving(Integer.toString(removeSpec.getServerId())).joining(toReconfigSpec(instances)).fromConfig(oldConfig.getVersion()).forEnsemble();
+
+                Assert.assertTrue(timing.awaitLatch(latch));
+
+                QuorumVerifier newConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+                ArrayList<InstanceSpec> newInstances = Lists.newArrayList(oldInstances);
+                newInstances.addAll(instances);
+                newInstances.remove(removeSpec);
+                assertConfig(newConfig, newInstances);
+            }
+        }
+    }
+
+    private CountDownLatch setChangeWaiter(CuratorFramework client) throws Exception
+    {
+        final CountDownLatch latch = new CountDownLatch(1);
+        Watcher watcher = new Watcher()
+        {
+            @Override
+            public void process(WatchedEvent event)
+            {
+                if ( event.getType() == Event.EventType.NodeDataChanged )
+                {
+                    latch.countDown();
+                }
+            }
+        };
+        client.getConfig().usingWatcher(watcher).forEnsemble();
+        return latch;
+    }
+
+    private void assertConfig(QuorumVerifier config, Collection<InstanceSpec> instances)
+    {
+        for ( InstanceSpec instance : instances )
+        {
+            QuorumPeer.QuorumServer quorumServer = config.getAllMembers().get((long)instance.getServerId());
+            Assert.assertNotNull(quorumServer, String.format("Looking for %s - found %s", instance.getServerId(), config.getAllMembers()));
+            Assert.assertEquals(quorumServer.clientAddr.getPort(), instance.getPort());
+        }
+    }
+
+    private List<String> toReconfigSpec(Collection<InstanceSpec> instances)
+    {
+        List<String> specs = Lists.newArrayList();
+        for ( InstanceSpec instance : instances ) {
+            specs.add("server." + instance.getServerId() + "=localhost:" + instance.getElectionPort() + ":" + instance.getQuorumPort() + ";" + instance.getPort());
         }
+        return specs;
     }
 
     private static QuorumVerifier toQuorumVerifier(byte[] bytes) throws Exception

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
index 2268055..7554ddd 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
@@ -19,6 +19,7 @@
 
 package org.apache.curator.framework.imps;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.curator.ensemble.EnsembleListener;
 import org.apache.curator.ensemble.dynamic.DynamicEnsembleProvider;
 import org.apache.curator.framework.CuratorFramework;
@@ -63,7 +64,13 @@ public class TestReconfigurationX
     @BeforeMethod
     public void setup() throws Exception
     {
-        cluster = new TestingCluster(5);
+        ImmutableList.Builder<InstanceSpec> builder = ImmutableList.builder();
+        for ( int i = 1; i <= 5; ++i )
+        {
+            builder.add(new InstanceSpec(null, -1, -1, -1, true, i, -1, -1));
+        }
+
+        cluster = new TestingCluster(builder.build());
         cluster.start();
 
         connectionString1to5 = cluster.getConnectString();
@@ -208,7 +215,7 @@ public class TestReconfigurationX
 
         //Remove Servers
         bytes = client.reconfig()
-            .adding("server.2=" + server2,
+            .withNewMembers("server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
@@ -220,7 +227,7 @@ public class TestReconfigurationX
         Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
 
         bytes = client.reconfig()
-            .adding("server.3=" + server3,
+            .withNewMembers("server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
             .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
@@ -233,7 +240,7 @@ public class TestReconfigurationX
 
         //Add Servers
         bytes = client.reconfig()
-            .adding("server.2=" + server2,
+            .withNewMembers("server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
@@ -245,7 +252,7 @@ public class TestReconfigurationX
         Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
 
         bytes = client.reconfig()
-            .adding("server.1=" + server1,
+            .withNewMembers("server.1=" + server1,
                 "server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
@@ -287,7 +294,7 @@ public class TestReconfigurationX
 
         //Remove Servers
         client.reconfig().inBackground(callback, latch)
-            .adding("server.2=" + server2,
+            .withNewMembers("server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
@@ -298,7 +305,7 @@ public class TestReconfigurationX
         Assert.assertEquals(qv.getAllMembers().size(), 4);
 
         client.reconfig().inBackground(callback, latch)
-            .adding("server.3=" + server3,
+            .withNewMembers("server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
             .fromConfig(qv.getVersion()).forEnsemble();
@@ -309,7 +316,7 @@ public class TestReconfigurationX
 
         //Add Servers
         client.reconfig().inBackground(callback, latch)
-            .adding("server.2=" + server2,
+            .withNewMembers("server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
                 "server.5=" + server5)
@@ -320,7 +327,7 @@ public class TestReconfigurationX
         Assert.assertEquals(qv.getAllMembers().size(), 4);
 
         client.reconfig().inBackground(callback, latch)
-            .adding("server.1=" + server1,
+            .withNewMembers("server.1=" + server1,
                 "server.2=" + server2,
                 "server.3=" + server3,
                 "server.4=" + server4,
@@ -332,14 +339,14 @@ public class TestReconfigurationX
         Assert.assertEquals(qv.getAllMembers().size(), 5);
     }
 
-    static QuorumVerifier getQuorumVerifier(byte[] bytes) throws Exception
+    private static QuorumVerifier getQuorumVerifier(byte[] bytes) throws Exception
     {
         Properties properties = new Properties();
         properties.load(new StringReader(new String(bytes)));
         return new QuorumMaj(properties);
     }
 
-    static InstanceSpec getInstance(TestingCluster cluster, int id)
+    private static InstanceSpec getInstance(TestingCluster cluster, int id)
     {
         for ( InstanceSpec spec : cluster.getInstances() )
         {
@@ -351,7 +358,7 @@ public class TestReconfigurationX
         throw new IllegalStateException("InstanceSpec with id:" + id + " not found");
     }
 
-    static String getServerString(QuorumVerifier qv, TestingCluster cluster, long id) throws Exception
+    private static String getServerString(QuorumVerifier qv, TestingCluster cluster, long id) throws Exception
     {
         String str = qv.getAllMembers().get(id).toString();
         //check if connection string is already there.
@@ -365,7 +372,7 @@ public class TestReconfigurationX
         }
     }
 
-    static String getConnectionString(TestingCluster cluster, long... ids) throws Exception
+    private static String getConnectionString(TestingCluster cluster, long... ids) throws Exception
     {
         StringBuilder sb = new StringBuilder();
         Map<Long, InstanceSpec> specs = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/curator/blob/d42ef172/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
----------------------------------------------------------------------
diff --git a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
index e2a1ae8..b8dada8 100644
--- a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
+++ b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
@@ -52,6 +52,18 @@ public class TestingCluster implements Closeable
     }
 
     /**
+     * Creates an ensemble comprised of <code>n</code> servers. Each server will use
+     * a temp directory and random ports
+     *
+     * @param instanceQty number of servers to create in the ensemble
+     * @param resetServerIds if true, server Ids are reset first
+     */
+    public TestingCluster(int instanceQty, boolean resetServerIds)
+    {
+        this(makeSpecs(instanceQty, resetServerIds));
+    }
+
+    /**
      * Creates an ensemble using the given server specs
      *
      * @param specs the server specs
@@ -99,17 +111,17 @@ public class TestingCluster implements Closeable
     public Collection<InstanceSpec> getInstances()
     {
         Iterable<InstanceSpec> transformed = Iterables.transform
-        (
-            servers,
-            new Function<TestingZooKeeperServer, InstanceSpec>()
-            {
-                @Override
-                public InstanceSpec apply(TestingZooKeeperServer server)
+            (
+                servers,
+                new Function<TestingZooKeeperServer, InstanceSpec>()
                 {
-                    return server.getInstanceSpec();
+                    @Override
+                    public InstanceSpec apply(TestingZooKeeperServer server)
+                    {
+                        return server.getInstanceSpec();
+                    }
                 }
-            }
-        );
+            );
         return Lists.newArrayList(transformed);
     }
 
@@ -244,7 +256,15 @@ public class TestingCluster implements Closeable
 
     private static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty)
     {
-        InstanceSpec.reset();
+        return makeSpecs(instanceQty, true);
+    }
+
+    private static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty, boolean resetServerIds)
+    {
+        if ( resetServerIds )
+        {
+            InstanceSpec.reset();
+        }
         ImmutableList.Builder<InstanceSpec> builder = ImmutableList.builder();
         for ( int i = 0; i < instanceQty; ++i )
         {


[05/10] curator git commit: missed a few

Posted by ra...@apache.org.
missed a few


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

Branch: refs/heads/CURATOR-3.0
Commit: e09388a5a7cc131643d685fd8efff64da15e168b
Parents: 36ddd58
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 22:00:37 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 22:00:37 2015 -0500

----------------------------------------------------------------------
 .../org/apache/curator/framework/imps/TestReconfiguration.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/e09388a5/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
index 37be4f1..ca00cba 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
@@ -118,7 +118,7 @@ public class TestReconfiguration extends BaseClassForTests
         client.reconfig().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().joining().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().withNewMembers().storingStatIn(stat).forEnsemble();
+        client.reconfig().withNewMembers().storingStatIn(stat).fromConfig(0).forEnsemble();
 
         client.reconfig().inBackground().leaving().forEnsemble();
         client.reconfig().inBackground().joining().forEnsemble();
@@ -142,7 +142,7 @@ public class TestReconfiguration extends BaseClassForTests
         client.reconfig().inBackground().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().inBackground().leaving().joining().storingStatIn(stat).fromConfig(0).forEnsemble();
         client.reconfig().inBackground().joining().leaving().storingStatIn(stat).fromConfig(0).forEnsemble();
-        client.reconfig().inBackground().withNewMembers().storingStatIn(stat).forEnsemble();
+        client.reconfig().inBackground().withNewMembers().storingStatIn(stat).fromConfig(0).forEnsemble();
     }
 
     @Test


[02/10] curator git commit: Merge branch 'CURATOR-3.0' into CURATOR-265

Posted by ra...@apache.org.
Merge branch 'CURATOR-3.0' into CURATOR-265

Conflicts:
	curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java


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

Branch: refs/heads/CURATOR-3.0
Commit: 4c3c8377935f8ae2c0f24c4a1010cf4bdef4e297
Parents: 2c0fca8 afa8f7a
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 19:22:10 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 19:22:10 2015 -0500

----------------------------------------------------------------------
 .../curator/framework/imps/TestFramework.java   |   4 +-
 .../recipes/leader/ChaosMonkeyCnxnFactory.java  |  24 +-
 .../recipes/leader/TestLeaderLatch.java         |   3 +-
 .../locks/TestInterProcessMutexBase.java        |   6 +-
 curator-test/pom.xml                            |   5 -
 .../apache/curator/test/BaseClassForTests.java  |   1 +
 .../apache/curator/test/ByteCodeRewrite.java    | 131 ----------
 .../curator/test/QuorumConfigBuilder.java       |  36 ++-
 .../org/apache/curator/test/TestingCluster.java |   5 -
 .../org/apache/curator/test/TestingServer.java  |   5 -
 .../curator/test/TestingZooKeeperMain.java      | 236 ++++++++++++-------
 .../curator/test/TestingZooKeeperServer.java    |   2 +
 pom.xml                                         |  21 +-
 13 files changed, 218 insertions(+), 261 deletions(-)
----------------------------------------------------------------------



[10/10] curator git commit: Merge branch 'CURATOR-3.0' into CURATOR-265

Posted by ra...@apache.org.
Merge branch 'CURATOR-3.0' into CURATOR-265


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

Branch: refs/heads/CURATOR-3.0
Commit: 0fe4d969f86836ecfcf27ab1164c422e771d1495
Parents: a7076bc df949e7
Author: randgalt <ra...@apache.org>
Authored: Thu Oct 8 19:09:13 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Thu Oct 8 19:09:13 2015 -0500

----------------------------------------------------------------------
 .../apache/curator/CuratorZookeeperClient.java  |   2 +-
 .../curator/framework/api/CreateBuilder.java    |  65 +----------
 .../framework/api/CreateBuilderMain.java        |  86 ++++++++++++++
 .../curator/framework/api/DeleteBuilder.java    |   4 +-
 .../framework/api/DeleteBuilderMain.java        |  23 ++++
 .../framework/imps/CreateBuilderImpl.java       |  61 ++++++++++
 .../framework/imps/DeleteBuilderImpl.java       |  21 ++++
 .../curator/framework/imps/NamespaceFacade.java |   6 -
 .../curator/framework/imps/TestFramework.java   | 117 +++++++++++++++++++
 9 files changed, 314 insertions(+), 71 deletions(-)
----------------------------------------------------------------------



[04/10] curator git commit: finalized the changes and removed old classes

Posted by ra...@apache.org.
finalized the changes and removed old classes


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

Branch: refs/heads/CURATOR-3.0
Commit: 36ddd58a31045addfd9d984353956f7a99c09221
Parents: d42ef17
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 21:49:12 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 21:49:12 2015 -0500

----------------------------------------------------------------------
 .../framework/api/ACLBackgroundPathable.java    |  25 --
 .../api/ACLVersionBackgroundPathable.java       |  25 --
 .../api/BackgroundPathableQuietly.java          |  23 -
 .../api/CreateModalPathAndBytesable.java        |  25 --
 .../api/IncrementalReconfigBuilder.java         |  33 --
 .../api/JoinAddStatConfigEnsembleable.java      |  34 --
 .../api/JoinLeaveStatConfigEnsembleable.java    |  34 --
 .../framework/api/JoinStatConfigurable.java     |  30 --
 .../api/LeaveAddStatConfigEnsembleable.java     |  33 --
 .../framework/api/SyncReconfigurable.java       |  30 --
 .../framework/imps/TestReconfiguration.java     |  58 ++-
 .../framework/imps/TestReconfigurationX.java    | 425 -------------------
 .../org/apache/curator/test/TestingCluster.java |  16 +-
 13 files changed, 49 insertions(+), 742 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLBackgroundPathable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLBackgroundPathable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ACLBackgroundPathable.java
deleted file mode 100644
index d63281d..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLBackgroundPathable.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * 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.api;
-
-public interface ACLBackgroundPathable<T> extends
-    ACLable<BackgroundPathable<T>>,
-    BackgroundPathable<T>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLVersionBackgroundPathable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLVersionBackgroundPathable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ACLVersionBackgroundPathable.java
deleted file mode 100644
index bc8e6bf..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/ACLVersionBackgroundPathable.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * 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.api;
-
-public interface ACLVersionBackgroundPathable<T> extends
-    ACLable<Versionable<BackgroundPathable<T>>>,
-    Versionable<BackgroundPathable<T>>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/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
deleted file mode 100644
index 13202aa..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundPathableQuietly.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * 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.api;
-
-public interface BackgroundPathableQuietly<T> extends BackgroundPathable<T>, Quietly<BackgroundPathable<T>>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/CreateModalPathAndBytesable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/CreateModalPathAndBytesable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/CreateModalPathAndBytesable.java
deleted file mode 100644
index 94bfe7e..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/CreateModalPathAndBytesable.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * 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.api;
-
-public interface CreateModalPathAndBytesable<T> extends
-    CreateModable<PathAndBytesable<T>>,
-    PathAndBytesable<T>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/IncrementalReconfigBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/IncrementalReconfigBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/IncrementalReconfigBuilder.java
deleted file mode 100644
index 0ad6426..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/IncrementalReconfigBuilder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 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.api;
-
-/**
- * An incremental reconfiguration builder.
- * This builder has access only to the incremental reconfiguration methods join and leave, so that we prevent
- * mixing concepts that can't be used together.
- * @param <T>
- */
-public interface IncrementalReconfigBuilder<T> extends
-        Joinable<IncrementalReconfigBuilder<T>>,
-        Leaveable<IncrementalReconfigBuilder<T>>,
-        DataCallbackable<AsyncReconfigurable>,
-        Statable<SyncReconfigurable> {
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
deleted file mode 100644
index 4356ba7..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.api;
-
-/**
- * An incremental reconfiguration builder.
- * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface JoinAddStatConfigEnsembleable extends
-    Joinable<AddStatConfigEnsembleable>,
-    Addable<JoinStatConfigurable>,
-    ConfigureEnsembleable,
-    Statable<ConfigureEnsembleable>
-{
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
deleted file mode 100644
index fac16a9..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.api;
-
-/**
- * An incremental reconfiguration builder.
- * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface JoinLeaveStatConfigEnsembleable extends
-    Joinable<LeaveStatConfigEnsembleable>,
-    Leaveable<JoinStatConfigEnsembleable>,
-    ConfigureEnsembleable,
-    Statable<ConfigureEnsembleable>
-{
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
deleted file mode 100644
index 18713e4..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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.api;
-
-/**
- * An incremental reconfiguration builder.
- * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface JoinStatConfigurable extends
-    Joinable<ConfigureEnsembleable>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
deleted file mode 100644
index b5125dc..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 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.api;
-
-/**
- * An non-incremental reconfiguration builder.
- * This builder has access only to the non-incremental reconfiguration methods withMembers, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface LeaveAddStatConfigEnsembleable extends
-    Leaveable<AddStatConfigEnsembleable>,
-    Addable<LeaveStatConfigEnsembleable>,
-    ConfigureEnsembleable,
-    Statable<ConfigureEnsembleable>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/main/java/org/apache/curator/framework/api/SyncReconfigurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/SyncReconfigurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/SyncReconfigurable.java
deleted file mode 100644
index bd7b96b..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/SyncReconfigurable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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.api;
-
-public interface SyncReconfigurable  {
-
-    /**
-     * Sets the configuration version to use.
-     * @param config    The version of the configuration.
-     * @return The configuration data.
-     * @throws Exception
-     */
-    byte[] fromConfig(long config) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
index 99e5a2e..37be4f1 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
@@ -25,10 +25,11 @@ import org.apache.curator.framework.CuratorFrameworkFactory;
 import org.apache.curator.framework.api.BackgroundCallback;
 import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
-import org.apache.curator.retry.RetryOneTime;
+import org.apache.curator.retry.ExponentialBackoffRetry;
 import org.apache.curator.test.BaseClassForTests;
 import org.apache.curator.test.InstanceSpec;
 import org.apache.curator.test.TestingCluster;
+import org.apache.curator.test.TestingZooKeeperServer;
 import org.apache.curator.test.Timing;
 import org.apache.curator.utils.CloseableUtils;
 import org.apache.zookeeper.WatchedEvent;
@@ -51,6 +52,7 @@ import java.util.concurrent.CountDownLatch;
 
 public class TestReconfiguration extends BaseClassForTests
 {
+    private final Timing timing = new Timing();
     private TestingCluster cluster;
 
     @BeforeMethod
@@ -146,7 +148,7 @@ public class TestReconfiguration extends BaseClassForTests
     @Test
     public void testBasicGetConfig() throws Exception
     {
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        try ( CuratorFramework client = newClient())
         {
             client.start();
             QuorumVerifier quorumVerifier = toQuorumVerifier(client.getConfig().forEnsemble());
@@ -158,8 +160,7 @@ public class TestReconfiguration extends BaseClassForTests
     @Test
     public void testAdd() throws Exception
     {
-        Timing timing = new Timing();
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        try ( CuratorFramework client = newClient())
         {
             client.start();
 
@@ -167,7 +168,7 @@ public class TestReconfiguration extends BaseClassForTests
             assertConfig(oldConfig, cluster.getInstances());
 
             CountDownLatch latch = setChangeWaiter(client);
-            try ( TestingCluster newCluster = new TestingCluster(1, false) )
+            try ( TestingCluster newCluster = new TestingCluster(TestingCluster.makeSpecs(1, false)) )
             {
                 newCluster.start();
 
@@ -186,8 +187,7 @@ public class TestReconfiguration extends BaseClassForTests
     @Test
     public void testAddAsync() throws Exception
     {
-        Timing timing = new Timing();
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        try ( CuratorFramework client = newClient())
         {
             client.start();
 
@@ -195,7 +195,7 @@ public class TestReconfiguration extends BaseClassForTests
             assertConfig(oldConfig, cluster.getInstances());
 
             CountDownLatch latch = setChangeWaiter(client);
-            try ( TestingCluster newCluster = new TestingCluster(1, false) )
+            try ( TestingCluster newCluster = new TestingCluster(TestingCluster.makeSpecs(1, false)) )
             {
                 newCluster.start();
 
@@ -227,8 +227,7 @@ public class TestReconfiguration extends BaseClassForTests
     @Test
     public void testAddAndRemove() throws Exception
     {
-        Timing timing = new Timing();
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(cluster.getConnectString(), new RetryOneTime(1)) )
+        try ( CuratorFramework client = newClient())
         {
             client.start();
 
@@ -237,7 +236,7 @@ public class TestReconfiguration extends BaseClassForTests
 
             CountDownLatch latch = setChangeWaiter(client);
 
-            try ( TestingCluster newCluster = new TestingCluster(1, false) )
+            try ( TestingCluster newCluster = new TestingCluster(TestingCluster.makeSpecs(1, false)) )
             {
                 newCluster.start();
 
@@ -264,6 +263,43 @@ public class TestReconfiguration extends BaseClassForTests
         }
     }
 
+    @Test
+    public void testNewMembers() throws Exception
+    {
+        cluster.close();
+        cluster = new TestingCluster(5);
+        List<TestingZooKeeperServer> servers = cluster.getServers();
+        List<InstanceSpec> smallCluster = Lists.newArrayList();
+        for ( int i = 0; i < 3; ++i )   // only start 3 of the 5
+        {
+            TestingZooKeeperServer server = servers.get(i);
+            server.start();
+            smallCluster.add(server.getInstanceSpec());
+        }
+
+        try ( CuratorFramework client = newClient())
+        {
+            client.start();
+
+            QuorumVerifier oldConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            Assert.assertEquals(cluster.getInstances().size(), 5);
+            assertConfig(oldConfig, cluster.getInstances());
+
+            CountDownLatch latch = setChangeWaiter(client);
+
+            client.reconfig().withNewMembers(toReconfigSpec(smallCluster)).forEnsemble();
+
+            Assert.assertTrue(timing.awaitLatch(latch));
+            QuorumVerifier newConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            assertConfig(newConfig, smallCluster);
+        }
+    }
+
+    private CuratorFramework newClient()
+    {
+        return CuratorFrameworkFactory.newClient(cluster.getConnectString(), timing.session(), timing.connection(), new ExponentialBackoffRetry(timing.forSleepingABit().milliseconds(), 3));
+    }
+
     private CountDownLatch setChangeWaiter(CuratorFramework client) throws Exception
     {
         final CountDownLatch latch = new CountDownLatch(1);

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
deleted file mode 100644
index 7554ddd..0000000
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfigurationX.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/**
- * 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 com.google.common.collect.ImmutableList;
-import org.apache.curator.ensemble.EnsembleListener;
-import org.apache.curator.ensemble.dynamic.DynamicEnsembleProvider;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.api.BackgroundCallback;
-import org.apache.curator.framework.api.CuratorEvent;
-import org.apache.curator.framework.ensemble.EnsembleTracker;
-import org.apache.curator.retry.RetryOneTime;
-import org.apache.curator.test.InstanceSpec;
-import org.apache.curator.test.TestingCluster;
-import org.apache.curator.test.Timing;
-import org.apache.curator.utils.CloseableUtils;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
-import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class TestReconfigurationX
-{
-    private static final Timing timing = new Timing();
-    private TestingCluster cluster;
-    private DynamicEnsembleProvider dynamicEnsembleProvider;
-    private WaitOnDelegateListener waitOnDelegateListener;
-    private EnsembleTracker ensembleTracker;
-    private CuratorFramework client;
-
-    private String connectionString1to5;
-    private String connectionString2to5;
-    private String connectionString3to5;
-
-    @BeforeMethod
-    public void setup() throws Exception
-    {
-        ImmutableList.Builder<InstanceSpec> builder = ImmutableList.builder();
-        for ( int i = 1; i <= 5; ++i )
-        {
-            builder.add(new InstanceSpec(null, -1, -1, -1, true, i, -1, -1));
-        }
-
-        cluster = new TestingCluster(builder.build());
-        cluster.start();
-
-        connectionString1to5 = cluster.getConnectString();
-        connectionString2to5 = getConnectionString(cluster, 2, 3, 4, 5);
-        connectionString3to5 = getConnectionString(cluster, 3, 4, 5);
-
-        dynamicEnsembleProvider = new DynamicEnsembleProvider(connectionString1to5);
-        client = CuratorFrameworkFactory.builder()
-            .ensembleProvider(dynamicEnsembleProvider)
-            .retryPolicy(new RetryOneTime(1))
-            .build();
-        client.start();
-        client.blockUntilConnected();
-
-        //Wrap around the dynamic ensemble provider, so that we can wait until it has received the event.
-        waitOnDelegateListener = new WaitOnDelegateListener(dynamicEnsembleProvider);
-        ensembleTracker = new EnsembleTracker(client);
-        ensembleTracker.getListenable().addListener(waitOnDelegateListener);
-        ensembleTracker.start();
-        //Wait for the initial event.
-        waitOnDelegateListener.waitForEvent();
-    }
-
-    @AfterMethod
-    public void tearDown() throws IOException
-    {
-        CloseableUtils.closeQuietly(ensembleTracker);
-        CloseableUtils.closeQuietly(client);
-        CloseableUtils.closeQuietly(cluster);
-    }
-
-    @Test
-    public void testSyncIncremental() throws Exception
-    {
-        Stat stat = new Stat();
-        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
-        Assert.assertNotNull(bytes);
-        QuorumVerifier qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-
-        //Remove Servers
-        bytes = client.reconfig().leaving("1").storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig().leaving("2").storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-
-        //Add Servers
-        bytes = client.reconfig().joining("server.2=" + server2).storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig().joining("server.1=" + server1).storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-    }
-
-    @Test
-    public void testAsyncIncremental() throws Exception
-    {
-        final AtomicReference<byte[]> bytes = new AtomicReference<>();
-        final BackgroundCallback callback = new BackgroundCallback()
-        {
-            @Override
-            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
-            {
-                bytes.set(event.getData());
-                //We only need the latch on getConfig.
-                if ( event.getContext() != null )
-                {
-                    ((CountDownLatch)event.getContext()).countDown();
-                }
-            }
-
-        };
-
-        CountDownLatch latch = new CountDownLatch(1);
-        client.getConfig().inBackground(callback, latch).forEnsemble();
-        Assert.assertTrue(timing.awaitLatch(latch));
-        Assert.assertNotNull(bytes.get());
-        QuorumVerifier qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-
-        //Remove Servers
-        client.reconfig().inBackground(callback).leaving("1").fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch).leaving("2").fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        //Add Servers
-        client.reconfig().inBackground(callback, latch).joining("server.2=" + server2).fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch).joining("server.1=" + server1).fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-    }
-
-    @Test
-    public void testSyncNonIncremental() throws Exception
-    {
-        Stat stat = new Stat();
-        byte[] bytes = client.getConfig().storingStatIn(stat).forEnsemble();
-        Assert.assertNotNull(bytes);
-        QuorumVerifier qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-        String server3 = getServerString(qv, cluster, 3L);
-        String server4 = getServerString(qv, cluster, 4L);
-        String server5 = getServerString(qv, cluster, 5L);
-
-        //Remove Servers
-        bytes = client.reconfig()
-            .withNewMembers("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig()
-            .withNewMembers("server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-
-        //Add Servers
-        bytes = client.reconfig()
-            .withNewMembers("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-
-        bytes = client.reconfig()
-            .withNewMembers("server.1=" + server1,
-                "server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .storingStatIn(stat).fromConfig(qv.getVersion()).forEnsemble();
-        qv = getQuorumVerifier(bytes);
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-    }
-
-    @Test
-    public void testAsyncNonIncremental() throws Exception
-    {
-        final AtomicReference<byte[]> bytes = new AtomicReference<>();
-        final BackgroundCallback callback = new BackgroundCallback()
-        {
-            @Override
-            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
-            {
-                bytes.set(event.getData());
-                ((CountDownLatch)event.getContext()).countDown();
-            }
-
-        };
-
-        CountDownLatch latch = new CountDownLatch(1);
-        client.getConfig().inBackground(callback, latch).forEnsemble();
-        Assert.assertTrue(timing.awaitLatch(latch));
-        Assert.assertNotNull(bytes.get());
-        QuorumVerifier qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-        String server1 = getServerString(qv, cluster, 1L);
-        String server2 = getServerString(qv, cluster, 2L);
-        String server3 = getServerString(qv, cluster, 3L);
-        String server4 = getServerString(qv, cluster, 4L);
-        String server5 = getServerString(qv, cluster, 5L);
-
-        //Remove Servers
-        client.reconfig().inBackground(callback, latch)
-            .withNewMembers("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch)
-            .withNewMembers("server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString3to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 3);
-
-        //Add Servers
-        client.reconfig().inBackground(callback, latch)
-            .withNewMembers("server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString2to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 4);
-
-        client.reconfig().inBackground(callback, latch)
-            .withNewMembers("server.1=" + server1,
-                "server.2=" + server2,
-                "server.3=" + server3,
-                "server.4=" + server4,
-                "server.5=" + server5)
-            .fromConfig(qv.getVersion()).forEnsemble();
-        waitOnDelegateListener.waitForEvent();
-        Assert.assertEquals(dynamicEnsembleProvider.getConnectionString(), connectionString1to5);
-        qv = getQuorumVerifier(bytes.get());
-        Assert.assertEquals(qv.getAllMembers().size(), 5);
-    }
-
-    private static QuorumVerifier getQuorumVerifier(byte[] bytes) throws Exception
-    {
-        Properties properties = new Properties();
-        properties.load(new StringReader(new String(bytes)));
-        return new QuorumMaj(properties);
-    }
-
-    private static InstanceSpec getInstance(TestingCluster cluster, int id)
-    {
-        for ( InstanceSpec spec : cluster.getInstances() )
-        {
-            if ( spec.getServerId() == id )
-            {
-                return spec;
-            }
-        }
-        throw new IllegalStateException("InstanceSpec with id:" + id + " not found");
-    }
-
-    private static String getServerString(QuorumVerifier qv, TestingCluster cluster, long id) throws Exception
-    {
-        String str = qv.getAllMembers().get(id).toString();
-        //check if connection string is already there.
-        if ( str.contains(";") )
-        {
-            return str;
-        }
-        else
-        {
-            return str + ";" + getInstance(cluster, (int)id).getConnectString();
-        }
-    }
-
-    private static String getConnectionString(TestingCluster cluster, long... ids) throws Exception
-    {
-        StringBuilder sb = new StringBuilder();
-        Map<Long, InstanceSpec> specs = new HashMap<>();
-        for ( InstanceSpec spec : cluster.getInstances() )
-        {
-            specs.put((long)spec.getServerId(), spec);
-        }
-        for ( long id : ids )
-        {
-            if ( sb.length() != 0 )
-            {
-                sb.append(",");
-            }
-            sb.append(specs.get(id).getConnectString());
-        }
-        return sb.toString();
-    }
-
-    //Simple EnsembleListener that can wait until the delegate handles the event.
-    private static class WaitOnDelegateListener implements EnsembleListener
-    {
-        private CountDownLatch latch = new CountDownLatch(1);
-
-        private final EnsembleListener delegate;
-
-        private WaitOnDelegateListener(EnsembleListener delegate)
-        {
-            this.delegate = delegate;
-        }
-
-        @Override
-        public void connectionStringUpdated(String connectionString)
-        {
-            delegate.connectionStringUpdated(connectionString);
-            latch.countDown();
-        }
-
-        public void waitForEvent() throws InterruptedException, TimeoutException
-        {
-            if ( timing.awaitLatch(latch) )
-            {
-                latch = new CountDownLatch(1);
-            }
-            else
-            {
-                throw new TimeoutException("Failed to receive event in time.");
-            }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/curator/blob/36ddd58a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
----------------------------------------------------------------------
diff --git a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
index b8dada8..3d38fe1 100644
--- a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
+++ b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
@@ -52,18 +52,6 @@ public class TestingCluster implements Closeable
     }
 
     /**
-     * Creates an ensemble comprised of <code>n</code> servers. Each server will use
-     * a temp directory and random ports
-     *
-     * @param instanceQty number of servers to create in the ensemble
-     * @param resetServerIds if true, server Ids are reset first
-     */
-    public TestingCluster(int instanceQty, boolean resetServerIds)
-    {
-        this(makeSpecs(instanceQty, resetServerIds));
-    }
-
-    /**
      * Creates an ensemble using the given server specs
      *
      * @param specs the server specs
@@ -254,12 +242,12 @@ public class TestingCluster implements Closeable
         return null;
     }
 
-    private static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty)
+    public static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty)
     {
         return makeSpecs(instanceQty, true);
     }
 
-    private static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty, boolean resetServerIds)
+    public static Map<InstanceSpec, Collection<InstanceSpec>> makeSpecs(int instanceQty, boolean resetServerIds)
     {
         if ( resetServerIds )
         {


[09/10] curator git commit: better test - shouldn't fail if slow

Posted by ra...@apache.org.
better test - shouldn't fail if slow


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

Branch: refs/heads/CURATOR-3.0
Commit: a7076bc8dd806bb824e33dcd2f8b5e53626b5691
Parents: c108466
Author: randgalt <ra...@apache.org>
Authored: Sat Sep 26 10:03:20 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Sat Sep 26 10:03:20 2015 -0500

----------------------------------------------------------------------
 .../framework/imps/TestFrameworkBackground.java    | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/a7076bc8/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkBackground.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkBackground.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkBackground.java
index 26cc941..6575018 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkBackground.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkBackground.java
@@ -20,6 +20,7 @@
 package org.apache.curator.framework.imps;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Queues;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
 import org.apache.curator.framework.api.BackgroundCallback;
@@ -30,15 +31,15 @@ import org.apache.curator.framework.state.ConnectionStateListener;
 import org.apache.curator.retry.RetryNTimes;
 import org.apache.curator.retry.RetryOneTime;
 import org.apache.curator.test.BaseClassForTests;
-import org.apache.curator.test.TestingServer;
 import org.apache.curator.test.Timing;
 import org.apache.curator.utils.CloseableUtils;
 import org.apache.zookeeper.KeeperException.Code;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
@@ -149,24 +150,22 @@ public class TestFrameworkBackground extends BaseClassForTests
         {
             client.start();
 
-            final CountDownLatch latch = new CountDownLatch(3);
-            final List<String> paths = Lists.newArrayList();
-            BackgroundCallback callback = new BackgroundCallback()
+            final BlockingQueue<String> paths = Queues.newLinkedBlockingQueue();
+                BackgroundCallback callback = new BackgroundCallback()
             {
                 @Override
                 public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
                 {
                     paths.add(event.getPath());
-                    latch.countDown();
                 }
             };
             client.create().inBackground(callback).forPath("/one");
             client.create().inBackground(callback).forPath("/one/two");
             client.create().inBackground(callback).forPath("/one/two/three");
 
-            latch.await();
-
-            Assert.assertEquals(paths, Arrays.asList("/one", "/one/two", "/one/two/three"));
+            Assert.assertEquals(paths.poll(timing.milliseconds(), TimeUnit.MILLISECONDS), "/one");
+            Assert.assertEquals(paths.poll(timing.milliseconds(), TimeUnit.MILLISECONDS), "/one/two");
+            Assert.assertEquals(paths.poll(timing.milliseconds(), TimeUnit.MILLISECONDS), "/one/two/three");
         }
         finally
         {


[06/10] curator git commit: Fixed newMembers test

Posted by ra...@apache.org.
Fixed newMembers test


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

Branch: refs/heads/CURATOR-3.0
Commit: a8ec17ece060484e0e6ce723568ed9505f6b82ef
Parents: e09388a
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 22:05:43 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 22:05:43 2015 -0500

----------------------------------------------------------------------
 .../org/apache/curator/framework/imps/TestReconfiguration.java    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/a8ec17ec/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
index ca00cba..e7d2229 100644
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
+++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReconfiguration.java
@@ -282,7 +282,7 @@ public class TestReconfiguration extends BaseClassForTests
             client.start();
 
             QuorumVerifier oldConfig = toQuorumVerifier(client.getConfig().forEnsemble());
-            Assert.assertEquals(cluster.getInstances().size(), 5);
+            Assert.assertEquals(oldConfig.getAllMembers().size(), 5);
             assertConfig(oldConfig, cluster.getInstances());
 
             CountDownLatch latch = setChangeWaiter(client);
@@ -291,6 +291,7 @@ public class TestReconfiguration extends BaseClassForTests
 
             Assert.assertTrue(timing.awaitLatch(latch));
             QuorumVerifier newConfig = toQuorumVerifier(client.getConfig().forEnsemble());
+            Assert.assertEquals(newConfig.getAllMembers().size(), 3);
             assertConfig(newConfig, smallCluster);
         }
     }


[08/10] curator git commit: License header

Posted by ra...@apache.org.
License header


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

Branch: refs/heads/CURATOR-3.0
Commit: c1084663aa8991a06cc7390180d07cbaf6c330e1
Parents: 2ff8985
Author: randgalt <ra...@apache.org>
Authored: Sat Sep 26 09:15:54 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Sat Sep 26 09:15:54 2015 -0500

----------------------------------------------------------------------
 .../framework/api/BackgroundEnsembleable.java     | 18 ++++++++++++++++++
 .../api/WatchBackgroundEnsembleable.java          | 18 ++++++++++++++++++
 2 files changed, 36 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/c1084663/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
index ae2b226..c8b323f 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundEnsembleable.java
@@ -1,3 +1,21 @@
+/**
+ * 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.api;
 
 public interface BackgroundEnsembleable<T> extends

http://git-wip-us.apache.org/repos/asf/curator/blob/c1084663/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
index 073cfe3..a0e5a13 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/WatchBackgroundEnsembleable.java
@@ -1,3 +1,21 @@
+/**
+ * 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.api;
 
 public interface WatchBackgroundEnsembleable<T> extends


[07/10] curator git commit: enforce single thread

Posted by ra...@apache.org.
enforce single thread


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

Branch: refs/heads/CURATOR-3.0
Commit: 2ff89856d6ee2d373cf91bc1a3bd388890604373
Parents: a8ec17e
Author: randgalt <ra...@apache.org>
Authored: Fri Sep 25 23:59:47 2015 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Sep 25 23:59:47 2015 -0500

----------------------------------------------------------------------
 pom.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/2ff89856/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0e7a732..0047d96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -622,6 +622,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
+                    <threadCount>1</threadCount>
                     <reuseForks>false</reuseForks>
                     <redirectTestOutputToFile>true</redirectTestOutputToFile>
                 </configuration>