- ${bc.name} |
+ ${bc.name} |
${bc.externalUrl} |
${bc.routingGroup} |
${bc.active?c} |
+ ${backendStates[bc.name].healthy} |
<#if backendStates?keys?size != 0 && backendStates[bc.name]??>
${backendStates[bc.name].state["QUEUED"]} |
| ${backendStates[bc.name].state["RUNNING"]} |
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/HaGatewayTestUtils.java b/gateway-ha/src/test/java/io/trino/gateway/ha/HaGatewayTestUtils.java
index f8ccfd575..49bf68046 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/HaGatewayTestUtils.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/HaGatewayTestUtils.java
@@ -31,6 +31,8 @@ public class HaGatewayTestUtils {
private static final OkHttpClient httpClient = new OkHttpClient();
private static final Random RANDOM = new Random();
+ public static final int WAIT_FOR_BACKEND_IN_SECONDS = 65;
+
public static void seedRequiredData(TestConfig testConfig) {
String jdbcUrl = "jdbc:h2:" + testConfig.getH2DbFilePath();
DataStoreConfiguration db = new DataStoreConfiguration(jdbcUrl, "sa", "sa", "org.h2.Driver", 4);
@@ -40,16 +42,26 @@ public static void seedRequiredData(TestConfig testConfig) {
connectionManager.close();
}
- public static void prepareMockBackend(
- WireMockServer backend, String endPoint, String expectedResonse) {
- backend.start();
+ public static void prepareMockPostBackend(
+ WireMockServer backend, String endPoint, String expectedResonse, int status) {
backend.stubFor(
WireMock.post(endPoint)
.willReturn(
WireMock.aResponse()
.withBody(expectedResonse)
.withHeader("Content-Encoding", "plain")
- .withStatus(200)));
+ .withStatus(status)));
+ }
+
+ public static void prepareMockGetBackend(
+ WireMockServer backend, String endPoint, String response, int status) {
+ backend.stubFor(
+ WireMock.get(endPoint)
+ .willReturn(
+ WireMock.aResponse()
+ .withBody(response)
+ .withHeader("Content-Encoding", "plain")
+ .withStatus(status)));
}
public static TestConfig buildGatewayConfigAndSeedDb(int routerPort, String configFile)
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaMultipleBackend.java b/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaMultipleBackend.java
index ad53b0fc2..dc0135aa7 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaMultipleBackend.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaMultipleBackend.java
@@ -1,5 +1,10 @@
package io.trino.gateway.ha;
+import static io.trino.gateway.ha.HaGatewayTestUtils.WAIT_FOR_BACKEND_IN_SECONDS;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_API_QUEUED_LIST_PATH;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_API_STATS_PATH;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_LOGIN_PATH;
+import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -7,7 +12,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import io.dropwizard.testing.junit5.DropwizardExtensionsSupport;
import io.trino.gateway.ha.config.ProxyBackendConfiguration;
+import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -18,11 +25,14 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
+import org.junit.jupiter.api.extension.ExtendWith;
@TestInstance(Lifecycle.PER_CLASS)
+@ExtendWith(DropwizardExtensionsSupport.class)
+@Slf4j
public class TestGatewayHaMultipleBackend {
- public static final String EXPECTED_RESPONSE1 = "{\"id\":\"testId1\"}";
- public static final String EXPECTED_RESPONSE2 = "{\"id\":\"testId2\"}";
+ public static final String EXPECTED_RESPONSE_1 = "{\"id\":\"testId1\"}";
+ public static final String EXPECTED_RESPONSE_2 = "{\"id\":\"testId2\"}";
public static final String CUSTOM_RESPONSE = "123";
public static final String CUSTOM_PATH = "/v1/custom/extra";
@@ -43,9 +53,25 @@ public class TestGatewayHaMultipleBackend {
@BeforeAll
public void setup() throws Exception {
- HaGatewayTestUtils.prepareMockBackend(adhocBackend, "/v1/statement", EXPECTED_RESPONSE1);
- HaGatewayTestUtils.prepareMockBackend(scheduledBackend, "/v1/statement", EXPECTED_RESPONSE2);
- HaGatewayTestUtils.prepareMockBackend(customBackend, CUSTOM_PATH, CUSTOM_RESPONSE);
+ adhocBackend.start();
+ scheduledBackend.start();
+ customBackend.start();
+ // mock adhocBackend response
+ HaGatewayTestUtils.prepareMockPostBackend(adhocBackend, "/v1/statement", EXPECTED_RESPONSE_1, 200);
+ HaGatewayTestUtils.prepareMockPostBackend(adhocBackend, UI_LOGIN_PATH, "", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(adhocBackend, UI_API_STATS_PATH, "{\"activeWorkers\": 1}", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(adhocBackend, UI_API_QUEUED_LIST_PATH, null, 200);
+
+ // mock scheduledBackend response
+ HaGatewayTestUtils.prepareMockPostBackend(scheduledBackend, "/v1/statement", EXPECTED_RESPONSE_2, 200);
+ HaGatewayTestUtils.prepareMockPostBackend(scheduledBackend, UI_LOGIN_PATH, "", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(scheduledBackend, UI_API_STATS_PATH, "{\"activeWorkers\": 1}", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(scheduledBackend, UI_API_QUEUED_LIST_PATH, null, 200);
+
+ HaGatewayTestUtils.prepareMockPostBackend(customBackend, CUSTOM_PATH, CUSTOM_RESPONSE, 200);
+ HaGatewayTestUtils.prepareMockPostBackend(customBackend, UI_LOGIN_PATH, "", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(customBackend, UI_API_STATS_PATH, "{\"activeWorkers\": 1}", 200);
+ HaGatewayTestUtils.prepareMockGetBackend(customBackend, UI_API_QUEUED_LIST_PATH, null, 200);
// seed database
HaGatewayTestUtils.TestConfig testConfig =
@@ -64,6 +90,8 @@ public void setup() throws Exception {
"custom", "http://localhost:" + customBackendPort, "externalUrl", true, "custom",
routerPort);
+ log.info("waiting for backend to become healthy");
+ SECONDS.sleep(WAIT_FOR_BACKEND_IN_SECONDS);
}
@Test
@@ -77,7 +105,7 @@ public void testCustomPath() throws Exception {
.addHeader("X-Trino-Routing-Group", "custom")
.build();
Response response1 = httpClient.newCall(request1).execute();
- assertEquals(response1.body().string(), CUSTOM_RESPONSE);
+ assertEquals(CUSTOM_RESPONSE, response1.body().string());
Request request2 =
new Request.Builder()
@@ -86,7 +114,7 @@ public void testCustomPath() throws Exception {
.addHeader("X-Trino-Routing-Group", "custom")
.build();
Response response2 = httpClient.newCall(request2).execute();
- assertEquals(response2.code(), 404);
+ assertEquals(404, response2.code());
}
@Test
@@ -100,7 +128,7 @@ public void testQueryDeliveryToMultipleRoutingGroups() throws Exception {
.post(requestBody)
.build();
Response response1 = httpClient.newCall(request1).execute();
- assertEquals(EXPECTED_RESPONSE1, response1.body().string());
+ assertEquals(EXPECTED_RESPONSE_1, response1.body().string());
// When X-Trino-Routing-Group is set in header, query should be routed to cluster under the
// routing group
Request request4 =
@@ -110,7 +138,7 @@ public void testQueryDeliveryToMultipleRoutingGroups() throws Exception {
.addHeader("X-Trino-Routing-Group", "scheduled")
.build();
Response response4 = httpClient.newCall(request4).execute();
- assertEquals(EXPECTED_RESPONSE2, response4.body().string());
+ assertEquals(EXPECTED_RESPONSE_2, response4.body().string());
}
@Test
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaSingleBackend.java b/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaSingleBackend.java
index 6a8268518..243d1e7e2 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaSingleBackend.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaSingleBackend.java
@@ -1,5 +1,13 @@
package io.trino.gateway.ha;
+import static io.trino.gateway.ha.HaGatewayTestUtils.WAIT_FOR_BACKEND_IN_SECONDS;
+import static io.trino.gateway.ha.HaGatewayTestUtils.prepareMockGetBackend;
+import static io.trino.gateway.ha.HaGatewayTestUtils.prepareMockPostBackend;
+import static io.trino.gateway.ha.HaGatewayTestUtils.setUpBackend;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_API_QUEUED_LIST_PATH;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_API_STATS_PATH;
+import static io.trino.gateway.ha.handler.QueryIdCachingProxyHandler.UI_LOGIN_PATH;
+import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -7,7 +15,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import io.dropwizard.testing.junit5.DropwizardExtensionsSupport;
import io.trino.gateway.ha.config.ProxyBackendConfiguration;
+import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -18,8 +28,11 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
+import org.junit.jupiter.api.extension.ExtendWith;
@TestInstance(Lifecycle.PER_CLASS)
+@ExtendWith(DropwizardExtensionsSupport.class)
+@Slf4j
public class TestGatewayHaSingleBackend {
public static final String EXPECTED_RESPONSE = "{\"id\":\"testId\"}";
int backendPort = 20000 + (int) (Math.random() * 1000);
@@ -31,7 +44,11 @@ public class TestGatewayHaSingleBackend {
@BeforeAll
public void setup() throws Exception {
- HaGatewayTestUtils.prepareMockBackend(backend, "/v1/statement", EXPECTED_RESPONSE);
+ backend.start();
+ prepareMockPostBackend(backend, "/v1/statement", EXPECTED_RESPONSE, 200);
+ prepareMockPostBackend(backend, UI_LOGIN_PATH, "", 200);
+ prepareMockGetBackend(backend, UI_API_STATS_PATH, "{\"activeWorkers\": 1}", 200);
+ prepareMockGetBackend(backend, UI_API_QUEUED_LIST_PATH, null, 200);
// seed database
HaGatewayTestUtils.TestConfig testConfig =
@@ -40,8 +57,10 @@ public void setup() throws Exception {
String[] args = {"server", testConfig.getConfigFilePath()};
HaGatewayLauncher.main(args);
// Now populate the backend
- HaGatewayTestUtils.setUpBackend(
- "trino1", "http://localhost:" + backendPort, "externalUrl", true, "adhoc", routerPort);
+ setUpBackend("trino1", "http://localhost:" + backendPort,"externalUrl",true, "adhoc", routerPort);
+
+ log.info("waiting for backend to become healthy");
+ SECONDS.sleep(WAIT_FOR_BACKEND_IN_SECONDS);
}
@Test
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestHaRoutingManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestHaRoutingManager.java
index 4cd43ae02..9906f1cbe 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestHaRoutingManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestHaRoutingManager.java
@@ -1,6 +1,7 @@
package io.trino.gateway.ha.router;
import io.trino.gateway.ha.HaGatewayTestUtils;
+import io.trino.gateway.ha.clustermonitor.BackendHealthState;
import io.trino.gateway.ha.config.DataStoreConfiguration;
import io.trino.gateway.ha.config.ProxyBackendConfiguration;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
@@ -49,8 +50,8 @@ private void addMockBackends() {
proxyBackend.setProxyTo(backend + ".trino.example.com");
proxyBackend.setExternalUrl("trino.example.com");
backendManager.addBackend(proxyBackend);
- //set backend as healthyti start with
- haRoutingManager.upateBackEndHealth(backend, true);
+ //set backend as healthy to start with
+ haRoutingManager.upateBackEndHealth(backend, BackendHealthState.HEALTHY);
}
//Keep only 1st backend as healthy, mark all the others as unhealthy
@@ -58,7 +59,7 @@ private void addMockBackends() {
for (int i = 1; i < numBackends; i++) {
backend = groupName + i;
- haRoutingManager.upateBackEndHealth(backend, false);
+ haRoutingManager.upateBackEndHealth(backend, BackendHealthState.UNHEALTHY);
}
assert (haRoutingManager.provideBackendForRoutingGroup(groupName, "")
diff --git a/gateway-ha/src/test/resources/test-config-template.yml b/gateway-ha/src/test/resources/test-config-template.yml
index 1dae38d27..e9a977f5f 100644
--- a/gateway-ha/src/test/resources/test-config-template.yml
+++ b/gateway-ha/src/test/resources/test-config-template.yml
@@ -17,11 +17,21 @@ dataStore:
password: sa
driver: org.h2.Driver
+backendState:
+ username: lb_query
+ ssl: false
+
+clusterStatsConfiguration:
+ useApi: true
+
modules:
- io.trino.gateway.ha.module.HaGatewayProviderModule
+ - io.trino.gateway.ha.module.ClusterStateListenerModule
+ - io.trino.gateway.ha.module.ClusterStatsMonitorModule
managedApps:
- io.trino.gateway.ha.GatewayManagedApp
+ - io.trino.gateway.ha.clustermonitor.ActiveClusterMonitor
extraWhitelistPaths:
- "/v1/custom"
|