From ddf02b02ab0a69cb9458e0887f79b6f7daee9a0b Mon Sep 17 00:00:00 2001 From: nmihajlovski Date: Thu, 30 Mar 2017 16:43:22 +0200 Subject: [PATCH] Replaced the ConnectionPool API by javax.sql.DataSource. --- .../src/main/resources/rapidoid-classes.txt | 6 +- .../org/rapidoid/jdbc/JDBCPoolC3P0Test.java | 7 +- .../org/rapidoid/jdbc/JDBCPoolHikariTest.java | 10 ++- .../org/rapidoid/jdbc/C3P0ConnectionPool.java | 83 ------------------- .../{ConnectionPool.java => C3P0Factory.java} | 28 +++++-- .../rapidoid/jdbc/HikariConnectionPool.java | 79 ------------------ ...ConnectionPool.java => HikariFactory.java} | 30 +++---- .../java/org/rapidoid/jdbc/JdbcClient.java | 81 +++++++++++------- .../java/org/rapidoid/sql/test/JDBCTest.java | 8 +- 9 files changed, 105 insertions(+), 227 deletions(-) delete mode 100644 rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0ConnectionPool.java rename rapidoid-sql/src/main/java/org/rapidoid/jdbc/{ConnectionPool.java => C3P0Factory.java} (55%) delete mode 100644 rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariConnectionPool.java rename rapidoid-sql/src/main/java/org/rapidoid/jdbc/{NoConnectionPool.java => HikariFactory.java} (61%) diff --git a/rapidoid-commons/src/main/resources/rapidoid-classes.txt b/rapidoid-commons/src/main/resources/rapidoid-classes.txt index 79d68660b3..99fd6d9a80 100644 --- a/rapidoid-commons/src/main/resources/rapidoid-classes.txt +++ b/rapidoid-commons/src/main/resources/rapidoid-classes.txt @@ -528,14 +528,12 @@ org.rapidoid.io.watch.Watch org.rapidoid.io.watch.WatcherThread org.rapidoid.io.watch.WatchingRefresherThread org.rapidoid.io.watch.WatchModule -org.rapidoid.jdbc.C3P0ConnectionPool -org.rapidoid.jdbc.ConnectionPool -org.rapidoid.jdbc.HikariConnectionPool +org.rapidoid.jdbc.C3P0Factory +org.rapidoid.jdbc.HikariFactory org.rapidoid.jdbc.JDBC org.rapidoid.jdbc.JdbcClient org.rapidoid.jdbc.JdbcData org.rapidoid.jdbc.JdbcUtil -org.rapidoid.jdbc.NoConnectionPool org.rapidoid.jdbc.ReadWriteMode org.rapidoid.jdbc.SQLModule org.rapidoid.job.CallbackExecutorJob diff --git a/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolC3P0Test.java b/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolC3P0Test.java index 58717e227e..4a82a1ee55 100644 --- a/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolC3P0Test.java +++ b/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolC3P0Test.java @@ -40,8 +40,8 @@ public void testJDBCPoolC3P0() { JDBC.h2("test1"); - C3P0ConnectionPool pool = (C3P0ConnectionPool) JDBC.api().init().pool(); - ComboPooledDataSource c3p0 = pool.pool(); + JdbcClient jdbc = JDBC.api().init(); + ComboPooledDataSource c3p0 = (ComboPooledDataSource) jdbc.dataSource(); // validate default config eq(c3p0.getMinPoolSize(), 5); @@ -73,8 +73,7 @@ public void testJDBCWithTextConfig() { JdbcClient jdbc = JDBC.api(); eq(jdbc.driver(), "org.h2.Driver"); - C3P0ConnectionPool pool = (C3P0ConnectionPool) JDBC.api().init().pool(); - ComboPooledDataSource c3p0 = pool.pool(); + ComboPooledDataSource c3p0 = (ComboPooledDataSource) jdbc.init().dataSource(); eq(c3p0.getMinPoolSize(), 5); eq(c3p0.getMaxPoolSize(), 123); diff --git a/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolHikariTest.java b/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolHikariTest.java index 9a5874e134..31d13dc1d6 100644 --- a/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolHikariTest.java +++ b/rapidoid-integration-tests/src/test/java/org/rapidoid/jdbc/JDBCPoolHikariTest.java @@ -20,9 +20,11 @@ * #L% */ +import com.zaxxer.hikari.HikariDataSource; import org.junit.Test; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.config.Conf; import org.rapidoid.http.IsolatedIntegrationTest; import org.rapidoid.u.U; import org.rapidoid.util.Msc; @@ -36,9 +38,11 @@ public class JDBCPoolHikariTest extends IsolatedIntegrationTest { @Test(timeout = 30000) public void testHikariPool() { + Conf.HIKARI.set("maximumPoolSize", 234); + JdbcClient jdbc = JDBC.api(); jdbc.h2("hikari-test"); - jdbc.pool(new HikariConnectionPool(jdbc)); + jdbc.dataSource(HikariFactory.createDataSourceFor(jdbc)); jdbc.execute("create table abc (id int, name varchar)"); jdbc.execute("insert into abc values (?, ?)", 123, "xyz"); @@ -51,7 +55,9 @@ record = Msc.lowercase(record); eq(record, expected); }); - isTrue(jdbc.pool() instanceof HikariConnectionPool); + HikariDataSource hikari = (HikariDataSource) jdbc.dataSource(); + + eq(hikari.getMaximumPoolSize(), 234); } } diff --git a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0ConnectionPool.java b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0ConnectionPool.java deleted file mode 100644 index 2ca73c00a6..0000000000 --- a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0ConnectionPool.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.rapidoid.jdbc; - -import com.mchange.v2.c3p0.ComboPooledDataSource; -import org.rapidoid.RapidoidThing; -import org.rapidoid.annotation.Authors; -import org.rapidoid.annotation.Since; -import org.rapidoid.config.Conf; -import org.rapidoid.u.U; - -import java.beans.PropertyVetoException; -import java.sql.Connection; -import java.sql.SQLException; - -/* - * #%L - * rapidoid-sql - * %% - * Copyright (C) 2014 - 2017 Nikolche Mihajlovski and contributors - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -@Authors("Nikolche Mihajlovski") -@Since("4.1.0") -public class C3P0ConnectionPool extends RapidoidThing implements ConnectionPool { - - private final ComboPooledDataSource pool = new ComboPooledDataSource(); - - public C3P0ConnectionPool(String jdbcUrl, String driverClass, String username, String password) { - init(jdbcUrl, driverClass, username, password); - } - - public C3P0ConnectionPool(JdbcClient jdbc) { - this(jdbc.url(), jdbc.driver(), jdbc.username(), jdbc.password()); - jdbc.pool(this); - } - - private void init(String jdbcUrl, String driverClass, String username, String password) { - - try { - pool.setDriverClass(driverClass); - } catch (PropertyVetoException e) { - throw U.rte("Cannot load JDBC driver!", e); - } - - pool.setJdbcUrl(jdbcUrl); - pool.setUser(username); - pool.setPassword(password); - - Conf.C3P0.applyTo(pool); - } - - @Override - public Connection getConnection(String jdbcUrl) throws SQLException { - U.must(U.eq(jdbcUrl, pool.getJdbcUrl()), "The JDBC URLs don't match: '%s' and '%s'!", jdbcUrl, pool.getJdbcUrl()); - return pool.getConnection(); - } - - @Override - public Connection getConnection(String jdbcUrl, String username, String password) throws SQLException { - return pool.getConnection(username, password); - } - - @Override - public void releaseConnection(Connection connection) throws SQLException { - connection.close(); - } - - public ComboPooledDataSource pool() { - return pool; - } -} diff --git a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/ConnectionPool.java b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0Factory.java similarity index 55% rename from rapidoid-sql/src/main/java/org/rapidoid/jdbc/ConnectionPool.java rename to rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0Factory.java index 5f0cd4e71d..e3a9c2b1c6 100644 --- a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/ConnectionPool.java +++ b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/C3P0Factory.java @@ -1,10 +1,14 @@ package org.rapidoid.jdbc; +import com.mchange.v2.c3p0.ComboPooledDataSource; +import org.rapidoid.RapidoidThing; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.config.Conf; +import org.rapidoid.u.U; -import java.sql.Connection; -import java.sql.SQLException; +import javax.sql.DataSource; +import java.beans.PropertyVetoException; /* * #%L @@ -28,12 +32,24 @@ @Authors("Nikolche Mihajlovski") @Since("4.1.0") -public interface ConnectionPool { +public class C3P0Factory extends RapidoidThing { - Connection getConnection(String jdbcUrl) throws SQLException; + public static DataSource createDataSourceFor(JdbcClient jdbc) { + ComboPooledDataSource pool = new ComboPooledDataSource(); - Connection getConnection(String jdbcUrl, String username, String password) throws SQLException; + pool.setJdbcUrl(jdbc.url()); + pool.setUser(jdbc.username()); + pool.setPassword(jdbc.password()); - void releaseConnection(Connection connection) throws SQLException; + try { + pool.setDriverClass(jdbc.driver()); + } catch (PropertyVetoException e) { + throw U.rte("Cannot load JDBC driver!", e); + } + + Conf.C3P0.applyTo(pool); + + return pool; + } } diff --git a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariConnectionPool.java b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariConnectionPool.java deleted file mode 100644 index d2003b8a04..0000000000 --- a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariConnectionPool.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.rapidoid.jdbc; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import org.rapidoid.RapidoidThing; -import org.rapidoid.annotation.Authors; -import org.rapidoid.annotation.Since; -import org.rapidoid.config.Conf; - -import java.sql.Connection; -import java.sql.SQLException; - -/* - * #%L - * rapidoid-sql - * %% - * Copyright (C) 2014 - 2017 Nikolche Mihajlovski and contributors - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -@Authors("Nikolche Mihajlovski") -@Since("5.3.4") -public class HikariConnectionPool extends RapidoidThing implements ConnectionPool { - - private final HikariDataSource pool; - - public HikariConnectionPool(String jdbcUrl, String driverClass, String username, String password) { - this.pool = init(jdbcUrl, driverClass, username, password); - } - - public HikariConnectionPool(JdbcClient jdbc) { - this(jdbc.url(), jdbc.driver(), jdbc.username(), jdbc.password()); - jdbc.pool(this); - } - - private HikariDataSource init(String jdbcUrl, String driverClass, String username, String password) { - HikariConfig config = new HikariConfig(); - - config.setJdbcUrl(jdbcUrl); - config.setUsername(username); - config.setPassword(password); - config.setDriverClassName(driverClass); - - Conf.HIKARI.applyTo(config); - - return new HikariDataSource(config); - } - - @Override - public Connection getConnection(String jdbcUrl) throws SQLException { - return pool.getConnection(); - } - - @Override - public Connection getConnection(String jdbcUrl, String username, String password) throws SQLException { - return pool.getConnection(username, password); - } - - @Override - public void releaseConnection(Connection connection) throws SQLException { - connection.close(); - } - - public HikariDataSource pool() { - return pool; - } -} diff --git a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/NoConnectionPool.java b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariFactory.java similarity index 61% rename from rapidoid-sql/src/main/java/org/rapidoid/jdbc/NoConnectionPool.java rename to rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariFactory.java index 8e528b1091..740056bf19 100644 --- a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/NoConnectionPool.java +++ b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/HikariFactory.java @@ -1,11 +1,13 @@ package org.rapidoid.jdbc; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; import org.rapidoid.RapidoidThing; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.config.Conf; -import java.sql.Connection; -import java.sql.SQLException; +import javax.sql.DataSource; /* * #%L @@ -28,22 +30,20 @@ */ @Authors("Nikolche Mihajlovski") -@Since("4.1.0") -public class NoConnectionPool extends RapidoidThing implements ConnectionPool { +@Since("5.3.4") +public class HikariFactory extends RapidoidThing { - @Override - public Connection getConnection(String jdbcUrl) throws SQLException { - return null; - } + public static DataSource createDataSourceFor(JdbcClient jdbc) { + HikariConfig config = new HikariConfig(); - @Override - public Connection getConnection(String jdbcUrl, String username, String password) throws SQLException { - return null; - } + config.setJdbcUrl(jdbc.url()); + config.setUsername(jdbc.username()); + config.setPassword(jdbc.password()); + config.setDriverClassName(jdbc.driver()); + + Conf.HIKARI.applyTo(config); - @Override - public void releaseConnection(Connection connection) throws SQLException { - connection.close(); + return new HikariDataSource(config); } } diff --git a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/JdbcClient.java b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/JdbcClient.java index b68450b6bd..7a8a9ba0b3 100644 --- a/rapidoid-sql/src/main/java/org/rapidoid/jdbc/JdbcClient.java +++ b/rapidoid-sql/src/main/java/org/rapidoid/jdbc/JdbcClient.java @@ -16,6 +16,7 @@ import org.rapidoid.util.Msc; import org.rapidoid.util.MscOpts; +import javax.sql.DataSource; import java.sql.*; import java.util.List; import java.util.Map; @@ -53,7 +54,7 @@ public class JdbcClient extends AutoManageable { private volatile String url; private volatile boolean usePool = true; - private volatile ConnectionPool pool; + private volatile DataSource dataSource; private volatile ReadWriteMode mode = ReadWriteMode.READ_WRITE; @@ -114,10 +115,18 @@ public synchronized JdbcClient driver(String driver) { return this; } - public synchronized JdbcClient pool(ConnectionPool pool) { - if (U.neq(this.pool, pool)) { - this.pool = pool; - this.usePool = pool != null; + /** + * Use dataSource(...) instead. + */ + @Deprecated + public synchronized JdbcClient pool(DataSource pool) { + return dataSource(pool); + } + + public synchronized JdbcClient dataSource(DataSource dataSource) { + if (U.neq(this.dataSource, dataSource)) { + this.dataSource = dataSource; + this.usePool = dataSource != null; this.initialized = false; } return this; @@ -193,21 +202,21 @@ private synchronized void ensureIsInitialized() { validate(); registerJDBCDriver(); - String maskedPassword = U.isEmpty(password) ? "" : ""; - Log.info("Initialized JDBC API", "!url", url, "!driver", driver, "!username", username, "!password", maskedPassword); - - if (pool == null) { - pool = usePool ? createPool() : new NoConnectionPool(); + if (this.dataSource == null) { + this.dataSource = this.usePool ? createPool() : null; } + String maskedPassword = U.isEmpty(password) ? "" : ""; + Log.info("Initialized JDBC API", "!url", url, "!driver", driver, "!username", username, "!password", maskedPassword, "!dataSource", dataSource); + initialized = true; } } - private ConnectionPool createPool() { + private DataSource createPool() { - if (MscOpts.hasC3P0()) return new C3P0ConnectionPool(this); - if (MscOpts.hasHikari()) return new HikariConnectionPool(this); + if (MscOpts.hasC3P0()) return C3P0Factory.createDataSourceFor(this); + if (MscOpts.hasHikari()) return HikariFactory.createDataSourceFor(this); throw U.rte("Cannot create JDBC connection pool, couldn't find Hikari nor C3P0!"); } @@ -398,33 +407,35 @@ public Results> query(String sql, Map namedArgs) private Connection provideConnection() { try { - Connection conn; + if (dataSource != null) { - if (username != null) { - String pass = U.safe(password); - conn = pool.getConnection(url); + Connection conn = dataSource.getConnection(); + U.notNull(conn, "JDBC connection"); + return conn; - if (conn == null) { - conn = DriverManager.getConnection(url, username, pass); - } } else { - conn = pool.getConnection(url); - - if (conn == null) { - conn = DriverManager.getConnection(url); - } + U.must(!usePool, "Expecting connection pool, but the data source is null!"); + return getConnectionFromDriver(); } - return conn; - } catch (SQLException e) { throw U.rte("Cannot create JDBC connection!", e); } } + private Connection getConnectionFromDriver() throws SQLException { + if (username != null) { + String pass = U.safe(password); + return DriverManager.getConnection(url, username, pass); + + } else { + return DriverManager.getConnection(url); + } + } + public void release(Connection connection) { try { - pool.releaseConnection(connection); + connection.close(); } catch (SQLException e) { Log.error("Error while releasing a JDBC connection!", e); } @@ -446,8 +457,16 @@ public String url() { return url; } - public ConnectionPool pool() { - return pool; + /** + * Use dataSource() instead. + */ + @Deprecated + public DataSource pool() { + return dataSource(); + } + + public DataSource dataSource() { + return dataSource; } public boolean usePool() { @@ -472,7 +491,7 @@ public String toString() { ", driver='" + driver + '\'' + ", url='" + url + '\'' + ", usePool=" + usePool + - ", pool=" + pool + + ", pool=" + dataSource + ", mode=" + mode + '}'; } diff --git a/rapidoid-sql/src/test/java/org/rapidoid/sql/test/JDBCTest.java b/rapidoid-sql/src/test/java/org/rapidoid/sql/test/JDBCTest.java index d53c062ef0..a6583328d0 100644 --- a/rapidoid-sql/src/test/java/org/rapidoid/sql/test/JDBCTest.java +++ b/rapidoid-sql/src/test/java/org/rapidoid/sql/test/JDBCTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.jdbc.C3P0ConnectionPool; +import org.rapidoid.jdbc.C3P0Factory; import org.rapidoid.jdbc.JDBC; import org.rapidoid.jdbc.JdbcClient; import org.rapidoid.u.U; @@ -58,7 +58,8 @@ public void testWithH2() { @Test public void testWithH2AndC3P0() { - new C3P0ConnectionPool(JDBC.h2("test")); + JdbcClient jdbc = JDBC.h2("test"); + jdbc.dataSource(C3P0Factory.createDataSourceFor(jdbc)); insertAndCheckData(JDBC.api()); } @@ -71,7 +72,8 @@ public void testWithHSQLDB() { @Test public void testWithHSQLDBAndC3P0() { - new C3P0ConnectionPool(JDBC.hsql("test")); + JdbcClient jdbc = JDBC.hsql("test"); + jdbc.dataSource(C3P0Factory.createDataSourceFor(jdbc)); insertAndCheckData(JDBC.api()); }