Skip to content

Commit 0bff7d3

Browse files
Felicity-3786felicity3786
authored andcommitted
[Improvement] JDBC Connection Configuration with Flexible SSL and Property Injection
1 parent 673bcf5 commit 0bff7d3

22 files changed

+572
-41
lines changed

gateway-ha/pom.xml

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@
8585
<classifier>classes</classifier>
8686
</dependency>
8787

88+
<dependency>
89+
<groupId>com.h2database</groupId>
90+
<artifactId>h2</artifactId>
91+
<version>1.4.192</version>
92+
</dependency>
93+
94+
<dependency>
95+
<groupId>com.mysql</groupId>
96+
<artifactId>mysql-connector-j</artifactId>
97+
<version>9.3.0</version>
98+
</dependency>
99+
88100
<dependency>
89101
<groupId>com.nimbusds</groupId>
90102
<artifactId>nimbus-jose-jwt</artifactId>
@@ -98,6 +110,12 @@
98110
<classifier>jdk11</classifier>
99111
</dependency>
100112

113+
<dependency>
114+
<groupId>com.oracle.database.jdbc</groupId>
115+
<artifactId>ojdbc11</artifactId>
116+
<version>23.8.0.25.04</version>
117+
</dependency>
118+
101119
<dependency>
102120
<groupId>com.squareup.okhttp3</groupId>
103121
<artifactId>okhttp-jvm</artifactId>
@@ -274,23 +292,14 @@
274292
</dependency>
275293

276294
<dependency>
277-
<groupId>org.weakref</groupId>
278-
<artifactId>jmxutils</artifactId>
279-
</dependency>
280-
281-
<dependency>
282-
<groupId>com.mysql</groupId>
283-
<artifactId>mysql-connector-j</artifactId>
284-
<version>9.3.0</version>
285-
<scope>runtime</scope>
295+
<groupId>org.postgresql</groupId>
296+
<artifactId>postgresql</artifactId>
297+
<version>42.7.5</version>
286298
</dependency>
287299

288300
<dependency>
289-
<groupId>com.oracle.database.jdbc</groupId>
290-
<artifactId>ojdbc11-production</artifactId>
291-
<version>23.8.0.25.04</version>
292-
<type>pom</type>
293-
<scope>runtime</scope>
301+
<groupId>org.weakref</groupId>
302+
<artifactId>jmxutils</artifactId>
294303
</dependency>
295304

296305
<!-- Required for ClusterStatsJdbcMonitor -->
@@ -330,13 +339,6 @@
330339
</dependency>
331340

332341
<!-- Test deps -->
333-
<dependency>
334-
<groupId>com.h2database</groupId>
335-
<artifactId>h2</artifactId>
336-
<version>1.4.192</version>
337-
<scope>test</scope>
338-
</dependency>
339-
340342
<dependency>
341343
<groupId>com.squareup.okhttp3</groupId>
342344
<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+
}
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
@@ -40,6 +40,7 @@
4040
import io.trino.gateway.ha.config.RoutingRulesConfiguration;
4141
import io.trino.gateway.ha.config.RulesExternalConfiguration;
4242
import io.trino.gateway.ha.config.UserConfiguration;
43+
import io.trino.gateway.ha.persistence.DefaultJdbcPropertiesProvider;
4344
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
4445
import io.trino.gateway.ha.router.BackendStateManager;
4546
import io.trino.gateway.ha.router.ForRouter;
@@ -121,10 +122,10 @@ public HaGatewayProviderModule(HaGatewayConfiguration configuration)
121122
oAuth2GatewayCookieConfigurationPropertiesProvider.initialize(configuration.getOauth2GatewayCookieConfiguration());
122123

123124
Jdbi jdbi = Jdbi.create(configuration.getDataStore().getJdbcUrl(), configuration.getDataStore().getUser(), configuration.getDataStore().getPassword());
124-
JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore());
125+
JdbcConnectionManager connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore(), new DefaultJdbcPropertiesProvider());
125126
resourceGroupsManager = new HaResourceGroupsManager(connectionManager);
126127
gatewayBackendManager = new HaGatewayManager(jdbi, configuration.getRouting());
127-
queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore().getJdbcUrl().startsWith("jdbc:oracle"));
128+
queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore());
128129
}
129130

130131
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)