diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/health/HealthzEndpoint.java b/server/src/main/java/org/cloudfoundry/identity/uaa/health/HealthzEndpoint.java index e9bfd4973da..aaf2c05558f 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/health/HealthzEndpoint.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/health/HealthzEndpoint.java @@ -11,12 +11,15 @@ import javax.sql.DataSource; import java.sql.Connection; -import java.sql.Statement; /** * Simple controller that just returns "ok" in a request body for the purposes * of monitoring health of the application. It also registers a shutdown hook * and returns "stopping" and a 503 when the process is shutting down. + * The background database check only establishes a connection from the pool + * without executing an additional query. The configured DataSource already + * runs a validation query on every connection borrow ({@code testOnBorrow=true}), + * so obtaining a connection is sufficient to verify database connectivity. */ @Controller public class HealthzEndpoint { @@ -25,6 +28,7 @@ public class HealthzEndpoint { private volatile Boolean wasLastConnectionSuccessful = null; private DataSource dataSource; + public HealthzEndpoint( @Value("${uaa.shutdown.sleep:10000}") final long sleepTime, final Runtime runtime, @@ -71,8 +75,7 @@ public String getHealthz(HttpServletResponse response) { @Scheduled(fixedRateString = "${uaa.health.db.rate:10000}") void isDataSourceConnectionAvailable() { - try (Connection c = dataSource.getConnection(); Statement statement = c.createStatement()) { - statement.execute("SELECT 1 from identity_zone;"); //"SELECT 1;" Not supported by HSQLDB + try (Connection c = dataSource.getConnection()) { wasLastConnectionSuccessful = true; return; } catch (Exception ex) { diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/health/HealthzEndpointTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/health/HealthzEndpointTests.java index 1183c3769bf..1f973baf133 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/health/HealthzEndpointTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/health/HealthzEndpointTests.java @@ -9,10 +9,8 @@ import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; -import java.sql.Statement; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,16 +24,13 @@ class HealthzEndpointTests { private Thread shutdownHook; private DataSource dataSource; private Connection connection; - private Statement statement; @BeforeEach void setUp() throws SQLException { Runtime mockRuntime = mock(Runtime.class); dataSource = mock(DataSource.class); connection = mock(Connection.class); - statement = mock(Statement.class); when(dataSource.getConnection()).thenReturn(connection); - when(connection.createStatement()).thenReturn(statement); endpoint = new HealthzEndpoint(SLEEP_UPON_SHUTDOWN, mockRuntime, dataSource); response = new MockHttpServletResponse(); @@ -51,14 +46,15 @@ void getHealthz() throws SQLException { } @Test - void getHealthz_connectionSuccess() { + void getHealthz_connectionSuccess() throws SQLException { endpoint.isDataSourceConnectionAvailable(); assertThat(endpoint.getHealthz(response)).isEqualTo("ok\n"); + verify(dataSource).getConnection(); } @Test void getHealthz_connectionFailed() throws SQLException { - when(statement.execute(anyString())).thenThrow(new SQLException()); + when(dataSource.getConnection()).thenThrow(new SQLException()); endpoint.isDataSourceConnectionAvailable(); assertThat(endpoint.getHealthz(response)).isEqualTo("Database Connection failed.\n"); assertThat(response.getStatus()).isEqualTo(503);