Skip to content

Commit 6ae2d9a

Browse files
authored
refactor: decouple dependencies and clean up initialization logic (#1541)
1 parent 92c97cd commit 6ae2d9a

File tree

78 files changed

+2182
-1272
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2182
-1272
lines changed

benchmarks/src/jmh/java/software/amazon/jdbc/benchmarks/ConnectionPluginManagerBenchmarks.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import software.amazon.jdbc.util.telemetry.TelemetryCounter;
7676
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
7777
import software.amazon.jdbc.util.telemetry.TelemetryGauge;
78-
import software.amazon.jdbc.wrapper.ConnectionWrapper;
7978

8079
@State(Scope.Benchmark)
8180
@Fork(3)
@@ -94,7 +93,6 @@ public class ConnectionPluginManagerBenchmarks {
9493
private ConnectionPluginManager pluginManagerWithNoPlugins;
9594

9695
@Mock ConnectionProvider mockConnectionProvider;
97-
@Mock ConnectionWrapper mockConnectionWrapper;
9896
@Mock FullServicesContainer mockServicesContainer;
9997
@Mock PluginService mockPluginService;
10098
@Mock PluginManagerService mockPluginManagerService;
@@ -162,15 +160,12 @@ public void setUpIteration() throws Exception {
162160

163161
TelemetryFactory telemetryFactory = new DefaultTelemetryFactory(propertiesWithPlugins);
164162

165-
pluginManager = new ConnectionPluginManager(mockConnectionProvider,
166-
null,
167-
mockConnectionWrapper,
168-
telemetryFactory);
169-
pluginManager.init(mockServicesContainer, propertiesWithPlugins, mockPluginManagerService, configurationProfile);
163+
pluginManager = new ConnectionPluginManager(propertiesWithPlugins, telemetryFactory, mockConnectionProvider, null);
164+
pluginManager.initPlugins(mockServicesContainer, configurationProfile);
170165

171-
pluginManagerWithNoPlugins = new ConnectionPluginManager(mockConnectionProvider, null,
172-
mockConnectionWrapper, telemetryFactory);
173-
pluginManagerWithNoPlugins.init(mockServicesContainer, propertiesWithoutPlugins, mockPluginManagerService, null);
166+
pluginManagerWithNoPlugins =
167+
new ConnectionPluginManager(propertiesWithoutPlugins, telemetryFactory, mockConnectionProvider, null);
168+
pluginManagerWithNoPlugins.initPlugins(mockServicesContainer, null);
174169
}
175170

176171
@TearDown(Level.Iteration)
@@ -180,17 +175,17 @@ public void tearDownIteration() throws Exception {
180175

181176
@Benchmark
182177
public ConnectionPluginManager initConnectionPluginManagerWithNoPlugins() throws SQLException {
183-
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider, null,
184-
mockConnectionWrapper, mockTelemetryFactory);
185-
manager.init(mockServicesContainer, propertiesWithoutPlugins, mockPluginManagerService, configurationProfile);
178+
final ConnectionPluginManager manager =
179+
new ConnectionPluginManager(propertiesWithoutPlugins, mockTelemetryFactory, mockConnectionProvider, null);
180+
manager.initPlugins(mockServicesContainer, configurationProfile);
186181
return manager;
187182
}
188183

189184
@Benchmark
190185
public ConnectionPluginManager initConnectionPluginManagerWithPlugins() throws SQLException {
191-
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider, null,
192-
mockConnectionWrapper, mockTelemetryFactory);
193-
manager.init(mockServicesContainer, propertiesWithPlugins, mockPluginManagerService, configurationProfile);
186+
final ConnectionPluginManager manager =
187+
new ConnectionPluginManager(propertiesWithPlugins, mockTelemetryFactory, mockConnectionProvider, null);
188+
manager.initPlugins(mockServicesContainer, configurationProfile);
194189
return manager;
195190
}
196191

benchmarks/src/jmh/java/software/amazon/jdbc/benchmarks/PluginBenchmarks.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@
6363
import software.amazon.jdbc.dialect.Dialect;
6464
import software.amazon.jdbc.hostavailability.SimpleHostAvailabilityStrategy;
6565
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
66-
import software.amazon.jdbc.util.monitoring.MonitorService;
67-
import software.amazon.jdbc.util.storage.StorageService;
6866
import software.amazon.jdbc.util.telemetry.GaugeCallable;
6967
import software.amazon.jdbc.util.telemetry.TelemetryContext;
7068
import software.amazon.jdbc.util.telemetry.TelemetryCounter;
@@ -84,17 +82,15 @@ public class PluginBenchmarks {
8482
private static final String FIELD_SERVER_ID = "SERVER_ID";
8583
private static final String FIELD_SESSION_ID = "SESSION_ID";
8684
private static final String CONNECTION_STRING = "jdbc:postgresql://my.domain.com";
85+
private static final String PG_PROTOCOL = "jdbc:postgresql://";
8786
private static final String PG_CONNECTION_STRING =
8887
"jdbc:aws-wrapper:postgresql://instance-0.XYZ.us-east-2.rds.amazonaws.com";
8988
private static final String TEST_HOST = "instance-0";
9089
private static final int TEST_PORT = 5432;
9190
private final HostSpec writerHostSpec = new HostSpecBuilder(new SimpleHostAvailabilityStrategy())
9291
.host(TEST_HOST).port(TEST_PORT).build();
9392

94-
@Mock private StorageService mockStorageService;
95-
@Mock private MonitorService mockMonitorService;
9693
@Mock private PluginService mockPluginService;
97-
@Mock private TargetDriverDialect mockTargetDriverDialect;
9894
@Mock private Dialect mockDialect;
9995
@Mock private ConnectionPluginManager mockConnectionPluginManager;
10096
@Mock private TelemetryFactory mockTelemetryFactory;
@@ -173,15 +169,11 @@ private ConnectionWrapper getConnectionWrapper(Properties props, String connStri
173169
return new TestConnectionWrapper(
174170
props,
175171
connString,
176-
mockConnectionProvider,
177-
mockTargetDriverDialect,
172+
PG_PROTOCOL,
178173
mockConnectionPluginManager,
179-
mockTelemetryFactory,
180174
mockPluginService,
181175
mockHostListProviderService,
182-
mockPluginManagerService,
183-
mockStorageService,
184-
mockMonitorService);
176+
mockPluginManagerService);
185177
}
186178

187179
@Benchmark

benchmarks/src/jmh/java/software/amazon/jdbc/benchmarks/testplugin/TestConnectionWrapper.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,29 @@
2020
import java.util.Properties;
2121
import org.checkerframework.checker.nullness.qual.NonNull;
2222
import software.amazon.jdbc.ConnectionPluginManager;
23-
import software.amazon.jdbc.ConnectionProvider;
2423
import software.amazon.jdbc.HostListProviderService;
2524
import software.amazon.jdbc.PluginManagerService;
2625
import software.amazon.jdbc.PluginService;
27-
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
28-
import software.amazon.jdbc.util.monitoring.MonitorService;
29-
import software.amazon.jdbc.util.storage.StorageService;
30-
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
3126
import software.amazon.jdbc.wrapper.ConnectionWrapper;
3227

3328
// Test class allowing for mocks to be used with ConnectionWrapper logic
3429
public class TestConnectionWrapper extends ConnectionWrapper {
35-
3630
public TestConnectionWrapper(
3731
@NonNull final Properties props,
3832
@NonNull final String url,
39-
@NonNull final ConnectionProvider defaultConnectionProvider,
40-
@NonNull final TargetDriverDialect driverDialect,
33+
@NonNull final String protocol,
4134
@NonNull final ConnectionPluginManager connectionPluginManager,
42-
@NonNull final TelemetryFactory telemetryFactory,
4335
@NonNull final PluginService pluginService,
4436
@NonNull final HostListProviderService hostListProviderService,
45-
@NonNull final PluginManagerService pluginManagerService,
46-
@NonNull final StorageService storageService,
47-
@NonNull final MonitorService monitorService)
37+
@NonNull final PluginManagerService pluginManagerService)
4838
throws SQLException {
4939
super(
5040
props,
5141
url,
52-
defaultConnectionProvider,
53-
driverDialect,
42+
protocol,
5443
connectionPluginManager,
55-
telemetryFactory,
5644
pluginService,
5745
hostListProviderService,
58-
pluginManagerService,
59-
storageService,
60-
monitorService);
46+
pluginManagerService);
6147
}
6248
}

