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

krisztiankasa 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 52b6fc322e0 HIVE-27805: Hive server2 connections limits bug (#6168)
52b6fc322e0 is described below

commit 52b6fc322e0ab7a1a94b7a966130c9bacfa4b00f
Author: Dayakar M <[email protected]>
AuthorDate: Fri Nov 7 11:41:36 2025 +0530

    HIVE-27805: Hive server2 connections limits bug (#6168)
---
 .../hive/service/cli/session/SessionManager.java   | 10 ++++-
 .../cli/TestCLIServiceConnectionLimits.java        | 48 ++++++++++++++++++++++
 .../cli/session/TestSessionManagerMetrics.java     | 30 ++++++++++++++
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git 
a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java 
b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
index 694768ae7da..274df88390e 100644
--- a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
+++ b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
@@ -458,6 +458,7 @@ public HiveSession createSession(SessionHandle 
sessionHandle, TProtocolVersion p
           hiveSessionUgi = (HiveSessionImplwithUGI) 
constructor.newInstance(sessionHandle,
               protocol, username, password, hiveConf, ipAddress, 
delegationToken, forwardedAddresses);
         } catch (Exception e) {
+          decrementConnectionsCount(username, ipAddress, forwardedAddresses);
           throw new HiveSQLException("Cannot initialize session class:" + 
sessionImplWithUGIclassName);
         }
       }
@@ -475,6 +476,7 @@ public HiveSession createSession(SessionHandle 
sessionHandle, TProtocolVersion p
         session = (HiveSession) constructor.newInstance(sessionHandle, 
protocol, username, password,
           hiveConf, ipAddress, forwardedAddresses);
         } catch (Exception e) {
+          decrementConnectionsCount(username, ipAddress, forwardedAddresses);
           throw new HiveSQLException("Cannot initialize session class:" + 
sessionImplclassName, e);
         }
       }
@@ -487,6 +489,7 @@ public HiveSession createSession(SessionHandle 
sessionHandle, TProtocolVersion p
       LOG.warn("Failed to open session", e);
       try {
         session.close();
+        decrementConnections(session);
       } catch (Throwable t) {
         LOG.warn("Error closing session", t);
       }
@@ -502,6 +505,7 @@ public HiveSession createSession(SessionHandle 
sessionHandle, TProtocolVersion p
       LOG.warn("Failed to execute session hooks", e);
       try {
         session.close();
+        decrementConnections(session);
       } catch (Throwable t) {
         LOG.warn("Error closing session", t);
       }
@@ -562,7 +566,11 @@ private String getOriginClientIpAddress(final String 
ipAddress, final List<Strin
 
   private void decrementConnections(final HiveSession session) {
     final String username = session.getUserName();
-    final String clientIpAddress = 
getOriginClientIpAddress(session.getIpAddress(), 
session.getForwardedAddresses());
+    decrementConnectionsCount(username, session.getIpAddress(), 
session.getForwardedAddresses());
+  }
+
+  private void decrementConnectionsCount(String username, String ipAddress, 
List<String> forwardedAddresses) {
+    final String clientIpAddress = getOriginClientIpAddress(ipAddress, 
forwardedAddresses);
     if (trackConnectionsPerUser(username)) {
       connectionsCount.computeIfPresent(username, (k, v) -> v).decrement();
     }
diff --git 
a/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
 
b/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
index dff6b6e8fe1..777184dad7c 100644
--- 
a/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
+++ 
b/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
@@ -17,11 +17,13 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.common.IPStackUtils;
 import org.apache.hive.service.cli.session.SessionManager;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
@@ -345,6 +347,52 @@ public void testConnectionForwardedIpAddresses() throws 
HiveSQLException {
     }
   }
 
+  @Test
+  public void testConnectionLimitPerUserWhenSessionCreationFails() throws 
HiveSQLException {
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER, 
2);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS, 
0);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
 0);
+    testConnectionLimits();
+  }
+
+  @Test
+  public void testConnectionLimitPerIpAddressWhenSessionCreationFails() throws 
HiveSQLException {
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER, 
0);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS, 
2);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
 0);
