Skip to content

Commit 28879c5

Browse files
committed
[Improvement] JDBC Connection Configuration with Flexible SSL and Property Injection
1 parent d654094 commit 28879c5

21 files changed

+541
-52
lines changed

gateway-ha/pom.xml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@
7676
<artifactId>guice</artifactId>
7777
</dependency>
7878

79+
<dependency>
80+
<groupId>com.mysql</groupId>
81+
<artifactId>mysql-connector-j</artifactId>
82+
<version>9.2.0</version>
83+
</dependency>
84+
7985
<dependency>
8086
<groupId>com.nimbusds</groupId>
8187
<artifactId>nimbus-jose-jwt</artifactId>
@@ -270,13 +276,6 @@
270276
<artifactId>jmxutils</artifactId>
271277
</dependency>
272278

273-
<dependency>
274-
<groupId>com.mysql</groupId>
275-
<artifactId>mysql-connector-j</artifactId>
276-
<version>9.2.0</version>
277-
<scope>runtime</scope>
278-
</dependency>
279-
280279
<dependency>
281280
<groupId>com.oracle.database.jdbc</groupId>
282281
<artifactId>ojdbc11-production</artifactId>

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public class DataStoreConfiguration
2222
private Integer queryHistoryHoursRetention = 4;
2323
private boolean runMigrationsEnabled = true;
2424

25+
// TODO: Refactor to decouple DataStoreConfiguration from a specific
26+
// database implementation after adopting the Airlift configuration framework (https://github.com/trinodb/trino-gateway/issues/378)
27+
private MysqlConfiguration mysqlConfiguration = new MysqlConfiguration();
28+
2529
public DataStoreConfiguration(String jdbcUrl, String user, String password, String driver, Integer queryHistoryHoursRetention, boolean runMigrationsEnabled)
2630
{
2731
this.jdbcUrl = jdbcUrl;
@@ -93,4 +97,14 @@ public void setRunMigrationsEnabled(boolean runMigrationsEnabled)
9397
{
9498
this.runMigrationsEnabled = runMigrationsEnabled;
9599
}
100+
101+
public MysqlConfiguration getMysqlConfiguration()
102+
{
103+
return mysqlConfiguration;
104+
}
105+
106+
public void setMysqlConfiguration(MysqlConfiguration mysqlConfig)
107+
{
108+
this.mysqlConfiguration = mysqlConfig;
109+
}
96110
}

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/QueryCountBasedRouterProvider.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,27 @@
1414
package io.trino.gateway.ha.module;
1515

1616
import com.google.inject.Provides;
17+
import com.google.inject.Singleton;
1718
import io.trino.gateway.ha.config.HaGatewayConfiguration;
19+
import io.trino.gateway.ha.router.GatewayBackendManager;
1820
import io.trino.gateway.ha.router.QueryCountBasedRouter;
21+
import io.trino.gateway.ha.router.QueryHistoryManager;
1922
import io.trino.gateway.ha.router.RoutingManager;
2023

2124
public class QueryCountBasedRouterProvider
2225
extends RouterBaseModule
2326
{
24-
private final QueryCountBasedRouter routingManager;
25-
2627
public QueryCountBasedRouterProvider(HaGatewayConfiguration configuration)
2728
{
2829
super(configuration);
29-
routingManager = new QueryCountBasedRouter(gatewayBackendManager, queryHistoryManager);
3030
}
3131

3232
@Provides
33-
public RoutingManager getRoutingManager()
33+
@Singleton
34+
public RoutingManager provideRoutingManager(
35+
GatewayBackendManager gatewayBackendManager,
36+
QueryHistoryManager queryHistoryManager)
3437
{
35-
return this.routingManager;
38+
return new QueryCountBasedRouter(gatewayBackendManager, queryHistoryManager);
3639
}
3740
}

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

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,76 @@
1515

1616
import com.google.inject.AbstractModule;
1717
import com.google.inject.Provides;
18+
import com.google.inject.Singleton;
19+
import com.google.inject.TypeLiteral;
20+
import io.trino.gateway.ha.config.DataStoreConfiguration;
1821
import io.trino.gateway.ha.config.HaGatewayConfiguration;
22+
import io.trino.gateway.ha.persistence.BasicJdbcPropertiesProvider;
1923
import io.trino.gateway.ha.persistence.JdbcConnectionManager;
24+
import io.trino.gateway.ha.persistence.JdbcPropertiesProvider;
25+
import io.trino.gateway.ha.persistence.JdbcPropertiesProviderFactory;
26+
import io.trino.gateway.ha.persistence.MySqlJdbcPropertiesProvider;
2027
import io.trino.gateway.ha.router.GatewayBackendManager;
2128
import io.trino.gateway.ha.router.HaGatewayManager;
2229
import io.trino.gateway.ha.router.HaQueryHistoryManager;
2330
import io.trino.gateway.ha.router.HaResourceGroupsManager;
2431
import io.trino.gateway.ha.router.QueryHistoryManager;
2532
import io.trino.gateway.ha.router.ResourceGroupsManager;
2633
import org.jdbi.v3.core.Jdbi;
34+
import org.jdbi.v3.sqlobject.SqlObjectPlugin;
35+
36+
import java.util.List;
37+
import java.util.Properties;
2738

