Skip to content

Commit d5a7bc1

Browse files
author
Dmitriy Fingerman
committed
HIVE-28775: HiveServer2: enabling HA Leader endpoint on a different port than WebUI
1 parent 38dc6b6 commit d5a7bc1

File tree

10 files changed

+457
-152
lines changed

10 files changed

+457
-152
lines changed

common/src/java/org/apache/hadoop/hive/conf/HiveConf.java

+2
Original file line numberDiff line numberDiff line change
@@ -3979,6 +3979,8 @@ public static enum ConfVars {
39793979
HIVE_SERVER2_WEBUI_BIND_HOST("hive.server2.webui.host", "0.0.0.0", "The host address the HiveServer2 WebUI will listen on"),
39803980
HIVE_SERVER2_WEBUI_PORT("hive.server2.webui.port", 10002, "The port the HiveServer2 WebUI will listen on. This can be"
39813981
+ "set to 0 or a negative integer to disable the web UI"),
3982+
HIVE_SERVER2_HEALTH_HA_PORT("hive.server2.health.ha.port", 11002, "The port the HiveServer2 health-ha web app will listen on. This can be"
3983+
+ "set to 0 or a negative integer to disable HS2 health-ha checking"),
39823984
HIVE_SERVER2_WEBUI_MAX_THREADS("hive.server2.webui.max.threads", 50, "The max HiveServer2 WebUI threads"),
39833985
HIVE_SERVER2_WEBUI_USE_SSL("hive.server2.webui.use.ssl", false,
39843986
"Set this to true for using SSL encryption for HiveServer2 WebUI."),

common/src/java/org/apache/hive/http/HttpServer.java

+200-64
Large diffs are not rendered by default.

data/conf/hive-site.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@
358358

359359
<property>
360360
<name>hive.server2.webui.max.threads</name>
361-
<value>4</value>
361+
<value>6</value>
362362
</property>
363363

364364
<property>

data/conf/mr/hive-site.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@
354354

355355
<property>
356356
<name>hive.server2.webui.max.threads</name>
357-
<value>4</value>
357+
<value>6</value>
358358
</property>
359359

360360
<property>

itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestActivePassiveHA.java

+101
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,72 @@ private static void setHAConfigs(Configuration conf) {
139139
conf.setInt(ConfVars.HIVE_ZOOKEEPER_CONNECTION_MAX_RETRIES.varname, 1);
140140
}
141141

142+
@Test(timeout = 60000)
143+
public void testHealthCheckHA() throws Exception {
144+
String instanceId1 = UUID.randomUUID().toString();
145+
miniHS2_1.start(getConfOverlay(instanceId1));
146+
147+
String leaderURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
148+
String healthCheckURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
149+
150+
String leaderURLHealthCheckPort = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/leader";
151+
String healthCheckURLWebUIPort = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/health-ha/leader";
152+
153+
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
154+
assertEquals(true, miniHS2_1.isLeader());
155+
156+
assertEquals("true", sendGet(leaderURL));
157+
assertEquals("true", sendGet(healthCheckURL));
158+
159+
assertEquals("Not Found", sendGet(leaderURLHealthCheckPort));
160+
assertEquals("Not Found", sendGet(healthCheckURLWebUIPort));
161+
}
162+
163+
@Test(timeout = 60000)
164+
public void testHealthCheckHAAuth() throws Exception {
165+
hiveConf1.setBoolVar(ConfVars.HIVE_SERVER2_WEBUI_ENABLE_CORS, true);
166+
setPamConfs(hiveConf1);
167+
PamAuthenticator pamAuthenticator = new TestHS2HttpServerPam.TestPamAuthenticator(hiveConf1);
168+
String instanceId1 = UUID.randomUUID().toString();
169+
miniHS2_1.setPamAuthenticator(pamAuthenticator);
170+
miniHS2_1.start(getSecureConfOverlay(instanceId1));
171+
172+
String leaderURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
173+
String healthCheckURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
174+
175+
String leaderURLHealthCheckPort = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/leader";
176+
String healthCheckURLWebUIPort = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/health-ha/leader";
177+
178+
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
179+
assertEquals(true, miniHS2_1.isLeader());
180+
181+
assertEquals("true", sendGet(leaderURL, true, true));
182+
assertEquals("true", sendGet(healthCheckURL, true, true));
183+
184+
try {
185+
sendGet(leaderURLHealthCheckPort, true, true);
186+
} catch (AssertionError e) {
187+
assertTrue(e.getMessage().contains("Not Found"));
188+
} catch (Exception e) {
189+
fail("Expected AssertionError");
190+
}
191+
192+
assertEquals("Not Found", sendGet(healthCheckURLWebUIPort, true, true));
193+
assertEquals("Method Not Allowed", sendDelete(healthCheckURL, true, true));
194+
assertEquals("Method Not Allowed", sendDelete(healthCheckURLWebUIPort, true, true));
195+
196+
try {
197+
sendDelete(leaderURLHealthCheckPort, true, true);
198+
} catch (AssertionError e) {
199+
assertTrue(e.getMessage().contains("Not Found"));
200+
} catch (Exception e) {
201+
fail("Expected AssertionError");
202+
}
203+
204+
String resp = sendDelete(leaderURL, true, true);
205+
assertTrue(resp.contains("Failover successful!"));
206+
}
207+
142208
@Test(timeout = 60000)
143209
public void testActivePassiveHA() throws Exception {
144210
String instanceId1 = UUID.randomUUID().toString();
@@ -150,10 +216,14 @@ public void testActivePassiveHA() throws Exception {
150216
assertEquals(true, miniHS2_1.isLeader());
151217
String url = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
152218
assertEquals("true", sendGet(url));
219+
String healthCheckURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
220+
assertEquals("true", sendGet(healthCheckURL));
153221

154222
assertEquals(false, miniHS2_2.isLeader());
155223
url = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
156224
assertEquals("false", sendGet(url));
225+
healthCheckURL = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
226+
assertEquals("false", sendGet(healthCheckURL));
157227

158228
url = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/peers";
159229
String resp = sendGet(url);
@@ -192,6 +262,8 @@ public void testActivePassiveHA() throws Exception {
192262
assertEquals(true, miniHS2_2.isLeader());
193263
url = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
194264
assertEquals("true", sendGet(url));
265+
healthCheckURL = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
266+
assertEquals("true", sendGet(healthCheckURL));
195267

196268
while (client.getAll().size() != 1) {
197269
Thread.sleep(100);
@@ -233,6 +305,8 @@ public void testActivePassiveHA() throws Exception {
233305
assertEquals(false, miniHS2_1.isLeader());
234306
url = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
235307
assertEquals("false", sendGet(url));
308+
healthCheckURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
309+
assertEquals("false", sendGet(healthCheckURL));
236310

237311
while (client.getAll().size() != 2) {
238312
Thread.sleep(100);
@@ -282,10 +356,14 @@ public void testConnectionActivePassiveHAServiceDiscovery() throws Exception {
282356
assertEquals(true, miniHS2_1.isLeader());
283357
String url = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
284358
assertEquals("true", sendGet(url));
359+
String healthCheckURL = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
360+
assertEquals("true", sendGet(healthCheckURL));
285361

286362
assertEquals(false, miniHS2_2.isLeader());
287363
url = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
288364
assertEquals("false", sendGet(url));
365+
healthCheckURL = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
366+
assertEquals("false", sendGet(healthCheckURL));
289367

290368
// miniHS2_1 will be leader
291369
String zkConnectString = zkServer.getConnectString();
@@ -347,11 +425,14 @@ public void testManualFailover() throws Exception {
347425
miniHS2_2.start(confOverlay);
348426
String url1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
349427
String url2 = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
428+
String healthCheckURL1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
429+
String healthCheckURL2 = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
350430

351431
// when we start miniHS2_1 will be leader (sequential start)
352432
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
353433
assertEquals(true, miniHS2_1.isLeader());
354434
assertEquals("true", sendGet(url1, true, true));
435+
assertEquals("true", sendGet(healthCheckURL1, true, true));
355436

356437
// trigger failover on miniHS2_1
357438
String resp = sendDelete(url1, true, true);
@@ -361,11 +442,13 @@ public void testManualFailover() throws Exception {
361442
assertEquals(true, miniHS2_1.getNotLeaderTestFuture().get());
362443
assertEquals(false, miniHS2_1.isLeader());
363444
assertEquals("false", sendGet(url1, true, true));
445+
assertEquals("false", sendGet(healthCheckURL1, true, true));
364446

365447
// make sure miniHS2_2 is the new leader
366448
assertEquals(true, miniHS2_2.getIsLeaderTestFuture().get());
367449
assertEquals(true, miniHS2_2.isLeader());
368450
assertEquals("true", sendGet(url2, true, true));
451+
assertEquals("true", sendGet(healthCheckURL2, true, true));
369452

370453
// send failover request again to miniHS2_1 and get a failure
371454
resp = sendDelete(url1, true, true);
@@ -379,8 +462,10 @@ public void testManualFailover() throws Exception {
379462
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
380463
assertEquals(true, miniHS2_1.isLeader());
381464
assertEquals("true", sendGet(url1, true, true));
465+
assertEquals("true", sendGet(healthCheckURL1, true, true));
382466
assertEquals(true, miniHS2_2.getNotLeaderTestFuture().get());
383467
assertEquals("false", sendGet(url2, true, true));
468+
assertEquals("false", sendGet(healthCheckURL2, true, true));
384469
assertEquals(false, miniHS2_2.isLeader());
385470
} finally {
386471
resetFailoverConfs();
@@ -404,10 +489,12 @@ public void testManualFailoverUnauthorized() throws Exception {
404489
miniHS2_2.start(confOverlay);
405490

406491
String url1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
492+
String healthCheckURL1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
407493
// when we start miniHS2_1 will be leader (sequential start)
408494
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
409495
assertEquals(true, miniHS2_1.isLeader());
410496
assertEquals("true", sendGet(url1, true));
497+
assertEquals("true", sendGet(healthCheckURL1, true));
411498

412499
// trigger failover on miniHS2_1 without authorization header
413500
assertTrue(sendDelete(url1, false).contains("Unauthorized"));
@@ -439,6 +526,7 @@ public void testNoConnectionOnPassive() throws Exception {
439526
miniHS2_2.setPamAuthenticator(pamAuthenticator2);
440527
miniHS2_2.start(confOverlay);
441528
String url1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
529+
String healthCheckURL1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
442530
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
443531
assertEquals(true, miniHS2_1.isLeader());
444532

@@ -454,6 +542,9 @@ public void testNoConnectionOnPassive() throws Exception {
454542
Thread.sleep(100);
455543
}
456544

545+
resp = sendDelete(healthCheckURL1, true);
546+
assertTrue(resp, resp.contains("Method Not Allowed"));
547+
457548
assertEquals(true, miniHS2_2.getIsLeaderTestFuture().get());
458549
assertEquals(true, miniHS2_2.isLeader());
459550

@@ -496,6 +587,8 @@ public void testClientConnectionsOnFailover() throws Exception {
496587
miniHS2_2.start(confOverlay);
497588
String url1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
498589
String url2 = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_WEBUI_PORT.varname) + "/leader";
590+
String healthCheckUrl1 = "http://localhost:" + hiveConf1.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
591+
String healthCheckUrl2 = "http://localhost:" + hiveConf2.get(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT.varname) + "/health-ha/leader";
499592
String zkJdbcUrl = miniHS2_1.getJdbcURL();
500593
String zkConnectString = zkServer.getConnectString();
501594
assertTrue(zkJdbcUrl.contains(zkConnectString));
@@ -504,6 +597,7 @@ public void testClientConnectionsOnFailover() throws Exception {
504597
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
505598
assertEquals(true, miniHS2_1.isLeader());
506599
assertEquals("true", sendGet(url1, true));
600+
assertEquals("true", sendGet(healthCheckUrl1, true));
507601

508602
// before failover, check if we are getting connection from miniHS2_1
509603
String hs2_1_directUrl = "jdbc:hive2://" + miniHS2_1.getHost() + ":" + miniHS2_1.getBinaryPort() +
@@ -523,15 +617,20 @@ public void testClientConnectionsOnFailover() throws Exception {
523617
Thread.sleep(100);
524618
}
525619

620+
resp = sendDelete(healthCheckUrl1, true);
621+
assertTrue(resp.contains("Method Not Allowed"));
622+
526623
// make sure miniHS2_1 is not leader
527624
assertEquals(true, miniHS2_1.getNotLeaderTestFuture().get());
528625
assertEquals(false, miniHS2_1.isLeader());
529626
assertEquals("false", sendGet(url1, true));
627+
assertEquals("false", sendGet(healthCheckUrl1, true));
530628

531629
// make sure miniHS2_2 is the new leader
532630
assertEquals(true, miniHS2_2.getIsLeaderTestFuture().get());
533631
assertEquals(true, miniHS2_2.isLeader());
534632
assertEquals("true", sendGet(url2, true));
633+
assertEquals("true", sendGet(healthCheckUrl2, true));
535634

536635
// when we make a new connection we should get it from miniHS2_2 this time
537636
String hs2_2_directUrl = "jdbc:hive2://" + miniHS2_2.getHost() + ":" + miniHS2_2.getHttpPort() +
@@ -555,8 +654,10 @@ public void testClientConnectionsOnFailover() throws Exception {
555654
assertEquals(true, miniHS2_1.getIsLeaderTestFuture().get());
556655
assertEquals(true, miniHS2_1.isLeader());
557656
assertEquals("true", sendGet(url1, true));
657+
assertEquals("true", sendGet(healthCheckUrl1, true));
558658
assertEquals(true, miniHS2_2.getNotLeaderTestFuture().get());
559659
assertEquals("false", sendGet(url2, true));
660+
assertEquals("false", sendGet(healthCheckUrl2, true));
560661
assertEquals(false, miniHS2_2.isLeader());
561662
// make sure miniHS2_2 closes all its connections
562663
while (miniHS2_2.getOpenSessionsCount() != 0) {

itests/util/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,17 @@ public abstract class AbstractHiveService {
3636
private int binaryPort;
3737
private int httpPort;
3838
private int webPort;
39+
private int healthHAPort;
3940
private boolean startedHiveService = false;
4041
private List<String> addedProperties = new ArrayList<String>();
4142

42-
public AbstractHiveService(HiveConf hiveConf, String hostname, int binaryPort, int httpPort, int webPort) {
43+
public AbstractHiveService(HiveConf hiveConf, String hostname, int binaryPort, int httpPort, int webPort, int healthHAPort) {
4344
this.hiveConf = hiveConf;
4445
this.hostname = hostname;
4546
this.binaryPort = binaryPort;
4647
this.httpPort = httpPort;
4748
this.webPort = webPort;
49+
this.healthHAPort = healthHAPort;
4850
}
4951

5052
/**
@@ -142,6 +144,10 @@ public int getWebPort() {
142144
return webPort;
143145
}
144146

147+
public int getHealthHAPort() {
148+
return healthHAPort;
149+
}
150+
145151
public boolean isStarted() {
146152
return startedHiveService;
147153
}

itests/util/src/main/java/org/apache/hive/jdbc/miniHS2/MiniHS2.java

+3
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ private MiniHS2(HiveConf hiveConf, MiniClusterType miniClusterType, boolean useM
292292
(usePortsFromConf ? hiveConf.getIntVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_HTTP_PORT) : MetaStoreTestUtils
293293
.findFreePort()),
294294
(usePortsFromConf ? hiveConf.getIntVar(ConfVars.HIVE_SERVER2_WEBUI_PORT) : MetaStoreTestUtils
295+
.findFreePort()),
296+
(usePortsFromConf ? hiveConf.getIntVar(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT) : MetaStoreTestUtils
295297
.findFreePort()));
296298
hiveConf.setLongVar(ConfVars.HIVE_SERVER2_MAX_START_ATTEMPTS, 3l);
297299
hiveConf.setTimeVar(ConfVars.HIVE_SERVER2_SLEEP_INTERVAL_BETWEEN_START_ATTEMPTS, 10,
@@ -379,6 +381,7 @@ private MiniHS2(HiveConf hiveConf, MiniClusterType miniClusterType, boolean useM
379381
hiveConf.setIntVar(ConfVars.HIVE_SERVER2_THRIFT_PORT, getBinaryPort());
380382
hiveConf.setIntVar(ConfVars.HIVE_SERVER2_THRIFT_HTTP_PORT, getHttpPort());
381383
hiveConf.setIntVar(ConfVars.HIVE_SERVER2_WEBUI_PORT, getWebPort());
384+
hiveConf.setIntVar(ConfVars.HIVE_SERVER2_HEALTH_HA_PORT, getHealthHAPort());
382385

383386
Path scratchDir = new Path(baseFsDir, "scratch");
384387
// Create root scratchdir with write all, so that user impersonation has no issues.

0 commit comments

Comments
 (0)