Skip to content

[Improvement] JDBC Connection Configuration with Flexible SSL and Property Injection #681

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
51 changes: 23 additions & 28 deletions gateway-ha/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@
<artifactId>guice</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.2.0</version>
</dependency>

<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
Expand All @@ -89,6 +101,12 @@
<classifier>jdk11</classifier>
</dependency>

<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.7.0.25.01</version>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
Expand Down Expand Up @@ -266,23 +284,14 @@
</dependency>

<dependency>
<groupId>org.weakref</groupId>
<artifactId>jmxutils</artifactId>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.2.0</version>
<scope>runtime</scope>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.5</version>
</dependency>

<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11-production</artifactId>
<version>23.7.0.25.01</version>
<type>pom</type>
<scope>runtime</scope>
<groupId>org.weakref</groupId>
<artifactId>jmxutils</artifactId>
</dependency>

<!-- Required for ClusterStatsJdbcMonitor -->
Expand Down Expand Up @@ -314,21 +323,7 @@
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.5</version>
<scope>runtime</scope>
</dependency>

<!-- Test deps -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
*/
package io.trino.gateway.ha.config;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import static java.util.Objects.requireNonNull;

public class DataStoreConfiguration
{
private String jdbcUrl;
Expand All @@ -21,10 +28,15 @@ public class DataStoreConfiguration
private String driver;
private Integer queryHistoryHoursRetention = 4;
private boolean runMigrationsEnabled = true;
private DataStoreType dataStoreType;

// TODO: Refactor to decouple DataStoreConfiguration from a specific
// database implementation after adopting the Airlift configuration framework (https://github.com/trinodb/trino-gateway/issues/378)
private MySqlConfiguration mySqlConfiguration = new MySqlConfiguration();

public DataStoreConfiguration(String jdbcUrl, String user, String password, String driver, Integer queryHistoryHoursRetention, boolean runMigrationsEnabled)
{
this.jdbcUrl = jdbcUrl;
this.jdbcUrl = requireNonNull(jdbcUrl, "jdbc must be set");
this.user = user;
this.password = password;
this.driver = driver;
Expand Down Expand Up @@ -93,4 +105,45 @@ public void setRunMigrationsEnabled(boolean runMigrationsEnabled)
{
this.runMigrationsEnabled = runMigrationsEnabled;
}

public MySqlConfiguration getMySqlConfiguration()
{
return mySqlConfiguration;
}

public void setMysqlConfiguration(MySqlConfiguration mysqlConfig)
{
this.mySqlConfiguration = mysqlConfig;
}

public DataStoreType getDataStoreType()
{
if (dataStoreType != null) {
return dataStoreType;
}
String jdbcUrl = getJdbcUrl();
try {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.acceptsURL(jdbcUrl)) {
for (DataStoreType dataStoreType : DataStoreType.values()) {
if (dataStoreType.getDriverClass().equals(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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the parameter. Same for others.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ebyhr, @xkrogen and I both think it's would make more sense to keep the mysql naming convention as we discussed in #681 (comment), wdyt?

{
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,28 @@
package io.trino.gateway.ha.module;

import com.google.inject.Provides;
import com.google.inject.Singleton;
import io.trino.gateway.ha.config.HaGatewayConfiguration;
import io.trino.gateway.ha.router.GatewayBackendManager;
import io.trino.gateway.ha.router.QueryCountBasedRouter;
import io.trino.gateway.ha.router.QueryHistoryManager;
import io.trino.gateway.ha.router.RoutingManager;

import static java.util.Objects.requireNonNull;

public class QueryCountBasedRouterProvider
extends RouterBaseModule
{
private final QueryCountBasedRouter routingManager;

public QueryCountBasedRouterProvider(HaGatewayConfiguration configuration)
{
super(configuration);
routingManager = new QueryCountBasedRouter(gatewayBackendManager, queryHistoryManager);
}
public QueryCountBasedRouterProvider(HaGatewayConfiguration configuration) {}

@Provides
public RoutingManager getRoutingManager()
@Singleton
public RoutingManager provideRoutingManager(
GatewayBackendManager gatewayBackendManager,
QueryHistoryManager queryHistoryManager)
{
return this.routingManager;
return new QueryCountBasedRouter(
requireNonNull(gatewayBackendManager, "gatewayBackendManager is null"),
requireNonNull(queryHistoryManager, "queryHistoryManager is null"));
}
}
Loading