2839
public class RouterBaseModule
2940
extends AbstractModule
3041
{
31-
final ResourceGroupsManager resourceGroupsManager;
32-
final GatewayBackendManager gatewayBackendManager;
33-
final QueryHistoryManager queryHistoryManager;
34-
final JdbcConnectionManager connectionManager;
42+
private final HaGatewayConfiguration configuration;
3543

3644
public RouterBaseModule(HaGatewayConfiguration configuration)
3745
{
38-
Jdbi jdbi = Jdbi.create(configuration.getDataStore().getJdbcUrl(), configuration.getDataStore().getUser(), configuration.getDataStore().getPassword());
39-
connectionManager = new JdbcConnectionManager(jdbi, configuration.getDataStore());
40-
resourceGroupsManager = new HaResourceGroupsManager(connectionManager);
41-
gatewayBackendManager = new HaGatewayManager(jdbi);
42-
queryHistoryManager = new HaQueryHistoryManager(jdbi, configuration.getDataStore().getJdbcUrl().startsWith("jdbc:oracle"));
46+
this.configuration = configuration;
4347
}
4448

45-
@Provides
46-
public JdbcConnectionManager getConnectionManager()
49+
@Override
50+
protected void configure()
4751
{
48-
return this.connectionManager;
49-
}
52+
bind(HaGatewayConfiguration.class).toInstance(configuration);
53+
bind(DataStoreConfiguration.class)
54+
.toInstance(configuration.getDataStore());
5055

51-
@Provides
52-
public ResourceGroupsManager getResourceGroupsManager()
53-
{
54-
return this.resourceGroupsManager;
56+
bind(ResourceGroupsManager.class).to(HaResourceGroupsManager.class);
57+
bind(GatewayBackendManager.class).to(HaGatewayManager.class);
58+
bind(QueryHistoryManager.class).to(HaQueryHistoryManager.class);
59+
60+
bind(new TypeLiteral<List<JdbcPropertiesProvider>>() {}).toInstance(List.of(
61+
new MySqlJdbcPropertiesProvider(),
62+
new BasicJdbcPropertiesProvider()));
63+
64+
bind(JdbcPropertiesProviderFactory.class).in(Singleton.class);
5565
}
5666

5767
@Provides
58-
public GatewayBackendManager getGatewayBackendManager()
68+
@Singleton
69+
public Jdbi provideJdbi(
70+
DataStoreConfiguration configuration,
71+
JdbcPropertiesProviderFactory providerFactory)
5972
{
60-
return this.gatewayBackendManager;
73+
Properties props = providerFactory
74+
.forConfig(configuration)
75+
.getProperties(configuration);
76+
Jdbi jdbi = Jdbi.create(configuration.getJdbcUrl(), props);
77+
jdbi.installPlugin(new SqlObjectPlugin());
78+
return jdbi;
6179
}
6280

6381
@Provides
64-
public QueryHistoryManager getQueryHistoryManager()
82+
@Singleton
83+
public JdbcConnectionManager provideConnectionManager(
84+
Jdbi jdbi,
85+
DataStoreConfiguration configuration,
86+
JdbcPropertiesProviderFactory providerFactory)
6587
{
66-
return this.queryHistoryManager;
88+
return new JdbcConnectionManager(jdbi, configuration, providerFactory.forConfig(configuration));
6789
}
6890
}

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,34 @@
1414
package io.trino.gateway.ha.module;
1515

1616
import com.google.inject.Provides;
17+
import com.google.inject.Singleton;
1718
import io.trino.gateway.ha.config.HaGatewayConfiguration;
19+
import io.trino.gateway.ha.router.GatewayBackendManager;
20+
import io.trino.gateway.ha.router.QueryHistoryManager;
1821
import io.trino.gateway.ha.router.RoutingManager;
1922
import io.trino.gateway.ha.router.StochasticRoutingManager;
2023

2124
public class StochasticRoutingManagerProvider
2225
extends RouterBaseModule
2326
{
24-
private final StochasticRoutingManager routingManager;
25-
2627
public StochasticRoutingManagerProvider(HaGatewayConfiguration configuration)
2728
{
2829
super(configuration);
29-
routingManager = new StochasticRoutingManager(gatewayBackendManager, queryHistoryManager);
3030
}
3131

3232
@Provides
33-
public StochasticRoutingManager getHaRoutingManager()
33+
@Singleton
34+
public StochasticRoutingManager provideStochasticRoutingManager(
35+
GatewayBackendManager gatewayBackendManager,
36+
QueryHistoryManager queryHistoryManager)
3437
{
35-
return this.routingManager;
38+
return new StochasticRoutingManager(gatewayBackendManager, queryHistoryManager);
3639
}
3740

3841
@Provides
39-
public RoutingManager getRoutingManager()
42+
@Singleton
43+
public RoutingManager provideRoutingManager(StochasticRoutingManager routingManager)
4044
{
41-
return getHaRoutingManager();
45+
return routingManager;
4246
}
4347
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
public class BasicJdbcPropertiesProvider
21+
implements JdbcPropertiesProvider
22+
{
23+
@Override
24+
public boolean supports(DataStoreConfiguration configuration)
25+
{
26+
return true;
27+
}
28+
29+
@Override
30+
public Properties getProperties(DataStoreConfiguration configuration)
31+
{
32+
Properties props = new Properties();
33+
props.setProperty("user", configuration.getUser());
34+
props.setProperty("password", configuration.getPassword());
35+
return props;
36+
}
37+
}

0 commit comments

Comments
 (0)