Skip to content

Commit c96a47e

Browse files
Felicity-3786felicity3786
authored andcommitted
[Improvement] JDBC Connection Configuration with Flexible SSL and Property Injection
1 parent e1b4ee7 commit c96a47e

23 files changed

+586
-48
lines changed

gateway-ha/pom.xml

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@
7878
<classifier>classes</classifier>
7979
</dependency>
8080

81+
<dependency>
82+
<groupId>com.h2database</groupId>
83+
<artifactId>h2</artifactId>
84+
<version>1.4.192</version>
85+
</dependency>
86+
87+
<dependency>
88+
<groupId>com.mysql</groupId>
89+
<artifactId>mysql-connector-j</artifactId>
90+
<version>9.3.0</version>
91+
</dependency>
92+
8193
<dependency>
8294
<groupId>com.nimbusds</groupId>
8395
<artifactId>nimbus-jose-jwt</artifactId>
@@ -91,6 +103,12 @@
91103
<classifier>jdk11</classifier>
92104
</dependency>
93105

106+
<dependency>
107+
<groupId>com.oracle.database.jdbc</groupId>
108+
<artifactId>ojdbc11</artifactId>
109+
<version>23.8.0.25.04</version>
110+
</dependency>
111+
94112
<dependency>
95113
<groupId>com.squareup.okhttp3</groupId>
96114
<artifactId>okhttp</artifactId>
@@ -268,23 +286,14 @@
268286
</dependency>
269287

270288
<dependency>
271-
<groupId>org.weakref</groupId>
272-
<artifactId>jmxutils</artifactId>
273-
</dependency>
274-
275-
<dependency>
276-
<groupId>com.mysql</groupId>
277-
<artifactId>mysql-connector-j</artifactId>
278-
<version>9.3.0</version>
279-
<scope>runtime</scope>
289+
<groupId>org.postgresql</groupId>
290+
<artifactId>postgresql</artifactId>
291+
<version>42.7.5</version>
280292
</dependency>
281293

282294
<dependency>
283-
<groupId>com.oracle.database.jdbc</groupId>
284-
<artifactId>ojdbc11-production</artifactId>
285-
<version>23.8.0.25.04</version>
286-
<type>pom</type>
287-
<scope>runtime</scope>
295+
<groupId>org.weakref</groupId>
296+
<artifactId>jmxutils</artifactId>
288297
</dependency>
289298

290299
<!-- Required for ClusterStatsJdbcMonitor -->
@@ -316,21 +325,7 @@
316325
<scope>runtime</scope>
317326
</dependency>
318327

319-
<dependency>
320-
<groupId>org.postgresql</groupId>
321-
<artifactId>postgresql</artifactId>
322-
<version>42.7.7</version>
323-
<scope>runtime</scope>
324-
</dependency>
325-
326328
<!-- Test deps -->
327-
<dependency>
328-
<groupId>com.h2database</groupId>
329-
<artifactId>h2</artifactId>
330-
<version>1.4.192</version>
331-
<scope>test</scope>
332-
</dependency>
333-
334329
<dependency>
335330
<groupId>com.squareup.okhttp3</groupId>
336331
<artifactId>mockwebserver</artifactId>

gateway-ha/src/main/java/io/trino/gateway/ha/config/DataStoreConfiguration.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
*/
1414
package io.trino.gateway.ha.config;
1515

