Skip to content

Commit 98d8c84

Browse files
committed
misc various test addition
* Datasource now implements ConnectionPoolDataSource
1 parent c9cdb0d commit 98d8c84

File tree

12 files changed

+514
-93
lines changed

12 files changed

+514
-93
lines changed

src/main/java/org/mariadb/jdbc/Configuration.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ public static Configuration parse(final String url) throws SQLException {
356356
* @throws SQLException if parsing exception occur
357357
*/
358358
public static Configuration parse(final String url, Properties prop) throws SQLException {
359-
if (url != null && url.startsWith("jdbc:mariadb:")) {
359+
if (acceptsUrl(url)) {
360360
return parseInternal(url, (prop == null) ? new Properties() : prop);
361361
}
362362
return null;
@@ -487,11 +487,8 @@ private static void mapPropertiesToOption(Builder builder, Properties properties
487487
}
488488
}
489489

490-
} catch (IllegalAccessException n) {
491-
n.printStackTrace();
492-
} catch (SecurityException s) {
493-
// only for jws, so never thrown
494-
throw new IllegalArgumentException("Security too restrictive : " + s.getMessage());
490+
} catch (IllegalAccessException | SecurityException s) {
491+
throw new IllegalArgumentException("Unexpected error", s);
495492
}
496493
builder._nonMappedOptions = nonMappedOptions;
497494
}