+    testConnectionLimits();
+  }
+
+  @Test
+  public void testConnectionLimitPerUserIpAddressWhenSessionCreationFails() 
throws HiveSQLException {
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER, 
0);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS, 
0);
+    
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
 2);
+    testConnectionLimits();
+  }
+
+  private void testConnectionLimits() {
+    CLIService service = getService(conf);
+    HashMap<String, String> sessionConf = new HashMap<>(1);
+    // modifying this property at runtime is not allowed, it will throw 
exception and session will not be created
+    sessionConf.put("hive.conf.locked.list", "test");
+    try {
+      // Here limit is set as 2 but if session creation fails it shouldn't 
increment the count and should not throw limit reached exception
+      for (int i = 0; i < 3; i++) {
+        try {
+          service.openSession(CLIService.SERVER_VERSION, "foo", "bar", 
IPStackUtils.resolveLoopbackAddress(),
+              sessionConf);
+        } catch (HiveSQLException he) {
+          Assert.assertEquals(
+              "Failed to open new session: Cannot modify hive.conf.locked.list 
at runtime. It is in the list of parameters that can't be modified at runtime 
or is prefixed by a restricted variable",
+              he.getMessage());
+        }
+      }
+    } finally {
+      service.stop();
+    }
+  }
+
   private CLIService getService(HiveConf conf) {
     conf.setVar(HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER,
       
"org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory");
diff --git 
a/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
 
b/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
index 9ed2a15e9a2..e227ff45e76 100644
--- 
a/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
+++ 
b/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
@@ -80,6 +80,7 @@ public void setup() throws Exception {
     //it maybe impact TestSessionCleanup, because they use the same location 
ConfVars.HIVE_SERVER2_LOGGING_OPERATION_LOG_LOCATION,
     // when we run testing in parallel on local machine with -DforkCount=x, it 
happen.
     conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_LOGGING_OPERATION_ENABLED, 
false);
+    conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER, 
2);
     MetricsFactory.init(conf);
 
     sm = new SessionManager(null, true);
@@ -396,4 +397,33 @@ public void testAbandonedSessionMetrics() throws Exception 
{
     } while (!expectedValue.equals(currentValue) && --count > 0);
     Assert.assertEquals(expectedValue, currentValue);
   }
+
+  @Test
+  public void testSessionLimitsPerUserWhenSessionCreationFails() throws 
Exception {
+    sm.start();
+    HashMap<String, String> sessionConf = new HashMap<>(1);
+    // modifying this property at runtime is not allowed, it will throw 
exception and session will not be created
+    sessionConf.put("hive.conf.locked.list", "test");
+    for (int i = 0; i < 3; i++) {
+      try {
+        sm.openSession(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V9, "user", 
"passw", "127.0.0.1", sessionConf);
+      } catch (HiveSQLException e) {
+        // Here 'hive.server2.limit.connections.per.user' property value set 
as 2 so when we create 3 sessions, for all 3 sessions it should throw exception 
with failure reason
+        // It should not throw exception with 'Connection limit per user 
reached (user: user limit: 2)' message
+        Assert.assertEquals(
+            "Failed to open new session: Cannot modify hive.conf.locked.list 
at runtime. It is in the list of parameters that can't be modified at runtime 
or is prefixed by a restricted variable",
+            e.getMessage());
+      }
+    }
+    SessionHandle handle = null;
+    // After 3 unsuccessful session creations now session creation with proper 
details should be able to create the session
+    try {
+      handle = sm.openSession(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V9, 
"user", "passw", "127.0.0.1",
+          new HashMap<String, String>());
+    } finally {
+      if (null != handle) {
+        sm.closeSession(handle);
+      }
+    }
+  }
 }

Reply via email to