2323import java .util .List ;
2424import java .util .Map ;
2525import java .util .Properties ;
26+ import java .util .concurrent .ConcurrentHashMap ;
27+ import java .util .concurrent .ConcurrentMap ;
28+ import java .util .concurrent .atomic .AtomicReference ;
2629import java .util .logging .Logger ;
2730import java .util .stream .Collectors ;
2831import org .checkerframework .checker .nullness .qual .Nullable ;
@@ -59,31 +62,31 @@ public class ConnectionPluginChainBuilder {
5962
6063 private static final int WEIGHT_RELATIVE_TO_PRIOR_PLUGIN = -1 ;
6164
62- protected static final Map <String , Class <? extends ConnectionPluginFactory > > pluginFactoriesByCode =
63- new HashMap <String , Class <? extends ConnectionPluginFactory > >() {
65+ protected static final Map <String , ConnectionPluginFactory > pluginFactoriesByCode =
66+ new HashMap <String , ConnectionPluginFactory >() {
6467 {
65- put ("executionTime" , ExecutionTimeConnectionPluginFactory . class );
66- put ("logQuery" , LogQueryConnectionPluginFactory . class );
67- put ("dataCache" , DataCacheConnectionPluginFactory . class );
68- put ("customEndpoint" , CustomEndpointPluginFactory . class );
69- put ("efm" , HostMonitoringConnectionPluginFactory . class );
70- put ("efm2" , software .amazon .jdbc .plugin .efm2 .HostMonitoringConnectionPluginFactory . class );
71- put ("failover" , FailoverConnectionPluginFactory . class );
72- put ("failover2" , software .amazon .jdbc .plugin .failover2 .FailoverConnectionPluginFactory . class );
73- put ("iam" , IamAuthConnectionPluginFactory . class );
74- put ("awsSecretsManager" , AwsSecretsManagerConnectionPluginFactory . class );
75- put ("federatedAuth" , FederatedAuthPluginFactory . class );
76- put ("okta" , OktaAuthPluginFactory . class );
77- put ("auroraStaleDns" , AuroraStaleDnsPluginFactory . class );
78- put ("readWriteSplitting" , ReadWriteSplittingPluginFactory . class );
79- put ("auroraConnectionTracker" , AuroraConnectionTrackerPluginFactory . class );
80- put ("driverMetaData" , DriverMetaDataConnectionPluginFactory . class );
81- put ("connectTime" , ConnectTimeConnectionPluginFactory . class );
82- put ("dev" , DeveloperConnectionPluginFactory . class );
83- put ("fastestResponseStrategy" , FastestResponseStrategyPluginFactory . class );
84- put ("initialConnection" , AuroraInitialConnectionStrategyPluginFactory . class );
85- put ("limitless" , LimitlessConnectionPluginFactory . class );
86- put ("bg" , BlueGreenConnectionPluginFactory . class );
68+ put ("executionTime" , new ExecutionTimeConnectionPluginFactory () );
69+ put ("logQuery" , new LogQueryConnectionPluginFactory () );
70+ put ("dataCache" , new DataCacheConnectionPluginFactory () );
71+ put ("customEndpoint" , new CustomEndpointPluginFactory () );
72+ put ("efm" , new HostMonitoringConnectionPluginFactory () );
73+ put ("efm2" , new software .amazon .jdbc .plugin .efm2 .HostMonitoringConnectionPluginFactory () );
74+ put ("failover" , new FailoverConnectionPluginFactory () );
75+ put ("failover2" , new software .amazon .jdbc .plugin .failover2 .FailoverConnectionPluginFactory () );
76+ put ("iam" , new IamAuthConnectionPluginFactory () );
77+ put ("awsSecretsManager" , new AwsSecretsManagerConnectionPluginFactory () );
78+ put ("federatedAuth" , new FederatedAuthPluginFactory () );
79+ put ("okta" , new OktaAuthPluginFactory () );
80+ put ("auroraStaleDns" , new AuroraStaleDnsPluginFactory () );
81+ put ("readWriteSplitting" , new ReadWriteSplittingPluginFactory () );
82+ put ("auroraConnectionTracker" , new AuroraConnectionTrackerPluginFactory () );
83+ put ("driverMetaData" , new DriverMetaDataConnectionPluginFactory () );
84+ put ("connectTime" , new ConnectTimeConnectionPluginFactory () );
85+ put ("dev" , new DeveloperConnectionPluginFactory () );
86+ put ("fastestResponseStrategy" , new FastestResponseStrategyPluginFactory () );
87+ put ("initialConnection" , new AuroraInitialConnectionStrategyPluginFactory () );
88+ put ("limitless" , new LimitlessConnectionPluginFactory () );
89+ put ("bg" , new BlueGreenConnectionPluginFactory () );
8790 }
8891 };
8992
@@ -119,17 +122,20 @@ public class ConnectionPluginChainBuilder {
119122 }
120123 };
121124
125+ protected static final ConcurrentMap <Class <? extends ConnectionPluginFactory >, ConnectionPluginFactory >
126+ pluginFactoriesByClass = new ConcurrentHashMap <>();
127+
122128 protected static final String DEFAULT_PLUGINS = "auroraConnectionTracker,failover2,efm2" ;
123129
124130 /*
125131 Internal class used for plugin factory sorting. It holds a reference to a plugin
126132 factory and an assigned weight.
127133 */
128134 private static class PluginFactoryInfo {
129- public Class <? extends ConnectionPluginFactory > factory ;
135+ public ConnectionPluginFactory factory ;
130136 public int weight ;
131137
132- public PluginFactoryInfo (final Class <? extends ConnectionPluginFactory > factory , final int weight ) {
138+ public PluginFactoryInfo (final ConnectionPluginFactory factory , final int weight ) {
133139 this .factory = factory ;
134140 this .weight = weight ;
135141 }
@@ -145,10 +151,41 @@ public List<ConnectionPlugin> getPlugins(
145151 throws SQLException {
146152
147153 List <ConnectionPlugin > plugins ;
148- List <Class <? extends ConnectionPluginFactory > > pluginFactories ;
154+ List <ConnectionPluginFactory > pluginFactories ;
149155
150156 if (configurationProfile != null && configurationProfile .getPluginFactories () != null ) {
151- pluginFactories = configurationProfile .getPluginFactories ();
157+ List <Class <? extends ConnectionPluginFactory >> pluginFactoryClasses = configurationProfile .getPluginFactories ();
158+ pluginFactories = new ArrayList <>(pluginFactoryClasses .size ());
159+
160+ for (final Class <? extends ConnectionPluginFactory > factoryClazz : pluginFactoryClasses ) {
161+ final AtomicReference <InstantiationException > lastException = new AtomicReference <>(null );
162+ final ConnectionPluginFactory factory = pluginFactoriesByClass .computeIfAbsent (factoryClazz , (key ) -> {
163+ try {
164+ return WrapperUtils .createInstance (
165+ factoryClazz ,
166+ ConnectionPluginFactory .class ,
167+ null ,
168+ (Object ) null );
169+
170+ } catch (InstantiationException ex ) {
171+ lastException .set (ex );
172+ }
173+ return null ;
174+ });
175+
176+ if (lastException .get () != null ) {
177+ throw new SQLException (
178+ Messages .get (
179+ "ConnectionPluginManager.unableToLoadPlugin" ,
180+ new Object [] {factoryClazz .getName ()}),
181+ SqlState .UNKNOWN_STATE .getState (),
182+ lastException .get ());
183+ }
184+
185+ if (factory != null ) {
186+ pluginFactories .add (factory );
187+ }
188+ }
152189 } else {
153190
154191 final List <String > pluginCodeList = getPluginCodes (props );
@@ -170,33 +207,20 @@ public List<ConnectionPlugin> getPlugins(
170207 if (PropertyDefinition .AUTO_SORT_PLUGIN_ORDER .getBoolean (props )) {
171208 pluginFactories = this .sortPluginFactories (pluginFactories );
172209
173- final List <Class <? extends ConnectionPluginFactory > > tempPluginFactories = pluginFactories ;
210+ final List <ConnectionPluginFactory > tempPluginFactories = pluginFactories ;
174211 LOGGER .finest (() ->
175212 "Plugins order has been rearranged. The following order is in effect: "
176213 + tempPluginFactories .stream ()
177- .map (Class :: getSimpleName )
214+ .map (x -> x . getClass (). getSimpleName () )
178215 .collect (Collectors .joining (", " )));
179216 }
180217
181- try {
182- final ConnectionPluginFactory [] factories =
183- WrapperUtils .loadClasses (
184- pluginFactories ,
185- ConnectionPluginFactory .class ,
186- "ConnectionPluginManager.unableToLoadPlugin" )
187- .toArray (new ConnectionPluginFactory [0 ]);
188-
189- // make a chain of connection plugins
190-
191- plugins = new ArrayList <>(factories .length + 1 );
192-
193- for (final ConnectionPluginFactory factory : factories ) {
194- plugins .add (factory .getInstance (pluginService , props ));
195- }
196-
197- } catch (final InstantiationException instEx ) {
198- throw new SQLException (instEx .getMessage (), SqlState .UNKNOWN_STATE .getState (), instEx );
218+ // make a chain of connection plugins
219+ plugins = new ArrayList <>(pluginFactories .size () + 1 );
220+ for (final ConnectionPluginFactory factory : pluginFactories ) {
221+ plugins .add (factory .getInstance (pluginService , props ));
199222 }
223+
200224 } else {
201225 plugins = new ArrayList <>(1 ); // one spot for default connection plugin
202226 }
@@ -221,13 +245,13 @@ public static List<String> getPluginCodes(final Properties props) {
221245 return StringUtils .split (pluginCodes , "," , true );
222246 }
223247
224- protected List <Class <? extends ConnectionPluginFactory > > sortPluginFactories (
225- final List <Class <? extends ConnectionPluginFactory > > unsortedPluginFactories ) {
248+ protected List <ConnectionPluginFactory > sortPluginFactories (
249+ final List <ConnectionPluginFactory > unsortedPluginFactories ) {
226250
227251 final ArrayList <PluginFactoryInfo > weights = new ArrayList <>();
228252 int lastWeight = 0 ;
229- for (Class <? extends ConnectionPluginFactory > pluginFactory : unsortedPluginFactories ) {
230- Integer pluginFactoryWeight = pluginWeightByPluginFactory .get (pluginFactory );
253+ for (ConnectionPluginFactory pluginFactory : unsortedPluginFactories ) {
254+ Integer pluginFactoryWeight = pluginWeightByPluginFactory .get (pluginFactory . getClass () );
231255
232256 if (pluginFactoryWeight == null || pluginFactoryWeight == WEIGHT_RELATIVE_TO_PRIOR_PLUGIN ) {
233257
0 commit comments