This is an automated email from the ASF dual-hosted git repository.
difin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new fc7fe353a4a HIVE-28782: Avoid unsafe splits on URIs that might contain
IPv6 literals (#5729) (Dmitriy Fingerman, reviewed by Ayush Saxena, Kokila N)
fc7fe353a4a is described below
commit fc7fe353a4a51d360ef799ede81e3770043b594d
Author: Dmitriy Fingerman <[email protected]>
AuthorDate: Wed Apr 9 10:10:19 2025 -0400
HIVE-28782: Avoid unsafe splits on URIs that might contain IPv6 literals
(#5729) (Dmitriy Fingerman, reviewed by Ayush Saxena, Kokila N)
HIVE-28782: Avoid unsafe splits on URIs that might contain IPv6 literals
---
.../java/org/apache/hive/common/IPStackUtils.java | 86 ++++++++++++++
.../org/apache/hive/common/IPStackUtilsTest.java | 90 +++++++++------
.../hive/jdbc/ZooKeeperHiveClientHelper.java | 10 +-
.../hive/jdbc/ZooKeeperHiveClientHelperTest.java | 120 ++++++++++++++++++++
.../hadoop/hive/ql/lockmgr/HiveLockObject.java | 7 +-
.../hadoop/hive/ql/lockmgr/TestHiveLockObject.java | 123 +++++++++++++++------
.../service/server/HS2ActivePassiveHARegistry.java | 8 +-
7 files changed, 366 insertions(+), 78 deletions(-)
diff --git a/common/src/java/org/apache/hive/common/IPStackUtils.java
b/common/src/java/org/apache/hive/common/IPStackUtils.java
index 7b24b8a0781..949b6f14be1 100644
--- a/common/src/java/org/apache/hive/common/IPStackUtils.java
+++ b/common/src/java/org/apache/hive/common/IPStackUtils.java
@@ -20,6 +20,8 @@
import com.google.common.annotations.VisibleForTesting;
import io.netty.util.NetUtil;
+import org.apache.commons.lang3.StringUtils;
+
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
@@ -219,4 +221,88 @@ public static String transformToIPv6(String ipv4, int
port) {
return ipv4;
}
}
+
+ /**
+ * Splits a given input string representing a Hostname or an IP address and
port into an `HostPort` object.
+ * The input string must be in the format of IPv4/IPv6/[IPv6]/hostname:port.
+ *
+ * @param input The input string containing the Hostname/IP address and
port, in the format
+ * "IPv4:port", "[IPv6]:port", "IPv6:port", or "hostname:port".
+ * @return A {@link HostPort} object containing the parsed IP address and
port number.
+ * @throws IllegalArgumentException If the input format is invalid, if the
host is null or empty,
+ * or if the port number is invalid.
+ */
+ public static HostPort getHostAndPort(String input) {
+ String host;
+ int port;
+
+ if (StringUtils.isEmpty(input)) {
+ throw new IllegalArgumentException("Input string is null or empty");
+ }
+
+ // Check if the input contains a colon, which separates the host and port
+ int colonIndex = input.lastIndexOf(':');
+ if (colonIndex == -1) {
+ throw new IllegalArgumentException("Input does not contain a port.");
+ }
+
+ // Extract the host and port parts
+ host = input.substring(0, colonIndex);
+ port = getPort(input.substring(colonIndex + 1));
+
+ // Check if the host is not null or empty
+ if (StringUtils.isEmpty(host) || host.equals("[]")) {
+ throw new IllegalArgumentException("Host address is null or empty.");
+ }
+
+ // Handle IPv6 addresses enclosed in square brackets (e.g., [IPv6]:port)
+ if (host.startsWith("[") && host.endsWith("]")) {
+ host = host.substring(1, host.length() - 1); // Remove the square
brackets
+ }
+
+ return new HostPort(host, port);
+ }
+
+ /**
+ * Returns an integer representation of the port number.
+ * Also validates whether the given string represents a valid port number.
+ * A valid port number is an integer between 0 and 65535 inclusive.
+ *
+ * @param portString The string representing the port number.
+ * @return {@code int} the port number.
+ */
+ public static int getPort(String portString) {
+ if (StringUtils.isEmpty(portString)) {
+ throw new IllegalArgumentException("port is null or empty");
+ }
+
+ int port = Integer.parseInt(portString);
+ validatePort(port);
+ return port;
+ }
+
+ private static void validatePort(int port) {
+ if (port < 0 || port > 65535) {
+ throw new IllegalArgumentException("Port number out of range
(0-65535).");
+ }
+ }
+
+ public static class HostPort {
+
+ private final String hostname;
+ private final int port;
+
+ public HostPort(String hostname, int port) {
+ this.hostname = hostname;
+ this.port = port;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public int getPort() {
+ return port;
+ }
+ }
}
diff --git a/common/src/test/org/apache/hive/common/IPStackUtilsTest.java
b/common/src/test/org/apache/hive/common/IPStackUtilsTest.java
index 4c89c0e9069..7b289ee275f 100644
--- a/common/src/test/org/apache/hive/common/IPStackUtilsTest.java
+++ b/common/src/test/org/apache/hive/common/IPStackUtilsTest.java
@@ -79,34 +79,12 @@ void testIPv4WildcardWhenIPv6IsNotPreferred() {
}
@Test
- void testConcatHostPortIPv4Host() {
+ void testConcatHostPort() {
assertEquals("192.168.1.1:8080",
IPStackUtils.concatHostPort("192.168.1.1", 8080));
- }
-
- @Test
- void testConcatHostPortIPv6Host() {
assertEquals("[2001:db8::1]:8080",
IPStackUtils.concatHostPort("2001:db8::1", 8080));
- }
-
- @Test
- void testConcatHostPortIPv6Loopback() {
assertEquals("[::1]:9090", IPStackUtils.concatHostPort("::1", 9090));
- }
-
- @Test
- void testConcatHostPortHostname() {
assertEquals("example.com:443", IPStackUtils.concatHostPort("example.com",
443));
}
-
- @Test
- void testConcatHostPortLoobackIPv4() {
- assertEquals("127.0.0.1:3306", IPStackUtils.concatHostPort("127.0.0.1",
3306));
- }
-
- @Test
- void testConcatHostPortLoopbackIPv6() {
- assertEquals("[::1]:3306", IPStackUtils.concatHostPort("::1", 3306));
- }
@Test
void testWildcardWhenIPv4StackIsForcedAndIPv4WildcardProvided() {
@@ -164,20 +142,68 @@ void
testWildcardWhenIPv6IsNotPreferredAndIPv6WildcardProvided() {
}
@Test
- void testWildcardWhenNonWildcardIPv4AddressProvided() {
- String result = IPStackUtils.adaptWildcardAddress("192.168.1.1");
- assertEquals("192.168.1.1", result);
+ void testAdaptWildcardAddress() {
+ assertEquals("192.168.1.1",
IPStackUtils.adaptWildcardAddress("192.168.1.1"));
+ assertEquals("2001:db8::1",
IPStackUtils.adaptWildcardAddress("2001:db8::1"));
+ assertEquals("example.com",
IPStackUtils.adaptWildcardAddress("example.com"));
+ }
+
+ // Test cases for getHostAndPort method
+
+ @Test
+ void testGetHostAndPortWithIPv4() {
+ IPStackUtils.HostPort result =
IPStackUtils.getHostAndPort("192.168.1.1:8080");
+ assertEquals("192.168.1.1", result.getHostname());
+ assertEquals(8080, result.getPort());
+ }
+
+ @Test
+ void testGetHostAndPortWithValidIPv6WithSquaredBrackets() {
+ IPStackUtils.HostPort result =
IPStackUtils.getHostAndPort("[2001:0db8::1]:8080");
+ assertEquals("2001:0db8::1", result.getHostname());
+ assertEquals(8080, result.getPort());
+ }
+
+ @Test
+ void testGetHostAndPortWithValidIPv6WithoutSquaredBrackets() {
+ IPStackUtils.HostPort result =
IPStackUtils.getHostAndPort("2001:0db8::1:8080");
+ assertEquals("2001:0db8::1", result.getHostname());
+ assertEquals(8080, result.getPort());
+ }
+
+ @Test
+ void testGetHostAndPortWithHostname() {
+ IPStackUtils.HostPort result =
IPStackUtils.getHostAndPort("example.com:80");
+ assertEquals("example.com", result.getHostname());
+ assertEquals(80, result.getPort());
}
@Test
- void testWildcardWhenNonWildcardIPv6AddressProvided() {
- String result = IPStackUtils.adaptWildcardAddress("2001:db8::1");
- assertEquals("2001:db8::1", result);
+ void testGetHostPortWithInvalidAndPort() {
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getHostAndPort("192.168.1.1:70000"),
+ "Port number out of range (0-65535).");
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getHostAndPort("192.168.1.1"),
+ "Input does not contain a port.");
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getHostAndPort(":8080"),
+ "Host address is null or empty.");
+ }
+
+ // Test cases for getPort method
+
+ @Test
+ void testGetPort() {
+ assertEquals(8080, IPStackUtils.getPort("8080"));
+ assertEquals(65535, IPStackUtils.getPort("65535"));
+ assertEquals(0, IPStackUtils.getPort("0"));
}
@Test
- void testWildcardWhenHostnameIsProvided() {
- String result = IPStackUtils.adaptWildcardAddress("example.com");
- assertEquals("example.com", result);
+ void testGetPortWithInvalidPort() {
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getPort("70000"),
+ "Port number out of range (0-65535).");
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getPort("-1"),
+ "Port number out of range (0-65535).");
+ assertThrows(IllegalArgumentException.class, () ->
IPStackUtils.getPort("abc"),
+ "For input string: \"abc\"");
}
}
\ No newline at end of file
diff --git a/jdbc/src/java/org/apache/hive/jdbc/ZooKeeperHiveClientHelper.java
b/jdbc/src/java/org/apache/hive/jdbc/ZooKeeperHiveClientHelper.java
index dfe21e71331..513113bb077 100644
--- a/jdbc/src/java/org/apache/hive/jdbc/ZooKeeperHiveClientHelper.java
+++ b/jdbc/src/java/org/apache/hive/jdbc/ZooKeeperHiveClientHelper.java
@@ -34,6 +34,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.common.SSLZookeeperFactory;
import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hive.common.IPStackUtils;
import org.apache.hive.jdbc.Utils.JdbcConnectionParams;
import org.apache.hive.service.server.HS2ActivePassiveHARegistry;
import org.apache.hive.service.server.HS2ActivePassiveHARegistryClient;
@@ -178,12 +179,13 @@ private static void
updateParamsWithZKServerNode(JdbcConnectionParams connParams
// it must be the server uri added by an older version HS2
Matcher matcher = kvPattern.matcher(dataStr);
if ((dataStr != null) && (!matcher.find())) {
- String[] split = dataStr.split(":");
- if (split.length != 2) {
+ try {
+ IPStackUtils.HostPort hostPort = IPStackUtils.getHostAndPort(dataStr);
+ connParams.setHost(hostPort.getHostname());
+ connParams.setPort(hostPort.getPort());
+ } catch (Exception e) {
throw new ZooKeeperHiveClientException("Unable to parse HiveServer2
URI from ZooKeeper data: " + dataStr);
}
- connParams.setHost(split[0]);
- connParams.setPort(Integer.parseInt(split[1]));
} else {
applyConfs(dataStr, connParams);
}
diff --git
a/jdbc/src/test/org/apache/hive/jdbc/ZooKeeperHiveClientHelperTest.java
b/jdbc/src/test/org/apache/hive/jdbc/ZooKeeperHiveClientHelperTest.java
new file mode 100644
index 00000000000..7b759482efc
--- /dev/null
+++ b/jdbc/src/test/org/apache/hive/jdbc/ZooKeeperHiveClientHelperTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.hive.jdbc;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.api.GetDataBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mock;
+
+import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(Parameterized.class)
+public class ZooKeeperHiveClientHelperTest {
+
+ private Utils.JdbcConnectionParams connParams;
+ private CuratorFramework mockZooKeeperClient;
+
+ @Mock
+ private GetDataBuilder mockGetDataBuilder;
+
+ private final String input;
+ private final String expectedHost;
+ private final int expectedPort;
+ private final boolean expectException;
+
+ public ZooKeeperHiveClientHelperTest(String input, String expectedHost, int
expectedPort, boolean expectException) {
+ this.input = input;
+ this.expectedHost = expectedHost;
+ this.expectedPort = expectedPort;
+ this.expectException = expectException;
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ // Valid cases
+ {"localhost:9090", "localhost", 9090, false}, // Hostname
+ {"192.168.1.1:8080", "192.168.1.1", 8080, false}, // IPv4
+ {"[2001:db8::1]:1234", "2001:db8::1", 1234, false}, // IPv6 with
square brackets
+ {"2001:db8::1:5678", "2001:db8::1", 5678, false}, // IPv6 without
square brackets
+
+ // Invalid cases (Invalid host and port format)
+ {"localhost", null, 0, true}, // Missing port
+ {":9090", null, 0, true}, // Missing hostname
+ {"192.168.1.1:", null, 0, true}, // Missing port after IPv4
+ {"[2001:db8::1]", null, 0, true}, // Missing port after IPv6 with
square brackets
+ {"invalid_host:port", null, 0, true} // Invalid host
+ });
+ }
+
+ @Before
+ public void setUp() {
+ connParams = new Utils.JdbcConnectionParams();
+ mockZooKeeperClient = mock(CuratorFramework.class);
+ mockGetDataBuilder = mock(GetDataBuilder.class);
+
+ // Mock the getData() method to return mockGetDataBuilder
+ when(mockZooKeeperClient.getData()).thenReturn(mockGetDataBuilder);
+ }
+
+ @Test
+ public void testUpdateParamsWithZKServerNode_HostPortParsing_Success()
throws Exception {
+ String serverNode = "testServerNode";
+
+ // Mock the behavior of getData().forPath() to return the data bytes
+
when(mockGetDataBuilder.forPath(anyString())).thenReturn(input.getBytes(StandardCharsets.UTF_8));
+
+ // Access the private method using reflection
+ Method updateParamsMethod =
ZooKeeperHiveClientHelper.class.getDeclaredMethod(
+ "updateParamsWithZKServerNode", Utils.JdbcConnectionParams.class,
CuratorFramework.class, String.class);
+
+ // Make the private method accessible
+ updateParamsMethod.setAccessible(true);
+
+ try {
+ // Call the private method under test
+ updateParamsMethod.invoke(null, connParams, mockZooKeeperClient,
serverNode);
+
+ if (expectException) {
+ fail("Expected IllegalArgumentException or
ZooKeeperHiveClientException due to invalid format.");
+ } else {
+ assertEquals(connParams.getHost(), expectedHost);
+ assertEquals(connParams.getPort(), expectedPort);
+ }
+ } catch (Exception e) {
+ // We expect exceptions for invalid input, so the test passes if we
catch them
+ assertTrue(expectException &&
+ e.getCause() instanceof IllegalArgumentException || e.getCause()
instanceof ZooKeeperHiveClientException);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/HiveLockObject.java
b/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/HiveLockObject.java
index 55ecbb45b9e..197196e0085 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/HiveLockObject.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/HiveLockObject.java
@@ -71,20 +71,21 @@ public HiveLockObjectData(String queryId, String lockTime,
String lockMode, Stri
/**
* Constructor
*
- * @param data String of the form "queryId:lockTime:lockMode:queryStr".
- * No ':' characters are allowed in any of the components.
+ * @param data String of the form
"queryId:lockTime:lockMode:queryStr[:clientIp]".
+ * No ':' characters are allowed in any of the first four components, but
the clientIp can contain colons (IPv6).
*/
public HiveLockObjectData(String data) {
if (data == null) {
return;
}
- String[] elem = data.split(":");
+ String[] elem = data.split(":", 5);
queryId = elem[0];
lockTime = StringInternUtils.internIfNotNull(elem[1]);
lockMode = elem[2];
queryStr = StringInternUtils.internIfNotNull(elem[3]);
if (elem.length >= 5) {
+ // The client IP is the suffix after the 4th colon, this can be IPv6
with colons
clientIp = elem[4];
}
}
diff --git
a/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestHiveLockObject.java
b/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestHiveLockObject.java
index 52f86bb0956..3fe1bb4829b 100644
--- a/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestHiveLockObject.java
+++ b/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestHiveLockObject.java
@@ -18,50 +18,103 @@
package org.apache.hadoop.hive.ql.lockmgr;
-import org.junit.Assert;
-
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject.HiveLockObjectData;
import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+@RunWith(Enclosed.class)
public class TestHiveLockObject {
- private HiveConf conf = new HiveConf();
+ public static class TestHiveLockObjectNonParametrized {
+ private final HiveConf conf = new HiveConf();
+
+ @Test
+ public void testEqualsAndHashCode() {
+ HiveLockObjectData data1 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "select * from mytable", conf);
+ HiveLockObjectData data2 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "select * from mytable", conf);
+ assertEquals(data1, data2);
+ assertEquals(data1.hashCode(), data2.hashCode());
- @Test
- public void testEqualsAndHashCode() {
- HiveLockObjectData data1 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "select * from mytable", conf);
- HiveLockObjectData data2 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "select * from mytable", conf);
- Assert.assertEquals(data1, data2);
- Assert.assertEquals(data1.hashCode(), data2.hashCode());
+ HiveLockObject obj1 = new HiveLockObject("mytable", data1);
+ HiveLockObject obj2 = new HiveLockObject("mytable", data2);
+ assertEquals(obj1, obj2);
+ assertEquals(obj1.hashCode(), obj2.hashCode());
+ }
- HiveLockObject obj1 = new HiveLockObject("mytable", data1);
- HiveLockObject obj2 = new HiveLockObject("mytable", data2);
- Assert.assertEquals(obj1, obj2);
- Assert.assertEquals(obj1.hashCode(), obj2.hashCode());
+ @Test
+ public void testTruncate() {
+ conf.setIntVar(HiveConf.ConfVars.HIVE_LOCK_QUERY_STRING_MAX_LENGTH,
1000000);
+ HiveLockObjectData data0 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "01234567890", conf);
+ assertEquals("With default settings query string should not be
truncated",
+ 11, data0.getQueryStr().length());
+ conf.setIntVar(HiveConf.ConfVars.HIVE_LOCK_QUERY_STRING_MAX_LENGTH, 10);
+ HiveLockObjectData data1 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "01234567890", conf);
+ HiveLockObjectData data2 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "0123456789", conf);
+ HiveLockObjectData data3 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ "012345678", conf);
+ HiveLockObjectData data4 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
+ null, conf);
+ assertEquals("Long string truncation failed", 10,
data1.getQueryStr().length());
+ assertEquals("String truncation failed", 10,
data2.getQueryStr().length());
+ assertEquals("Short string should not be truncated", 9,
data3.getQueryStr().length());
+ assertNull("Null query string handling failed", data4.getQueryStr());
+ }
}
- @Test
- public void testTruncate() {
- conf.setIntVar(HiveConf.ConfVars.HIVE_LOCK_QUERY_STRING_MAX_LENGTH,
1000000);
- HiveLockObjectData data0 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "01234567890", conf);
- Assert.assertEquals("With default settings query string should not be
truncated",
- data0.getQueryStr().length(), 11);
- conf.setIntVar(HiveConf.ConfVars.HIVE_LOCK_QUERY_STRING_MAX_LENGTH, 10);
- HiveLockObjectData data1 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "01234567890", conf);
- HiveLockObjectData data2 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "0123456789", conf);
- HiveLockObjectData data3 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- "012345678", conf);
- HiveLockObjectData data4 = new HiveLockObjectData("ID1", "SHARED",
"1997-07-01",
- null, conf);
- Assert.assertEquals("Long string truncation failed",
data1.getQueryStr().length(), 10);
- Assert.assertEquals("String truncation failed",
data2.getQueryStr().length(), 10);
- Assert.assertEquals("Short string should not be truncated",
data3.getQueryStr().length(), 9);
- Assert.assertNull("Null query string handling failed",
data4.getQueryStr());
+ @RunWith(Parameterized.class)
+ public static class TestHiveLockObjectParametrized {
+
+ private final String data;
+ private final String expectedQueryId;
+ private final String expectedLockTime;
+ private final String expectedLockMode;
+ private final String expectedQueryStr;
+ private final String expectedClientIp;
+
+ public TestHiveLockObjectParametrized(String data, String expectedQueryId,
String expectedLockTime,
+ String expectedLockMode, String
expectedQueryStr, String expectedClientIp) {
+ this.data = data;
+ this.expectedQueryId = expectedQueryId;
+ this.expectedLockTime = expectedLockTime;
+ this.expectedLockMode = expectedLockMode;
+ this.expectedQueryStr = expectedQueryStr;
+ this.expectedClientIp = expectedClientIp;
+ }
+
+ // Method to supply the parameters for the parameterized test
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ { "query1:2025-03-31:EXPLICIT:SELECT * FROM table", "query1",
"2025-03-31", "EXPLICIT", "SELECT * FROM table", null },
+ { "query2:2025-03-31:EXPLICIT:SELECT * FROM table:192.168.0.1",
"query2", "2025-03-31", "EXPLICIT", "SELECT * FROM table", "192.168.0.1" },
+ { "query3:2025-03-31:EXPLICIT:SELECT * FROM
table:2001:0db8:85a3:0000:0000:8a2e:0370:7334", "query3", "2025-03-31",
"EXPLICIT", "SELECT * FROM table", "2001:0db8:85a3:0000:0000:8a2e:0370:7334" },
+ { "query5:2025-03-31:EXPLICIT:SELECT * FROM table:some.company.com",
"query5", "2025-03-31", "EXPLICIT", "SELECT * FROM table", "some.company.com" }
+ });
+ }
+
+ @Test
+ public void testConstructor() {
+ HiveLockObjectData lockObjectData = new HiveLockObjectData(data);
+
+ assertEquals("queryId should match", expectedQueryId,
lockObjectData.getQueryId());
+ assertEquals("lockTime should match", expectedLockTime,
lockObjectData.getLockTime());
+ assertEquals("lockMode should match", expectedLockMode,
lockObjectData.getLockMode());
+ assertEquals("queryStr should match", expectedQueryStr,
lockObjectData.getQueryStr());
+ assertEquals("clientIp should match", expectedClientIp,
lockObjectData.getClientIp());
+ }
}
}
diff --git
a/service/src/java/org/apache/hive/service/server/HS2ActivePassiveHARegistry.java
b/service/src/java/org/apache/hive/service/server/HS2ActivePassiveHARegistry.java
index f7dbe3c4831..bf0f53636ec 100644
---
a/service/src/java/org/apache/hive/service/server/HS2ActivePassiveHARegistry.java
+++
b/service/src/java/org/apache/hive/service/server/HS2ActivePassiveHARegistry.java
@@ -42,8 +42,8 @@
import org.apache.hadoop.registry.client.binding.RegistryTypeUtils;
import org.apache.hadoop.registry.client.types.Endpoint;
import org.apache.hadoop.registry.client.types.ServiceRecord;
-import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hive.common.IPStackUtils;
import org.apache.hive.service.ServiceException;
import org.apache.hive.service.auth.AuthType;
import org.slf4j.Logger;
@@ -173,9 +173,9 @@ private void addEndpointToServiceRecord(
private void updateEndpoint(final ServiceRecord srv, final String
endpointName) {
final String instanceUri = srv.get(INSTANCE_URI_CONFIG);
- final String[] tokens = instanceUri.split(":");
- final String hostname = tokens[0];
- final int port = Integer.parseInt(tokens[1]);
+ IPStackUtils.HostPort hostPort = IPStackUtils.getHostAndPort(instanceUri);
+ final String hostname = hostPort.getHostname();
+ final int port = hostPort.getPort();
Endpoint urlEndpoint = RegistryTypeUtils.ipcEndpoint(endpointName, new
InetSocketAddress(hostname, port));
srv.addInternalEndpoint(urlEndpoint);
LOG.info("Added {} endpoint to service record", urlEndpoint);