|
1 | 1 | package com.openblocks.plugin.mssql; |
2 | 2 |
|
3 | | -import static com.openblocks.sdk.exception.PluginCommonError.DATASOURCE_ARGUMENT_ERROR; |
4 | | -import static com.openblocks.sdk.exception.PluginCommonError.DATASOURCE_TIMEOUT_ERROR; |
5 | | -import static com.openblocks.sdk.exception.PluginCommonError.QUERY_EXECUTION_ERROR; |
6 | | -import static com.openblocks.sdk.plugin.common.QueryExecutionUtils.querySharedScheduler; |
7 | 3 | import static org.apache.commons.lang3.StringUtils.isNotBlank; |
8 | 4 |
|
9 | | -import java.time.Duration; |
10 | | -import java.util.HashSet; |
11 | | -import java.util.Set; |
12 | | -import java.util.concurrent.TimeUnit; |
13 | | -import java.util.concurrent.TimeoutException; |
14 | | -import java.util.function.Supplier; |
15 | | - |
16 | 5 | import org.apache.commons.lang3.StringUtils; |
17 | 6 | import org.pf4j.Extension; |
18 | 7 |
|
19 | 8 | import com.openblocks.plugin.mssql.model.MssqlDatasourceConfig; |
20 | | -import com.openblocks.sdk.config.dynamic.ConfigCenter; |
21 | | -import com.openblocks.sdk.exception.PluginException; |
22 | | -import com.openblocks.sdk.models.DatasourceTestResult; |
23 | | -import com.openblocks.sdk.plugin.common.DatasourceConnector; |
| 9 | +import com.openblocks.plugin.sql.SqlBasedConnector; |
24 | 10 | import com.zaxxer.hikari.HikariConfig; |
25 | | -import com.zaxxer.hikari.HikariDataSource; |
26 | | -import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException; |
27 | | - |
28 | | -import reactor.core.publisher.Mono; |
29 | 11 |
|
30 | 12 | @Extension |
31 | | -public class MssqlConnector implements DatasourceConnector<HikariDataSource, MssqlDatasourceConfig> { |
| 13 | +public class MssqlConnector extends SqlBasedConnector<MssqlDatasourceConfig> { |
32 | 14 | private static final String JDBC_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; |
33 | 15 |
|
34 | | - private static final long LEAK_DETECTION_THRESHOLD_MS = Duration.ofSeconds(30).toMillis(); |
35 | | - private final Supplier<Duration> createConnectionTimeout; |
36 | | - private final Supplier<Long> connectionPoolIdleTimeoutMillis; |
37 | | - private final Supplier<Integer> connectionPoolMaxPoolSize; |
38 | | - |
39 | | - public MssqlConnector(ConfigCenter configCenter) { |
40 | | - this.createConnectionTimeout = configCenter.mysqlPlugin().ofInteger("createConnectionTimeout", 5000) |
41 | | - .then(Duration::ofMillis); |
42 | | - this.connectionPoolMaxPoolSize = configCenter.mysqlPlugin().ofInteger("connectionPoolMaxPoolSize", 50); |
43 | | - this.connectionPoolIdleTimeoutMillis = configCenter.mysqlPlugin().ofInteger("connectionPoolIdleTimeoutMinutes", 6) |
44 | | - .then(Duration::ofMinutes) |
45 | | - .then(Duration::toMillis); |
| 16 | + protected MssqlConnector() { |
| 17 | + super(50); |
46 | 18 | } |
47 | 19 |
|
48 | 20 | @Override |
49 | | - public Set<String> validateConfig(MssqlDatasourceConfig connectionConfig) { |
50 | | - |
51 | | - Set<String> invalids = new HashSet<>(); |
52 | | - |
53 | | - String host = connectionConfig.getHost(); |
54 | | - if (StringUtils.isBlank(host)) { |
55 | | - invalids.add("HOST_EMPTY"); |
56 | | - } |
57 | | - |
58 | | - if (host.contains("/") || host.contains(":")) { |
59 | | - invalids.add("HOST_WITH_COLON"); |
60 | | - } |
61 | | - |
62 | | - if (StringUtils.equalsIgnoreCase(host, "localhost") || StringUtils.equals(host, "127.0.0.1")) { |
63 | | - invalids.add("INVALID_HOST"); |
64 | | - } |
65 | | - |
66 | | - if (StringUtils.isBlank(connectionConfig.getDatabase())) { |
67 | | - invalids.add("DATABASE_NAME_EMPTY"); |
68 | | - } |
69 | | - |
70 | | - return invalids; |
| 21 | + protected String getJdbcDriver() { |
| 22 | + return JDBC_DRIVER; |
71 | 23 | } |
72 | 24 |
|
73 | 25 | @Override |
74 | | - public Mono<HikariDataSource> createConnection(MssqlDatasourceConfig connectionConfig) { |
75 | | - try { |
76 | | - Class.forName(JDBC_DRIVER); |
77 | | - } catch (ClassNotFoundException e) { |
78 | | - return Mono.error(new PluginException(QUERY_EXECUTION_ERROR, "LOAD_SQLSERVER_JDBC_ERROR")); |
79 | | - } |
80 | | - |
81 | | - return Mono.fromSupplier(() -> createHikariDataSource(connectionConfig)) |
82 | | - .timeout(createConnectionTimeout.get()) |
83 | | - .onErrorMap(TimeoutException.class, error -> new PluginException(DATASOURCE_TIMEOUT_ERROR, "DATASOURCE_TIMEOUT_ERROR")) |
84 | | - .onErrorResume(exception -> { |
85 | | - if (exception instanceof PluginException) { |
86 | | - return Mono.error(exception); |
87 | | - } |
88 | | - return Mono.error(new PluginException(DATASOURCE_ARGUMENT_ERROR, "DATASOURCE_ARGUMENT_ERROR", exception.getMessage())); |
89 | | - }) |
90 | | - .subscribeOn(querySharedScheduler()); |
91 | | - } |
92 | | - |
93 | | - private HikariDataSource createHikariDataSource(MssqlDatasourceConfig datasourceConfig) throws PluginException { |
94 | | - |
95 | | - HikariConfig config = new HikariConfig(); |
96 | | - config.setDriverClassName(JDBC_DRIVER); |
97 | | - config.setMinimumIdle(1); |
98 | | - config.setMaxLifetime(TimeUnit.HOURS.toMillis(2)); |
99 | | - config.setKeepaliveTime(TimeUnit.MINUTES.toMillis(3)); |
100 | | - config.setIdleTimeout(connectionPoolIdleTimeoutMillis.get()); |
101 | | - config.setMaximumPoolSize(connectionPoolMaxPoolSize.get()); |
102 | | - config.setLeakDetectionThreshold(LEAK_DETECTION_THRESHOLD_MS); |
103 | | - config.setConnectionTimeout(250); |
104 | | - config.setValidationTimeout(TimeUnit.SECONDS.toMillis(3)); |
105 | | - config.setInitializationFailTimeout(TimeUnit.SECONDS.toMillis(4)); |
106 | | - |
| 26 | + protected void setUpConfigs(MssqlDatasourceConfig datasourceConfig, HikariConfig config) { |
107 | 27 | // Set authentication properties |
108 | 28 | String username = datasourceConfig.getUsername(); |
109 | 29 | if (StringUtils.isNotEmpty(username)) { |
@@ -158,40 +78,6 @@ private HikariDataSource createHikariDataSource(MssqlDatasourceConfig datasource |
158 | 78 |
|
159 | 79 | config.setJdbcUrl(urlBuilder.toString()); |
160 | 80 | config.setReadOnly(datasourceConfig.isReadonly()); |
161 | | - |
162 | | - HikariDataSource datasource; |
163 | | - try { |
164 | | - datasource = new HikariDataSource(config); |
165 | | - } catch (PoolInitializationException e) { |
166 | | - throw new PluginException(DATASOURCE_ARGUMENT_ERROR, "DATASOURCE_ARGUMENT_ERROR", e.getMessage()); |
167 | | - } |
168 | | - |
169 | | - return datasource; |
170 | | - } |
171 | | - |
172 | | - @Override |
173 | | - public Mono<Void> destroyConnection(HikariDataSource hikariDataSource) { |
174 | | - return Mono.fromRunnable(() -> { |
175 | | - if (hikariDataSource != null) { |
176 | | - hikariDataSource.close(); |
177 | | - } |
178 | | - }) |
179 | | - .subscribeOn(querySharedScheduler()) |
180 | | - .then(); |
181 | | - } |
182 | | - |
183 | | - @Override |
184 | | - public Mono<DatasourceTestResult> testConnection(MssqlDatasourceConfig connectionConfig) { |
185 | | - return doCreateConnection(connectionConfig) |
186 | | - .map(hikariDataSource -> { |
187 | | - if (hikariDataSource != null) { |
188 | | - hikariDataSource.close(); |
189 | | - } |
190 | | - |
191 | | - return DatasourceTestResult.testSuccess(); |
192 | | - }) |
193 | | - .onErrorResume(error -> Mono.just(DatasourceTestResult.testFail(error))) |
194 | | - .subscribeOn(querySharedScheduler()); |
195 | 81 | } |
196 | 82 |
|
197 | 83 | } |
0 commit comments