16+
import java.sql.Driver;
17+
import java.sql.DriverManager;
18+
import java.sql.SQLException;
19+
import java.util.Enumeration;
20+
21+
import static java.util.Objects.requireNonNull;
22+
1623
public class DataStoreConfiguration
1724
{
1825
private String jdbcUrl;
@@ -21,10 +28,15 @@ public class DataStoreConfiguration
2128
private String driver;
2229
private Integer queryHistoryHoursRetention = 4;
2330
private boolean runMigrationsEnabled = true;
31+
private DataStoreType dataStoreType;
32+
33+
// TODO: Refactor to decouple DataStoreConfiguration from a specific
34+
// database implementation after adopting the Airlift configuration framework (https://github.com/trinodb/trino-gateway/issues/378)
35+
private MySqlConfiguration mySqlConfiguration = new MySqlConfiguration();
2436

2537
public DataStoreConfiguration(String jdbcUrl, String user, String password, String driver, Integer queryHistoryHoursRetention, boolean runMigrationsEnabled)
2638
{
27-
this.jdbcUrl = jdbcUrl;
39+
this.jdbcUrl = requireNonNull(jdbcUrl, "jdbc must be set");
2840
this.user = user;
2941
this.password = password;
3042
this.driver = driver;
@@ -93,4 +105,45 @@ public void setRunMigrationsEnabled(boolean runMigrationsEnabled)
93105
{
94106
this.runMigrationsEnabled = runMigrationsEnabled;
95107
}
108+
109+
public MySqlConfiguration getMySqlConfiguration()
110+
{
111+
return mySqlConfiguration;
112+
}
113+
114+
public void setMysqlConfiguration(MySqlConfiguration mySqlConfig)
115+
{
116+
this.mySqlConfiguration = mySqlConfig;
117+
}
118+
119+
public DataStoreType getDataStoreType()
120+
{
121+
if (dataStoreType != null) {
122+
return dataStoreType;
123+
}
124+
String jdbcUrl = getJdbcUrl();
125+
try {
126+
Enumeration<Driver> drivers = DriverManager.getDrivers();
127+
while (drivers.hasMoreElements()) {
128+
Driver driver = drivers.nextElement();
129+
if (driver.acceptsURL(jdbcUrl)) {
130+
for (DataStoreType dataStoreType : DataStoreType.values()) {
131+
if (dataStoreType.getDriverClass().isAssignableFrom(driver.getClass())) {
132+
return dataStoreType;
133+
}
134+
}
135+
break;
136+
}
137+
}
138+
}
139+
catch (SQLException e) {
140+
throw new RuntimeException("Error enumerating JDBC drivers", e);
141+
}
142+
throw new IllegalStateException("Unable to infer DataStoreType for URL: " + jdbcUrl);
143+
}
144+
145+
public void setDataStoreType(DataStoreType backendType)
146+
{
147+
this.dataStoreType = backendType;
148+
}
96149
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.trino.gateway.ha.config;
15+
16+
import java.sql.Driver;
17+
18+
public enum DataStoreType {
19+
ORACLE(oracle.jdbc.driver.OracleDriver.class),
20+
MYSQL(com.mysql.cj.jdbc.Driver.class),
21+
POSTGRES(org.postgresql.Driver.class),
22+
H2(org.h2.Driver.class);
23+
24+
private final Class<? extends Driver> driverClass;
25+
26+
DataStoreType(Class<? extends Driver> driverClass)
27+
{
28+
this.driverClass = driverClass;
29+
}
30+
31+
/**
32+
* Returns the JDBC Driver class associated with this data store type.
33+
*/
34+
public Class<? extends Driver> getDriverClass()
35+
{
36+
return driverClass;
37+
}
38+
}

gateway-ha/src/main/java/io/trino/gateway/ha/config/HaGatewayConfiguration.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class HaGatewayConfiguration
4343
private List<String> statementPaths = ImmutableList.of(V1_STATEMENT_PATH);
4444
private boolean includeClusterHostInResponse;
4545
private ProxyResponseConfiguration proxyResponseConfiguration = new ProxyResponseConfiguration();
46+
private boolean oracleBackend;
4647

4748
private RequestAnalyzerConfig requestAnalyzerConfig = new RequestAnalyzerConfig();
4849

@@ -297,4 +298,14 @@ public HaGatewayConfigurationException(String message)
297298
super(message);
298299
}
299300
}
301+
302+
public boolean isOracleBackend()
303+
{
304+
return oracleBackend;
305+
}
306+
307+
public void setOracleBackend(boolean oracleBackend)
308+
{
309+
this.oracleBackend = oracleBackend;
310+
}
300311
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.trino.gateway.ha.config;
15+
16+
import com.mysql.cj.conf.PropertyDefinitions.SslMode;
17+
18+
/**
19+
* Configuration for MySQL SSL (client cert and truststore settings).
20+
*/
21+
public class MySqlConfiguration
22+
{
23+
private SslMode sslMode = SslMode.DISABLED;
24+
private String clientCertificateKeyStoreUrl;
25+
private String clientCertificateKeyStorePassword;
26+
private String clientCertificateKeyStoreType;
27+
private String trustCertificateKeyStoreUrl;
28+
private String trustCertificateKeyStorePassword;
29+
30+
public SslMode getSslMode()
31+
{
32+
return sslMode;
33+
}
34+
35+
public MySqlConfiguration setSslMode(SslMode sslMode)
36+
{
37+
this.sslMode = sslMode;
38+
return this;
39+
}
40+
41+
public String getClientCertificateKeyStoreUrl()
42+
{
43+
return clientCertificateKeyStoreUrl;
44+
}
45+
46+
public MySqlConfiguration setClientCertificateKeyStoreUrl(String url)
47+
{
48+
this.clientCertificateKeyStoreUrl = url;
49+
return this;
50+
}
51+
52+
public String getClientCertificateKeyStorePassword()
53+
{
54+
return clientCertificateKeyStorePassword;
55+
}
56+
57+
public MySqlConfiguration setClientCertificateKeyStorePassword(String password)
58+
{
59+
this.clientCertificateKeyStorePassword = password;
60+
return this;
61+
}
62+
63+
public String getClientCertificateKeyStoreType()
64+
{
65+
return clientCertificateKeyStoreType;
66+
}
67+
68+
public MySqlConfiguration setClientCertificateKeyStoreType(String type)
69+
{
70+
this.clientCertificateKeyStoreType = type;
71+
return this;
72+
}
73+
74+
public String getTrustCertificateKeyStoreUrl()
75+
{
76+
return trustCertificateKeyStoreUrl;
77+
}
78+
79+
public MySqlConfiguration setTrustCertificateKeyStoreUrl(String url)
80+
{
81+
this.trustCertificateKeyStoreUrl = url;
82+
return this;
83+
}
84+
85+
public String getTrustCertificateKeyStorePassword()
86+
{
87+
return trustCertificateKeyStorePassword;
88+
}
89+
90+
public MySqlConfiguration setTrustCertificateKeyStorePassword(String password)
91+
{
92+
this.trustCertificateKeyStorePassword = password;
93+
return this;
94+
}
95+
}

gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import io.trino.gateway.ha.config.RoutingRulesConfiguration;
4040
import io.trino.gateway.ha.config.RulesExternalConfiguration;
4141
import io.trino.gateway.ha.config.UserConfiguration;
42+
import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
4243
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
4344
import io.trino.gateway.ha.router.BackendStateManager;
4445
import io.trino.gateway.ha.router.ForRouter;
@@ -117,10 +118,10 @@ public HaGatewayProviderModule(HaGatewayConfiguration configuration)
117118
oAuth2GatewayCookieConfigurationPropertiesProvider.initialize(configuration.getOauth2GatewayCookieConfiguration());
118119

119120
Jdbi jdbi = Jdbi.create(configuration.getDataStore().getJdbcUrl(), configuration.getDataStore().getUser(), configuration.getDataStore().getPassword());
120-
JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore());
121+
JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore(), new DefaultJdbcPropertiesProvider());
121122
resourceGroupsManager = new HaResourceGroupsManager(connectionManager);
122123
gatewayBackendManager = new HaGatewayManager(jdbi, configuration.getRouting());
123-
queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore().getJdbcUrl().startsWith("jdbc:oracle"));
124+
queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore());
124125
}
125126

126127
private LbOAuthManager getOAuthManager(HaGatewayConfiguration configuration)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.trino.gateway.ha.persistence;
15+
16+
import io.trino.gateway.ha.config.DataStoreConfiguration;
17+
18+
import java.util.Properties;
19+
20+
/**
21+
* Default JDBC properties provider used as a fallback when no database-specific
22+
* {@link JdbcPropertiesProvider} supports the given {@link DataStoreConfiguration}.
23+
*
24+
* <p>This provider simply sets the basic "user" and "password" properties
25+
* and should always be the last provider in the list of available providers.
26+
*
27+
* <p>If a more specific provider (e.g., for MySQL, Oracle, etc.) supports the configuration,
28+
* it should be preferred over this basic fallback.
29+
*/
30+
public class DefaultJdbcPropertiesProvider
31+
implements JdbcPropertiesProvider
32+
{
33+
@Override
34+
public boolean supports(DataStoreConfiguration configuration)
35+
{
36+
return true;
37+
}
38+
39+
@Override
40+
public Properties getProperties(DataStoreConfiguration configuration)
41+
{
42+
Properties properties = new Properties();
43+
properties.setProperty("user", configuration.getUser());
44+
properties.setProperty("password", configuration.getPassword());
45+
return properties;
46+
}
47+
}

0 commit comments

Comments
 (0)