src/main/java/org/mariadb/jdbc/Driver.java

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,40 +103,37 @@ public boolean acceptsURL(String url) {
103103
* @throws SQLException if there is a problem getting the property info
104104
*/
105105
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
106-
if (url != null && !url.isEmpty()) {
107-
Configuration conf = Configuration.parse(url, info);
108-
if (conf == null) {
109-
return new DriverPropertyInfo[0];
110-
}
106+
Configuration conf = Configuration.parse(url, info);
107+
if (conf == null) {
108+
return new DriverPropertyInfo[0];
109+
}
111110

112-
Properties propDesc = new Properties();
113-
try (InputStream inputStream =
114-
Driver.class.getClassLoader().getResourceAsStream("driver.properties")) {
115-
propDesc.load(inputStream);
116-
} catch (IOException io) {
117-
// eat
118-
}
111+
Properties propDesc = new Properties();
112+
try (InputStream inputStream =
113+
Driver.class.getClassLoader().getResourceAsStream("driver.properties")) {
114+
propDesc.load(inputStream);
115+
} catch (IOException io) {
116+
// eat
117+
}
119118

120-
List<DriverPropertyInfo> props = new ArrayList<>();
121-
for (Field field : Configuration.Builder.class.getDeclaredFields()) {
122-
if (!field.getName().startsWith("_")) {
123-
try {
124-
Field fieldConf = Configuration.class.getDeclaredField(field.getName());
125-
fieldConf.setAccessible(true);
126-
Object obj = fieldConf.get(conf);
127-
String value = obj == null ? null : obj.toString();
128-
DriverPropertyInfo propertyInfo = new DriverPropertyInfo(field.getName(), value);
129-
propertyInfo.description = value == null ? "" : (String) propDesc.get(field.getName());
130-
propertyInfo.required = false;
131-
props.add(propertyInfo);
132-
} catch (IllegalAccessException | NoSuchFieldException e) {
133-
// eat error
134-
}
119+
List<DriverPropertyInfo> props = new ArrayList<>();
120+
for (Field field : Configuration.Builder.class.getDeclaredFields()) {
121+
if (!field.getName().startsWith("_")) {
122+
try {
123+
Field fieldConf = Configuration.class.getDeclaredField(field.getName());
124+
fieldConf.setAccessible(true);
125+
Object obj = fieldConf.get(conf);
126+
String value = obj == null ? null : obj.toString();
127+
DriverPropertyInfo propertyInfo = new DriverPropertyInfo(field.getName(), value);
128+
propertyInfo.description = value == null ? "" : (String) propDesc.get(field.getName());
129+
propertyInfo.required = false;
130+
props.add(propertyInfo);
131+
} catch (IllegalAccessException | NoSuchFieldException e) {
132+
// eat error
135133
}
136134
}
137-
return props.toArray(new DriverPropertyInfo[0]);
138135
}
139-
return new DriverPropertyInfo[0];
136+
return props.toArray(new DriverPropertyInfo[0]);
140137
}
141138

142139
/**

src/main/java/org/mariadb/jdbc/MariaDbDataSource.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1+
/*
2+
* MariaDB Client for Java
3+
*
4+
* Copyright (c) 2012-2014 Monty Program Ab.
5+
* Copyright (c) 2015-2020 MariaDB Corporation Ab.
6+
*
7+
* This library is free software; you can redistribute it and/or modify it under
8+
* the terms of the GNU Lesser General Public License as published by the Free
9+
* Software Foundation; either version 2.1 of the License, or (at your option)
10+
* any later version.
11+
*
12+
* This library is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15+
* for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License along
18+
* with this library; if not, write to Monty Program Ab info@montyprogram.com.
19+
*
20+
*/
21+
122
package org.mariadb.jdbc;
223

324
import java.io.PrintWriter;
425
import java.sql.*;
526
import java.sql.Connection;
627
import java.util.logging.Logger;
28+
import javax.sql.ConnectionPoolDataSource;
729
import javax.sql.DataSource;
30+
import javax.sql.PooledConnection;
831

9-
public class MariaDbDataSource implements DataSource {
32+
public class MariaDbDataSource implements DataSource, ConnectionPoolDataSource {
1033

1134
private final Configuration conf;
1235

@@ -158,4 +181,20 @@ public void setLoginTimeout(int seconds) {
158181
public Logger getParentLogger() {
159182
return null;
160183
}
184+
185+
@Override
186+
public PooledConnection getPooledConnection() throws SQLException {
187+
return Driver.connect(conf);
188+
}
189+
190+
@Override
191+
public PooledConnection getPooledConnection(String username, String password)
192+
throws SQLException {
193+
try {
194+
Configuration conf = this.conf.clone(username, password);
195+
return Driver.connect(conf);
196+
} catch (CloneNotSupportedException cloneNotSupportedException) {
197+
throw new SQLException(cloneNotSupportedException);
198+
}
199+
}
161200
}

src/main/java/org/mariadb/jdbc/client/MultiPrimaryClient.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class MultiPrimaryClient implements Client {
5555
private static final Logger logger = Loggers.getLogger(MultiPrimaryClient.class);
5656

5757
protected static final ConcurrentMap<HostAddress, Long> denyList = new ConcurrentHashMap<>();
58-
protected static final long DENY_TIMEOUT = 60_000L;
58+
protected long deniedListTimeout;
5959
protected final Configuration conf;
6060
protected boolean closed = false;
6161
protected final ReentrantLock lock;
@@ -64,6 +64,8 @@ public class MultiPrimaryClient implements Client {
6464
public MultiPrimaryClient(Configuration conf, ReentrantLock lock) throws SQLException {
6565
this.conf = conf;
6666
this.lock = lock;
67+
deniedListTimeout =
68+
Long.parseLong(conf.nonMappedOptions().getProperty("deniedListTimeout", "60000"));
6769
currentClient = connectHost(false, false);
6870
}
6971

@@ -92,12 +94,16 @@ protected Client connectHost(boolean readOnly, boolean failFast) throws SQLExcep
9294
: new ClientImpl(conf, host.get(), lock, false);
9395
} catch (SQLNonTransientConnectionException sqle) {
9496
lastSqle = sqle;
95-
denyList.putIfAbsent(host.get(), System.currentTimeMillis() + DENY_TIMEOUT);
97+
denyList.putIfAbsent(host.get(), System.currentTimeMillis() + deniedListTimeout);
9698
maxRetries--;
9799
}
98100
}
99101

100-
if (failFast) throw lastSqle;
102+
if (failFast) {
103+
throw (lastSqle != null)
104+
? lastSqle
105+
: new SQLNonTransientConnectionException("No host not blacklisted");
106+
}
101107

102108
// All server corresponding to type are in deny list
103109
// return the one with lower denylist timeout
@@ -123,7 +129,7 @@ protected Client connectHost(boolean readOnly, boolean failFast) throws SQLExcep
123129
lastSqle = sqle;
124130
host.ifPresent(
125131
hostAddress ->
126-
denyList.putIfAbsent(hostAddress, System.currentTimeMillis() + DENY_TIMEOUT));
132+
denyList.putIfAbsent(hostAddress, System.currentTimeMillis() + deniedListTimeout));
127133
maxRetries--;
128134
if (maxRetries > 0) {
129135
try {
@@ -141,7 +147,8 @@ protected Client connectHost(boolean readOnly, boolean failFast) throws SQLExcep
141147

142148
protected void reConnect() throws SQLException {
143149

144-
denyList.putIfAbsent(currentClient.getHostAddress(), System.currentTimeMillis() + DENY_TIMEOUT);
150+
denyList.putIfAbsent(
151+
currentClient.getHostAddress(), System.currentTimeMillis() + deniedListTimeout);
145152
logger.info("Connection error on {}", currentClient.getHostAddress());
146153
try {
147154
Client oldClient = currentClient;

src/main/java/org/mariadb/jdbc/client/MultiPrimaryReplicaClient.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
*/
4949
public class MultiPrimaryReplicaClient extends MultiPrimaryClient {
5050
private static final Logger logger = Loggers.getLogger(MultiPrimaryReplicaClient.class);
51-
protected static final long NEXT_TRY_TIMEOUT = 30_000L;
51+
protected long waitTimeout;
5252
private Client replicaClient;
5353
private Client primaryClient;
5454
private boolean requestReadOnly;
@@ -58,12 +58,13 @@ public class MultiPrimaryReplicaClient extends MultiPrimaryClient {
5858
public MultiPrimaryReplicaClient(Configuration conf, ReentrantLock lock) throws SQLException {
5959
super(conf, lock);
6060
primaryClient = currentClient;
61-
61+
waitTimeout =
62+
Long.parseLong(conf.nonMappedOptions().getProperty("waitReconnectTimeout", "30000"));
6263
try {
6364
replicaClient = connectHost(true, false);
6465
} catch (SQLException e) {
6566
replicaClient = null;
66-
nextTryReplica = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
67+
nextTryReplica = System.currentTimeMillis() + waitTimeout;
6768
}
6869
}
6970

@@ -76,7 +77,7 @@ private void reconnectIfNeeded() {
7677
primaryClient = connectHost(false, true);
7778
nextTryPrimary = -1;
7879
} catch (SQLException e) {
79-
nextTryPrimary = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
80+
nextTryPrimary = System.currentTimeMillis() + waitTimeout;
8081
}
8182
}
8283

@@ -90,7 +91,7 @@ private void reconnectIfNeeded() {
9091
currentClient = replicaClient;
9192
}
9293
} catch (SQLException e) {
93-
nextTryReplica = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
94+
nextTryReplica = System.currentTimeMillis() + waitTimeout;
9495
}
9596
}
9697
}
@@ -107,7 +108,8 @@ private void reconnectIfNeeded() {
107108
*/
108109
@Override
109110
protected void reConnect() throws SQLException {
110-
denyList.putIfAbsent(currentClient.getHostAddress(), System.currentTimeMillis() + DENY_TIMEOUT);
111+
denyList.putIfAbsent(
112+
currentClient.getHostAddress(), System.currentTimeMillis() + deniedListTimeout);
111113
logger.info("Connection error on {}", currentClient.getHostAddress());
112114
try {
113115
Client oldClient = currentClient;
@@ -132,7 +134,7 @@ protected void reConnect() throws SQLException {
132134

133135
} catch (SQLNonTransientConnectionException e) {
134136
if (requestReadOnly) {
135-
nextTryReplica = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
137+
nextTryReplica = System.currentTimeMillis() + waitTimeout;
136138
if (primaryClient != null) {
137139
// connector will use primary client until some replica is up
138140
currentClient = primaryClient;
@@ -270,12 +272,12 @@ public void close() throws SQLException {
270272
}
271273
closed = true;
272274
try {
273-
primaryClient.close();
275+
if (primaryClient != null) primaryClient.close();
274276
} catch (SQLException e) {
275277
// eat
276278
}
277279
try {
278-
replicaClient.close();
280+
if (replicaClient != null) replicaClient.close();
279281
} catch (SQLException e) {
280282
// eat
281283
}
@@ -299,7 +301,7 @@ public void setReadOnly(boolean readOnly) throws SQLException {
299301
currentClient = replicaClient;
300302
syncNewState(primaryClient);
301303
} catch (SQLException e) {
302-
nextTryReplica = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
304+
nextTryReplica = System.currentTimeMillis() + waitTimeout;
303305
}
304306
}
305307
}
@@ -314,7 +316,7 @@ public void setReadOnly(boolean readOnly) throws SQLException {
314316
primaryClient = connectHost(false, false);
315317
nextTryPrimary = -1;
316318
} catch (SQLException e) {
317-
nextTryPrimary = System.currentTimeMillis() + NEXT_TRY_TIMEOUT;
319+
nextTryPrimary = System.currentTimeMillis() + waitTimeout;
318320
throw new SQLNonTransientConnectionException(
319321
"Driver has failed to reconnect a primary connection", "08000");
320322
}

src/test/java/org/mariadb/jdbc/Common.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.sql.SQLException;
3131
import java.time.Duration;
3232
import java.time.Instant;
33+
import java.util.Locale;
3334
import java.util.Optional;
3435
import java.util.Properties;
3536
import org.junit.jupiter.api.*;
@@ -121,7 +122,9 @@ public Connection createProxyCon(HaMode mode, String opts) throws SQLException {
121122

122123
String url = mDefUrl.replaceAll("//([^/]*)/", "//localhost:" + proxy.getLocalPort() + "/");
123124
if (mode != HaMode.NONE) {
124-
url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:sequential:");
125+
url =
126+
url.replaceAll(
127+
"jdbc:mariadb:", "jdbc:mariadb:" + mode.name().toLowerCase(Locale.ROOT) + ":");
125128
}
126129
if (conf.sslMode() == SslMode.VERIFY_FULL) {
127130
url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");

0 commit comments

Comments
 (0)