Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b94b7f2
wip
aaron-congo Aug 15, 2025
29a58cb
Replace PluginService#forceConnect with ConnectionService#open in Clu…
aaron-congo Aug 15, 2025
f59930d
Add notes for how to fix the current issues
aaron-congo Aug 15, 2025
8fc6d1a
Integ test passing
aaron-congo Aug 18, 2025
b4e5b3a
Pass ConnectionService to ReaderFailoverHandler
aaron-congo Aug 19, 2025
a2342be
Adapted ReaderFailoverHandler, IT passing
aaron-congo Aug 19, 2025
cedbc1b
Merge branch 'main' into failover-handlers
aaron-congo Aug 20, 2025
8108551
Add hostAvailabilityMap to WriterFailoverResult
aaron-congo Aug 20, 2025
0a38ab3
Add hostAvailabilityMap to ReaderFailoverResult
aaron-congo Aug 20, 2025
1a7e2bc
Initialize HostListProvider in PartialPluginService constructor
aaron-congo Aug 20, 2025
a965c3f
Pass ConnectionService as constructor arg to failover handlers
aaron-congo Aug 21, 2025
a3d8a5e
PR suggestions
aaron-congo Aug 22, 2025
4df33da
Fix checkstyle
aaron-congo Aug 22, 2025
7a863c9
ReaderFailoverHandler tests passing
aaron-congo Aug 22, 2025
370d73f
WriterFailoverHandler tests passing
aaron-congo Aug 22, 2025
435f71a
FailoverConnectionPluginTests passing
aaron-congo Aug 22, 2025
7ba0f85
Merge branch 'main' into failover-handlers
aaron-congo Aug 22, 2025
6ebf706
Rename plugin to spyPlugin in FailoverConnectionPluginTest
aaron-congo Aug 22, 2025
7711a9e
Fix failing MonitorServiceImplTest tests
aaron-congo Aug 22, 2025
9928517
Fix failover1 integration test
aaron-congo Aug 26, 2025
6a338f2
testServerFailoverWithIdleConnections uses the correct failover plugin
aaron-congo Aug 26, 2025
367b6a5
Merge branch 'main' into failover-handlers
aaron-congo Aug 26, 2025
faa0915
Fix javadocs
aaron-congo Aug 26, 2025
23e177a
wip
aaron-congo Aug 26, 2025
e1af3eb
Add extra logging to debug IT failure
aaron-congo Aug 29, 2025
c077ee2
Fix bug where cached reader connection was incorrectly closed
aaron-congo Aug 29, 2025
a27cf9f
Merge branch 'main' into failover-handlers
aaron-congo Aug 29, 2025
73cf143
wip
aaron-congo Aug 29, 2025
99de6eb
Fix javadoc
aaron-congo Aug 29, 2025
f1eb529
Merge branch 'failover-handlers' into service-container-utility
aaron-congo Aug 29, 2025
9311447
wip
aaron-congo Aug 29, 2025
f987164
Add ConnectionProvider arg to FullServicesContainer constructor
aaron-congo Sep 2, 2025
47d2e20
Utils.getWriter, PluginService.getDefaultConnectionProvider, isolate …
aaron-congo Sep 2, 2025
fec3639
Merge branch 'main' into failover-handlers
aaron-congo Sep 2, 2025
f7b8db9
Fix failing integration tests
aaron-congo Sep 3, 2025
104d303
Fix dead markdown link
aaron-congo Sep 3, 2025
9fbc65f
Merge branch 'failover-handlers' into service-container-utility
aaron-congo Sep 3, 2025
04ac3c8
wip
aaron-congo Sep 3, 2025
bef4ea8
wip
aaron-congo Sep 3, 2025
cc9421a
Build successful
aaron-congo Sep 3, 2025
3f7fb28
Failover test passing
aaron-congo Sep 4, 2025
edeea73
PR suggestions
aaron-congo Sep 5, 2025
60dbc4e
Merge branch 'failover-handlers' into service-container-utility
aaron-congo Sep 5, 2025
cb6e6ec
Rename to ServiceUtility
aaron-congo Sep 8, 2025
77dccce
Fix unit tests
aaron-congo Sep 15, 2025
85252d0
Cleanup
aaron-congo Sep 15, 2025
85bb5c5
Merge branch 'main' into service-container-utility
aaron-congo Sep 15, 2025
c465a00
Cleanup
aaron-congo Sep 15, 2025
b2a107d
cleanup
aaron-congo Sep 15, 2025
e635745
Fix checkstyle
aaron-congo Sep 15, 2025
b695b86
wip
aaron-congo Sep 16, 2025
be51cc7
compiles with tests commented out
aaron-congo Sep 17, 2025
060dab6
Change ConnectionContext#getPropsCopy to getProps
aaron-congo Sep 18, 2025
f0410f9
Fix test failures
aaron-congo Sep 19, 2025
a612b03
ConnectionContext#getUrl -> ConnectionContext#getInitialConnectionString
aaron-congo Sep 19, 2025
7c253da
ConnectionContext -> ConnectionInfo
aaron-congo Sep 19, 2025
d81dfe3
fix: store connection string instead of protocol in knownEndpointDial…
aaron-congo Sep 22, 2025
bb1ef95
Uncomment tests
aaron-congo Sep 24, 2025
f0f3826
Tests compiling
aaron-congo Sep 24, 2025
6b9e23a
Checkstyle passing
aaron-congo Sep 24, 2025
0e8eac9
Fix unit tests
aaron-congo Sep 25, 2025
fcad2df
ConnectionInfo -> ConnectConfig
aaron-congo Sep 27, 2025
6611719
ConnectInfo -> ConnectParams
aaron-congo Sep 29, 2025
59d7f62
Merge branch 'main' into connection-context
aaron-congo Sep 29, 2025
8094624
Merge branch 'main' into connection-context
aaron-congo Oct 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
import software.amazon.jdbc.PluginService;
import software.amazon.jdbc.PropertyDefinition;
import software.amazon.jdbc.benchmarks.testplugin.BenchmarkPluginFactory;
import software.amazon.jdbc.dialect.Dialect;
import software.amazon.jdbc.hostavailability.SimpleHostAvailabilityStrategy;
import software.amazon.jdbc.profile.ConfigurationProfile;
import software.amazon.jdbc.profile.ConfigurationProfileBuilder;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
import software.amazon.jdbc.util.FullServicesContainer;
import software.amazon.jdbc.util.connection.ConnectConfig;
import software.amazon.jdbc.util.telemetry.DefaultTelemetryFactory;
import software.amazon.jdbc.util.telemetry.GaugeCallable;
import software.amazon.jdbc.util.telemetry.TelemetryContext;
Expand All @@ -88,16 +88,19 @@ public class ConnectionPluginManagerBenchmarks {
private static final String WRITER_SESSION_ID = "MASTER_SESSION_ID";
private static final String FIELD_SERVER_ID = "SERVER_ID";
private static final String FIELD_SESSION_ID = "SESSION_ID";
private Properties propertiesWithoutPlugins;
private Properties propertiesWithPlugins;
private static final String url = "protocol//url";
private ConnectConfig pluginsContext;
private ConnectConfig noPluginsContext;
private ConnectionPluginManager pluginManager;
private ConnectionPluginManager pluginManagerWithNoPlugins;

@Mock ConnectionProvider mockConnectionProvider;
@Mock ConnectionWrapper mockConnectionWrapper;
@Mock ConnectConfig mockConnectConfig;
@Mock FullServicesContainer mockServicesContainer;
@Mock PluginService mockPluginService;
@Mock PluginManagerService mockPluginManagerService;
@Mock TargetDriverDialect mockDriverDialect;
@Mock TelemetryFactory mockTelemetryFactory;
@Mock HostListProviderService mockHostListProvider;
@Mock Connection mockConnection;
Expand All @@ -123,12 +126,7 @@ public static void main(String[] args) throws RunnerException {
public void setUpIteration() throws Exception {
closeable = openMocks(this);

when(mockConnectionProvider.connect(
anyString(),
any(Dialect.class),
any(TargetDriverDialect.class),
any(HostSpec.class),
any(Properties.class))).thenReturn(mockConnection);
when(mockConnectionProvider.connect(any(), any(HostSpec.class))).thenReturn(mockConnection);
when(mockTelemetryFactory.openTelemetryContext(anyString(), any())).thenReturn(mockTelemetryContext);
when(mockTelemetryFactory.openTelemetryContext(eq(null), any())).thenReturn(mockTelemetryContext);
when(mockTelemetryFactory.createCounter(anyString())).thenReturn(mockTelemetryCounter);
Expand All @@ -153,24 +151,26 @@ public void setUpIteration() throws Exception {
.withPluginFactories(pluginFactories)
.build();

propertiesWithoutPlugins = new Properties();
propertiesWithoutPlugins.setProperty(PropertyDefinition.PLUGINS.name, "");
Properties noPluginsProps = new Properties();
noPluginsProps.setProperty(PropertyDefinition.PLUGINS.name, "");
this.noPluginsContext = new ConnectConfig(url, mockDriverDialect, noPluginsProps);

propertiesWithPlugins = new Properties();
propertiesWithPlugins.setProperty(PropertyDefinition.PROFILE_NAME.name, "benchmark");
propertiesWithPlugins.setProperty(PropertyDefinition.ENABLE_TELEMETRY.name, "false");
Properties pluginsProps = new Properties();
pluginsProps.setProperty(PropertyDefinition.PROFILE_NAME.name, "benchmark");
pluginsProps.setProperty(PropertyDefinition.ENABLE_TELEMETRY.name, "false");
this.pluginsContext = new ConnectConfig(url, mockDriverDialect, pluginsProps);

TelemetryFactory telemetryFactory = new DefaultTelemetryFactory(propertiesWithPlugins);
TelemetryFactory telemetryFactory = new DefaultTelemetryFactory(pluginsProps);

pluginManager = new ConnectionPluginManager(mockConnectionProvider,
null,
mockConnectionWrapper,
telemetryFactory);
pluginManager.init(mockServicesContainer, propertiesWithPlugins, mockPluginManagerService, configurationProfile);
pluginManager.init(mockServicesContainer, pluginsProps, mockPluginManagerService, configurationProfile);

pluginManagerWithNoPlugins = new ConnectionPluginManager(mockConnectionProvider, null,
mockConnectionWrapper, telemetryFactory);
pluginManagerWithNoPlugins.init(mockServicesContainer, propertiesWithoutPlugins, mockPluginManagerService, null);
pluginManagerWithNoPlugins.init(mockServicesContainer, noPluginsProps, mockPluginManagerService, null);
}

@TearDown(Level.Iteration)
Expand All @@ -182,34 +182,32 @@ public void tearDownIteration() throws Exception {
public ConnectionPluginManager initConnectionPluginManagerWithNoPlugins() throws SQLException {
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider, null,
mockConnectionWrapper, mockTelemetryFactory);
manager.init(mockServicesContainer, propertiesWithoutPlugins, mockPluginManagerService, configurationProfile);
manager.init(mockServicesContainer, this.noPluginsContext.getProps(), mockPluginManagerService, configurationProfile);
return manager;
}

@Benchmark
public ConnectionPluginManager initConnectionPluginManagerWithPlugins() throws SQLException {
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider, null,
mockConnectionWrapper, mockTelemetryFactory);
manager.init(mockServicesContainer, propertiesWithPlugins, mockPluginManagerService, configurationProfile);
manager.init(mockServicesContainer, this.pluginsContext.getProps(), mockPluginManagerService, configurationProfile);
return manager;
}

@Benchmark
public Connection connectWithPlugins() throws SQLException {
return pluginManager.connect(
"driverProtocol",
mockConnectConfig,
new HostSpecBuilder(new SimpleHostAvailabilityStrategy()).host("host").build(),
propertiesWithPlugins,
true,
null);
}

@Benchmark
public Connection connectWithNoPlugins() throws SQLException {
return pluginManagerWithNoPlugins.connect(
"driverProtocol",
mockConnectConfig,
new HostSpecBuilder(new SimpleHostAvailabilityStrategy()).host("host").build(),
propertiesWithoutPlugins,
true,
null);
}
Expand Down Expand Up @@ -240,21 +238,13 @@ public Integer executeWithNoPlugins() {

@Benchmark
public ConnectionPluginManager initHostProvidersWithPlugins() throws SQLException {
pluginManager.initHostProvider(
"protocol",
"url",
propertiesWithPlugins,
mockHostListProvider);
pluginManager.initHostProvider(this.pluginsContext, mockHostListProvider);
return pluginManager;
}

@Benchmark
public ConnectionPluginManager initHostProvidersWithNoPlugins() throws SQLException {
pluginManagerWithNoPlugins.initHostProvider(
"protocol",
"url",
propertiesWithoutPlugins,
mockHostListProvider);
pluginManagerWithNoPlugins.initHostProvider(this.noPluginsContext, mockHostListProvider);
return pluginManager;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
import software.amazon.jdbc.dialect.Dialect;
import software.amazon.jdbc.hostavailability.SimpleHostAvailabilityStrategy;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
import software.amazon.jdbc.util.connection.ConnectionService;
import software.amazon.jdbc.util.connection.ConnectConfig;
import software.amazon.jdbc.util.monitoring.MonitorService;
import software.amazon.jdbc.util.storage.StorageService;
import software.amazon.jdbc.util.telemetry.GaugeCallable;
Expand Down Expand Up @@ -94,7 +94,6 @@ public class PluginBenchmarks {

@Mock private StorageService mockStorageService;
@Mock private MonitorService mockMonitorService;
@Mock private ConnectionService mockConnectionService;
@Mock private PluginService mockPluginService;
@Mock private TargetDriverDialect mockTargetDriverDialect;
@Mock private Dialect mockDialect;
Expand Down Expand Up @@ -124,7 +123,7 @@ public static void main(String[] args) throws RunnerException {
@Setup(Level.Iteration)
public void setUpIteration() throws Exception {
closeable = MockitoAnnotations.openMocks(this);
when(mockConnectionPluginManager.connect(any(), any(), any(Properties.class), anyBoolean(), any()))
when(mockConnectionPluginManager.connect(any(), any(), anyBoolean(), any()))
.thenReturn(mockConnection);
when(mockConnectionPluginManager.execute(
any(), any(), any(), eq(JdbcMethod.CONNECTION_CREATESTATEMENT), any(), any()))
Expand All @@ -135,12 +134,7 @@ public void setUpIteration() throws Exception {
when(mockTelemetryFactory.createCounter(anyString())).thenReturn(mockTelemetryCounter);
// noinspection unchecked
when(mockTelemetryFactory.createGauge(anyString(), any(GaugeCallable.class))).thenReturn(mockTelemetryGauge);
when(mockConnectionProvider.connect(
anyString(),
any(Dialect.class),
any(TargetDriverDialect.class),
any(HostSpec.class),
any(Properties.class))).thenReturn(mockConnection);
when(mockConnectionProvider.connect(any(ConnectConfig.class), any(HostSpec.class))).thenReturn(mockConnection);
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet);
when(mockResultSet.next()).thenReturn(true, true, false);
Expand Down Expand Up @@ -183,8 +177,7 @@ private ConnectionWrapper getConnectionWrapper(Properties props, String connStri
mockHostListProviderService,
mockPluginManagerService,
mockStorageService,
mockMonitorService,
mockConnectionService);
mockMonitorService);
}

@Benchmark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Logger;
import software.amazon.jdbc.ConnectionPlugin;
Expand All @@ -37,6 +36,7 @@
import software.amazon.jdbc.OldConnectionSuggestedAction;
import software.amazon.jdbc.cleanup.CanReleaseResources;
import software.amazon.jdbc.hostavailability.SimpleHostAvailabilityStrategy;
import software.amazon.jdbc.util.connection.ConnectConfig;

public class BenchmarkPlugin implements ConnectionPlugin, CanReleaseResources {
final List<String> resources = new ArrayList<>();
Expand All @@ -58,18 +58,21 @@ public <T, E extends Exception> T execute(Class<T> resultClass, Class<E> excepti
}

@Override
public Connection connect(String driverProtocol, HostSpec hostSpec, Properties props,
boolean isInitialConnection, JdbcCallable<Connection, SQLException> connectFunc)
throws SQLException {
public Connection connect(
final ConnectConfig connectConfig,
final HostSpec hostSpec,
final boolean isInitialConnection,
final JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
LOGGER.finer(() -> String.format("connect=''%s''", hostSpec.getHost()));
resources.add("connect");
return connectFunc.call();
}

@Override
public Connection forceConnect(String driverProtocol, HostSpec hostSpec, Properties props,
boolean isInitialConnection, JdbcCallable<Connection, SQLException> forceConnectFunc)
throws SQLException {
public Connection forceConnect(
ConnectConfig connectConfig,
HostSpec hostSpec,
boolean isInitialConnection, JdbcCallable<Connection, SQLException> forceConnectFunc) throws SQLException {
LOGGER.finer(() -> String.format("forceConnect=''%s''", hostSpec.getHost()));
resources.add("forceConnect");
return forceConnectFunc.call();
Expand All @@ -93,10 +96,11 @@ public HostSpec getHostSpecByStrategy(List<HostSpec> hosts, HostRole role, Strin
}

@Override
public void initHostProvider(String driverProtocol, String initialUrl, Properties props,
public void initHostProvider(
ConnectConfig connectConfig,
HostListProviderService hostListProviderService,
JdbcCallable<Void, SQLException> initHostProviderFunc) {
LOGGER.finer(() -> String.format("initHostProvider=''%s''", initialUrl));
LOGGER.finer(() -> String.format("initHostProvider=''%s''", connectConfig.getInitialConnectionString()));
resources.add("initHostProvider");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import software.amazon.jdbc.PluginManagerService;
import software.amazon.jdbc.PluginService;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
import software.amazon.jdbc.util.connection.ConnectionService;
import software.amazon.jdbc.util.monitoring.MonitorService;
import software.amazon.jdbc.util.storage.StorageService;
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
Expand All @@ -45,8 +44,7 @@ public TestConnectionWrapper(
@NonNull final HostListProviderService hostListProviderService,
@NonNull final PluginManagerService pluginManagerService,
@NonNull final StorageService storageService,
@NonNull final MonitorService monitorService,
@NonNull final ConnectionService connectionService)
@NonNull final MonitorService monitorService)
throws SQLException {
super(
props,
Expand All @@ -58,6 +56,7 @@ public TestConnectionWrapper(
pluginService,
hostListProviderService,
pluginManagerService,
storageService, monitorService, connectionService);
storageService,
monitorService);
}
}
18 changes: 12 additions & 6 deletions docs/development-guide/LoadablePlugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,12 @@ public class BadPlugin extends AbstractConnectionPlugin {
return new HashSet<>(Collections.singletonList("*"));
}

@Override
public Connection connect(String driverProtocol, HostSpec hostSpec, Properties props, boolean isInitialConnection,
JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
@Override
public Connection connect(
final ConnectConfig connectConfig,
final HostSpec hostSpec,
final boolean isInitialConnection,
final JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
// Bad Practice #2: using driver-specific objects.
// Not all drivers support the same configuration parameters. For instance, while MySQL Connector/J Supports "database",
// PGJDBC uses "dbname" for database names.
Expand Down Expand Up @@ -167,9 +170,12 @@ public class GoodExample extends AbstractConnectionPlugin {
return jdbcMethodFunc.call();
}

@Override
public Connection connect(String driverProtocol, HostSpec hostSpec, Properties props, boolean isInitialConnection,
JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
@Override
public Connection connect(
final ConnectConfig connectConfig,
final HostSpec hostSpec,
final boolean isInitialConnection,
final JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
if (PropertyDefinition.USER.getString(props) == null) {
PropertyDefinition.TARGET_DRIVER_USER_PROPERTY_NAME.set(props, "defaultUser");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import software.amazon.jdbc.ConnectionProviderManager;
import software.amazon.jdbc.HikariPooledConnectionProvider;
import software.amazon.jdbc.HostSpec;
import software.amazon.jdbc.PropertyDefinition;
import software.amazon.jdbc.plugin.failover.FailoverFailedSQLException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package software.amazon;

import com.mysql.cj.jdbc.MysqlDataSource;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class HikariExample {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

package example.spring;

import com.zaxxer.hikari.HikariConfig;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.hibernate.exception.JDBCConnectionException;
Expand All @@ -40,10 +37,6 @@
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import software.amazon.jdbc.HikariPooledConnectionProvider;
import software.amazon.jdbc.HostSpec;
import software.amazon.jdbc.profile.ConfigurationProfileBuilder;
import software.amazon.jdbc.profile.ConfigurationProfilePresetCodes;

@Configuration
@EnableTransactionManagement
Expand Down
Loading
Loading