BAEL-3340: Guide to FlexyPool (#13867)

* fix: correct log4j config

* fix: correct antrun plugin config

* feat: guide to flexypool

See https://jira.baeldung.com/browse/BAEL-3340

* fix(lint): format project

* fix(lint): format pom.xml

* fix(lint): format pom.xml
This commit is contained in:
Chrys Exaucet 2023-04-25 02:41:48 +00:00 committed by GitHub
parent 178782aebf
commit 087561956f
4 changed files with 186 additions and 1 deletions

View File

@ -1 +1,4 @@
log4j.rootLogger=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.logger.org.datanucleus=DEBUG

View File

@ -115,6 +115,24 @@
<artifactId>mysql</artifactId>
<version>${testcontainers-version}</version>
</dependency>
<!-- flexypool -->
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-micrometer-metrics</artifactId>
<version>${flexy-pool.version}</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-hikaricp</artifactId>
<version>${flexy-pool.version}</version>
<exclusions>
<exclusion>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-dropwizard-metrics</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Core dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -147,6 +165,7 @@
<plugins>
<!-- Reladomo -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven-antrun-plugin.version}</version>
<executions>
@ -284,6 +303,7 @@
<HikariCP.version>5.0.1</HikariCP.version>
<ebean.version>13.15.2</ebean.version>
<debezium.version>2.1.3.Final</debezium.version>
<flexy-pool.version>2.2.3</flexy-pool.version>
<testcontainers-version>1.17.6</testcontainers-version>
</properties>

View File

@ -0,0 +1,109 @@
package com.baeldung.libraries.flexypool;
import com.vladmihalcea.flexypool.FlexyPoolDataSource;
import com.vladmihalcea.flexypool.adaptor.HikariCPPoolAdapter;
import com.vladmihalcea.flexypool.config.Configuration;
import com.vladmihalcea.flexypool.connection.ConnectionDecoratorFactoryResolver;
import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeThresholdExceededEvent;
import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeoutEvent;
import com.vladmihalcea.flexypool.event.ConnectionLeaseTimeThresholdExceededEvent;
import com.vladmihalcea.flexypool.event.EventListener;
import com.vladmihalcea.flexypool.metric.micrometer.MicrometerMetrics;
import com.vladmihalcea.flexypool.strategy.IncrementPoolOnTimeoutConnectionAcquiringStrategy;
import com.vladmihalcea.flexypool.strategy.RetryConnectionAcquiringStrategy;
import com.vladmihalcea.flexypool.strategy.UniqueNamingStrategy;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@org.springframework.context.annotation.Configuration
public class FlexypoolConfig {
@SuppressWarnings("unchecked")
@Bean(initMethod = "start", destroyMethod = "stop")
public FlexyPoolDataSource<HikariDataSource> flexypoolDataSource() {
Configuration<HikariDataSource> configuration = flexypoolConfiguration();
return new FlexyPoolDataSource<>(configuration, new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Factory<>(5), new RetryConnectionAcquiringStrategy.Factory<>(2));
}
@Bean
public Configuration<HikariDataSource> flexypoolConfiguration() {
HikariDataSource dataSource = hikariDataSource();
return new Configuration.Builder<>(UUID.randomUUID().toString(), dataSource, HikariCPPoolAdapter.FACTORY).setMetricsFactory(MicrometerMetrics::new)
.setConnectionProxyFactory(ConnectionDecoratorFactoryResolver.INSTANCE.resolve())
.setMetricLogReporterMillis(TimeUnit.SECONDS.toMillis(5))
.setMetricNamingUniqueName(UniqueNamingStrategy.INSTANCE)
.setJmxEnabled(true)
.setJmxAutoStart(true)
.setConnectionAcquireTimeThresholdMillis(50L)
.setConnectionLeaseTimeThresholdMillis(250L)
.setEventListenerResolver(() -> Arrays.asList(new ConnectionAcquireTimeoutEventListener(), new ConnectionAcquireTimeThresholdExceededEventListener(), new ConnectionLeaseTimeThresholdExceededEventListener()))
.build();
}
@Bean
public HikariDataSource hikariDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'");
config.setUsername("");
config.setPassword("");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("minimumPoolSize", "1");
config.addDataSourceProperty("maximumPoolSize", "3");
config.addDataSourceProperty("connectionTimeout", "1000");
return new HikariDataSource(config);
}
}
class ConnectionAcquireTimeThresholdExceededEventListener extends EventListener<ConnectionAcquireTimeThresholdExceededEvent> {
public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeThresholdExceededEventListener.class);
public ConnectionAcquireTimeThresholdExceededEventListener() {
super(ConnectionAcquireTimeThresholdExceededEvent.class);
}
@Override
public void on(ConnectionAcquireTimeThresholdExceededEvent event) {
LOGGER.info("ConnectionAcquireTimeThresholdExceededEvent Caught event {}", event);
}
}
class ConnectionLeaseTimeThresholdExceededEventListener extends EventListener<ConnectionLeaseTimeThresholdExceededEvent> {
public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionLeaseTimeThresholdExceededEventListener.class);
public ConnectionLeaseTimeThresholdExceededEventListener() {
super(ConnectionLeaseTimeThresholdExceededEvent.class);
}
@Override
public void on(ConnectionLeaseTimeThresholdExceededEvent event) {
LOGGER.info("ConnectionLeaseTimeThresholdExceededEvent Caught event {}", event);
}
}
class ConnectionAcquireTimeoutEventListener extends EventListener<ConnectionAcquireTimeoutEvent> {
public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeoutEventListener.class);
public ConnectionAcquireTimeoutEventListener() {
super(ConnectionAcquireTimeoutEvent.class);
}
@Override
public void on(ConnectionAcquireTimeoutEvent event) {
LOGGER.info("ConnectionAcquireTimeoutEvent Caught event {}", event);
}
}

View File

@ -0,0 +1,53 @@
package com.baeldung.libraries.flexypool;
import com.baeldung.libraries.hikaricp.Employee;
import com.vladmihalcea.flexypool.FlexyPoolDataSource;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class FlexypoolDemoApplication {
private static FlexyPoolDataSource<HikariDataSource> poolDataSource;
public FlexypoolDemoApplication(FlexyPoolDataSource<HikariDataSource> poolDataSource) {
FlexypoolDemoApplication.poolDataSource = poolDataSource;
}
public static List<Employee> getEmployees() throws SQLException {
String SQL_QUERY = "select * from emp";
List<Employee> employees;
try (Connection con = poolDataSource.getConnection(); PreparedStatement pst = con.prepareStatement(SQL_QUERY); ResultSet rs = pst.executeQuery();) {
employees = new ArrayList<>();
Employee employee;
while (rs.next()) {
employee = new Employee();
employee.setEmpNo(rs.getInt("empno"));
employee.setEname(rs.getString("ename"));
employee.setJob(rs.getString("job"));
employee.setMgr(rs.getInt("mgr"));
employee.setHiredate(rs.getDate("hiredate"));
employee.setSal(rs.getInt("sal"));
employee.setComm(rs.getInt("comm"));
employee.setDeptno(rs.getInt("deptno"));
employees.add(employee);
}
}
return employees;
}
public static void main(String[] args) throws SQLException {
SpringApplication.run(FlexypoolDemoApplication.class, args);
List<Employee> employees = getEmployees();
System.out.println(employees);
}
}