Explorar el Código

ZOOKEEPER-1894. ObserverTest.testObserver fails consistently. (michim via camille)

git-svn-id: https://svn.apache.org/repos/asf/zookeeper/trunk@1582572 13f79535-47bb-0310-9956-ffa450edef68
Camille Fournier hace 11 años
padre
commit
bf399b1cbc

+ 2 - 0
CHANGES.txt

@@ -581,6 +581,8 @@ BUGFIXES:
 
   ZOOKEEPER-1901. [JDK8] Sort children for comparison in AsyncOps tests
   (Andrew Purtell via michim)
+  
+  ZOOKEEPER-1894. ObserverTest.testObserver fails consistently. (michim via camille)
 
   ZOOKEEPER-1263. fix handling of min/max session timeout value initialization
   (Rakesh R via michim)

+ 59 - 0
src/java/main/org/apache/zookeeper/common/HostNameUtils.java

@@ -0,0 +1,59 @@
+/*
+ * 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.zookeeper.common;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+/**
+ * A class with hostname related utility methods.
+ */
+public class HostNameUtils {
+
+    private HostNameUtils() {
+        // non instantiable and non inheritable
+    }
+
+    /**
+     * Returns the hostname or IP address of {@link java.net.InetSocketAddress}.
+     *
+     * This method returns the IP address if the
+     * {@link java.net.InetSocketAddress} was created with a literal IP address,
+     * and it doesn't perform a reverse DNS lookup. The goal of this method is
+     * to substitute {@link java.net.InetSocketAddress#getHostString()}, which
+     * is only available since Java 7.
+     *
+     * This method checks if the input InetSocketAddress was constructed with a
+     * literal IP address by calling toString() on the underlying
+     * {@link java.net.InetAddress}. It returns a string with the form
+     * "hostname/literal IP address", and the hostname part is empty if the
+     * input {@link java.net.InetSocketAddress} was created with an IP address.
+     * There are 2 implementations of {@link java.net.InetAddress},
+     * {@link java.net.Inet4Address} and {@link java.net.Inet6Address}, and both
+     * classes are final, so we can trust the return value of the toString()
+     * method.
+     *
+     * @return the hostname or IP address of {@link java.net.InetSocketAddress}.
+     * @see java.net.InetSocketAddress#getHostString()
+     */
+    public static String getHostString(InetSocketAddress socketAddress) {
+        InetAddress address = socketAddress.getAddress();
+        return (address != null && address.toString().startsWith("/")) ?
+               address.getHostAddress() :
+               socketAddress.getHostName();
+    }
+}

+ 4 - 1
src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java

@@ -47,6 +47,7 @@ import java.util.Set;
 import org.apache.zookeeper.KeeperException.NoNodeException;
 import org.apache.zookeeper.ZooDefs;
 import org.apache.zookeeper.common.AtomicFileOutputStream;
+import org.apache.zookeeper.common.HostNameUtils;
 import org.apache.zookeeper.jmx.MBeanRegistry;
 import org.apache.zookeeper.jmx.ZKMBeanInfo;
 import org.apache.zookeeper.server.DataNode;
@@ -233,7 +234,9 @@ public class QuorumPeer extends ZooKeeperThread implements QuorumStats.Provider
             else if (type == LearnerType.PARTICIPANT) sw.append(":participant");            
             if (clientAddr!=null){
                 sw.append(";");
-                sw.append(clientAddr.getHostName() + ":" + String.valueOf(clientAddr.getPort()));
+                sw.append(HostNameUtils.getHostString(clientAddr));
+                sw.append(":");
+                sw.append(String.valueOf(clientAddr.getPort()));
             }
             return sw.toString();       
         }

+ 97 - 0
src/java/test/org/apache/zookeeper/common/HostNameUtilsTest.java

@@ -0,0 +1,97 @@
+/*
+ * 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.zookeeper.common;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HostNameUtilsTest {
+
+    private String validName = "example.com";
+    private String invalidName = "example.com_invalid";
+    private int port = 123;
+
+    @Test
+    public void testWildcard() {
+        InetSocketAddress socketAddress = new InetSocketAddress(port);
+        Assert.assertEquals("InetSocketAddress with no host. " +
+                            "Expecting 0.0.0.0.",
+                            socketAddress.getAddress().getHostAddress(),
+                            HostNameUtils.getHostString(socketAddress));
+    }
+
+    @Test
+    public void testHostName() {
+        InetSocketAddress socketAddress =
+            new InetSocketAddress(validName, port);
+        Assert.assertEquals("InetSocketAddress with a valid hostname",
+                            validName,
+                            HostNameUtils.getHostString(socketAddress));
+
+        socketAddress = new InetSocketAddress(invalidName, port);
+        Assert.assertEquals("InetSocketAddress with an invalid hostname",
+                            invalidName,
+                            HostNameUtils.getHostString(socketAddress));
+    }
+
+    @Test
+    public void testGetByAddress() {
+        try {
+            byte[] byteAddress = new byte[]{1, 2, 3, 4};
+            InetAddress address = InetAddress.getByAddress(byteAddress);
+            InetSocketAddress socketAddress =
+                new InetSocketAddress(address, port);
+            Assert.assertEquals("getByAddress with byte address only.",
+                                address.getHostAddress(),
+                                HostNameUtils.getHostString(socketAddress));
+
+            address = InetAddress.getByAddress(validName, byteAddress);
+            socketAddress = new InetSocketAddress(address, port);
+            Assert.assertEquals("getByAddress with a valid hostname and byte " +
+                                "address.",
+                                validName,
+                                HostNameUtils.getHostString(socketAddress));
+
+            address = InetAddress.getByAddress(invalidName, byteAddress);
+            socketAddress = new InetSocketAddress(address, port);
+            Assert.assertEquals("getByAddress with an invalid hostname and " +
+                                "byte address.",
+                                invalidName,
+                                HostNameUtils.getHostString(socketAddress));
+        } catch (UnknownHostException ex) {
+            Assert.fail(ex.toString());
+        }
+    }
+
+    @Test
+    public void testGetByName() {
+        try {
+            InetAddress address = InetAddress.getByName(validName);
+            InetSocketAddress socketAddress =
+                new InetSocketAddress(address, port);
+            Assert.assertEquals("getByName with a valid hostname.",
+                                validName,
+                                HostNameUtils.getHostString(socketAddress));
+        } catch (UnknownHostException ex) {
+            Assert.fail(ex.toString());
+        }
+    }
+}