Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add jdbc config if connections should be flushed when returning to the pool #20657

Merged
merged 1 commit into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.sql.SQLException;
Expand Down Expand Up @@ -60,6 +61,7 @@ private static void testDataSource(AgroalDataSource dataSource, String username,
agroalConnectionFactoryConfiguration.jdbcTransactionIsolation());
assertTrue(agroalConnectionFactoryConfiguration.trackJdbcResources());
assertTrue(dataSource.getConfiguration().metricsEnabled());
assertFalse(configuration.flushOnClose());
assertEquals(newConnectionSql, agroalConnectionFactoryConfiguration.initialSql());
assertThat(agroalConnectionFactoryConfiguration.jdbcProperties())
.contains(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.quarkus.agroal.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.sql.Connection;
import java.sql.SQLException;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.jboss.logging.Logger;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.agroal.api.AgroalDataSource;
import io.agroal.api.AgroalPoolInterceptor;
import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
import io.quarkus.test.QuarkusUnitTest;

class FlushOnCloseDataSourceConfigTest {

private static final Logger LOGGER = Logger.getLogger(FlushOnCloseDataSourceConfigTest.class);

@Inject
AgroalDataSource defaultDataSource;

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addClasses(FlushOnCloseDataSourceConfigTest.class)
.addClasses(ClientUserTrackerInterceptor.class))
.withConfigurationResource("base.properties")
// Setting Compatibility MODE to MySQL to enable all the client-info properties on the connection
.overrideConfigKey("quarkus.datasource.jdbc.url", "jdbc:h2:tcp://localhost/mem:flushing;MODE=MySQL")
.overrideConfigKey("quarkus.datasource.jdbc.min-size", "1")
.overrideConfigKey("quarkus.datasource.jdbc.initial-size", "1")
.overrideConfigKey("quarkus.datasource.jdbc.max-size", "2")
.overrideConfigKey("quarkus.datasource.jdbc.flush-on-close", "true");

@Test
void testFlushOnCloseDataSourceConnection() throws SQLException {
AgroalConnectionPoolConfiguration configuration = defaultDataSource.getConfiguration().connectionPoolConfiguration();

assertTrue(configuration.flushOnClose());

try (Connection connection = defaultDataSource.getConnection()) {
connection.setClientInfo("ClientUser", "1");
connection.prepareStatement("SELECT 1").executeQuery();
try (Connection conn2 = defaultDataSource.getConnection()) {
conn2.setClientInfo("ClientUser", "2");
conn2.prepareStatement("SELECT 1").executeQuery();
}
}

try (Connection connection = defaultDataSource.getConnection()) {
assertEquals("1", connection.getClientInfo("ClientUser"));
try (Connection conn2 = defaultDataSource.getConnection()) {
// new connection should not contain any mark ClientUser
assertNull(conn2.getClientInfo("ClientUser"));
}
}
}

@Singleton
static class ClientUserTrackerInterceptor implements AgroalPoolInterceptor {

@Override
public void onConnectionAcquire(Connection connection) {
try {
LOGGER.info("connection acquired ClientUser:" + connection.getClientInfo("ClientUser"));
} catch (SQLException e) {
Assertions.fail(e);
}
}

@Override
public void onConnectionReturn(Connection connection) {
try {
// Connection marked "ClientUser:2" must not return to the pool.
assertNotEquals("2", connection.getClientInfo("ClientUser"));
LOGGER.info("connection returned ClientUser:" + connection.getClientInfo("ClientUser"));
} catch (SQLException e) {
Assertions.fail(e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ public class DataSourceJdbcRuntimeConfig {
@ConfigItem
public boolean extendedLeakReport;

/**
* Allows connections to be flushed upon return to the pool. It's not enabled by default.
*/
@ConfigItem
public boolean flushOnClose;

/**
* When enabled Agroal will be able to produce a warning when a connection is returned
* to the pool without the application having closed all open statements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ public boolean isValid(Connection connection) {
poolConfiguration.transactionRequirement(dataSourceJdbcRuntimeConfig.transactionRequirement.get());
}
poolConfiguration.enhancedLeakReport(dataSourceJdbcRuntimeConfig.extendedLeakReport);
poolConfiguration.flushOnClose(dataSourceJdbcRuntimeConfig.flushOnClose);
}

public DataSourceBuildTimeConfig getDataSourceBuildTimeConfig(String dataSourceName) {
Expand Down