Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration Profiles #711

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -71,6 +71,9 @@
import software.amazon.jdbc.util.telemetry.TelemetryCounter;
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
import software.amazon.jdbc.util.telemetry.TelemetryGauge;
import software.amazon.jdbc.profile.ConfigurationProfile;
import software.amazon.jdbc.profile.ConfigurationProfileBuilder;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
import software.amazon.jdbc.wrapper.ConnectionWrapper;

@State(Scope.Benchmark)
Expand Down Expand Up @@ -101,6 +104,7 @@ public class ConnectionPluginManagerBenchmarks {
@Mock TelemetryContext mockTelemetryContext;
@Mock TelemetryCounter mockTelemetryCounter;
@Mock TelemetryGauge mockTelemetryGauge;
ConfigurationProfile configurationProfile;
private AutoCloseable closeable;

public static void main(String[] args) throws RunnerException {
Expand All @@ -120,7 +124,11 @@ public void setUpIteration() throws Exception {

when(mockConnectionProvider.connect(anyString(), any(Properties.class))).thenReturn(
mockConnection);
when(mockConnectionProvider.connect(anyString(), any(Dialect.class), any(HostSpec.class),
when(mockConnectionProvider.connect(
anyString(),
any(Dialect.class),
any(TargetDriverDialect.class),
any(HostSpec.class),
any(Properties.class))).thenReturn(mockConnection);
when(mockTelemetryFactory.openTelemetryContext(anyString(), any())).thenReturn(mockTelemetryContext);
when(mockTelemetryFactory.openTelemetryContext(eq(null), any())).thenReturn(mockTelemetryContext);
Expand All @@ -140,9 +148,11 @@ public void setUpIteration() throws Exception {
final List<Class<? extends ConnectionPluginFactory>> pluginFactories = new ArrayList<>(
Collections.nCopies(10, BenchmarkPluginFactory.class));

DriverConfigurationProfiles.addOrReplaceProfile(
"benchmark",
pluginFactories);
configurationProfile = ConfigurationProfileBuilder.get()
.withName("benchmark")
.withPluginFactories(pluginFactories)
.build();

propertiesWithoutPlugins = new Properties();
propertiesWithoutPlugins.setProperty(PropertyDefinition.PLUGINS.name, "");

Expand All @@ -152,12 +162,15 @@ public void setUpIteration() throws Exception {

TelemetryFactory telemetryFactory = new DefaultTelemetryFactory(propertiesWithPlugins);

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

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

@TearDown(Level.Iteration)
Expand All @@ -167,17 +180,17 @@ public void tearDownIteration() throws Exception {

@Benchmark
public ConnectionPluginManager initConnectionPluginManagerWithNoPlugins() throws SQLException {
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider,
final ConnectionPluginManager manager = new ConnectionPluginManager(mockConnectionProvider, null,
mockConnectionWrapper, mockTelemetryFactory);
manager.init(mockPluginService, propertiesWithoutPlugins, mockPluginManagerService);
manager.init(mockPluginService, propertiesWithoutPlugins, mockPluginManagerService, configurationProfile);
return manager;
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import software.amazon.jdbc.util.telemetry.TelemetryCounter;
import software.amazon.jdbc.util.telemetry.TelemetryFactory;
import software.amazon.jdbc.util.telemetry.TelemetryGauge;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
import software.amazon.jdbc.wrapper.ConnectionWrapper;

@State(Scope.Benchmark)
Expand All @@ -87,6 +88,7 @@ public class PluginBenchmarks {
.host(TEST_HOST).port(TEST_PORT).build();

@Mock private PluginService mockPluginService;
@Mock private Dialect mockDialect;
@Mock private ConnectionPluginManager mockConnectionPluginManager;
@Mock private TelemetryFactory mockTelemetryFactory;
@Mock TelemetryContext mockTelemetryContext;
Expand Down Expand Up @@ -127,7 +129,11 @@ public void setUpIteration() throws Exception {
when(mockTelemetryFactory.createGauge(anyString(), any(GaugeCallable.class))).thenReturn(mockTelemetryGauge);
when(mockConnectionProvider.connect(anyString(), any(Properties.class))).thenReturn(
mockConnection);
when(mockConnectionProvider.connect(anyString(), any(Dialect.class), any(HostSpec.class),
when(mockConnectionProvider.connect(
anyString(),
any(Dialect.class),
any(TargetDriverDialect.class),
any(HostSpec.class),
any(Properties.class))).thenReturn(mockConnection);
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet);
Expand All @@ -139,6 +145,7 @@ public void setUpIteration() throws Exception {
when(mockStatement.getConnection()).thenReturn(mockConnection);
when(this.mockPluginService.acceptsStrategy(any(), eq("random"))).thenReturn(true);
when(this.mockPluginService.getCurrentHostSpec()).thenReturn(writerHostSpec);
when(this.mockPluginService.getDialect()).thenReturn(mockDialect);
}

@TearDown(Level.Iteration)
Expand Down Expand Up @@ -302,11 +309,14 @@ public ResultSet executeStatementWithExecutionTimePlugin() throws SQLException {
@Benchmark
public ResultSet executeStatementWithTelemetryDisabled() throws SQLException {
try (
ConnectionWrapper wrapper = new ConnectionWrapper(
ConnectionWrapper wrapper = new TestConnectionWrapper(
disabledTelemetry(),
CONNECTION_STRING,
mockConnectionProvider,
mockTelemetryFactory);
mockConnectionPluginManager,
mockTelemetryFactory,
mockPluginService,
mockHostListProviderService,
mockPluginManagerService);
Statement statement = wrapper.createStatement();
ResultSet resultSet = statement.executeQuery("some sql")) {
return resultSet;
Expand All @@ -316,11 +326,14 @@ public ResultSet executeStatementWithTelemetryDisabled() throws SQLException {
@Benchmark
public ResultSet executeStatementWithTelemetry() throws SQLException {
try (
ConnectionWrapper wrapper = new ConnectionWrapper(
ConnectionWrapper wrapper = new TestConnectionWrapper(
useTelemetry(),
CONNECTION_STRING,
mockConnectionProvider,
mockTelemetryFactory);
mockConnectionPluginManager,
mockTelemetryFactory,
mockPluginService,
mockHostListProviderService,
mockPluginManagerService);
Statement statement = wrapper.createStatement();
ResultSet resultSet = statement.executeQuery("some sql")) {
return resultSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Properties;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
import software.amazon.jdbc.plugin.AuroraConnectionTrackerPluginFactory;
import software.amazon.jdbc.plugin.AuroraHostListConnectionPluginFactory;
import software.amazon.jdbc.plugin.AwsSecretsManagerConnectionPluginFactory;
Expand All @@ -40,6 +41,7 @@
import software.amazon.jdbc.plugin.failover.FailoverConnectionPluginFactory;
import software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPluginFactory;
import software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPluginFactory;
import software.amazon.jdbc.profile.ConfigurationProfile;
import software.amazon.jdbc.profile.DriverConfigurationProfiles;
import software.amazon.jdbc.util.Messages;
import software.amazon.jdbc.util.SqlState;
Expand Down Expand Up @@ -116,25 +118,17 @@ public PluginFactoryInfo(final Class<? extends ConnectionPluginFactory> factory,
public List<ConnectionPlugin> getPlugins(
final PluginService pluginService,
final ConnectionProvider defaultConnProvider,
final ConnectionProvider effectiveConnProvider,
final PluginManagerService pluginManagerService,
final Properties props)
final Properties props,
@Nullable ConfigurationProfile configurationProfile)
throws SQLException {

List<ConnectionPlugin> plugins;
List<Class<? extends ConnectionPluginFactory>> pluginFactories;

final String profileName = PropertyDefinition.PROFILE_NAME.getString(props);

if (profileName != null) {

if (!DriverConfigurationProfiles.contains(profileName)) {
throw new SQLException(
Messages.get(
"ConnectionPluginManager.configurationProfileNotFound",
new Object[] {profileName}));
}
pluginFactories = DriverConfigurationProfiles.getPluginFactories(profileName);

if (configurationProfile != null && configurationProfile.getPluginFactories() != null) {
pluginFactories = configurationProfile.getPluginFactories();
} else {

String pluginCodes = PropertyDefinition.PLUGINS.getString(props);
Expand Down Expand Up @@ -194,8 +188,12 @@ public List<ConnectionPlugin> getPlugins(
}

// add default connection plugin to the tail
final ConnectionPlugin defaultPlugin =
new DefaultConnectionPlugin(pluginService, defaultConnProvider, pluginManagerService);
final ConnectionPlugin defaultPlugin = new DefaultConnectionPlugin(
pluginService,
defaultConnProvider,
effectiveConnProvider,
pluginManagerService);

plugins.add(defaultPlugin);

return plugins;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import software.amazon.jdbc.plugin.failover.FailoverConnectionPlugin;
import software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPlugin;
import software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPlugin;
import software.amazon.jdbc.profile.ConfigurationProfile;
import software.amazon.jdbc.util.Messages;
import software.amazon.jdbc.util.SqlMethodAnalyzer;
import software.amazon.jdbc.util.WrapperUtils;
Expand All @@ -57,6 +58,7 @@
* <p>THIS CLASS IS NOT MULTI-THREADING SAFE IT'S EXPECTED TO HAVE ONE INSTANCE OF THIS MANAGER PER
* JDBC CONNECTION
*/
@SuppressWarnings("deprecation")
public class ConnectionPluginManager implements CanReleaseResources, Wrapper {

protected static final Map<Class<? extends ConnectionPlugin>, String> pluginNameByClass =
Expand Down Expand Up @@ -91,18 +93,22 @@ public class ConnectionPluginManager implements CanReleaseResources, Wrapper {

protected Properties props = new Properties();
protected List<ConnectionPlugin> plugins;
protected final ConnectionProvider defaultConnProvider;
protected final @NonNull ConnectionProvider defaultConnProvider;
protected final @Nullable ConnectionProvider effectiveConnProvider;
protected final ConnectionWrapper connectionWrapper;
protected PluginService pluginService;
protected TelemetryFactory telemetryFactory;

@SuppressWarnings("rawtypes")
protected final Map<String, PluginChainJdbcCallable> pluginChainFuncMap = new HashMap<>();

public ConnectionPluginManager(final ConnectionProvider defaultConnProvider,
final ConnectionWrapper connectionWrapper,
final TelemetryFactory telemetryFactory) {
public ConnectionPluginManager(
final @NonNull ConnectionProvider defaultConnProvider,
final @Nullable ConnectionProvider effectiveConnProvider,
final @NonNull ConnectionWrapper connectionWrapper,
final @NonNull TelemetryFactory telemetryFactory) {
this.defaultConnProvider = defaultConnProvider;
this.effectiveConnProvider = effectiveConnProvider;
this.connectionWrapper = connectionWrapper;
this.telemetryFactory = telemetryFactory;
}
Expand All @@ -111,26 +117,29 @@ public ConnectionPluginManager(final ConnectionProvider defaultConnProvider,
* This constructor is for testing purposes only.
*/
ConnectionPluginManager(
final ConnectionProvider defaultConnProvider,
final @NonNull ConnectionProvider defaultConnProvider,
final @Nullable ConnectionProvider effectiveConnProvider,
final Properties props,
final ArrayList<ConnectionPlugin> plugins,
final ConnectionWrapper connectionWrapper,
final PluginService pluginService,
final TelemetryFactory telemetryFactory) {
this(defaultConnProvider, props, plugins, connectionWrapper, telemetryFactory);
this(defaultConnProvider, effectiveConnProvider, props, plugins, connectionWrapper, telemetryFactory);
this.pluginService = pluginService;
}

/**
* This constructor is for testing purposes only.
*/
ConnectionPluginManager(
final ConnectionProvider defaultConnProvider,
final @NonNull ConnectionProvider defaultConnProvider,
final @Nullable ConnectionProvider effectiveConnProvider,
final Properties props,
final ArrayList<ConnectionPlugin> plugins,
final ConnectionWrapper connectionWrapper,
final TelemetryFactory telemetryFactory) {
this.defaultConnProvider = defaultConnProvider;
this.effectiveConnProvider = effectiveConnProvider;
this.props = props;
this.plugins = plugins;
this.connectionWrapper = connectionWrapper;
Expand All @@ -156,10 +165,14 @@ public void unlock() {
* @param pluginService a reference to a plugin service that plugin can use
* @param props the configuration of the connection
* @param pluginManagerService a reference to a plugin manager service
* @param configurationProfile a profile configuration defined by the user
* @throws SQLException if errors occurred during the execution
*/
public void init(
final PluginService pluginService, final Properties props, final PluginManagerService pluginManagerService)
final PluginService pluginService,
final Properties props,
final PluginManagerService pluginManagerService,
@Nullable ConfigurationProfile configurationProfile)
throws SQLException {

this.props = props;
Expand All @@ -170,8 +183,10 @@ public void init(
this.plugins = pluginChainBuilder.getPlugins(
this.pluginService,
this.defaultConnProvider,
this.effectiveConnProvider,
pluginManagerService,
props);
props,
configurationProfile);
}

protected <T, E extends Exception> T executeWithSubscribedPlugins(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import software.amazon.jdbc.dialect.Dialect;
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;

/**
* Implement this interface in order to handle the physical connection creation process.
Expand Down Expand Up @@ -74,6 +75,7 @@ HostSpec getHostSpecByStrategy(
*
* @param protocol the connection protocol (example "jdbc:mysql://")
* @param dialect the database dialect
* @param targetDriverDialect the target driver dialect
* @param hostSpec the HostSpec containing the host-port information for the host to connect to
* @param props the Properties to use for the connection
* @return {@link Connection} resulting from the given connection information
Expand All @@ -82,13 +84,15 @@ HostSpec getHostSpecByStrategy(
Connection connect(
@NonNull String protocol,
@NonNull Dialect dialect,
@NonNull TargetDriverDialect targetDriverDialect,
@NonNull HostSpec hostSpec,
@NonNull Properties props)
throws SQLException;

/**
* Called once per connection that needs to be created.
* This method is deprecated. Use {@link #connect(String, Dialect, HostSpec, Properties)} instead.
* This method is deprecated.
* Use {@link #connect(String, Dialect, TargetDriverDialect, HostSpec, Properties)} instead.
*
* @param url the connection URL
* @param props the Properties to use for the connection
Expand Down
Loading
Loading