wrapper/src/main/java/software/amazon/jdbc/ConnectionPluginChainBuilder.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ public List<ConnectionPlugin> getPlugins(
146146
final FullServicesContainer servicesContainer,
147147
final ConnectionProvider defaultConnProvider,
148148
final ConnectionProvider effectiveConnProvider,
149-
final PluginManagerService pluginManagerService,
150149
final Properties props,
151150
@Nullable ConfigurationProfile configurationProfile) throws SQLException {
152151

@@ -234,7 +233,7 @@ public List<ConnectionPlugin> getPlugins(
234233
servicesContainer.getPluginService(),
235234
defaultConnProvider,
236235
effectiveConnProvider,
237-
pluginManagerService);
236+
servicesContainer.getPluginManagerService());
238237

239238
plugins.add(defaultPlugin);
240239

wrapper/src/main/java/software/amazon/jdbc/ConnectionPluginManager.java

Lines changed: 16 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,9 @@
5151
import software.amazon.jdbc.util.FullServicesContainer;
5252
import software.amazon.jdbc.util.Messages;
5353
import software.amazon.jdbc.util.Utils;
54-
import software.amazon.jdbc.util.WrapperUtils;
5554
import software.amazon.jdbc.util.telemetry.TelemetryContext;
5655
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
5756
import software.amazon.jdbc.util.telemetry.TelemetryTraceLevel;
58-
import software.amazon.jdbc.wrapper.ConnectionWrapper;
5957

