This is an automated email from the ASF dual-hosted git repository. randgalt pushed a commit to branch CURATOR-558-zk36-updates in repository https://gitbox.apache.org/repos/asf/curator.git
commit 7bec37667acce8fda1e5a207787f92f69125f8c0 Author: randgalt <randg...@apache.org> AuthorDate: Sat Nov 2 11:40:44 2019 -0500 CURATOR-549 Bring Curator up to ZooKeeper 3.5.6 in preparation for supporting persistent recursive watchers while maintaining background compatability with previous versions of ZK. Added a new module to make sure we maintain compatibility with ZK 3.5.x. ZooKeeper 3.6.0 has some significant changes from previous versions. The reconfig APIs have moved into a new class, ZooKeeperAdmin. This class existed in 3.5.x but wasn't required. Now it is. A bunch of little things changed in the ZK server code [...] There is a new module, curator-test-zk35. It forces ZooKeeper 3.5.6 and performs selected tests from the other modules to ensure compatibility. Tests annotated with TestNG groups zk35 and zk35Compatibility are tested. Group zk36 is excluded. Note: these tests will only run from Maven. I don't think IntelliJ/Eclipse support the Maven syntax I used. Support persistent watchers in ZK 3.6+ while maintaining background compatability with previous versions of ZK. Added a new module to make sure we maintain comaptibility with ZK 3.5.x --- .../org/apache/curator/utils/Compatibility.java | 104 +++++++++++++ .../curator/utils/DefaultZookeeperFactory.java | 3 +- ...rFactory.java => NonAdminZookeeperFactory.java} | 2 +- .../java/org/apache/curator/TestIs36.java} | 21 ++- .../apache/curator/framework/CuratorFramework.java | 1 + .../curator/framework/api/CuratorEventType.java | 7 +- .../imps/CuratorMultiTransactionRecord.java | 34 +++-- .../curator/framework/imps/EnsembleTracker.java | 4 +- .../framework/imps/ReconfigBuilderImpl.java | 5 +- .../framework/imps/RemoveWatchesBuilderImpl.java | 9 +- .../apache/curator/framework/imps/Watching.java | 10 +- .../curator/framework/imps/TestFramework.java | 6 +- .../curator/framework/imps/TestFrameworkEdges.java | 2 + .../framework/imps/TestReconfiguration.java | 1 + ...tRemoveWatches.java => TestWatchesBuilder.java} | 8 +- .../curator/framework/imps/TestWithCluster.java | 2 + .../state/TestConnectionStateManager.java | 2 + .../framework/recipes/cache/BaseTestTreeCache.java | 4 +- .../framework/recipes/cache/TestNodeCache.java | 2 + .../recipes/cache/TestPathChildrenCache.java | 2 + .../cache/TestPathChildrenCacheInCluster.java | 2 + .../framework/recipes/cache/TestTreeCache.java | 2 + .../recipes/leader/ChaosMonkeyCnxnFactory.java | 8 +- .../framework/recipes/leader/TestLeaderLatch.java | 2 + .../locks/TestInterProcessSemaphoreCluster.java | 2 + curator-test-zk35/pom.xml | 161 +++++++++++++++++++++ .../java/org/apache/curator/zk35/TestIs35.java | 21 +-- .../src/test/resources/log4j.properties | 27 ++++ curator-test/pom.xml | 10 ++ .../org/apache/curator/test/BaseClassForTests.java | 23 ++- .../org/apache/curator/test/Compatibility.java | 115 +++++++++++++++ ...stBase.java => FailedServerStartException.java} | 17 ++- .../org/apache/curator/test/TestingCluster.java | 2 +- .../apache/curator/test/TestingQuorumPeerMain.java | 6 +- .../apache/curator/test/TestingZooKeeperMain.java | 26 +++- .../org/apache/curator/test/ZooKeeperMainFace.java | 6 +- .../test/compatibility/CuratorTestBase.java | 4 +- .../x/async/details/AsyncCuratorFrameworkImpl.java | 14 +- pom.xml | 51 +++++-- 39 files changed, 636 insertions(+), 92 deletions(-) diff --git a/curator-client/src/main/java/org/apache/curator/utils/Compatibility.java b/curator-client/src/main/java/org/apache/curator/utils/Compatibility.java new file mode 100644 index 0000000..fa43d35 --- /dev/null +++ b/curator-client/src/main/java/org/apache/curator/utils/Compatibility.java @@ -0,0 +1,104 @@ +/** + * 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.utils; + +import org.apache.zookeeper.server.quorum.QuorumPeer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; + +/** + * Utils to help with ZK version compatibility + */ +public class Compatibility +{ + private static final Method getReachableOrOneMethod; + private static final Field addrField; + + private static final Logger log = LoggerFactory.getLogger(Compatibility.class); + + static + { + Method localGetReachableOrOneMethod; + try + { + Class<?> multipleAddressesClass = Class.forName("org.apache.zookeeper.server.quorum.MultipleAddresses"); + localGetReachableOrOneMethod = multipleAddressesClass.getMethod("getReachableOrOne"); + LoggerFactory.getLogger(Compatibility.class).info("Using org.apache.zookeeper.server.quorum.MultipleAddresses"); + } + catch ( ReflectiveOperationException ignore ) + { + localGetReachableOrOneMethod = null; + } + getReachableOrOneMethod = localGetReachableOrOneMethod; + + Field localAddrField; + try + { + localAddrField = QuorumPeer.QuorumServer.class.getField("addr"); + } + catch ( NoSuchFieldException e ) + { + localAddrField = null; + LoggerFactory.getLogger(Compatibility.class).error("Could not get addr field! Reconfiguration fail!"); + } + addrField = localAddrField; + } + + public static boolean hasGetReachableOrOneMethod() + { + return (getReachableOrOneMethod != null); + } + + public static boolean hasAddrField() + { + return (addrField != null); + } + + public static String getHostAddress(QuorumPeer.QuorumServer server) + { + InetSocketAddress address = null; + if ( getReachableOrOneMethod != null ) + { + try + { + address = (InetSocketAddress)getReachableOrOneMethod.invoke(server.addr); + } + catch ( Exception e ) + { + log.error("Could not call getReachableOrOneMethod.invoke({})", server.addr, e); + } + } + else if (addrField != null) + { + try + { + address = (InetSocketAddress)addrField.get(server); + } + catch ( Exception e ) + { + log.error("Could not call addrField.get({})", server, e); + } + } + return (address != null) ? address.getAddress().getHostAddress() : "unknown"; + } +} diff --git a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java b/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java index 42279d0..acd32e7 100644 --- a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java +++ b/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java @@ -20,12 +20,13 @@ package org.apache.curator.utils; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.admin.ZooKeeperAdmin; public class DefaultZookeeperFactory implements ZookeeperFactory { @Override public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception { - return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly); + return new ZooKeeperAdmin(connectString, sessionTimeout, watcher, canBeReadOnly); } } diff --git a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java b/curator-client/src/main/java/org/apache/curator/utils/NonAdminZookeeperFactory.java similarity index 94% copy from curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java copy to curator-client/src/main/java/org/apache/curator/utils/NonAdminZookeeperFactory.java index 42279d0..6163df5 100644 --- a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java +++ b/curator-client/src/main/java/org/apache/curator/utils/NonAdminZookeeperFactory.java @@ -21,7 +21,7 @@ package org.apache.curator.utils; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; -public class DefaultZookeeperFactory implements ZookeeperFactory +public class NonAdminZookeeperFactory implements ZookeeperFactory { @Override public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception diff --git a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java b/curator-client/src/test/java/org/apache/curator/TestIs36.java similarity index 63% copy from curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java copy to curator-client/src/test/java/org/apache/curator/TestIs36.java index 42279d0..2bad9b9 100644 --- a/curator-client/src/main/java/org/apache/curator/utils/DefaultZookeeperFactory.java +++ b/curator-client/src/test/java/org/apache/curator/TestIs36.java @@ -16,16 +16,25 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.curator.utils; +package org.apache.curator; -import org.apache.zookeeper.Watcher; -import org.apache.zookeeper.ZooKeeper; +import org.apache.curator.test.compatibility.CuratorTestBase; +import org.apache.curator.utils.Compatibility; +import org.testng.Assert; +import org.testng.annotations.Test; -public class DefaultZookeeperFactory implements ZookeeperFactory +public class TestIs36 extends CuratorTestBase { + @Test(groups = zk36Group) + public void testIsZk36() + { + Assert.assertTrue(Compatibility.hasGetReachableOrOneMethod()); + Assert.assertTrue(Compatibility.hasAddrField()); + } + @Override - public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception + protected void createServer() { - return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly); + // NOP } } diff --git a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java index 8b39ebd..a686b94 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java @@ -194,6 +194,7 @@ public interface CuratorFramework extends Closeable /** * Start a remove watches builder. + * * @return builder object */ public RemoveWatchesBuilder watches(); diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java index 5dea211..89e1490 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java @@ -96,5 +96,10 @@ public enum CuratorEventType /** * Event sent when client is being closed */ - CLOSING + CLOSING, + + /** + * Corresponds to {@link org.apache.curator.framework.CuratorFramework#watchers()} + */ + ADD_WATCH } diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java index 3e72609..06fbecb 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java @@ -16,49 +16,57 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.curator.framework.imps; import com.google.common.collect.Lists; import org.apache.curator.framework.api.transaction.OperationType; import org.apache.curator.framework.api.transaction.TypeAndPath; -import org.apache.zookeeper.MultiTransactionRecord; import org.apache.zookeeper.Op; import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -class CuratorMultiTransactionRecord extends MultiTransactionRecord +class CuratorMultiTransactionRecord implements Iterable<Op> { - private final List<TypeAndPath> metadata = Lists.newArrayList(); - - @Override - public final void add(Op op) - { - throw new UnsupportedOperationException(); - } + private final List<TypeAndPath> metadata = Lists.newArrayList(); + private final List<Op> ops = new ArrayList<>(); void add(Op op, OperationType type, String forPath) { - super.add(op); + ops.add(op); metadata.add(new TypeAndPath(type, forPath)); } - TypeAndPath getMetadata(int index) + TypeAndPath getMetadata(int index) { return metadata.get(index); } - int metadataSize() + int metadataSize() { return metadata.size(); } void addToDigest(MessageDigest digest) { - for ( Op op : this ) + for ( Op op : ops ) { digest.update(op.getPath().getBytes()); digest.update(Integer.toString(op.getType()).getBytes()); digest.update(op.toRequestRecord().toString().getBytes()); } } + + @Override + public Iterator<Op> iterator() + { + return ops.iterator(); + } + + int size() + { + return ops.size(); + } } diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java index b2c55f6..75bb68a 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java @@ -31,6 +31,7 @@ import org.apache.curator.framework.api.CuratorEventType; import org.apache.curator.framework.api.CuratorWatcher; import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; +import org.apache.curator.utils.Compatibility; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; @@ -39,7 +40,6 @@ import org.apache.zookeeper.server.quorum.flexible.QuorumMaj; import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.io.ByteArrayInputStream; import java.io.Closeable; import java.util.Properties; @@ -182,7 +182,7 @@ public class EnsembleTracker implements Closeable, CuratorWatcher String hostAddress; if ( server.clientAddr.getAddress().isAnyLocalAddress() ) { - hostAddress = server.addr.getAddress().getHostAddress(); + hostAddress = Compatibility.getHostAddress(server); } else { 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 97be59a..0386e5e 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 @@ -24,6 +24,7 @@ import org.apache.curator.RetryLoop; import org.apache.curator.TimeTrace; import org.apache.curator.framework.api.*; import org.apache.zookeeper.AsyncCallback; +import org.apache.zookeeper.admin.ZooKeeperAdmin; import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.server.DataTree; import java.util.Arrays; @@ -268,7 +269,7 @@ public class ReconfigBuilderImpl implements ReconfigBuilder, BackgroundOperation client.processBackgroundOperation(data, event); } }; - client.getZooKeeper().reconfig(joining, leaving, newMembers, fromConfig, callback, backgrounding.getContext()); + ((ZooKeeperAdmin)client.getZooKeeper()).reconfigure(joining, leaving, newMembers, fromConfig, callback, backgrounding.getContext()); } catch ( Throwable e ) { @@ -287,7 +288,7 @@ public class ReconfigBuilderImpl implements ReconfigBuilder, BackgroundOperation @Override public byte[] call() throws Exception { - return client.getZooKeeper().reconfig(joining, leaving, newMembers, fromConfig, responseStat); + return ((ZooKeeperAdmin)client.getZooKeeper()).reconfigure(joining, leaving, newMembers, fromConfig, responseStat); } } ); diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java index e14deff..961d5f0 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/RemoveWatchesBuilderImpl.java @@ -201,8 +201,13 @@ public class RemoveWatchesBuilderImpl implements RemoveWatchesBuilder, RemoveWat } return null; - } - + } + + protected CuratorFrameworkImpl getClient() + { + return client; + } + private void pathInBackground(final String path) { OperationAndData.ErrorCallback<String> errorCallback = null; diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/Watching.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/Watching.java index daa5dd3..5bad7e7 100644 --- a/curator-framework/src/main/java/org/apache/curator/framework/imps/Watching.java +++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/Watching.java @@ -23,7 +23,7 @@ import org.apache.curator.framework.api.CuratorWatcher; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.Watcher; -class Watching +public class Watching { private final Watcher watcher; private final CuratorWatcher curatorWatcher; @@ -31,7 +31,7 @@ class Watching private final CuratorFrameworkImpl client; private NamespaceWatcher namespaceWatcher; - Watching(CuratorFrameworkImpl client, boolean watched) + public Watching(CuratorFrameworkImpl client, boolean watched) { this.client = client; this.watcher = null; @@ -39,7 +39,7 @@ class Watching this.watched = watched; } - Watching(CuratorFrameworkImpl client, Watcher watcher) + public Watching(CuratorFrameworkImpl client, Watcher watcher) { this.client = client; this.watcher = watcher; @@ -47,7 +47,7 @@ class Watching this.watched = false; } - Watching(CuratorFrameworkImpl client, CuratorWatcher watcher) + public Watching(CuratorFrameworkImpl client, CuratorWatcher watcher) { this.client = client; this.watcher = null; @@ -55,7 +55,7 @@ class Watching this.watched = false; } - Watching(CuratorFrameworkImpl client) + public Watching(CuratorFrameworkImpl client) { this.client = client; watcher = null; diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFramework.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFramework.java index 8b22812..db4a9a5 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFramework.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFramework.java @@ -31,6 +31,7 @@ import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.RetryOneTime; import org.apache.curator.test.BaseClassForTests; import org.apache.curator.test.Timing; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.test.compatibility.Timing2; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.utils.EnsurePath; @@ -58,9 +59,10 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @SuppressWarnings("deprecation") +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestFramework extends BaseClassForTests { - @BeforeMethod + @BeforeMethod(alwaysRun = true) @Override public void setup() throws Exception { @@ -68,7 +70,7 @@ public class TestFramework extends BaseClassForTests super.setup(); } - @AfterMethod + @AfterMethod(alwaysRun = true) @Override public void teardown() throws Exception { diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java index 811bad4..feb22ab 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestFrameworkEdges.java @@ -39,6 +39,7 @@ import org.apache.curator.test.BaseClassForTests; import org.apache.curator.test.InstanceSpec; import org.apache.curator.test.TestingCluster; import org.apache.curator.test.TestingServer; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.test.compatibility.Timing2; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.utils.ZKPaths; @@ -62,6 +63,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestFrameworkEdges extends BaseClassForTests { private final Logger log = LoggerFactory.getLogger(getClass()); 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 1ff2805..258428c 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 @@ -56,6 +56,7 @@ import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestReconfiguration extends CuratorTestBase { private final Timing2 timing = new Timing2(); diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWatchesBuilder.java similarity index 97% rename from curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java rename to curator-framework/src/test/java/org/apache/curator/framework/imps/TestWatchesBuilder.java index 82f2cf4..a777e2f 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestRemoveWatches.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWatchesBuilder.java @@ -30,8 +30,8 @@ import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.retry.RetryOneTime; -import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.test.Timing; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; @@ -44,7 +44,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -public class TestRemoveWatches extends CuratorTestBase +public class TestWatchesBuilder extends CuratorTestBase { private AtomicReference<ConnectionState> registerConnectionStateListener(CuratorFramework client) { @@ -608,8 +608,8 @@ public class TestRemoveWatches extends CuratorTestBase { CloseableUtils.closeQuietly(client); } - } - + } + private static class CountDownWatcher implements Watcher { private String path; private EventType eventType; diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWithCluster.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWithCluster.java index 7e8ffbb..2f84317 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWithCluster.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestWithCluster.java @@ -18,6 +18,7 @@ */ package org.apache.curator.framework.imps; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; @@ -33,6 +34,7 @@ import org.testng.Assert; import org.testng.annotations.Test; import java.util.concurrent.CountDownLatch; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestWithCluster { @Test diff --git a/curator-framework/src/test/java/org/apache/curator/framework/state/TestConnectionStateManager.java b/curator-framework/src/test/java/org/apache/curator/framework/state/TestConnectionStateManager.java index ff48468..1dbb5e7 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/state/TestConnectionStateManager.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/state/TestConnectionStateManager.java @@ -22,6 +22,7 @@ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.RetryOneTime; import org.apache.curator.test.BaseClassForTests; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.test.compatibility.Timing2; import org.apache.curator.utils.CloseableUtils; import org.testng.Assert; @@ -29,6 +30,7 @@ import org.testng.annotations.Test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestConnectionStateManager extends BaseClassForTests { @Test diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/BaseTestTreeCache.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/BaseTestTreeCache.java index 175ccdf..246704f 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/BaseTestTreeCache.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/BaseTestTreeCache.java @@ -96,7 +96,7 @@ public class BaseTestTreeCache extends BaseClassForTests } @Override - @BeforeMethod + @BeforeMethod(alwaysRun = true) public void setup() throws Exception { super.setup(); @@ -111,7 +111,7 @@ public class BaseTestTreeCache extends BaseClassForTests } @Override - @AfterMethod + @AfterMethod(alwaysRun = true) public void teardown() throws Exception { try diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestNodeCache.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestNodeCache.java index c3361c3..bed4606 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestNodeCache.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestNodeCache.java @@ -20,6 +20,7 @@ package org.apache.curator.framework.recipes.cache; import org.apache.curator.framework.imps.TestCleanState; import org.apache.curator.test.BaseClassForTests; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.test.compatibility.Timing2; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.framework.CuratorFramework; @@ -39,6 +40,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestNodeCache extends BaseClassForTests { @Test diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCache.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCache.java index 4ebe9ef..878ce48 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCache.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCache.java @@ -32,6 +32,7 @@ import org.apache.curator.test.BaseClassForTests; import org.apache.curator.test.ExecuteCalledWatchingExecutorService; import org.apache.curator.test.TestingServer; import org.apache.curator.test.Timing; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; @@ -44,6 +45,7 @@ import java.util.concurrent.atomic.AtomicReference; import static org.testng.AssertJUnit.assertNotNull; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestPathChildrenCache extends BaseClassForTests { @Test diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCacheInCluster.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCacheInCluster.java index cd87125..a9728b5 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCacheInCluster.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestPathChildrenCacheInCluster.java @@ -20,6 +20,7 @@ package org.apache.curator.framework.recipes.cache; import com.google.common.collect.Queues; import org.apache.curator.test.BaseClassForTests; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; @@ -34,6 +35,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestPathChildrenCacheInCluster extends BaseClassForTests { @Test(enabled = false) // this test is very flakey - it needs to be re-written at some point diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java index 3e59d1a..22b0369 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/cache/TestTreeCache.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.api.UnhandledErrorListener; import org.apache.curator.framework.recipes.cache.TreeCacheEvent.Type; +import org.apache.curator.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.apache.zookeeper.CreateMode; import org.testng.Assert; @@ -30,6 +31,7 @@ import org.testng.annotations.Test; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicBoolean; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestTreeCache extends BaseTestTreeCache { @Test diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java index 4cb342c..07e9a17 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java @@ -19,11 +19,11 @@ package org.apache.curator.framework.recipes.leader; +import org.apache.curator.test.Compatibility; import org.apache.curator.test.TestingZooKeeperMain; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.proto.CreateRequest; import org.apache.zookeeper.server.ByteBufferInputStream; -import org.apache.zookeeper.server.NIOServerCnxn; import org.apache.zookeeper.server.NIOServerCnxnFactory; import org.apache.zookeeper.server.Request; import org.apache.zookeeper.server.ZooKeeperServer; @@ -92,7 +92,7 @@ public class ChaosMonkeyCnxnFactory extends NIOServerCnxnFactory log.debug("Rejected : " + si.toString()); // Still reject request log.debug("Still not ready for " + remaining + "ms"); - ((NIOServerCnxn)si.cnxn).close(); + Compatibility.serverCnxnClose(si.cnxn); return; } // Submit the request to the legacy Zookeeper server @@ -113,13 +113,13 @@ public class ChaosMonkeyCnxnFactory extends NIOServerCnxnFactory firstError = System.currentTimeMillis(); // The znode has been created, close the connection and don't tell it to client log.warn("Closing connection right after " + createRequest.getPath() + " creation"); - ((NIOServerCnxn)si.cnxn).close(); + Compatibility.serverCnxnClose(si.cnxn); } } catch ( Exception e ) { // Should not happen - ((NIOServerCnxn)si.cnxn).close(); + Compatibility.serverCnxnClose(si.cnxn); } } } diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java index 3d9e9b7..1fc9ff3 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java @@ -37,6 +37,7 @@ 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.test.compatibility.CuratorTestBase; import org.apache.curator.test.compatibility.Timing2; import org.apache.curator.utils.CloseableUtils; import org.testng.Assert; @@ -60,6 +61,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.stream.IntStream; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestLeaderLatch extends BaseClassForTests { private static final String PATH_NAME = "/one/two/me"; diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessSemaphoreCluster.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessSemaphoreCluster.java index ed56f15..10d4192 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessSemaphoreCluster.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessSemaphoreCluster.java @@ -30,6 +30,7 @@ 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.test.compatibility.CuratorTestBase; import org.apache.curator.utils.CloseableUtils; import org.testng.Assert; import org.testng.annotations.Test; @@ -46,6 +47,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +@Test(groups = CuratorTestBase.zk35TestCompatibilityGroup) public class TestInterProcessSemaphoreCluster extends BaseClassForTests { @Test diff --git a/curator-test-zk35/pom.xml b/curator-test-zk35/pom.xml new file mode 100644 index 0000000..0f1948a --- /dev/null +++ b/curator-test-zk35/pom.xml @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.apache.curator</groupId> + <artifactId>apache-curator</artifactId> + <version>4.2.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>curator-test-zk35</artifactId> + + <properties> + <zookeeper-35-version>3.5.7</zookeeper-35-version> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-framework</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-x-async</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-recipes</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + <version>${zookeeper-35-version}</version> + <exclusions> + <exclusion> + <groupId>com.sun.jmx</groupId> + <artifactId>jmxri</artifactId> + </exclusion> + <exclusion> + <groupId>com.sun.jdmk</groupId> + <artifactId>jmxtools</artifactId> + </exclusion> + <exclusion> + <groupId>javax.jms</groupId> + <artifactId>jms</artifactId> + </exclusion> + <exclusion> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-test</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-recipes</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + <type>test-jar</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-framework</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + </exclusion> + </exclusions> + <type>test-jar</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <executions> + <execution> + <phase>deploy</phase> + <configuration> + <skip>true</skip> + </configuration> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <dependenciesToScan> + <dependency>org.apache.curator:curator-framework</dependency> + <dependency>org.apache.curator:curator-recipes</dependency> + </dependenciesToScan> + <groups>zk35TestCompatibility</groups> + <excludedGroups>zk36</excludedGroups> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java b/curator-test-zk35/src/test/java/org/apache/curator/zk35/TestIs35.java similarity index 70% copy from curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java copy to curator-test-zk35/src/test/java/org/apache/curator/zk35/TestIs35.java index 946ac1a..c1a18e2 100644 --- a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java +++ b/curator-test-zk35/src/test/java/org/apache/curator/zk35/TestIs35.java @@ -16,16 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.curator.test; +package org.apache.curator.zk35; -import org.apache.zookeeper.server.quorum.QuorumPeerConfig; -import java.io.Closeable; +import org.apache.curator.utils.Compatibility; +import org.testng.Assert; +import org.testng.annotations.Test; -public interface ZooKeeperMainFace extends Closeable +public class TestIs35 { - public void runFromConfig(QuorumPeerConfig config) throws Exception; - - public void blockUntilStarted() throws Exception; - - public void kill(); + @Test + public void testIsZk35() + { + Assert.assertFalse(Compatibility.hasGetReachableOrOneMethod()); + Assert.assertTrue(Compatibility.hasAddrField()); + } } + diff --git a/curator-test-zk35/src/test/resources/log4j.properties b/curator-test-zk35/src/test/resources/log4j.properties new file mode 100644 index 0000000..2a85e0d --- /dev/null +++ b/curator-test-zk35/src/test/resources/log4j.properties @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +log4j.rootLogger=ERROR, console + +log4j.logger.org.apache.curator=DEBUG, console +log4j.additivity.org.apache.curator=false + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p %c %x %m [%t]%n diff --git a/curator-test/pom.xml b/curator-test/pom.xml index 3683b7d..4f0c5a2 100644 --- a/curator-test/pom.xml +++ b/curator-test/pom.xml @@ -41,6 +41,16 @@ </dependency> <dependency> + <groupId>io.dropwizard.metrics</groupId> + <artifactId>metrics-core</artifactId> + </dependency> + + <dependency> + <groupId>org.xerial.snappy</groupId> + <artifactId>snappy-java</artifactId> + </dependency> + + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> diff --git a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java index 51af821..d4bbffb 100644 --- a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java +++ b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java @@ -113,7 +113,7 @@ public class BaseClassForTests context.getSuite().addListener(methodListener2); } - @BeforeMethod + @BeforeMethod(alwaysRun = true) public void setup() throws Exception { if ( INTERNAL_PROPERTY_DONT_LOG_CONNECTION_ISSUES != null ) @@ -123,7 +123,17 @@ public class BaseClassForTests System.setProperty(INTERNAL_PROPERTY_REMOVE_WATCHERS_IN_FOREGROUND, "true"); System.setProperty(INTERNAL_PROPERTY_VALIDATE_NAMESPACE_WATCHER_MAP_EMPTY, "true"); - createServer(); + try + { + createServer(); + } + catch ( FailedServerStartException ignore ) + { + log.warn("Failed to start server - retrying 1 more time"); + // server creation failed - we've sometime seen this with re-used addresses, etc. - retry one more time + closeServer(); + createServer(); + } } protected void createServer() throws Exception @@ -136,17 +146,22 @@ public class BaseClassForTests } catch ( BindException e ) { - System.err.println("Getting bind exception - retrying to allocate server"); server = null; + throw new FailedServerStartException("Getting bind exception - retrying to allocate server"); } } } - @AfterMethod + @AfterMethod(alwaysRun = true) public void teardown() throws Exception { System.clearProperty(INTERNAL_PROPERTY_VALIDATE_NAMESPACE_WATCHER_MAP_EMPTY); System.clearProperty(INTERNAL_PROPERTY_REMOVE_WATCHERS_IN_FOREGROUND); + closeServer(); + } + + private void closeServer() + { if ( server != null ) { try diff --git a/curator-test/src/main/java/org/apache/curator/test/Compatibility.java b/curator-test/src/main/java/org/apache/curator/test/Compatibility.java new file mode 100644 index 0000000..b3d7926 --- /dev/null +++ b/curator-test/src/main/java/org/apache/curator/test/Compatibility.java @@ -0,0 +1,115 @@ +/** + * 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.test; + +import org.apache.zookeeper.server.ServerCnxn; +import org.apache.zookeeper.server.ServerCnxnFactory; +import java.lang.reflect.Method; + +@SuppressWarnings({"unchecked", "rawtypes"}) +public class Compatibility +{ + private static final Method closeAllWithReasonMethod; + private static final Method closeAllMethod; + private static final Method closeWithReasonMethod; + private static final Method closeMethod; + private static final Object disconnectReasonObj; + + static + { + Object localDisconnectReasonObj; + Method localCloseAllWithReasonMethod; + Method localCloseAllMethod; + Method localCloseWithReasonMethod; + Method localCloseMethod; + try + { + Class disconnectReasonClass = Class.forName("org.apache.zookeeper.server.ServerCnxn$DisconnectReason"); + localDisconnectReasonObj = Enum.valueOf(disconnectReasonClass, "UNKNOWN"); + localCloseAllWithReasonMethod = ServerCnxnFactory.class.getDeclaredMethod("closeAll", disconnectReasonClass); + localCloseWithReasonMethod = ServerCnxn.class.getDeclaredMethod("close", disconnectReasonClass); + localCloseAllMethod = null; + localCloseMethod = null; + + localCloseAllWithReasonMethod.setAccessible(true); + localCloseWithReasonMethod.setAccessible(true); + } + catch ( Throwable e ) + { + localDisconnectReasonObj = null; + localCloseAllWithReasonMethod = null; + localCloseWithReasonMethod = null; + try + { + localCloseAllMethod = ServerCnxnFactory.class.getDeclaredMethod("closeAll"); + localCloseMethod = ServerCnxn.class.getDeclaredMethod("close"); + + localCloseAllMethod.setAccessible(true); + localCloseMethod.setAccessible(true); + } + catch ( Throwable ex ) + { + throw new IllegalStateException("Could not reflectively find ServerCnxnFactory/ServerCnxn close methods"); + } + } + disconnectReasonObj = localDisconnectReasonObj; + closeAllWithReasonMethod = localCloseAllWithReasonMethod; + closeAllMethod = localCloseAllMethod; + closeMethod = localCloseMethod; + closeWithReasonMethod = localCloseWithReasonMethod; + } + + public static void serverCnxnFactoryCloseAll(ServerCnxnFactory factory) + { + try + { + if ( closeAllMethod != null ) + { + closeAllMethod.invoke(factory); + } + else + { + closeAllWithReasonMethod.invoke(factory, disconnectReasonObj); + } + } + catch ( Exception e ) + { + throw new RuntimeException("Could not close factory", e); + } + } + + public static void serverCnxnClose(ServerCnxn cnxn) + { + try + { + if ( closeMethod != null ) + { + closeMethod.invoke(cnxn); + } + else + { + closeWithReasonMethod.invoke(cnxn, disconnectReasonObj); + } + } + catch ( Exception e ) + { + throw new RuntimeException("Could not close connection", e); + } + } +} diff --git a/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java b/curator-test/src/main/java/org/apache/curator/test/FailedServerStartException.java similarity index 75% copy from curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java copy to curator-test/src/main/java/org/apache/curator/test/FailedServerStartException.java index 830db1f..81b87e0 100644 --- a/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java +++ b/curator-test/src/main/java/org/apache/curator/test/FailedServerStartException.java @@ -16,12 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.curator.test.compatibility; +package org.apache.curator.test; -import org.apache.curator.test.BaseClassForTests; -import org.testng.annotations.Listeners; - -public class CuratorTestBase extends BaseClassForTests +public class FailedServerStartException extends IllegalStateException { - protected final Timing2 timing = new Timing2(); + public FailedServerStartException(Throwable cause) + { + super(cause); + } + + public FailedServerStartException(String s) + { + super(s); + } } 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 3d38fe1..58da2c0 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 @@ -225,7 +225,7 @@ public class TestingCluster implements Closeable */ public InstanceSpec findConnectionInstance(ZooKeeper client) throws Exception { - Method m = client.getClass().getDeclaredMethod("testableRemoteSocketAddress"); + Method m = ZooKeeper.class.getDeclaredMethod("testableRemoteSocketAddress"); m.setAccessible(true); InetSocketAddress address = (InetSocketAddress)m.invoke(client); if ( address != null ) diff --git a/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java b/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java index 3b3ab26..de9ea92 100644 --- a/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java +++ b/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java @@ -39,7 +39,7 @@ class TestingQuorumPeerMain extends QuorumPeerMain implements ZooKeeperMainFace Field cnxnFactoryField = QuorumPeer.class.getDeclaredField("cnxnFactory"); cnxnFactoryField.setAccessible(true); ServerCnxnFactory cnxnFactory = (ServerCnxnFactory)cnxnFactoryField.get(quorumPeer); - cnxnFactory.closeAll(); + Compatibility.serverCnxnFactoryCloseAll(cnxnFactory); Field ssField = cnxnFactory.getClass().getDeclaredField("ss"); ssField.setAccessible(true); @@ -70,7 +70,7 @@ class TestingQuorumPeerMain extends QuorumPeerMain implements ZooKeeperMainFace } @Override - public void blockUntilStarted() throws Exception + public void blockUntilStarted() { long startTime = System.currentTimeMillis(); while ( (quorumPeer == null) && ((System.currentTimeMillis() - startTime) <= TestingZooKeeperMain.MAX_WAIT_MS) ) @@ -87,7 +87,7 @@ class TestingQuorumPeerMain extends QuorumPeerMain implements ZooKeeperMainFace } if ( quorumPeer == null ) { - throw new Exception("quorumPeer never got set"); + throw new FailedServerStartException("quorumPeer never got set"); } } } diff --git a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java index 574b4f5..d53fb08 100644 --- a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java +++ b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java @@ -81,7 +81,7 @@ public class TestingZooKeeperMain implements ZooKeeperMainFace { if ( cnxnFactory != null ) { - cnxnFactory.closeAll(); + Compatibility.serverCnxnFactoryCloseAll(cnxnFactory); Field ssField = cnxnFactory.getClass().getDeclaredField("ss"); ssField.setAccessible(true); @@ -140,11 +140,11 @@ public class TestingZooKeeperMain implements ZooKeeperMainFace @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") @Override - public void blockUntilStarted() throws Exception + public void blockUntilStarted() { - if(!timing.awaitLatch(latch)) + if (!timing.awaitLatch(latch)) { - throw new IllegalStateException("Timed out waiting for server startup"); + throw new FailedServerStartException("Timed out waiting for server startup"); } if ( zkServer != null ) @@ -154,19 +154,27 @@ public class TestingZooKeeperMain implements ZooKeeperMainFace { while ( !zkServer.isRunning() ) { - zkServer.wait(); + try + { + zkServer.wait(); + } + catch ( InterruptedException e ) + { + Thread.currentThread().interrupt(); + throw new FailedServerStartException("Server start interrupted"); + } } } } else { - throw new Exception("No zkServer."); + throw new FailedServerStartException("No zkServer."); } Exception exception = startingException.get(); if ( exception != null ) { - throw exception; + throw new FailedServerStartException(exception); } } @@ -264,7 +272,9 @@ public class TestingZooKeeperMain implements ZooKeeperMainFace { public TestZooKeeperServer(FileTxnSnapLog txnLog, ServerConfig config) { - super(txnLog, config.getTickTime(), config.getMinSessionTimeout(), config.getMaxSessionTimeout(), null); + this.setTxnLogFactory(txnLog); + this.setMinSessionTimeout(config.getMinSessionTimeout()); + this.setMaxSessionTimeout(config.getMaxSessionTimeout()); } private final AtomicBoolean isRunning = new AtomicBoolean(false); diff --git a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java index 946ac1a..904e601 100644 --- a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java +++ b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java @@ -23,9 +23,9 @@ import java.io.Closeable; public interface ZooKeeperMainFace extends Closeable { - public void runFromConfig(QuorumPeerConfig config) throws Exception; + void runFromConfig(QuorumPeerConfig config) throws Exception; - public void blockUntilStarted() throws Exception; + void blockUntilStarted(); - public void kill(); + void kill(); } diff --git a/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java b/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java index 830db1f..093a3ce 100644 --- a/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java +++ b/curator-test/src/main/java/org/apache/curator/test/compatibility/CuratorTestBase.java @@ -19,9 +19,11 @@ package org.apache.curator.test.compatibility; import org.apache.curator.test.BaseClassForTests; -import org.testng.annotations.Listeners; public class CuratorTestBase extends BaseClassForTests { + public static final String zk36Group = "zk36"; + public static final String zk35TestCompatibilityGroup = "zk35TestCompatibility"; + protected final Timing2 timing = new Timing2(); } diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncCuratorFrameworkImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncCuratorFrameworkImpl.java index 167cf50..07c3398 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncCuratorFrameworkImpl.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncCuratorFrameworkImpl.java @@ -26,7 +26,9 @@ import org.apache.curator.framework.imps.CuratorFrameworkImpl; import org.apache.curator.framework.imps.CuratorMultiTransactionImpl; import org.apache.curator.framework.imps.GetACLBuilderImpl; import org.apache.curator.framework.imps.SyncBuilderImpl; -import org.apache.curator.x.async.*; +import org.apache.curator.x.async.AsyncCuratorFramework; +import org.apache.curator.x.async.AsyncStage; +import org.apache.curator.x.async.WatchMode; import org.apache.curator.x.async.api.*; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.data.ACL; @@ -221,6 +223,16 @@ public class AsyncCuratorFrameworkImpl implements AsyncCuratorFramework return new AsyncGetConfigBuilderImpl(client, filters, getBuilderWatchMode()); } + Filters getFilters() + { + return filters; + } + + CuratorFrameworkImpl getClient() + { + return client; + } + private WatchMode getBuilderWatchMode() { return watched ? watchMode : null; diff --git a/pom.xml b/pom.xml index b702b77..46e5641 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <jdk-version>1.${short-jdk-version}</jdk-version> <!-- versions --> - <zookeeper-version>3.5.7</zookeeper-version> + <zookeeper-version>3.6.0</zookeeper-version> <maven-bundle-plugin-version>4.1.0</maven-bundle-plugin-version> <maven-javadoc-plugin-version>3.0.1</maven-javadoc-plugin-version> <doxia-module-confluence-version>1.8</doxia-module-confluence-version> @@ -85,25 +85,27 @@ <guava-failureaccess-version>1.0.1</guava-failureaccess-version> <testng-version>6.14.3</testng-version> <swift-version>0.23.1</swift-version> - <dropwizard-version>1.3.7</dropwizard-version> <maven-shade-plugin-version>3.2.1</maven-shade-plugin-version> <slf4j-version>1.7.25</slf4j-version> <clirr-maven-plugin-version>2.8</clirr-maven-plugin-version> + <dropwizard-version>3.2.5</dropwizard-version> + <snappy-version>1.1.7</snappy-version> <!-- OSGi Properties --> - <osgi.export.package /> - <osgi.import.package /> - <osgi.private.package /> - <osgi.dynamic.import /> - <osgi.require.bundle /> - <osgi.export.service /> - <osgi.activator /> + <osgi.export.package/> + <osgi.import.package/> + <osgi.private.package/> + <osgi.dynamic.import/> + <osgi.require.bundle/> + <osgi.export.service/> + <osgi.activator/> </properties> <scm> <url>https://github.com/apache/curator.git</url> <connection>scm:git:https://gitbox.apache.org/repos/asf/curator.git</connection> - <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/curator.git</developerConnection> + <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/curator.git + </developerConnection> <tag>apache-curator-3.2.0</tag> </scm> @@ -317,6 +319,7 @@ <module>curator-x-discovery</module> <module>curator-x-discovery-server</module> <module>curator-x-async</module> + <module>curator-test-zk35</module> </modules> <dependencyManagement> @@ -566,6 +569,24 @@ <artifactId>dropwizard-logging</artifactId> <version>${dropwizard-version}</version> </dependency> + + <dependency> + <groupId>io.dropwizard.metrics</groupId> + <artifactId>metrics-core</artifactId> + <version>${dropwizard-version}</version> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.xerial.snappy</groupId> + <artifactId>snappy-java</artifactId> + <version>${snappy-version}</version> + </dependency> </dependencies> </dependencyManagement> @@ -581,7 +602,6 @@ <artifactId>maven-javadoc-plugin</artifactId> <version>${maven-javadoc-plugin-version}</version> <configuration> - <aggregate>true</aggregate> <additionalJOptions> <additionalJOption>-J-Xmx1g</additionalJOption> </additionalJOptions> @@ -942,5 +962,14 @@ </plugins> </build> </profile> + <profile> + <id>staging-repo</id> + <repositories> + <repository> + <id>staging-repo</id> + <url>https://repository.apache.org/content/groups/staging/</url> + </repository> + </repositories> + </profile> </profiles> </project>