Repository: zookeeper Updated Branches: refs/heads/master f4cbb689a -> e116d32b6
ZOOKEEPER-2847: Cannot bind to client port when reconfig based on old static config Fixed the issue where clientPortAddress in the static config is not correctly saved in QuorumVerifier. This can cause zookeeper attempting to re-bind to a port already in use during dynamic reconfiguration, failing to recognize that the new port and the current port are identical. Author: Yisong Yue <yisong...@fb.com> Reviewers: h...@apache.org Closes #620 from yisong-yue/ZOOKEEPER-2847 Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/e116d32b Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/e116d32b Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/e116d32b Branch: refs/heads/master Commit: e116d32b63039fe9f0677f0af76c0a77fe74c82b Parents: f4cbb68 Author: Yisong Yue <yisong...@fb.com> Authored: Fri Sep 21 21:43:45 2018 -0700 Committer: Michael Han <h...@apache.org> Committed: Fri Sep 21 21:43:45 2018 -0700 ---------------------------------------------------------------------- .../server/quorum/QuorumPeerConfig.java | 1 + .../server/quorum/QuorumPeerConfigTest.java | 33 ++++++++++++++++++++ 2 files changed, 34 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zookeeper/blob/e116d32b/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java b/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java index 19558cf..6aaf172 100644 --- a/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java +++ b/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java @@ -712,6 +712,7 @@ public class QuorumPeerConfig { " is different from client address found in dynamic file: " + qs.clientAddr); } if (qs != null && qs.clientAddr != null) clientPortAddress = qs.clientAddr; + if (qs != null && qs.clientAddr == null) qs.clientAddr = clientPortAddress; } private void setupPeerType() { http://git-wip-us.apache.org/repos/asf/zookeeper/blob/e116d32b/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerConfigTest.java ---------------------------------------------------------------------- diff --git a/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerConfigTest.java b/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerConfigTest.java index 3f5a2b2..524fcee 100644 --- a/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerConfigTest.java +++ b/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerConfigTest.java @@ -24,10 +24,12 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; +import java.net.InetSocketAddress; import java.util.Properties; import org.apache.zookeeper.common.ZKConfig; import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException; +import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer; import org.junit.Test; public class QuorumPeerConfigTest { @@ -114,6 +116,37 @@ public class QuorumPeerConfigTest { quorumPeerConfig.parseProperties(zkProp); } + /** + * Extend the existing QuorumPeerConfig to set the server id. + */ + public static class MockQuorumPeerConfig extends QuorumPeerConfig { + public MockQuorumPeerConfig(long serverId) { + this.serverId = serverId; + } + } + + /** + * Test case for https://issues.apache.org/jira/browse/ZOOKEEPER-2847 + */ + @Test + public void testClientAddrFromClientPort() + throws IOException, ConfigException { + long serverId = 1; + QuorumPeerConfig quorumPeerConfig = new MockQuorumPeerConfig(serverId); + Properties zkProp = getDefaultZKProperties(); + int clientPort = 12345; + zkProp.setProperty("clientPort", Integer.toString(clientPort)); + zkProp.setProperty("server.1", "127.0.0.1:2889:3889:participant"); + quorumPeerConfig.parseProperties(zkProp); + + QuorumServer qs = + quorumPeerConfig.getQuorumVerifier().getAllMembers().get(serverId); + InetSocketAddress expectedAddress = + new InetSocketAddress("0.0.0.0", clientPort); + assertEquals(expectedAddress, quorumPeerConfig.getClientPortAddress()); + assertEquals(quorumPeerConfig.getClientPortAddress(), qs.clientAddr); + } + private Properties getDefaultZKProperties() { Properties zkProp = new Properties(); zkProp.setProperty("dataDir", new File("myDataDir").getAbsolutePath());