drivers = DriverManager.getDrivers();
+ while (drivers.hasMoreElements()) {
+ Driver driver = drivers.nextElement();
+ if (driver.acceptsURL(jdbcUrl)) {
+ for (DataStoreType dataStoreType : DataStoreType.values()) {
+ if (dataStoreType.getDriverClass().isAssignableFrom(driver.getClass())) {
+ return dataStoreType;
+ }
+ }
+ break;
+ }
+ }
+ }
+ catch (SQLException e) {
+ throw new RuntimeException("Error enumerating JDBC drivers", e);
+ }
+ throw new IllegalStateException("Unable to infer DataStoreType for URL: " + jdbcUrl);
+ }
+
+ public void setDataStoreType(DataStoreType backendType)
+ {
+ this.dataStoreType = backendType;
+ }
}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/config/DataStoreType.java b/gateway-ha/src/main/java/io/trino/gateway/ha/config/DataStoreType.java
new file mode 100644
index 000000000..fdff99836
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/config/DataStoreType.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.config;
+
+import java.sql.Driver;
+
+public enum DataStoreType {
+ ORACLE(oracle.jdbc.driver.OracleDriver.class),
+ MYSQL(com.mysql.cj.jdbc.Driver.class),
+ POSTGRES(org.postgresql.Driver.class),
+ H2(org.h2.Driver.class);
+
+ private final Class extends Driver> driverClass;
+
+ DataStoreType(Class extends Driver> driverClass)
+ {
+ this.driverClass = driverClass;
+ }
+
+ /**
+ * Returns the JDBC Driver class associated with this data store type.
+ */
+ public Class extends Driver> getDriverClass()
+ {
+ return driverClass;
+ }
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/config/MySqlConfiguration.java b/gateway-ha/src/main/java/io/trino/gateway/ha/config/MySqlConfiguration.java
new file mode 100644
index 000000000..5eb2d6aea
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/config/MySqlConfiguration.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.config;
+
+import com.mysql.cj.conf.PropertyDefinitions.SslMode;
+
+/**
+ * Configuration for MySQL SSL (client cert and truststore settings).
+ */
+public class MySqlConfiguration
+{
+ private SslMode sslMode = SslMode.DISABLED;
+ private String clientCertificateKeyStoreUrl;
+ private String clientCertificateKeyStorePassword;
+ private String clientCertificateKeyStoreType;
+ private String trustCertificateKeyStoreUrl;
+ private String trustCertificateKeyStorePassword;
+
+ public SslMode getSslMode()
+ {
+ return sslMode;
+ }
+
+ public MySqlConfiguration setSslMode(SslMode sslMode)
+ {
+ this.sslMode = sslMode;
+ return this;
+ }
+
+ public String getClientCertificateKeyStoreUrl()
+ {
+ return clientCertificateKeyStoreUrl;
+ }
+
+ public MySqlConfiguration setClientCertificateKeyStoreUrl(String url)
+ {
+ this.clientCertificateKeyStoreUrl = url;
+ return this;
+ }
+
+ public String getClientCertificateKeyStorePassword()
+ {
+ return clientCertificateKeyStorePassword;
+ }
+
+ public MySqlConfiguration setClientCertificateKeyStorePassword(String password)
+ {
+ this.clientCertificateKeyStorePassword = password;
+ return this;
+ }
+
+ public String getClientCertificateKeyStoreType()
+ {
+ return clientCertificateKeyStoreType;
+ }
+
+ public MySqlConfiguration setClientCertificateKeyStoreType(String type)
+ {
+ this.clientCertificateKeyStoreType = type;
+ return this;
+ }
+
+ public String getTrustCertificateKeyStoreUrl()
+ {
+ return trustCertificateKeyStoreUrl;
+ }
+
+ public MySqlConfiguration setTrustCertificateKeyStoreUrl(String url)
+ {
+ this.trustCertificateKeyStoreUrl = url;
+ return this;
+ }
+
+ public String getTrustCertificateKeyStorePassword()
+ {
+ return trustCertificateKeyStorePassword;
+ }
+
+ public MySqlConfiguration setTrustCertificateKeyStorePassword(String password)
+ {
+ this.trustCertificateKeyStorePassword = password;
+ return this;
+ }
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java b/gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java
index 1db9e149a..43ad3820d 100644
--- a/gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java
@@ -39,6 +39,7 @@
import io.trino.gateway.ha.config.RoutingRulesConfiguration;
import io.trino.gateway.ha.config.RulesExternalConfiguration;
import io.trino.gateway.ha.config.UserConfiguration;
+import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
import io.trino.gateway.ha.router.BackendStateManager;
import io.trino.gateway.ha.router.ForRouter;
@@ -117,10 +118,10 @@ public HaGatewayProviderModule(HaGatewayConfiguration configuration)
oAuth2GatewayCookieConfigurationPropertiesProvider.initialize(configuration.getOauth2GatewayCookieConfiguration());
Jdbi jdbi = Jdbi.create(configuration.getDataStore().getJdbcUrl(), configuration.getDataStore().getUser(), configuration.getDataStore().getPassword());
- JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore());
+ JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore(), new DefaultJdbcPropertiesProvider());
resourceGroupsManager = new HaResourceGroupsManager(connectionManager);
gatewayBackendManager = new HaGatewayManager(jdbi, configuration.getRouting());
- queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore().getJdbcUrl().startsWith("jdbc:oracle"));
+ queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore());
}
private LbOAuthManager getOAuthManager(HaGatewayConfiguration configuration)
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/DefaultJdbcPropertiesProvider.java b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/DefaultJdbcPropertiesProvider.java
new file mode 100644
index 000000000..39b984262
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/DefaultJdbcPropertiesProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.persistence;
+
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+
+import java.util.Properties;
+
+/**
+ * Default JDBC properties provider used as a fallback when no database-specific
+ * {@link JdbcPropertiesProvider} supports the given {@link DataStoreConfiguration}.
+ *
+ * This provider simply sets the basic "user" and "password" properties
+ * and should always be the last provider in the list of available providers.
+ *
+ *
If a more specific provider (e.g., for MySQL, Oracle, etc.) supports the configuration,
+ * it should be preferred over this basic fallback.
+ */
+public class DefaultJdbcPropertiesProvider
+ implements JdbcPropertiesProvider
+{
+ @Override
+ public boolean supports(DataStoreConfiguration configuration)
+ {
+ return true;
+ }
+
+ @Override
+ public Properties getProperties(DataStoreConfiguration configuration)
+ {
+ Properties properties = new Properties();
+ properties.setProperty("user", configuration.getUser());
+ properties.setProperty("password", configuration.getPassword());
+ return properties;
+ }
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcConnectionManager.java b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcConnectionManager.java
index 2506b3f2a..f1e20a02e 100644
--- a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcConnectionManager.java
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcConnectionManager.java
@@ -14,6 +14,8 @@
package io.trino.gateway.ha.persistence;
import com.google.common.annotations.VisibleForTesting;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
import io.airlift.log.Logger;
import io.trino.gateway.ha.config.DataStoreConfiguration;
import io.trino.gateway.ha.persistence.dao.QueryHistoryDao;
@@ -24,27 +26,32 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
+import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.Objects.requireNonNull;
+@Singleton
public class JdbcConnectionManager
{
private static final Logger log = Logger.get(JdbcConnectionManager.class);
private final Jdbi jdbi;
private final DataStoreConfiguration configuration;
+ private final JdbcPropertiesProvider jdbcPropertiesProvider;
private final ScheduledExecutorService executorService =
Executors.newSingleThreadScheduledExecutor();
- public JdbcConnectionManager(Jdbi jdbi, DataStoreConfiguration configuration)
+ @Inject
+ public JdbcConnectionManager(Jdbi jdbi, DataStoreConfiguration configuration, JdbcPropertiesProvider jdbcPropertiesProvider)
{
this.jdbi = requireNonNull(jdbi, "jdbi is null")
.installPlugin(new SqlObjectPlugin())
.registerRowMapper(new RecordAndAnnotatedConstructorMapper());
this.configuration = configuration;
+ this.jdbcPropertiesProvider = requireNonNull(jdbcPropertiesProvider, "jdbcPropertiesProvider is null");
startCleanUps();
}
@@ -58,12 +65,18 @@ public Jdbi getJdbi(@Nullable String routingGroupDatabase)
if (routingGroupDatabase == null) {
return jdbi;
}
+ Properties properties = jdbcPropertiesProvider.getProperties(configuration);
- return Jdbi.create(buildJdbcUrl(routingGroupDatabase), configuration.getUser(), configuration.getPassword())
+ return Jdbi.create(buildJdbcUrl(routingGroupDatabase), properties)
.installPlugin(new SqlObjectPlugin())
.registerRowMapper(new RecordAndAnnotatedConstructorMapper());
}
+ public DataStoreConfiguration getConfiguration()
+ {
+ return configuration;
+ }
+
@VisibleForTesting
String buildJdbcUrl(@Nullable String routingGroupDatabase)
{
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProvider.java b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProvider.java
new file mode 100644
index 000000000..878f2d503
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.persistence;
+
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+
+import java.util.Properties;
+
+/**
+ * Given a DataStoreConfiguration, produce the proper JDBC driver properties.
+ * Different implementations can handle MySQL, Postgres, H2, etc.
+ */
+public interface JdbcPropertiesProvider
+{
+ boolean supports(DataStoreConfiguration config);
+
+ Properties getProperties(DataStoreConfiguration config);
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProviderFactory.java b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProviderFactory.java
new file mode 100644
index 000000000..aa2105383
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/JdbcPropertiesProviderFactory.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.persistence;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+
+import java.util.List;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+@Singleton
+public class JdbcPropertiesProviderFactory
+{
+ private final List providers;
+
+ @Inject
+ public JdbcPropertiesProviderFactory(List orderedProviders)
+ {
+ this.providers = ImmutableList.copyOf(requireNonNull(orderedProviders, "providers is null"));
+ }
+
+ public JdbcPropertiesProvider forConfig(DataStoreConfiguration config)
+ {
+ return providers.stream()
+ .filter(provider -> provider.supports(config))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(
+ format("No JdbcPropertiesProvider for driver: %s", config.getDriver())));
+ }
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/MySqlJdbcPropertiesProvider.java b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/MySqlJdbcPropertiesProvider.java
new file mode 100644
index 000000000..3710b5039
--- /dev/null
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/persistence/MySqlJdbcPropertiesProvider.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.persistence;
+
+import com.mysql.cj.conf.PropertyDefinitions.SslMode;
+import com.mysql.cj.conf.PropertyKey;
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.config.MySqlConfiguration;
+
+import java.util.Locale;
+import java.util.Properties;
+
+import static java.util.Objects.requireNonNull;
+
+public class MySqlJdbcPropertiesProvider
+ implements JdbcPropertiesProvider
+{
+ @Override
+ public boolean supports(DataStoreConfiguration configuration)
+ {
+ return configuration.getDriver() != null
+ && configuration.getJdbcUrl() != null
+ && configuration.getJdbcUrl().toLowerCase(Locale.ROOT).startsWith("jdbc:mysql");
+ }
+
+ @Override
+ public Properties getProperties(DataStoreConfiguration configuration)
+ {
+ Properties properties = new Properties();
+ properties.setProperty("user", configuration.getUser());
+
+ MySqlConfiguration mySqlConfiguration = configuration.getMySqlConfiguration();
+ properties.setProperty(PropertyKey.sslMode.getKeyName(), mySqlConfiguration.getSslMode().toString());
+
+ if (SslMode.VERIFY_CA.equals(mySqlConfiguration.getSslMode())) {
+ requireNonNull(mySqlConfiguration.getClientCertificateKeyStoreUrl(),
+ "clientCertificateKeyStoreUrl must be set when sslMode=VERIFY_CA");
+ requireNonNull(mySqlConfiguration.getClientCertificateKeyStorePassword(),
+ "clientCertificateKeyStorePassword must be set when sslMode=VERIFY_CA");
+ requireNonNull(mySqlConfiguration.getTrustCertificateKeyStoreUrl(),
+ "trustCertificateKeyStoreUrl must be set when sslMode=VERIFY_CA");
+ requireNonNull(mySqlConfiguration.getTrustCertificateKeyStorePassword(),
+ "trustCertificateKeyStorePassword must be set when sslMode=VERIFY_CA");
+
+ properties.setProperty(PropertyKey.clientCertificateKeyStoreUrl.getKeyName(),
+ mySqlConfiguration.getClientCertificateKeyStoreUrl());
+ properties.setProperty(PropertyKey.clientCertificateKeyStorePassword.getKeyName(),
+ mySqlConfiguration.getClientCertificateKeyStorePassword());
+ if (mySqlConfiguration.getClientCertificateKeyStoreType() != null) {
+ properties.setProperty(
+ PropertyKey.clientCertificateKeyStoreType.getKeyName(),
+ mySqlConfiguration.getClientCertificateKeyStoreType());
+ }
+ properties.setProperty(PropertyKey.trustCertificateKeyStoreUrl.getKeyName(),
+ mySqlConfiguration.getTrustCertificateKeyStoreUrl());
+ properties.setProperty(PropertyKey.trustCertificateKeyStorePassword.getKeyName(),
+ mySqlConfiguration.getTrustCertificateKeyStorePassword());
+ }
+ else {
+ properties.setProperty("password", configuration.getPassword());
+ }
+ return properties;
+ }
+}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaGatewayManager.java b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaGatewayManager.java
index db5ad7d0f..619d5c698 100644
--- a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaGatewayManager.java
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaGatewayManager.java
@@ -14,6 +14,7 @@
package io.trino.gateway.ha.router;
import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
import io.airlift.log.Logger;
import io.trino.gateway.ha.config.ProxyBackendConfiguration;
import io.trino.gateway.ha.config.RoutingConfiguration;
@@ -36,6 +37,7 @@ public class HaGatewayManager
private final GatewayBackendDao dao;
private final String defaultRoutingGroup;
+ @Inject
public HaGatewayManager(Jdbi jdbi, RoutingConfiguration routingConfiguration)
{
dao = requireNonNull(jdbi, "jdbi is null").onDemand(GatewayBackendDao.class);
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaQueryHistoryManager.java b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaQueryHistoryManager.java
index 5a6dfad36..f14c8b40f 100644
--- a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaQueryHistoryManager.java
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaQueryHistoryManager.java
@@ -14,6 +14,9 @@
package io.trino.gateway.ha.router;
import com.google.common.base.Strings;
+import com.google.inject.Inject;
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.config.DataStoreType;
import io.trino.gateway.ha.domain.TableData;
import io.trino.gateway.ha.domain.request.QueryHistoryRequest;
import io.trino.gateway.ha.domain.response.DistributionResponse;
@@ -38,12 +41,14 @@ public class HaQueryHistoryManager
private static final int FIRST_PAGE_NO = 1;
private final QueryHistoryDao dao;
- private final boolean isOracleBackend;
+ private final DataStoreType backend;
- public HaQueryHistoryManager(Jdbi jdbi, boolean isOracleBackend)
+ @Inject
+ public HaQueryHistoryManager(Jdbi jdbi, DataStoreConfiguration configuration)
{
+ requireNonNull(configuration, "DataStoreConfiguration is null");
dao = requireNonNull(jdbi, "jdbi is null").onDemand(QueryHistoryDao.class);
- this.isOracleBackend = isOracleBackend;
+ this.backend = configuration.getDataStoreType();
}
@Override
@@ -70,10 +75,10 @@ public List fetchQueryHistory(Optional user)
{
List histories;
if (user.isPresent()) {
- histories = dao.findRecentQueriesByUserName(user.orElseThrow(), isOracleBackend);
+ histories = dao.findRecentQueriesByUserName(user.orElseThrow(), backend == DataStoreType.ORACLE);
}
else {
- histories = dao.findRecentQueries(isOracleBackend);
+ histories = dao.findRecentQueries(backend == DataStoreType.ORACLE);
}
return upcast(histories);
}
diff --git a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaResourceGroupsManager.java b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaResourceGroupsManager.java
index 462c17094..4d8c5d64a 100644
--- a/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaResourceGroupsManager.java
+++ b/gateway-ha/src/main/java/io/trino/gateway/ha/router/HaResourceGroupsManager.java
@@ -14,6 +14,7 @@
package io.trino.gateway.ha.router;
import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
import io.trino.gateway.ha.persistence.dao.ExactMatchSourceSelectors;
import io.trino.gateway.ha.persistence.dao.ExactMatchSourceSelectorsDao;
@@ -36,6 +37,7 @@ public class HaResourceGroupsManager
private final JdbcConnectionManager connectionManager;
private final ExactMatchSourceSelectorsDao exactMatchSourceSelectorsDao;
+ @Inject
public HaResourceGroupsManager(JdbcConnectionManager connectionManager)
{
this.connectionManager = connectionManager;
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/TestTrinoResource.java b/gateway-ha/src/test/java/io/trino/gateway/ha/TestTrinoResource.java
index 99a00dcb6..b81a83a22 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/TestTrinoResource.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/TestTrinoResource.java
@@ -15,6 +15,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
import io.trino.gateway.ha.router.HaResourceGroupsManager;
import okhttp3.MediaType;
@@ -66,7 +67,7 @@ void setup()
// Setup resource group manager
DataStoreConfiguration db = new DataStoreConfiguration(postgresql.getJdbcUrl(), postgresql.getUsername(), postgresql.getPassword(), "org.postgresql.Driver", 4, true);
Jdbi jdbi = Jdbi.create(postgresql.getJdbcUrl(), postgresql.getUsername(), postgresql.getPassword());
- connectionManager = new JdbcConnectionManager(jdbi, db);
+ connectionManager = new JdbcConnectionManager(jdbi, db, new DefaultJdbcPropertiesProvider());
resourceGroupManager = new HaResourceGroupsManager(connectionManager);
// Start Trino Gateway so migrations are run to create tables before inserting test data
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/TestingJdbcConnectionManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/TestingJdbcConnectionManager.java
index 1f60a0dfb..d0f0802a6 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/TestingJdbcConnectionManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/TestingJdbcConnectionManager.java
@@ -14,6 +14,7 @@
package io.trino.gateway.ha;
import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
import org.jdbi.v3.core.Jdbi;
import org.testcontainers.containers.JdbcDatabaseContainer;
@@ -33,12 +34,12 @@ public static JdbcConnectionManager createTestingJdbcConnectionManager()
HaGatewayTestUtils.seedRequiredData(tempH2DbDir.getAbsolutePath());
DataStoreConfiguration db = new DataStoreConfiguration(jdbcUrl, "sa", "sa", "org.h2.Driver", 4, false);
Jdbi jdbi = Jdbi.create(jdbcUrl, "sa", "sa");
- return new JdbcConnectionManager(jdbi, db);
+ return new JdbcConnectionManager(jdbi, db, new DefaultJdbcPropertiesProvider());
}
public static JdbcConnectionManager createTestingJdbcConnectionManager(JdbcDatabaseContainer> container, DataStoreConfiguration config)
{
Jdbi jdbi = Jdbi.create(container.getJdbcUrl(), container.getUsername(), container.getPassword());
- return new JdbcConnectionManager(jdbi, config);
+ return new JdbcConnectionManager(jdbi, config, new DefaultJdbcPropertiesProvider());
}
}
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcConnectionManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcConnectionManager.java
index 8a3ff454c..f3be6e43a 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcConnectionManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcConnectionManager.java
@@ -108,7 +108,7 @@ void testBuildJdbcUrlWithNullJdbcUrlThrowsException()
DataStoreConfiguration dataStoreConfiguration = Mockito.mock(DataStoreConfiguration.class);
when(dataStoreConfiguration.getJdbcUrl()).thenReturn(null);
- JdbcConnectionManager connectionManager = new JdbcConnectionManager(Jdbi.create("jdbc:h2:/mydb", "sa", "sa"), dataStoreConfiguration);
+ JdbcConnectionManager connectionManager = new JdbcConnectionManager(Jdbi.create("jdbc:h2:/mydb", "sa", "sa"), dataStoreConfiguration, new DefaultJdbcPropertiesProvider());
assertThatThrownBy(() -> connectionManager.buildJdbcUrl(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("JDBC URL cannot be null");
@@ -126,6 +126,6 @@ void testBuildJdbcUrlWithNoSlashThrowsException()
private static JdbcConnectionManager createConnectionManager(String jdbcUrl)
{
DataStoreConfiguration db = new DataStoreConfiguration(jdbcUrl, "sa", "sa", "", 4, true);
- return new JdbcConnectionManager(Jdbi.create(jdbcUrl, "sa", "sa"), db);
+ return new JdbcConnectionManager(Jdbi.create(jdbcUrl, "sa", "sa"), db, new DefaultJdbcPropertiesProvider());
}
}
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcPropertiesProviderFactory.java b/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcPropertiesProviderFactory.java
new file mode 100644
index 000000000..d3399dc68
--- /dev/null
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/persistence/TestJdbcPropertiesProviderFactory.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.gateway.ha.persistence;
+
+import com.mysql.cj.conf.PropertyDefinitions.SslMode;
+import com.mysql.cj.conf.PropertyKey;
+import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.config.MySqlConfiguration;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+final class TestJdbcPropertiesProviderFactory
+{
+ private static JdbcPropertiesProviderFactory factoryFor()
+ {
+ List providers = Arrays.asList(
+ new MySqlJdbcPropertiesProvider(),
+ new DefaultJdbcPropertiesProvider());
+ return new JdbcPropertiesProviderFactory(providers);
+ }
+
+ private DataStoreConfiguration makeMySqlConfig(SslMode mode)
+ {
+ DataStoreConfiguration db = new DataStoreConfiguration();
+ db.setDriver("com.mysql.Driver");
+ db.setJdbcUrl("jdbc:mysql://host/db");
+ db.setUser("root");
+ db.setPassword("root123");
+ MySqlConfiguration mySqlConfiguration = db.getMySqlConfiguration();
+ mySqlConfiguration.setSslMode(mode);
+ return db;
+ }
+
+ private DataStoreConfiguration makeH2Config()
+ {
+ DataStoreConfiguration db = new DataStoreConfiguration();
+ db.setDriver("org.h2.Driver");
+ db.setJdbcUrl("jdbc:h2:mem:test");
+ db.setUser("sa");
+ db.setPassword("sa");
+ return db;
+ }
+
+ @Test
+ void testBasicProviderWhenH2()
+ {
+ DataStoreConfiguration cfg = makeH2Config();
+ JdbcPropertiesProviderFactory factory = factoryFor();
+ DefaultJdbcPropertiesProvider provider = (DefaultJdbcPropertiesProvider) factory.forConfig(cfg);
+ assertThat(provider).isInstanceOf(DefaultJdbcPropertiesProvider.class);
+
+ Properties properties = provider.getProperties(cfg);
+ assertThat(properties)
+ .hasSize(2)
+ .containsEntry("user", "sa")
+ .containsEntry("password", "sa");
+ }
+
+ @Test
+ void testMysqlProviderWhenSslDisabled()
+ {
+ DataStoreConfiguration cfg = makeMySqlConfig(SslMode.DISABLED);
+ JdbcPropertiesProviderFactory factory = factoryFor();
+ JdbcPropertiesProvider provider = factory.forConfig(cfg);
+ assertThat(provider).isInstanceOf(MySqlJdbcPropertiesProvider.class);
+
+ Properties properties = provider.getProperties(cfg);
+ assertThat(properties.getProperty("user")).isEqualTo("root");
+ assertThat(properties.getProperty("password")).isEqualTo("root123");
+ assertThat(properties.getProperty(PropertyKey.sslMode.getKeyName()))
+ .isEqualTo("DISABLED");
+
+ assertThat(properties).doesNotContainKeys(
+ PropertyKey.clientCertificateKeyStoreUrl.getKeyName(),
+ PropertyKey.clientCertificateKeyStorePassword.getKeyName(),
+ PropertyKey.clientCertificateKeyStoreType.getKeyName(),
+ PropertyKey.trustCertificateKeyStoreUrl.getKeyName(),
+ PropertyKey.trustCertificateKeyStorePassword.getKeyName());
+ }
+
+ @Test
+ void testMysqlProviderWhenVerifyCa()
+ {
+ DataStoreConfiguration cfg = makeMySqlConfig(SslMode.VERIFY_CA);
+ JdbcPropertiesProviderFactory factory = factoryFor();
+ MySqlConfiguration mysqlConfig = cfg.getMySqlConfiguration();
+ mysqlConfig.setClientCertificateKeyStoreUrl("file:/tmp/cli.p12")
+ .setClientCertificateKeyStorePassword("cpw")
+ .setClientCertificateKeyStoreType("PKCS12")
+ .setTrustCertificateKeyStoreUrl("file:/tmp/trs.p12")
+ .setTrustCertificateKeyStorePassword("tpw");
+
+ JdbcPropertiesProvider provider = factory.forConfig(cfg);
+ assertThat(provider).isInstanceOf(MySqlJdbcPropertiesProvider.class);
+
+ Properties properties = provider.getProperties(cfg);
+ assertThat(properties.getProperty("user")).isEqualTo("root");
+ assertThat(properties.getProperty(PropertyKey.sslMode.getKeyName()))
+ .isEqualTo("VERIFY_CA");
+ assertThat(properties.getProperty(PropertyKey.clientCertificateKeyStoreUrl.getKeyName()))
+ .isEqualTo("file:/tmp/cli.p12");
+ assertThat(properties.getProperty(PropertyKey.trustCertificateKeyStoreUrl.getKeyName()))
+ .isEqualTo("file:/tmp/trs.p12");
+ }
+}
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseExternalUrlQueryHistoryTest.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseExternalUrlQueryHistoryTest.java
index d795b0194..45bdd7159 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseExternalUrlQueryHistoryTest.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseExternalUrlQueryHistoryTest.java
@@ -49,7 +49,7 @@ protected BaseExternalUrlQueryHistoryTest(JdbcDatabaseContainer> container)
true);
FlywayMigration.migrate(config);
JdbcConnectionManager jdbcConnectionManager = createTestingJdbcConnectionManager(container, config);
- queryHistoryManager = new HaQueryHistoryManager(jdbcConnectionManager.getJdbi(), container.getJdbcUrl().startsWith("jdbc:oracle"));
+ queryHistoryManager = new HaQueryHistoryManager(jdbcConnectionManager.getJdbi(), config);
}
@AfterAll
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseTestQueryHistoryManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseTestQueryHistoryManager.java
index 3f5de4bbc..777b6611f 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseTestQueryHistoryManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/BaseTestQueryHistoryManager.java
@@ -50,7 +50,7 @@ void setUp()
true);
FlywayMigration.migrate(config);
JdbcConnectionManager jdbcConnectionManager = createTestingJdbcConnectionManager(container, config);
- queryHistoryManager = new HaQueryHistoryManager(jdbcConnectionManager.getJdbi(), container.getJdbcUrl().startsWith("jdbc:oracle"));
+ queryHistoryManager = new HaQueryHistoryManager(jdbcConnectionManager.getJdbi(), jdbcConnectionManager.getConfiguration());
}
@AfterAll
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestRoutingManagerNotFound.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestRoutingManagerNotFound.java
index 8f4154623..6d6d9ed0f 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestRoutingManagerNotFound.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestRoutingManagerNotFound.java
@@ -31,7 +31,7 @@ public TestRoutingManagerNotFound()
routingConfiguration.setDefaultRoutingGroup("default");
GatewayBackendManager backendManager = new HaGatewayManager(connectionManager.getJdbi(), routingConfiguration);
- QueryHistoryManager historyManager = new HaQueryHistoryManager(connectionManager.getJdbi(), false);
+ QueryHistoryManager historyManager = new HaQueryHistoryManager(connectionManager.getJdbi(), connectionManager.getConfiguration());
this.routingManager = new StochasticRoutingManager(backendManager, historyManager, routingConfiguration);
}
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestSpecificDbResourceGroupsManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestSpecificDbResourceGroupsManager.java
index f78b80377..10a4da47b 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestSpecificDbResourceGroupsManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestSpecificDbResourceGroupsManager.java
@@ -15,6 +15,7 @@
import io.trino.gateway.ha.HaGatewayTestUtils;
import io.trino.gateway.ha.config.DataStoreConfiguration;
+import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
import org.jdbi.v3.core.Jdbi;
import org.junit.jupiter.api.BeforeAll;
@@ -48,7 +49,7 @@ void setUp()
DataStoreConfiguration db = new DataStoreConfiguration(jdbcUrl, "sa",
"sa", "org.h2.Driver", 4, false);
Jdbi jdbi = Jdbi.create(jdbcUrl, "sa", "sa");
- JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, db);
+ JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, db, new DefaultJdbcPropertiesProvider());
super.resourceGroupManager = new HaResourceGroupsManager(connectionManager);
}
diff --git a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestStochasticRoutingManager.java b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestStochasticRoutingManager.java
index 38f60ab22..b28723a54 100644
--- a/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestStochasticRoutingManager.java
+++ b/gateway-ha/src/test/java/io/trino/gateway/ha/router/TestStochasticRoutingManager.java
@@ -38,7 +38,7 @@ void setUp()
JdbcConnectionManager connectionManager = createTestingJdbcConnectionManager();
RoutingConfiguration routingConfiguration = new RoutingConfiguration();
backendManager = new HaGatewayManager(connectionManager.getJdbi(), routingConfiguration);
- historyManager = new HaQueryHistoryManager(connectionManager.getJdbi(), false);
+ historyManager = new HaQueryHistoryManager(connectionManager.getJdbi(), connectionManager.getConfiguration());
haRoutingManager = new StochasticRoutingManager(backendManager, historyManager, routingConfiguration);
}