6058
/**
6159
* This class creates and handles a chain of {@link ConnectionPlugin} for each connection.
@@ -92,29 +90,25 @@ public class ConnectionPluginManager implements CanReleaseResources, Wrapper {
9290
}
9391
};
9492

95-
private final ReentrantLock lock = new ReentrantLock();
96-
97-
protected Properties props = new Properties();
98-
protected List<ConnectionPlugin> plugins;
99-
protected final @NonNull ConnectionProvider defaultConnProvider;
100-
protected final @Nullable ConnectionProvider effectiveConnProvider;
101-
protected final ConnectionWrapper connectionWrapper;
102-
protected FullServicesContainer servicesContainer;
103-
protected PluginService pluginService;
104-
protected TelemetryFactory telemetryFactory;
105-
protected boolean isTelemetryInUse;
10693
@SuppressWarnings("rawtypes")
10794
protected final PluginChainJdbcCallableInfo[] pluginChainFuncMap =
10895
new PluginChainJdbcCallableInfo[JdbcMethod.ALL.id + 1]; // it should be the last element in JdbcMethod enum
96+
protected final ReentrantLock lock = new ReentrantLock();
97+
protected final Properties props;
98+
protected final TelemetryFactory telemetryFactory;
99+
protected final boolean isTelemetryInUse;
100+
protected final ConnectionProvider defaultConnProvider;
101+
protected final @Nullable ConnectionProvider effectiveConnProvider;
102+
protected List<ConnectionPlugin> plugins;
109103

110104
public ConnectionPluginManager(
105+
final @NonNull Properties props,
106+
final @NonNull TelemetryFactory telemetryFactory,
111107
final @NonNull ConnectionProvider defaultConnProvider,
112-
final @Nullable ConnectionProvider effectiveConnProvider,
113-
final @Nullable ConnectionWrapper connectionWrapper,
114-
final @NonNull TelemetryFactory telemetryFactory) {
108+
final @Nullable ConnectionProvider effectiveConnProvider) {
109+
this.props = props;
115110
this.defaultConnProvider = defaultConnProvider;
116111
this.effectiveConnProvider = effectiveConnProvider;
117-
this.connectionWrapper = connectionWrapper;
118112
this.telemetryFactory = telemetryFactory;
119113
this.isTelemetryInUse = telemetryFactory.inUse();
120114
}
@@ -127,28 +121,11 @@ public ConnectionPluginManager(
127121
final @Nullable ConnectionProvider effectiveConnProvider,
128122
final Properties props,
129123
final List<ConnectionPlugin> plugins,
130-
final ConnectionWrapper connectionWrapper,
131-
final PluginService pluginService,
132-
final TelemetryFactory telemetryFactory) {
133-
this(defaultConnProvider, effectiveConnProvider, props, plugins, connectionWrapper, telemetryFactory);
134-
this.pluginService = pluginService;
135-
}
136-
137-
/**
138-
* This constructor is for testing purposes only.
139-
*/
140-
ConnectionPluginManager(
141-
final @NonNull ConnectionProvider defaultConnProvider,
142-
final @Nullable ConnectionProvider effectiveConnProvider,
143-
final Properties props,
144-
final List<ConnectionPlugin> plugins,
145-
final ConnectionWrapper connectionWrapper,
146124
final TelemetryFactory telemetryFactory) {
147125
this.defaultConnProvider = defaultConnProvider;
148126
this.effectiveConnProvider = effectiveConnProvider;
149127
this.props = props;
150128
this.plugins = plugins;
151-
this.connectionWrapper = connectionWrapper;
152129
this.telemetryFactory = telemetryFactory;
153130
this.isTelemetryInUse = telemetryFactory.inUse();
154131
}
@@ -170,30 +147,18 @@ public void unlock() {
170147
* connection plugin in the chain.
171148
*
172149
* @param servicesContainer the service container for the services required by this class.
173-
* @param props the configuration of the connection
174-
* @param pluginManagerService a reference to a plugin manager service
175150
* @param configurationProfile a profile configuration defined by the user
176151
* @throws SQLException if errors occurred during the execution
177152
*/
178-
public void init(
153+
public void initPlugins(
179154
final FullServicesContainer servicesContainer,
180-
final Properties props,
181-
final PluginManagerService pluginManagerService,
182155
@Nullable ConfigurationProfile configurationProfile) throws SQLException {
183-
184-
this.props = props;
185-
this.servicesContainer = servicesContainer;
186-
this.pluginService = servicesContainer.getPluginService();
187-
this.telemetryFactory = servicesContainer.getTelemetryFactory();
188-
this.isTelemetryInUse = telemetryFactory.inUse();
189-
190156
ConnectionPluginChainBuilder pluginChainBuilder = new ConnectionPluginChainBuilder();
191157
this.plugins = pluginChainBuilder.getPlugins(
192-
this.servicesContainer,
158+
servicesContainer,
193159
this.defaultConnProvider,
194160
this.effectiveConnProvider,
195-
pluginManagerService,
196-
props,
161+
this.props,
197162
configurationProfile);
198163
}
199164

@@ -223,14 +188,8 @@ protected <T, E extends Exception> T executeWithSubscribedPlugins(
223188
this.pluginChainFuncMap[jdbcMethod.id] = pluginChainJdbcCallableInfo;
224189
}
225190

226-
227-
if (pluginChainJdbcCallableInfo == null) {
228-
throw new RuntimeException("Error processing this JDBC call.");
229-
}
230-
231191
if (jdbcMethod.alwaysUsePipeline || pluginChainJdbcCallableInfo.isSubscribed) {
232192
// noinspection unchecked
233-
@SuppressWarnings("unchecked")
234193
PluginChainJdbcCallable<T, E> pluginChainFunc = pluginChainJdbcCallableInfo.func;
235194
return pluginChainFunc.call(pluginPipeline, jdbcMethodFunc, pluginToSkip);
236195
} else {
@@ -320,10 +279,6 @@ protected <E extends Exception> void notifySubscribedPlugins(
320279
}
321280
}
322281

323-
public ConnectionWrapper getConnectionWrapper() {
324-
return this.connectionWrapper;
325-
}
326-
327282
public TelemetryFactory getTelemetryFactory() {
328283
return this.telemetryFactory;
329284
}
@@ -345,18 +300,6 @@ public <T, E extends Exception> T execute(
345300
final JdbcCallable<T, E> jdbcMethodFunc,
346301
final Object[] jdbcMethodArgs)
347302
throws E {
348-
349-
// The target driver may block on Statement.getConnection().
350-
if (jdbcMethod.shouldLockConnection && jdbcMethod.checkBoundedConnection) {
351-
final Connection conn = WrapperUtils.getConnectionFromSqlObject(methodInvokeOn);
352-
if (conn != null && conn != this.pluginService.getCurrentConnection()) {
353-
throw WrapperUtils.wrapExceptionIfNeeded(
354-
exceptionClass,
355-
new SQLException(
356-
Messages.get("ConnectionPluginManager.invokedAgainstOldConnection", new Object[]{methodInvokeOn})));
357-
}
358-
}
359-
360303
return executeWithSubscribedPlugins(
361304
jdbcMethod,
362305
(plugin, func) ->
@@ -635,9 +578,7 @@ public <T> T unwrap(Class<T> iface) throws SQLException {
635578
if (iface == ConnectionPluginManager.class) {
636579
return iface.cast(this);
637580
}
638-
if (iface == PluginService.class) {
639-
return iface.cast(this.pluginService);
640-
}
581+
641582
if (this.plugins == null) {
642583
return null;
643584
}
@@ -647,6 +588,7 @@ public <T> T unwrap(Class<T> iface) throws SQLException {
647588
return iface.cast(p);
648589
}
649590
}
591+
650592
return null;
651593
}
652594

wrapper/src/main/java/software/amazon/jdbc/Driver.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@
5959
import software.amazon.jdbc.util.CoreServicesContainer;
6060
import software.amazon.jdbc.util.DriverInfo;
6161
import software.amazon.jdbc.util.FullServicesContainer;
62-
import software.amazon.jdbc.util.FullServicesContainerImpl;
6362
import software.amazon.jdbc.util.Messages;
6463
import software.amazon.jdbc.util.PropertyUtils;
6564
import software.amazon.jdbc.util.RdsUtils;
65+
import software.amazon.jdbc.util.ServiceUtility;
6666
import software.amazon.jdbc.util.StringUtils;
6767
import software.amazon.jdbc.util.WrapperUtils;
6868
import software.amazon.jdbc.util.monitoring.MonitorService;
@@ -110,6 +110,7 @@ public class Driver implements java.sql.Driver {
110110

111111
private final StorageService storageService;
112112
private final MonitorService monitorService;
113+
private final ConnectionUrlParser urlParser = new ConnectionUrlParser();
113114

114115
public Driver() {
115116
this(CoreServicesContainer.getInstance());
@@ -239,18 +240,20 @@ public Connection connect(final String url, final Properties info) throws SQLExc
239240
effectiveConnectionProvider = configurationProfile.getConnectionProvider();
240241
}
241242

242-
FullServicesContainer servicesContainer =
243-
new FullServicesContainerImpl(storageService, monitorService, defaultConnectionProvider, telemetryFactory);
244-
245-
return new ConnectionWrapper(
246-
servicesContainer,
247-
props,
248-
driverUrl,
243+
String targetDriverProtocol = urlParser.getProtocol(driverUrl);
244+
FullServicesContainer servicesContainer = ServiceUtility.getInstance().createStandardServiceContainer(
245+
storageService,
246+
monitorService,
249247
defaultConnectionProvider,
250248
effectiveConnectionProvider,
249+
telemetryFactory,
250+
driverUrl,
251+
targetDriverProtocol,
251252
targetDriverDialect,
253+
props,
252254
configurationProfile);
253255

256+
return new ConnectionWrapper(servicesContainer, props, url, targetDriverProtocol, configurationProfile);
254257
} catch (Exception ex) {
255258
if (context != null) {
256259
context.setException(ex);

0 commit comments

Comments
 (0)