This is an automated email from the ASF dual-hosted git repository.

smengcl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new aac57526e3e HDDS-16307. Construct listeners from separate host and 
port values (#11130)
aac57526e3e is described below

commit aac57526e3eb1d4b3bfd6fd92752fe8d382a0b80
Author: rjgoyln <[email protected]>
AuthorDate: Fri Sep 25 06:52:33 2026 +0800

    HDDS-16307. Construct listeners from separate host and port values (#11130)
    
    Generated-by: Claude Code (Opus 5)
---
 .../java/org/apache/hadoop/hdds/HddsUtils.java     |  2 +-
 .../java/org/apache/hadoop/hdds/TestHddsUtils.java | 16 ++++++
 .../org/apache/hadoop/hdds/server/ServerUtils.java |  3 +-
 .../hadoop/hdds/server/http/BaseHttpServer.java    | 24 +++++++--
 .../apache/hadoop/hdds/utils/HddsServerUtil.java   | 30 +++++------
 .../apache/hadoop/hdds/server/TestServerUtils.java | 16 ++++++
 .../hdds/server/http/TestBaseHttpServer.java       | 30 +++++++++++
 .../java/org/apache/hadoop/hdds/scm/ScmUtils.java  | 33 ++++++------
 .../apache/hadoop/hdds/scm/TestHddsServerUtil.java | 39 ++++++++++++++
 .../org/apache/hadoop/hdds/scm/TestScmUtils.java   | 63 ++++++++++++++++++++++
 .../java/org/apache/hadoop/ozone/TestOmUtils.java  | 18 +++++++
 11 files changed, 235 insertions(+), 39 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsUtils.java 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsUtils.java
index b4bebeb8b27..93a84f7c6f7 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsUtils.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsUtils.java
@@ -403,7 +403,7 @@ public static String getHostName(ConfigurationSource conf)
         .orElse(conf.getInt(HDDS_DATANODE_CLIENT_PORT_KEY,
             HDDS_DATANODE_CLIENT_PORT_DEFAULT));
 
-    return NetUtils.createSocketAddr(host + ":" + port);
+    return NetUtils.createSocketAddr(getHostPortString(host, port));
   }
 
   /**
diff --git 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/TestHddsUtils.java 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/TestHddsUtils.java
index 8fdf6de7b50..065dc8b6829 100644
--- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/TestHddsUtils.java
+++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/TestHddsUtils.java
@@ -17,12 +17,16 @@
 
 package org.apache.hadoop.hdds;
 
+import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_DATANODE_CLIENT_ADDRESS_KEY;
+import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_DATANODE_CLIENT_BIND_HOST_KEY;
 import static org.apache.hadoop.hdds.HddsUtils.processForLogging;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_DATANODE_PORT_KEY;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_PIPELINE_OWNER_CONTAINER_COUNT;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
@@ -102,6 +106,18 @@ void testGetHostPortString() {
     assertEquals("[2001:db8::1]:9858", 
HddsUtils.getHostPortString("[2001:db8::1]", 9858));
   }
 
+  @Test
+  void testGetDatanodeRpcAddressWithIPv6BindHost() throws Exception {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    conf.set(HDDS_DATANODE_CLIENT_BIND_HOST_KEY, "::");
+    conf.set(HDDS_DATANODE_CLIENT_ADDRESS_KEY, "[2001:db8::1]:100");
+
+    InetSocketAddress addr = HddsUtils.getDatanodeRpcAddress(conf);
+
+    assertEquals(InetAddress.getByName("::"), addr.getAddress());
+    assertEquals(100, addr.getPort());
+  }
+
   @Test
   void testParseRatisRoleStringIPv4() {
     String input = "hostname1:9894:LEADER:peer-uuid-123:192.168.1.1";
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/ServerUtils.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/ServerUtils.java
index 481df512496..092bfaa88e4 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/ServerUtils.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/ServerUtils.java
@@ -26,6 +26,7 @@
 import java.util.Collection;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hdds.HddsConfigKeys;
+import org.apache.hadoop.hdds.HddsUtils;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeType;
@@ -120,7 +121,7 @@ public static InetSocketAddress 
updateListenAddress(OzoneConfiguration conf,
     InetSocketAddress updatedAddr = new InetSocketAddress(addr.getHostString(),
         listenAddr.getPort());
     conf.set(addressKey,
-        addr.getHostString() + ":" + listenAddr.getPort());
+        HddsUtils.getHostPortString(addr.getHostString(), 
listenAddr.getPort()));
     return updatedAddr;
   }
 
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
index 9b2a0a61fda..7d673e2d8b4 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
@@ -19,6 +19,7 @@
 
 import static org.apache.hadoop.hdds.HddsUtils.createDir;
 import static org.apache.hadoop.hdds.HddsUtils.getHostNameFromConfigKeys;
+import static org.apache.hadoop.hdds.HddsUtils.getHostPortString;
 import static org.apache.hadoop.hdds.HddsUtils.getPortNumberFromConfigKeys;
 import static org.apache.hadoop.hdds.server.ServerUtils.getOzoneMetaDirPath;
 import static org.apache.hadoop.hdds.server.http.HttpConfig.getHttpPolicy;
@@ -223,7 +224,7 @@ public static HttpServer2.Builder 
newHttpServer2BuilderForOzone(
         builder.setFindPort(true);
       }
 
-      URI uri = URI.create("http://"; + NetUtils.getHostPortString(httpAddr));
+      URI uri = newEndpointUri("http", httpAddr);
       builder.addEndpoint(uri);
       LOG.info("Starting Web-server for {} at: {}", name, uri);
     }
@@ -236,7 +237,7 @@ public static HttpServer2.Builder 
newHttpServer2BuilderForOzone(
         builder.setFindPort(true);
       }
 
-      URI uri = URI.create("https://"; + NetUtils.getHostPortString(httpsAddr));
+      URI uri = newEndpointUri("https", httpsAddr);
       builder.addEndpoint(uri);
       LOG.info("Starting Web-server for {} at: {}", name, uri);
     }
@@ -281,6 +282,17 @@ protected WebAppContext getWebAppContext() {
     return httpServer.getWebAppContext();
   }
 
+  /**
+   * Build a listener endpoint URI. Jetty reads the host and port straight off
+   * this URI, and an unbracketed IPv6 authority parses to a null host and a
+   * port of -1 without raising, which binds the server to every interface on
+   * an ephemeral port.
+   */
+  static URI newEndpointUri(String scheme, InetSocketAddress addr) {
+    return URI.create(scheme + "://"
+        + getHostPortString(addr.getHostName(), addr.getPort()));
+  }
+
   protected InetSocketAddress getBindAddress(String bindHostKey,
       String addressKey, String bindHostDefault, int bindPortdefault) {
     final Optional<String> bindHost =
@@ -295,7 +307,7 @@ protected InetSocketAddress getBindAddress(String 
bindHostKey,
     String hostName = bindHost.orElse(addressHost.orElse(bindHostDefault));
 
     return NetUtils.createSocketAddr(
-        hostName + ":" + addressPort.orElse(bindPortdefault));
+        getHostPortString(hostName, addressPort.orElse(bindPortdefault)));
   }
 
   /**
@@ -358,14 +370,16 @@ public void updateConnectorAddress() {
     int connIdx = 0;
     if (policy.isHttpEnabled()) {
       httpAddress = httpServer.getConnectorAddress(connIdx++);
-      String realAddress = 
NetUtils.getHostPortString(NetUtils.getConnectAddress(httpAddress));
+      InetSocketAddress connectAddress = 
NetUtils.getConnectAddress(httpAddress);
+      String realAddress = getHostPortString(connectAddress.getHostName(), 
connectAddress.getPort());
       conf.set(getHttpAddressKey(), realAddress);
       LOG.info("HTTP server of {} listening at http://{}";, name, realAddress);
     }
 
     if (policy.isHttpsEnabled()) {
       httpsAddress = httpServer.getConnectorAddress(connIdx);
-      String realAddress = 
NetUtils.getHostPortString(NetUtils.getConnectAddress(httpsAddress));
+      InetSocketAddress connectAddress = 
NetUtils.getConnectAddress(httpsAddress);
+      String realAddress = getHostPortString(connectAddress.getHostName(), 
connectAddress.getPort());
       conf.set(getHttpsAddressKey(), realAddress);
       LOG.info("HTTPS server of {} listening at https://{}";, name, 
realAddress);
     }
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
index e2d5536ffaf..7ffe7c7a643 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
@@ -28,6 +28,7 @@
 import static org.apache.hadoop.hdds.HddsUtils.getHostName;
 import static org.apache.hadoop.hdds.HddsUtils.getHostNameFromConfigKeys;
 import static org.apache.hadoop.hdds.HddsUtils.getHostPort;
+import static org.apache.hadoop.hdds.HddsUtils.getHostPortString;
 import static org.apache.hadoop.hdds.HddsUtils.getPortNumberFromConfigKeys;
 import static org.apache.hadoop.hdds.HddsUtils.getScmServiceId;
 import static 
org.apache.hadoop.hdds.recon.ReconConfigKeys.OZONE_RECON_ADDRESS_KEY;
@@ -267,7 +268,7 @@ public static InetSocketAddress getScmClientBindAddress(
         .orElse(conf.getInt(ScmConfigKeys.OZONE_SCM_CLIENT_PORT_KEY,
             ScmConfigKeys.OZONE_SCM_CLIENT_PORT_DEFAULT));
 
-    return NetUtils.createSocketAddr(host + ":" + port);
+    return NetUtils.createSocketAddr(getHostPortString(host, port));
   }
 
   /**
@@ -288,7 +289,7 @@ public static InetSocketAddress 
getScmBlockClientBindAddress(
         .orElse(conf.getInt(ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_PORT_KEY,
             ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_PORT_DEFAULT));
 
-    return NetUtils.createSocketAddr(host + ":" + port);
+    return NetUtils.createSocketAddr(getHostPortString(host, port));
   }
 
   /**
@@ -307,12 +308,10 @@ public static InetSocketAddress getScmSecurityInetAddress(
     final OptionalInt port = getPortNumberFromConfigKeys(conf,
         ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_ADDRESS_KEY);
 
-    return NetUtils.createSocketAddr(
-        host
-            + ":" + port
-            .orElse(conf.getInt(ScmConfigKeys
-                    .OZONE_SCM_SECURITY_SERVICE_PORT_KEY,
-                ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_PORT_DEFAULT)));
+    return NetUtils.createSocketAddr(getHostPortString(host,
+        port.orElse(conf.getInt(
+            ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_PORT_KEY,
+            ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_PORT_DEFAULT))));
   }
 
   /**
@@ -330,10 +329,10 @@ public static InetSocketAddress getScmDataNodeBindAddress(
     final OptionalInt port = getPortNumberFromConfigKeys(conf,
         ScmConfigKeys.OZONE_SCM_DATANODE_ADDRESS_KEY);
 
-    return NetUtils.createSocketAddr(
-        host.orElse(ScmConfigKeys.OZONE_SCM_DATANODE_BIND_HOST_DEFAULT) + ":" +
-            port.orElse(conf.getInt(OZONE_SCM_DATANODE_PORT_KEY,
-                ScmConfigKeys.OZONE_SCM_DATANODE_PORT_DEFAULT)));
+    return NetUtils.createSocketAddr(getHostPortString(
+        host.orElse(ScmConfigKeys.OZONE_SCM_DATANODE_BIND_HOST_DEFAULT),
+        port.orElse(conf.getInt(OZONE_SCM_DATANODE_PORT_KEY,
+            ScmConfigKeys.OZONE_SCM_DATANODE_PORT_DEFAULT))));
   }
 
   /**
@@ -351,10 +350,9 @@ public static InetSocketAddress 
getReconDataNodeBindAddress(
     final OptionalInt port = getPortNumberFromConfigKeys(conf,
         ReconConfigKeys.OZONE_RECON_DATANODE_ADDRESS_KEY);
 
-    return NetUtils.createSocketAddr(
-        host.orElse(
-            ReconConfigKeys.OZONE_RECON_DATANODE_BIND_HOST_DEFAULT) + ":" +
-            port.orElse(ReconConfigKeys.OZONE_RECON_DATANODE_PORT_DEFAULT));
+    return NetUtils.createSocketAddr(getHostPortString(
+        host.orElse(ReconConfigKeys.OZONE_RECON_DATANODE_BIND_HOST_DEFAULT),
+        port.orElse(ReconConfigKeys.OZONE_RECON_DATANODE_PORT_DEFAULT)));
   }
 
   /**
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/TestServerUtils.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/TestServerUtils.java
index 7a50a09cb21..b9344a0f472 100644
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/TestServerUtils.java
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/TestServerUtils.java
@@ -30,6 +30,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.net.InetSocketAddress;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -53,6 +54,21 @@ public class TestServerUtils {
   @TempDir
   private Path folder;
 
+  /**
+   * The address written back after a server binds must stay parseable, so an
+   * IPv6 listen address is bracketed rather than joined with a plain colon.
+   */
+  @Test
+  public void testUpdateListenAddressBracketsIPv6() {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    InetSocketAddress bindAddr = new InetSocketAddress("2001:db8::1", 0);
+    InetSocketAddress listenAddr = new InetSocketAddress("2001:db8::1", 9860);
+
+    ServerUtils.updateListenAddress(conf, "test.address.key", bindAddr, 
listenAddr);
+
+    assertEquals("[2001:db8:0:0:0:0:0:1]:9860", conf.get("test.address.key"));
+  }
+
   /**
    * Test case for {@link ServerUtils#getPermissions}.
    * Verifies the retrieval of permissions for different configs.
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestBaseHttpServer.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestBaseHttpServer.java
index f96c9a52163..7a7df2422a1 100644
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestBaseHttpServer.java
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestBaseHttpServer.java
@@ -21,6 +21,8 @@
 
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URI;
 import java.nio.file.Path;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
@@ -137,6 +139,34 @@ protected String getHttpAuthConfigPrefix() {
     assertEquals("/1.2.3.4:1234", baseHttpServer
         .getBindAddress("bindhostkey", "addresskey",
             "default", 65).toString());
+
+    // An IPv6 bind host, wildcard or literal, must survive being combined with
+    // the port. Assert on the address rather than toString(), whose bracketing
+    // of IPv6 literals is a JDK detail.
+    conf.set("bindhostkey", "::");
+
+    InetSocketAddress wildcard = baseHttpServer
+        .getBindAddress("bindhostkey", "addresskey", "default", 65);
+    assertEquals(InetAddress.getByName("::"), wildcard.getAddress());
+    assertEquals(1234, wildcard.getPort());
+
+    conf.set("bindhostkey", "2001:db8::1");
+
+    InetSocketAddress literal = baseHttpServer
+        .getBindAddress("bindhostkey", "addresskey", "default", 65);
+    assertEquals(InetAddress.getByName("2001:db8::1"), literal.getAddress());
+    assertEquals(1234, literal.getPort());
+  }
+
+  @Test
+  void endpointUriKeepsHostAndPort() {
+    URI ipv4 = BaseHttpServer.newEndpointUri("http", new 
InetSocketAddress("192.0.2.1", 9874));
+    assertEquals("192.0.2.1", ipv4.getHost());
+    assertEquals(9874, ipv4.getPort());
+
+    URI ipv6 = BaseHttpServer.newEndpointUri("https", new 
InetSocketAddress("2001:db8::1", 9875));
+    assertEquals("[2001:db8:0:0:0:0:0:1]", ipv6.getHost());
+    assertEquals(9875, ipv6.getPort());
   }
 
   @ParameterizedTest
diff --git 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ScmUtils.java 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ScmUtils.java
index a5465aa993d..59444813f03 100644
--- 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ScmUtils.java
+++ 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ScmUtils.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hdds.scm;
 
 import static org.apache.hadoop.hdds.HddsUtils.getHostNameFromConfigKeys;
+import static org.apache.hadoop.hdds.HddsUtils.getHostPortString;
 import static org.apache.hadoop.hdds.HddsUtils.getPortNumberFromConfigKeys;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_ADDRESS_KEY;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_BIND_HOST_DEFAULT;
@@ -85,14 +86,13 @@ public static InetSocketAddress 
getScmBlockProtocolServerAddress(
       logWarn(OZONE_SCM_BLOCK_CLIENT_ADDRESS_KEY,
           OZONE_SCM_BLOCK_CLIENT_PORT_KEY);
     }
-    return NetUtils.createSocketAddr(
-        host.orElse(
-            OZONE_SCM_BLOCK_CLIENT_BIND_HOST_DEFAULT) + ":" +
-            port.orElse(conf.getInt(
-                ConfUtils.addKeySuffixes(OZONE_SCM_BLOCK_CLIENT_PORT_KEY,
-                    localScmServiceId, nodeId),
-                conf.getInt(OZONE_SCM_BLOCK_CLIENT_PORT_KEY,
-                    OZONE_SCM_BLOCK_CLIENT_PORT_DEFAULT))));
+    return NetUtils.createSocketAddr(getHostPortString(
+        host.orElse(OZONE_SCM_BLOCK_CLIENT_BIND_HOST_DEFAULT),
+        port.orElse(conf.getInt(
+            ConfUtils.addKeySuffixes(OZONE_SCM_BLOCK_CLIENT_PORT_KEY,
+                localScmServiceId, nodeId),
+            conf.getInt(OZONE_SCM_BLOCK_CLIENT_PORT_KEY,
+                OZONE_SCM_BLOCK_CLIENT_PORT_DEFAULT)))));
   }
 
   public static String getScmBlockProtocolServerAddressKey(
@@ -118,12 +118,12 @@ public static InetSocketAddress 
getClientProtocolServerAddress(
       logWarn(OZONE_SCM_CLIENT_ADDRESS_KEY, OZONE_SCM_CLIENT_PORT_KEY);
     }
 
-    return NetUtils.createSocketAddr(host + ":" +
+    return NetUtils.createSocketAddr(getHostPortString(host,
         port.orElse(
             conf.getInt(ConfUtils.addKeySuffixes(OZONE_SCM_CLIENT_PORT_KEY,
                 localScmServiceId, nodeId),
             conf.getInt(OZONE_SCM_CLIENT_PORT_KEY,
-                OZONE_SCM_CLIENT_PORT_DEFAULT))));
+                OZONE_SCM_CLIENT_PORT_DEFAULT)))));
   }
 
   public static String getClientProtocolServerAddressKey(
@@ -145,12 +145,13 @@ public static InetSocketAddress getScmDataNodeBindAddress(
       logWarn(OZONE_SCM_DATANODE_ADDRESS_KEY, OZONE_SCM_DATANODE_PORT_KEY);
     }
 
-    return NetUtils.createSocketAddr(
-        host.orElse(OZONE_SCM_DATANODE_BIND_HOST_DEFAULT) + ":" +
-            port.orElse(conf.getInt(ConfUtils.addKeySuffixes(
-                OZONE_SCM_DATANODE_PORT_KEY, localScmServiceId, nodeId),
-                conf.getInt(OZONE_SCM_DATANODE_PORT_KEY,
-                    OZONE_SCM_DATANODE_PORT_DEFAULT))));
+    return NetUtils.createSocketAddr(getHostPortString(
+        host.orElse(OZONE_SCM_DATANODE_BIND_HOST_DEFAULT),
+        port.orElse(conf.getInt(
+            ConfUtils.addKeySuffixes(OZONE_SCM_DATANODE_PORT_KEY,
+                localScmServiceId, nodeId),
+            conf.getInt(OZONE_SCM_DATANODE_PORT_KEY,
+                OZONE_SCM_DATANODE_PORT_DEFAULT)))));
   }
 
   public static String getScmDataNodeBindAddressKey(
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtil.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtil.java
index 46edbf13c8d..f277741b378 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtil.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtil.java
@@ -27,6 +27,7 @@
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -35,6 +36,7 @@
 import java.util.List;
 import java.util.Map;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.recon.ReconConfigKeys;
 import org.apache.hadoop.hdds.scm.ha.SCMNodeInfo;
 import org.apache.hadoop.hdds.scm.net.HostAndPort;
 import org.apache.hadoop.hdds.utils.HddsServerUtil;
@@ -180,6 +182,43 @@ public void testScmDataNodeBindHostDefault() {
     assertEquals(200, addr.getPort());
   }
 
+  /**
+   * Verify that a bind host holding an IPv6 literal, including the wildcard
+   * {@code ::}, yields a usable listener address.
+   */
+  @Test
+  void testBindAddressesAcceptIPv6BindHost() throws Exception {
+    final OzoneConfiguration conf = new OzoneConfiguration();
+    conf.set(ScmConfigKeys.OZONE_SCM_CLIENT_BIND_HOST_KEY, "::");
+    conf.set(ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_BIND_HOST_KEY, "::");
+    conf.set(ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_BIND_HOST_KEY, "::");
+    conf.set(ScmConfigKeys.OZONE_SCM_DATANODE_BIND_HOST_KEY, "2001:db8::1");
+    conf.set(ReconConfigKeys.OZONE_RECON_DATANODE_BIND_HOST_KEY, 
"2001:db8::1");
+
+    final InetAddress wildcard = InetAddress.getByName("::");
+    final InetAddress literal = InetAddress.getByName("2001:db8::1");
+
+    InetSocketAddress addr = HddsServerUtil.getScmClientBindAddress(conf);
+    assertEquals(wildcard, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_CLIENT_PORT_DEFAULT, addr.getPort());
+
+    addr = HddsServerUtil.getScmBlockClientBindAddress(conf);
+    assertEquals(wildcard, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_PORT_DEFAULT, 
addr.getPort());
+
+    addr = HddsServerUtil.getScmSecurityInetAddress(conf);
+    assertEquals(wildcard, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_PORT_DEFAULT, 
addr.getPort());
+
+    addr = HddsServerUtil.getScmDataNodeBindAddress(conf);
+    assertEquals(literal, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_DATANODE_PORT_DEFAULT, 
addr.getPort());
+
+    addr = HddsServerUtil.getReconDataNodeBindAddress(conf);
+    assertEquals(literal, addr.getAddress());
+    assertEquals(ReconConfigKeys.OZONE_RECON_DATANODE_PORT_DEFAULT, 
addr.getPort());
+  }
+
   @Test
   void testGetSCMAddresses() {
     final OzoneConfiguration conf = new OzoneConfiguration();
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestScmUtils.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestScmUtils.java
new file mode 100644
index 00000000000..7660ab1f4f9
--- /dev/null
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestScmUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.hadoop.hdds.scm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.ha.ConfUtils;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test the SCM utility class.
+ */
+public class TestScmUtils {
+
+  private static final String SERVICE_ID = "scmservice";
+  private static final String NODE_ID = "scm1";
+
+  /**
+   * Verify that a per-node bind host holding an IPv6 literal, including the
+   * wildcard {@code ::}, yields a usable listener address.
+   */
+  @Test
+  void testHaBindAddressesAcceptIPv6BindHost() throws Exception {
+    final OzoneConfiguration conf = new OzoneConfiguration();
+    
conf.set(ConfUtils.addKeySuffixes(ScmConfigKeys.OZONE_SCM_CLIENT_BIND_HOST_KEY, 
SERVICE_ID, NODE_ID), "::");
+    
conf.set(ConfUtils.addKeySuffixes(ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_BIND_HOST_KEY,
 SERVICE_ID, NODE_ID), "::");
+    
conf.set(ConfUtils.addKeySuffixes(ScmConfigKeys.OZONE_SCM_DATANODE_BIND_HOST_KEY,
 SERVICE_ID, NODE_ID),
+        "2001:db8::1");
+
+    final InetAddress wildcard = InetAddress.getByName("::");
+    final InetAddress literal = InetAddress.getByName("2001:db8::1");
+
+    InetSocketAddress addr = ScmUtils.getClientProtocolServerAddress(conf, 
SERVICE_ID, NODE_ID);
+    assertEquals(wildcard, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_CLIENT_PORT_DEFAULT, addr.getPort());
+
+    addr = ScmUtils.getScmBlockProtocolServerAddress(conf, SERVICE_ID, 
NODE_ID);
+    assertEquals(wildcard, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_PORT_DEFAULT, 
addr.getPort());
+
+    addr = ScmUtils.getScmDataNodeBindAddress(conf, SERVICE_ID, NODE_ID);
+    assertEquals(literal, addr.getAddress());
+    assertEquals(ScmConfigKeys.OZONE_SCM_DATANODE_PORT_DEFAULT, 
addr.getPort());
+  }
+}
diff --git 
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOmUtils.java 
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOmUtils.java
index 0657d3b4b24..1765ad55523 100644
--- a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOmUtils.java
+++ b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOmUtils.java
@@ -437,6 +437,24 @@ public void testShouldSendToFollowerImpliesIsReadOnly() {
     }
   }
 
+  @Test
+  void testOmAddressesBracketIPv6Literals() {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    conf.set(OZONE_OM_ADDRESS_KEY, "[2001:db8::1]:9999");
+
+    assertEquals("[2001:db8::1]:9999", OmUtils.getOmRpcAddress(conf));
+
+    String peerAddressKey = OZONE_OM_ADDRESS_KEY + ".omservice.om1";
+    conf.set(peerAddressKey, "2001:db8::2");
+    assertEquals("[2001:db8::2]:" + OMConfigKeys.OZONE_OM_PORT_DEFAULT,
+        OmUtils.getOmRpcAddress(conf, peerAddressKey));
+
+    assertEquals("[2001:db8::3]:" + 
OMConfigKeys.OZONE_OM_HTTP_BIND_PORT_DEFAULT,
+        OmUtils.getHttpAddressForOMPeerNode(conf, "omservice", "om1", 
"2001:db8::3"));
+    assertEquals("[2001:db8::3]:" + 
OMConfigKeys.OZONE_OM_HTTPS_BIND_PORT_DEFAULT,
+        OmUtils.getHttpsAddressForOMPeerNode(conf, "omservice", "om1", 
"2001:db8::3"));
+  }
+
   @Test
   public void testResolveOmHostAcceptsIpv6Literal() {
     // A bracketed or bare IPv6 literal must parse into a host:port authority.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to