3939import software .amazon .jdbc .targetdriverdialect .ConnectInfo ;
4040import software .amazon .jdbc .targetdriverdialect .TargetDriverDialect ;
4141import software .amazon .jdbc .util .Messages ;
42+ import software .amazon .jdbc .util .Pair ;
4243import software .amazon .jdbc .util .PropertyUtils ;
4344import software .amazon .jdbc .util .RdsUrlType ;
4445import software .amazon .jdbc .util .RdsUtils ;
@@ -61,17 +62,22 @@ public class HikariPooledConnectionProvider implements PooledConnectionProvider,
6162 });
6263
6364 protected static final RdsUtils rdsUtils = new RdsUtils ();
64- protected static SlidingExpirationCache <PoolKey , HikariDataSource > databasePools =
65- new SlidingExpirationCache <>(
66- (hikariDataSource ) -> hikariDataSource .getHikariPoolMXBean ().getActiveConnections () == 0 ,
67- HikariDataSource ::close
68- );
6965 protected static long poolExpirationCheckNanos = TimeUnit .MINUTES .toNanos (30 );
7066 protected final HikariPoolConfigurator poolConfigurator ;
7167 protected final HikariPoolMapping poolMapping ;
7268 protected final AcceptsUrlFunc acceptsUrlFunc ;
7369 protected final LeastConnectionsHostSelector leastConnectionsHostSelector ;
7470
71+ static {
72+ HikariPoolsHolder .databasePools .setShouldDisposeFunc (
73+ (hikariDataSource ) -> {
74+ if (hikariDataSource instanceof HikariDataSource ) {
75+ return ((HikariDataSource ) hikariDataSource ).getHikariPoolMXBean ().getActiveConnections () == 0 ;
76+ }
77+ return true ;
78+ });
79+ }
80+
7581 /**
7682 * {@link HikariPooledConnectionProvider} constructor. This class can be passed to
7783 * {@link ConnectionProviderManager#setConnectionProvider} to enable internal connection pools for
@@ -114,7 +120,7 @@ public HikariPooledConnectionProvider(
114120 this .poolConfigurator = hikariPoolConfigurator ;
115121 this .poolMapping = mapping ;
116122 this .acceptsUrlFunc = null ;
117- this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (databasePools );
123+ this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (HikariPoolsHolder . databasePools );
118124 }
119125
120126 /**
@@ -151,8 +157,8 @@ public HikariPooledConnectionProvider(
151157 this .poolMapping = mapping ;
152158 this .acceptsUrlFunc = null ;
153159 poolExpirationCheckNanos = poolExpirationNanos ;
154- databasePools .setCleanupIntervalNanos (poolCleanupNanos );
155- this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (databasePools );
160+ HikariPoolsHolder . databasePools .setCleanupIntervalNanos (poolCleanupNanos );
161+ this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (HikariPoolsHolder . databasePools );
156162 }
157163
158164 /**
@@ -193,8 +199,8 @@ public HikariPooledConnectionProvider(
193199 this .poolMapping = mapping ;
194200 this .acceptsUrlFunc = acceptsUrlFunc ;
195201 poolExpirationCheckNanos = poolExpirationNanos ;
196- databasePools .setCleanupIntervalNanos (poolCleanupNanos );
197- this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (databasePools );
202+ HikariPoolsHolder . databasePools .setCleanupIntervalNanos (poolCleanupNanos );
203+ this .leastConnectionsHostSelector = new LeastConnectionsHostSelector (HikariPoolsHolder . databasePools );
198204 }
199205
200206
@@ -272,8 +278,8 @@ public Connection connect(
272278 final HostSpec finalHostSpec = connectionHostSpec ;
273279 dialect .prepareConnectProperties (copy , protocol , finalHostSpec );
274280
275- final HikariDataSource ds = databasePools .computeIfAbsent (
276- new PoolKey (hostSpec .getUrl (), getPoolKey (finalHostSpec , copy )),
281+ final HikariDataSource ds = ( HikariDataSource ) HikariPoolsHolder . databasePools .computeIfAbsent (
282+ Pair . create (hostSpec .getUrl (), getPoolKey (finalHostSpec , copy )),
277283 (lambdaPoolKey ) -> createHikariDataSource (protocol , finalHostSpec , copy , targetDriverDialect ),
278284 poolExpirationCheckNanos
279285 );
@@ -297,22 +303,7 @@ protected String getPoolKey(HostSpec hostSpec, Properties props) {
297303
298304 @ Override
299305 public void releaseResources () {
300- databasePools .getEntries ().forEach ((poolKey , pool ) -> {
301- if (!pool .isClosed ()) {
302- pool .close ();
303- }
304- });
305- databasePools .clear ();
306- }
307-
308- // For testing purposes
309- public static void clearCache () {
310- databasePools .getEntries ().forEach ((poolKey , pool ) -> {
311- if (!pool .isClosed ()) {
312- pool .close ();
313- }
314- });
315- databasePools .clear ();
306+ HikariPoolsHolder .closeAllPools ();
316307 }
317308
318309 /**
@@ -378,7 +369,7 @@ protected void configurePool(
378369 * @return the number of active connection pools
379370 */
380371 public int getHostCount () {
381- return databasePools .size ();
372+ return HikariPoolsHolder . databasePools .size ();
382373 }
383374
384375 /**
@@ -388,8 +379,8 @@ public int getHostCount() {
388379 */
389380 public Set <String > getHosts () {
390381 return Collections .unmodifiableSet (
391- databasePools .getEntries ().keySet ().stream ()
392- .map (poolKey -> poolKey .url )
382+ HikariPoolsHolder . databasePools .getEntries ().keySet ().stream ()
383+ .map (poolKey -> ( String ) poolKey .getValue1 () )
393384 .collect (Collectors .toSet ()));
394385 }
395386
@@ -398,8 +389,8 @@ public Set<String> getHosts() {
398389 *
399390 * @return a set containing every key associated with an active connection pool
400391 */
401- public Set <PoolKey > getKeys () {
402- return databasePools .getEntries ().keySet ();
392+ public Set <Pair > getKeys () {
393+ return HikariPoolsHolder . databasePools .getEntries ().keySet ();
403394 }
404395
405396 @ Override
@@ -413,7 +404,7 @@ public String getTargetName() {
413404 public void logConnections () {
414405 LOGGER .finest (() -> {
415406 final StringBuilder builder = new StringBuilder ();
416- databasePools .getEntries ().forEach ((key , dataSource ) -> {
407+ HikariPoolsHolder . databasePools .getEntries ().forEach ((key , dataSource ) -> {
417408 builder .append ("\t [ " );
418409 builder .append (key ).append (":" );
419410 builder .append ("\n \t {" );
@@ -436,51 +427,8 @@ HikariDataSource createHikariDataSource(
436427 return new HikariDataSource (config );
437428 }
438429
439- public static class PoolKey {
440- private final @ NonNull String url ;
441- private final @ NonNull String extraKey ;
442-
443- public PoolKey (final @ NonNull String url , final @ NonNull String extraKey ) {
444- this .url = url ;
445- this .extraKey = extraKey ;
446- }
447-
448- public String getUrl () {
449- return this .url ;
450- }
451-
452- @ Override
453- public int hashCode () {
454- final int prime = 31 ;
455- int result = 1 ;
456- result = prime * result + ((url == null ) ? 0 : url .hashCode ()) + ((extraKey == null ) ? 0 : extraKey .hashCode ());
457- return result ;
458- }
459-
460- @ Override
461- public boolean equals (final Object obj ) {
462- if (this == obj ) {
463- return true ;
464- }
465- if (obj == null ) {
466- return false ;
467- }
468- if (getClass () != obj .getClass ()) {
469- return false ;
470- }
471- final PoolKey other = (PoolKey ) obj ;
472- return this .url .equals (other .url ) && this .extraKey .equals (other .extraKey );
473- }
474-
475- @ Override
476- public String toString () {
477- return "PoolKey [url=" + url + ", extraKey=" + extraKey + "]" ;
478- }
479-
480- }
481-
482430 // For testing purposes only
483- void setDatabasePools (SlidingExpirationCache <PoolKey , HikariDataSource > connectionPools ) {
484- databasePools = connectionPools ;
431+ void setDatabasePools (SlidingExpirationCache <Pair , AutoCloseable > connectionPools ) {
432+ HikariPoolsHolder . databasePools = connectionPools ;
485433 }
486434}
0 commit comments