JdbcCatalogMetricsSource.registerDatasourceMetrics(DataSource dataSource) currently performs an unconditional cast to BasicDataSource. This makes the method unsafe for any valid DataSource implementation, and it can fail at runtime with a ClassCastException. The improvement needed is to make datasource metric registration robust across non-DBCP DataSource instances, or at minimum fail safely.
Update registerDatasourceMetrics to handle non-BasicDataSource inputs safely, rather than casting directly.
Here's a unit test to show the issue:
public class TestJdbcCatalogMetricsSource {
@Test
public void testRegisterDatasourceMetricsWithNonBasicDataSource() {
JdbcCatalogMetricsSource source = new JdbcCatalogMetricsSource("metalake", "catalog");
DataSource nonBasicDataSource =
new DataSource() {
@Override
public Connection getConnection() {
return null;
}
@Override
public Connection getConnection(String username, String password) {
return null;
}
@Override
public PrintWriter getLogWriter() {
return null;
}
@Override
public void setLogWriter(PrintWriter out) {}
@Override
public void setLoginTimeout(int seconds) {}
@Override
public int getLoginTimeout() {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return Logger.getGlobal();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new SQLException("Not a wrapper");
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return false;
}
};
Assertions.assertDoesNotThrow(() -> source.registerDatasourceMetrics(nonBasicDataSource));
}
}