3232import java .util .concurrent .Executors ;
3333import java .util .concurrent .TimeoutException ;
3434
35+ import com .google .common .collect .ImmutableMap ;
36+
3537import static java .util .concurrent .TimeUnit .SECONDS ;
3638
3739public class ClusterStatsJdbcMonitor
3840 implements ClusterStatsMonitor
3941{
4042 private static final Logger log = Logger .get (ClusterStatsJdbcMonitor .class );
4143
42- private final Properties properties ; // TODO Avoid using a mutable field
44+ private final ImmutableMap <String , String > properties ; // Replaced mutable Properties with ImmutableMap
45+ private final JdbcMonitorConfiguration jdbcConfig ;
4346 private final Duration queryTimeout ;
4447
4548 private static final String STATE_QUERY = "SELECT state, COUNT(*) as count "
@@ -49,16 +52,17 @@ public class ClusterStatsJdbcMonitor
4952
5053 public ClusterStatsJdbcMonitor (BackendStateConfiguration backendStateConfiguration , MonitorConfiguration monitorConfiguration )
5154 {
52- properties = new Properties ();
53- properties .setProperty ("user" , backendStateConfiguration .getUsername ());
54- properties .setProperty ("password" , backendStateConfiguration .getPassword ());
55- properties .setProperty ("SSL" , String .valueOf (backendStateConfiguration .getSsl ()));
56- // explicitPrepare is a valid property for Trino versions >= 431. To avoid compatibility
57- // issues with versions < 431, this property is left unset when explicitPrepare=true, which is the default
58- if (!monitorConfiguration .isExplicitPrepare ()) {
59- properties .setProperty ("explicitPrepare" , "false" );
60- }
55+ this .jdbcConfig = JdbcMonitorConfiguration .from (backendStateConfiguration , monitorConfiguration );
6156 queryTimeout = monitorConfiguration .getQueryTimeout ();
57+
58+ // Create immutable properties map to avoid mutable field anti-pattern
59+ Properties baseProperties = jdbcConfig .toProperties ();
60+ ImmutableMap .Builder <String , String > propertiesBuilder = ImmutableMap .builder ();
61+ for (String key : baseProperties .stringPropertyNames ()) {
62+ propertiesBuilder .put (key , baseProperties .getProperty (key ));
63+ }
64+ this .properties = propertiesBuilder .build ();
65+
6266 log .info ("state check configured" );
6367 }
6468
@@ -68,24 +72,28 @@ public ClusterStats monitor(ProxyBackendConfiguration backend)
6872 String url = backend .getProxyTo ();
6973 ClusterStats .Builder clusterStats = ClusterStatsMonitor .getClusterStatsBuilder (backend );
7074 String jdbcUrl ;
75+ Properties connectionProperties ;
7176 try {
7277 URL parsedUrl = new URL (url );
7378 jdbcUrl = String
7479 .format ("jdbc:trino://%s:%s/system" ,
7580 parsedUrl .getHost (),
7681 parsedUrl .getPort () == -1 ? parsedUrl .getDefaultPort () : parsedUrl .getPort ());
77- // automatically set ssl config based on url protocol
78- properties .setProperty ("SSL" , String .valueOf (parsedUrl .getProtocol ().equals ("https" )));
82+
83+ // Create connection properties from immutable map
84+ connectionProperties = new Properties ();
85+ connectionProperties .putAll (properties );
86+ connectionProperties .setProperty ("SSL" , String .valueOf (parsedUrl .getProtocol ().equals ("https" )));
7987 }
8088 catch (MalformedURLException e ) {
81- log .error ("could not parse backend url %s " , url );
82- return clusterStats . build (); // TODO Invalid configuration should fail
89+ log .error ("Invalid backend URL configuration: %s " , url );
90+ throw new IllegalArgumentException ( "Invalid backend URL: " + url , e );
8391 }
8492
85- try (Connection conn = DriverManager .getConnection (jdbcUrl , properties );
93+ try (Connection conn = DriverManager .getConnection (jdbcUrl , connectionProperties );
8694 PreparedStatement statement = SimpleTimeLimiter .create (Executors .newSingleThreadExecutor ()).callWithTimeout (
8795 () -> conn .prepareStatement (STATE_QUERY ), 10 , SECONDS )) {
88- statement .setString (1 , ( String ) properties . get ( "user" ));
96+ statement .setString (1 , jdbcConfig . getUsername ( ));
8997 statement .setQueryTimeout ((int ) queryTimeout .roundTo (SECONDS ));
9098 Map <String , Integer > partialState = new HashMap <>();
9199 ResultSet rs = statement .executeQuery ();
0 commit comments