/** * Configures the connection pool * * @return true if the connection pool was setup correctly, false otherwise * @since 4.0.6 */ boolean configureConnPool() { YamlConfiguration config = SettingsManager.getInstance().getConfig(); try { Class.forName("com.mysql.jdbc.Driver"); //also you need the MySQL driver plugin.getLogger().info("Creating HikariCP Configuration..."); HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setJdbcUrl(config.getString("stats.database.address")); hikariConfig.setUsername(config.getString("stats.database.user")); hikariConfig.setPassword(config.getString("stats.database.password")); hikariConfig.setMaximumPoolSize(config.getInt("stats.database.maximum-pool-size")); plugin.getLogger().info("Setting up MySQL Connection pool..."); connectionPool = new HikariPool(hikariConfig); // setup the connection pool plugin.getLogger().info("Connection pool successfully configured. "); } catch (ClassNotFoundException e) { plugin.getLogger().info("Connection failed! Returning to file stats."); e.printStackTrace(); //you should use exception wrapping on real-production code return false; } return true; }
@Test public void testDerbyDataSource() throws SQLException { BQRuntime runtime = testFactory.app("-c", "classpath:HikariCPDerbyIT.yml") .autoLoadModules() .createRuntime(); DataSource ds4 = runtime.getInstance(DataSourceFactory.class).forName("derby4"); assertNotNull(ds4); assertTrue(ds4 instanceof HikariDataSource); HikariDataSource hikariDS = (HikariDataSource) ds4; assertEquals("org.apache.derby.jdbc.EmbeddedDataSource", hikariDS.getDataSourceClassName()); HikariPool pool = (HikariPool) hikariDS.getHikariPoolMXBean(); assertTrue(pool.getUnwrappedDataSource().getClass().isAssignableFrom(EmbeddedDataSource.class)); try (Connection c = hikariDS.getConnection()) { assertEquals("jdbc:derby:target/derby4", c.getMetaData().getURL()); } }
@Test public void testDerbyDriverDataSource() throws SQLException { BQRuntime runtime = testFactory.app("-c", "classpath:HikariCPDerbyIT.yml") .autoLoadModules() .createRuntime(); DataSource ds5 = runtime.getInstance(DataSourceFactory.class).forName("derby5"); assertNotNull(ds5); assertTrue(ds5 instanceof HikariDataSource); HikariDataSource hikariDS = (HikariDataSource) ds5; assertEquals("org.apache.derby.jdbc.EmbeddedDriver", hikariDS.getDriverClassName()); HikariPool pool = (HikariPool) hikariDS.getHikariPoolMXBean(); assertTrue(pool.getUnwrappedDataSource() instanceof DriverDataSource); try (Connection c = hikariDS.getConnection()) { assertEquals("jdbc:derby:", c.getMetaData().getURL()); } }
public void list() { System.out.print(String.format("%1$15s", "DataSource")); System.out.print(String.format("%1$15s", "Max Cn")); System.out.print(String.format("%1$15s", "Active Cn")); System.out.print(String.format("%1$15s", "Free Cn")); System.out.print(String.format("%1$15s", "Cn Wait")); System.out.print("\n"); for (Map.Entry<String, HikariDataSource> entry : dbMap.entrySet()) { HikariPool pool = getPool(entry.getValue()); int totalConnections = pool.getTotalConnections(); int activeConnections = pool.getActiveConnections(); int freeConnections = totalConnections - activeConnections; int connectionWaiting = pool.getThreadsAwaitingConnection(); System.out.print(String.format("%1$15s", entry.getKey())); System.out.print(String.format("%1$15s", totalConnections)); System.out.print(String.format("%1$15s", activeConnections)); System.out.print(String.format("%1$15s", freeConnections)); System.out.print(String.format("%1$15s", connectionWaiting)); System.out.print("\n"); } }
private HikariCpConfig(final JsonObject config) { final HikariConfig hikariConfig = new HikariConfig(); // Init hikariCp, refer to offical site // https://github.com/brettwooldridge/HikariCP hikariConfig.setDriverClassName(config.getString("driverClassName")); hikariConfig.setJdbcUrl(config.getString("jdbcUrl")); hikariConfig.setUsername(config.getString("username")); hikariConfig.setPassword(config.getString("password")); hikariConfig.setCatalog(config.getString("catalog")); // Init data source final HikariDataSource dataSource = new HikariDataSource(hikariConfig); this.pool = new HikariPool(dataSource); }
/** * Attempts to create a {@link HikariDataSource} by making an initial connection to the database. * Retries a number of times, with a delay between each retry, according to the provided {@link PatterdaleRuntimeParameters}. * * Failed attempts are logged as well as when the number of retries has exceeded. * * @param runtimeParams The app configuration defined in `patterdale.yml`. * @param databaseDefinition The details of the database being connected to. * @param passwords The separate store of passwords, the matching password will be found according to the `databaseDefinition`. * @param logger to log. * @return A data source for a successful connection to the database. */ public static HikariDataSource retriableDataSource(PatterdaleRuntimeParameters runtimeParams, DatabaseDefinition databaseDefinition, Passwords passwords, Logger logger) { RetryPolicy retryPolicy = new RetryPolicy() .retryOn(HikariPool.PoolInitializationException.class) .withDelay(runtimeParams.connectionRetryDelayInSeconds(), TimeUnit.SECONDS) .withMaxRetries(runtimeParams.maxConnectionRetries()); return Failsafe.with(retryPolicy) .onRetry((result, failure, context) -> logRetry(runtimeParams, databaseDefinition, logger)) .onFailedAttempt((result, failure, context) -> logFailedAttempt(databaseDefinition, logger)) .onRetriesExceeded(throwable -> logRetriesExceeded(databaseDefinition, logger)) .get(() -> dataSource(runtimeParams, databaseDefinition, passwords, logger)); }
/** * Construct a HikariDataSource with the specified configuration. * * @param configuration a HikariConfig instance */ public HikariDataSource(HikariConfig configuration) { configuration.validate(); configuration.copyState(this); LOGGER.info("{} - is starting.", configuration.getPoolName()); pool = fastPathPool = new HikariPool(this); }
/** {@inheritDoc} */ @Override public Connection getConnection() throws SQLException { if (isClosed()) { throw new SQLException("HikariDataSource " + this + " has been closed."); } if (fastPathPool != null) { return fastPathPool.getConnection(); } // See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java HikariPool result = pool; if (result == null) { synchronized (this) { result = pool; if (result == null) { validate(); LOGGER.info("{} - is starting.", getPoolName()); pool = result = new HikariPool(this); } } } return result.getConnection(); }
@Test public void testShutdown2() throws SQLException { Assert.assertSame("StubConnection count not as expected", 0, StubConnection.count.get()); StubConnection.slowCreate = true; HikariConfig config = new HikariConfig(); config.setMinimumIdle(10); config.setMaximumPoolSize(10); config.setInitializationFailFast(true); config.setConnectionTestQuery("VALUES 1"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); HikariDataSource ds = new HikariDataSource(config); HikariPool pool = TestElf.getPool(ds); UtilityElf.quietlySleep(1200L); Assert.assertTrue("Totals connection count not as expected, ", pool.getTotalConnections() > 0); ds.close(); Assert.assertSame("Active connection count not as expected, ", 0, pool.getActiveConnections()); Assert.assertSame("Idle connection count not as expected, ", 0, pool.getIdleConnections()); Assert.assertSame("Total connection count not as expected", 0, pool.getTotalConnections()); Assert.assertTrue(ds.toString().startsWith("HikariDataSource (") && ds.toString().endsWith(")")); }
@Test public void testShutdown3() throws SQLException { Assert.assertSame("StubConnection count not as expected", 0, StubConnection.count.get()); StubConnection.slowCreate = false; HikariConfig config = new HikariConfig(); config.setMinimumIdle(5); config.setMaximumPoolSize(5); config.setInitializationFailFast(true); config.setConnectionTestQuery("VALUES 1"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); HikariDataSource ds = new HikariDataSource(config); HikariPool pool = TestElf.getPool(ds); UtilityElf.quietlySleep(1200L); Assert.assertTrue("Totals connection count not as expected, ", pool.getTotalConnections() == 5); ds.close(); Assert.assertSame("Active connection count not as expected, ", 0, pool.getActiveConnections()); Assert.assertSame("Idle connection count not as expected, ", 0, pool.getIdleConnections()); Assert.assertSame("Total connection count not as expected", 0, pool.getTotalConnections()); }
@Test public void testShutdown5() throws SQLException { Assert.assertSame("StubConnection count not as expected", 0, StubConnection.count.get()); HikariConfig config = new HikariConfig(); config.setMinimumIdle(5); config.setMaximumPoolSize(5); config.setInitializationFailFast(true); config.setConnectionTestQuery("VALUES 1"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); HikariDataSource ds = new HikariDataSource(config); HikariPool pool = TestElf.getPool(ds); Connection[] connections = new Connection[5]; for (int i = 0; i < 5; i++) { connections[i] = ds.getConnection(); } Assert.assertTrue("Totals connection count not as expected, ", pool.getTotalConnections() == 5); ds.close(); Assert.assertSame("Active connection count not as expected, ", 0, pool.getActiveConnections()); Assert.assertSame("Idle connection count not as expected, ", 0, pool.getIdleConnections()); Assert.assertSame("Total connection count not as expected", 0, pool.getTotalConnections()); }
@Test public void testLeakDetection() throws SQLException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos, true); TestElf.setSlf4jTargetStream(LeakTask.class, ps); HikariConfig config = new HikariConfig(); config.setMinimumIdle(0); config.setMaximumPoolSize(4); config.setPoolName("test"); config.setThreadFactory(Executors.defaultThreadFactory()); config.setMetricRegistry(null); config.setLeakDetectionThreshold(TimeUnit.SECONDS.toMillis(1)); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); TestElf.setConfigUnitTest(true); final HikariDataSource ds = new HikariDataSource(config); try { TestElf.setSlf4jLogLevel(HikariPool.class, LocationAwareLogger.DEBUG_INT); TestElf.getPool(ds).logPoolState(); Connection connection = ds.getConnection(); UtilityElf.quietlySleep(TimeUnit.SECONDS.toMillis(4)); connection.close(); UtilityElf.quietlySleep(TimeUnit.SECONDS.toMillis(1)); ps.close(); String s = new String(baos.toByteArray()); Assert.assertNotNull("Exception string was null", s); Assert.assertTrue("Expected exception to contain 'Apparent connection leak detected' but contains *" + s + "*", s.contains("Apparent connection leak detected")); } finally { TestElf.setConfigUnitTest(false); ds.close(); } }
public static HikariPool getPool(HikariDataSource ds) { try { Field field = ds.getClass().getDeclaredField("pool"); field.setAccessible(true); return (HikariPool) field.get(ds); } catch (Exception e) { throw new RuntimeException(e); } }
@SuppressWarnings("unchecked") public static HashMap<Object, HikariPool> getMultiPool(HikariDataSource ds) { try { Field field = ds.getClass().getDeclaredField("multiPool"); field.setAccessible(true); return (HashMap<Object, HikariPool>) field.get(ds); } catch (Exception e) { throw new RuntimeException(e); } }
public HikariPool getPool(HikariDataSource ds) { try { Field field = ds.getClass().getDeclaredField("pool"); field.setAccessible(true); return (HikariPool) field.get(ds); } catch (Exception e) { throw new RuntimeException(e); } }
public VoteStorage initializeVoteStorage() throws IOException { String storage = configuration.getString("storage.database"); if (!SUPPORTED_STORAGE.contains(storage)) { SuperbVote.getPlugin().getLogger().info("Storage method '" + storage + "' is not valid, using JSON storage."); storage = "json"; } switch (storage) { case "json": String file = configuration.getString("storage.json.file"); if (file == null) { file = "votes.json"; SuperbVote.getPlugin().getLogger().info("No file found in configuration, using 'votes.json'."); } return new JsonVoteStorage(new File(SuperbVote.getPlugin().getDataFolder(), file)); case "mysql": String host = configuration.getString("storage.mysql.host", "localhost"); int port = configuration.getInt("storage.mysql.port", 3306); String username = configuration.getString("storage.mysql.username", "root"); String password = configuration.getString("storage.mysql.password", ""); String database = configuration.getString("storage.mysql.database", "superbvote"); String table = configuration.getString("storage.mysql.table", "superbvote"); boolean readOnly = configuration.getBoolean("storage.mysql.read-only"); HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database); config.setUsername(username); config.setPassword(password); config.setMinimumIdle(2); config.setMaximumPoolSize(6); HikariPool pool = new HikariPool(config); MysqlVoteStorage mysqlVoteStorage = new MysqlVoteStorage(pool, table, readOnly); mysqlVoteStorage.initialize(); return mysqlVoteStorage; } return null; }
@Inject public MySQLDatabase(Reflector reflector, ModuleManager mm, FileManager fm, LogFactory logFactory) { this.mm = mm; this.mm.registerBinding(Database.class, this); File pluginFolder = mm.getBasePath(); // Disable HikariPool Debug ConsoleSpam ((Logger)LogManager.getLogger(HikariPool.class)).setLevel(Level.INFO); ((Logger)LogManager.getLogger("com.zaxxer.hikari.pool.PoolBase")).setLevel(Level.INFO); // really? now pkg-private ((Logger)LogManager.getLogger(HikariConfig.class)).setLevel(Level.INFO); // Setting up Logger... this.logger = mm.getLoggerFor(Database.class); AsyncFileTarget target = new AsyncFileTarget.Builder(LoggingUtil.getLogFile(fm, "Database").toPath(), LoggingUtil.getFileFormat(true, false) ).setAppend(true).setCycler(LoggingUtil.getCycler()).setThreadFactory(threadFactory).build(); target.setLevel(LogLevel.DEBUG); logger.addTarget(target); LogTarget parentTarget = logger.addDelegate(logFactory.getLog(LogFactory.class)); parentTarget.appendFilter(new PrefixFilter("[DB] ")); parentTarget.setLevel(LogLevel.INFO); this.config = reflector.load(MySQLDatabaseConfiguration.class, new File(pluginFolder, "database.yml")); }
public HikariPool getPool() { return this.pool; }
private HikariPool getHikariPool() { return (HikariPool) new DirectFieldAccessor(getDataSource()) .getPropertyValue("pool"); }
ConnectivityHealthCheck(final HikariPool pool, final long checkTimeoutMs) { this.pool = pool; this.checkTimeoutMs = (checkTimeoutMs > 0 && checkTimeoutMs != Integer.MAX_VALUE ? checkTimeoutMs : TimeUnit.SECONDS.toMillis(10)); }
@Test public void testShutdown1() throws SQLException { Assert.assertSame("StubConnection count not as expected", 0, StubConnection.count.get()); StubConnection.slowCreate = true; HikariConfig config = new HikariConfig(); config.setMinimumIdle(0); config.setMaximumPoolSize(10); config.setInitializationFailFast(false); config.setConnectionTestQuery("VALUES 1"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); final HikariDataSource ds = new HikariDataSource(config); HikariPool pool = TestElf.getPool(ds); Thread[] threads = new Thread[10]; for (int i = 0; i < 10; i++) { threads[i] = new Thread() { public void run() { try { if (ds.getConnection() != null) { UtilityElf.quietlySleep(TimeUnit.SECONDS.toMillis(1)); } } catch (SQLException e) { } } }; threads[i].setDaemon(true); threads[i].start(); } UtilityElf.quietlySleep(1200L); Assert.assertTrue("Totals connection count not as expected, ", pool.getTotalConnections() > 0); ds.close(); Assert.assertSame("Active connection count not as expected, ", 0, pool.getActiveConnections()); Assert.assertSame("Idle connection count not as expected, ", 0, pool.getIdleConnections()); Assert.assertSame("Total connection count not as expected", 0, pool.getTotalConnections()); Assert.assertTrue(ds.isClosed()); }
@Test public void testSuspendResume() throws Exception { HikariConfig config = new HikariConfig(); config.setMinimumIdle(3); config.setMaximumPoolSize(3); config.setAllowPoolSuspension(true); config.setConnectionTestQuery("VALUES 1"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); TestElf.setSlf4jLogLevel(HikariPool.class, LocationAwareLogger.DEBUG_INT); final HikariDataSource ds = new HikariDataSource(config); try { HikariPool pool = TestElf.getPool(ds); while (pool.getTotalConnections() < 3) { quietlySleep(50); } Thread t = new Thread(new Runnable() { public void run() { try { ds.getConnection(); ds.getConnection(); } catch (Exception e) { Assert.fail(); } } }); Connection c3 = ds.getConnection(); Assert.assertEquals(2, pool.getIdleConnections()); pool.suspendPool(); t.start(); quietlySleep(500); Assert.assertEquals(2, pool.getIdleConnections()); c3.close(); Assert.assertEquals(3, pool.getIdleConnections()); pool.resumePool(); quietlySleep(500); Assert.assertEquals(1, pool.getIdleConnections()); } finally { ds.close(); } }