diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionCheck.java b/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionCheck.java deleted file mode 100644 index b11df2229..000000000 --- a/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionCheck.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed 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 io.trino.gateway.ha.router; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.Socket; -import java.time.Duration; -import java.time.Instant; - -class ConnectionCheck -{ - static final int NO_CHECK_YET = -100; - static final int TCP_CHECK_FAILURE = -1; - static final int TCP_CHECK_SUCCESS = 0; - private static final Logger log = LoggerFactory.getLogger(ConnectionCheck.class); - - private Instant lastCheckTime; - private int checkCode; - private final String server; - private final int port; - private final int checkInterval; - private final int failCount; - private int failCounter; - private final int disableDuration; - - ConnectionCheck(String host, int serverPort, int checkInterval, - int failCount, int disableDuration) - { - this.lastCheckTime = Instant.EPOCH; - this.checkCode = NO_CHECK_YET; - this.server = host; - this.port = serverPort; - this.checkInterval = checkInterval; - this.failCount = failCount; - this.failCounter = 0; - this.disableDuration = disableDuration; - } - - boolean isCheckNeeded() - { - try { - Instant now = Instant.now(); - log.info("time now is {}", now); - log.info("last check was at {}", lastCheckTime); - log.info("check interval is {}", checkInterval); - long diff = Duration.between(lastCheckTime, now).toMillis(); - lastCheckTime = now; - return diff > checkInterval; - } - catch (ArithmeticException ex) { - log.error("Error", ex); - } - return true; - } - - boolean isCheckDisabled() - { - if (failCounter < failCount) { - log.info("fail count is NOT reached"); - return false; - } - - log.info("fail count is reached"); - try { - Instant now = Instant.now(); - log.info("time now is {}", now); - log.info("last check was at {}", lastCheckTime); - log.info("disabled duration is {}", disableDuration); - long diff = Duration.between(lastCheckTime, now).toSeconds(); - return diff < disableDuration; - } - catch (ArithmeticException ex) { - log.error("Error", ex); - } - return true; - } - - Socket makeSocket(String server, int port) - throws IOException - { - return new Socket(server, port); - } - - int tcpCheck() - { - log.debug("trying the tcp check for {}:{}", server, port); - - if (isCheckDisabled()) { - return checkCode; - } - - if (!isCheckNeeded()) { - return checkCode; - } - - try (Socket socket = makeSocket(server, port)) { - checkCode = TCP_CHECK_SUCCESS; - log.info("able to connect to {}:{}", server, port); - failCounter = 0; - } - catch (Exception ex) { - log.error("Error while connecting to {}:{}", server, port, ex); - log.error("FailCounter {}", failCounter); - checkCode = TCP_CHECK_FAILURE; - ++failCounter; - } - - return checkCode; - } -} diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionChecker.java b/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionChecker.java deleted file mode 100644 index f723d74da..000000000 --- a/gateway-ha/src/main/java/io/trino/gateway/ha/router/ConnectionChecker.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed 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 io.trino.gateway.ha.router; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; - -import static java.lang.String.format; - -public class ConnectionChecker -{ - private static final Logger log = LoggerFactory.getLogger(ConnectionChecker.class); - private final HashMap connectionChecks; - - ConnectionChecker() - { - connectionChecks = new HashMap(); - } - - ConnectionCheck getChecker(String server, int port, int interval, - int failcount, int disableDuration) - { - String key = format("%s-%d-%d-%d-%d", server, port, interval, failcount, disableDuration); - log.info("key is {}", key); - ConnectionCheck obj = connectionChecks.get(key); - - if (obj == null) { - log.info("didn't find key {}", key); - obj = new ConnectionCheck(server, port, interval, failcount, disableDuration); - connectionChecks.put(key, obj); - } - - return obj; - } - - /** - * Check the tcp connectivity to be used in the routing rules. - * - * @param server server to connect for the check - * @param port port to connect for the check - * @param interval minimum time between 2 checks, in ms - * @param failCount how many times the check needs to fail consecutively - * before we call it a failure - * @param disableDuration how long the check should be disabled - * after it has failed in seconds - */ - public boolean tcpCheck(String server, int port, - int interval, int failCount, int disableDuration) - { - ConnectionCheck checker = getChecker(server, port, interval, failCount, disableDuration); - return checker.tcpCheck() == ConnectionCheck.TCP_CHECK_SUCCESS; - } -} diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestTcpChecks.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestTcpChecks.java deleted file mode 100644 index 24ca09b35..000000000 --- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestTcpChecks.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed 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 io.trino.gateway.ha.router; - -import jakarta.servlet.http.HttpServletRequest; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -@TestInstance(PER_CLASS) -public class TestTcpChecks -{ - @Test - public void testTcpRuleCheck() - { - String host = "localhost"; - int port = 8888; - int checkInterval = 1000; //in ms - ConnectionChecker checker = mock(ConnectionChecker.class); - when(checker.tcpCheck(host, port, checkInterval, 1, 0)).thenReturn(true); - - HttpServletRequest mockRequest = mock(HttpServletRequest.class); - when(mockRequest.getAttribute("connectionChecker")).thenReturn(checker); - - String rulesFile = "src/test/resources/rules/routing_rules_tcp_connection.yml"; - RoutingGroupSelector routingGroupSelector = RoutingGroupSelector.byRoutingRulesEngine(rulesFile); - - assertThat(routingGroupSelector.findRoutingGroup(mockRequest)).isEqualTo("cli"); - } - - @Test - public void testConnectionCheckerSuccess() - throws Exception - { - // Test successful connection check - int checkInterval = 1000; //in ms - ConnectionChecker checker = new ConnectionChecker(); - ConnectionCheck check = spy(checker.getChecker("abc", 1111, checkInterval, 1, 0)); - doReturn(mock(Socket.class)).when(check).makeSocket("abc", 1111); - assertThat(check.tcpCheck()).isEqualTo(ConnectionCheck.TCP_CHECK_SUCCESS); - - // If our interval to check the request is 1000ms then connection check is needed - TimeUnit.SECONDS.sleep(2); - assertThat(check.isCheckNeeded()).isTrue(); - - // If the interval to check 1000 ms then we won't need a check - TimeUnit.MILLISECONDS.sleep(100); - assertThat(check.isCheckNeeded()).isFalse(); - } - - @Test - public void testConnectionCheckerFailures() - throws Exception - { - int checkInterval = 1000; //in ms - ConnectionChecker checker = new ConnectionChecker(); - - // Test failed connection check - String host = "xyz"; - int port = 1111; - int failcount = 3; - int disableDuration = 10; //in sec - ConnectionCheck check = spy(checker.getChecker(host, port, checkInterval, - failcount, disableDuration)); - doAnswer(invocation -> { - throw new UnknownHostException(host); - }).when(check).makeSocket(host, port); - - // test the disable check - for (int i = 0; i < failcount; ++i) { - // wait for checkinterval, fail till failcount is reached to disable the check - TimeUnit.MILLISECONDS.sleep(1100); - assertThat(check.tcpCheck()).isNotEqualTo(ConnectionCheck.TCP_CHECK_SUCCESS); - } - // Make the server available and check if the failure contines for disableDuration - doReturn(mock(Socket.class)).when(check).makeSocket(host, port); - TimeUnit.SECONDS.sleep(6); - assertThat(check.tcpCheck()).isNotEqualTo(ConnectionCheck.TCP_CHECK_SUCCESS); - TimeUnit.SECONDS.sleep(6); - assertThat(check.tcpCheck()).isEqualTo(ConnectionCheck.TCP_CHECK_SUCCESS); - - // We maintain a map of the checkers, so verify that we got the same check back, as before - Object checkObj = checker.getChecker(host, port, checkInterval, - failcount, disableDuration); - assertThat(checker.getChecker(host, port, checkInterval, failcount, disableDuration)) - .isEqualTo(checkObj); - - assertThat(checker.getChecker(host, port, checkInterval + 10, failcount, disableDuration)) - .isNotEqualTo(checkObj); - assertThat(checker.getChecker(host, port, checkInterval, failcount + 1, disableDuration)) - .isNotEqualTo(checkObj); - assertThat(checker.getChecker(host, port, checkInterval, failcount, disableDuration + 10)) - .isNotEqualTo(checkObj); - } -} diff --git a/gateway-ha/src/test/resources/rules/routing_rules_tcp_connection.yml b/gateway-ha/src/test/resources/rules/routing_rules_tcp_connection.yml deleted file mode 100644 index 4b81c370d..000000000 --- a/gateway-ha/src/test/resources/rules/routing_rules_tcp_connection.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: "tcp check" -description: "Route based on if a tcp connection is working" -condition: "request.getAttribute(\"connectionChecker\").tcpCheck(\"localhost\", 8888, 1000, 1, 0)" -actions: - - "result.put(\"routingGroup\", \"cli\")"