Merge pull request #23403 from fabio-grassi-gbs

* pr/23403:
  Polish "Add support for Oracle UCP"
  Add support for Oracle UCP

Closes gh-23403
pull/23540/head
Stephane Nicoll 4 years ago
commit a983fb9559

@ -82,6 +82,8 @@ public class DocumentConfigurationProperties extends DefaultTask {
.withKeyPrefixes("spring.couchbase", "spring.elasticsearch", "spring.h2", "spring.influx",
"spring.mongodb", "spring.neo4j", "spring.redis", "spring.dao", "spring.data",
"spring.datasource", "spring.jooq", "spring.jdbc", "spring.jpa", "spring.r2dbc")
.addOverride("spring.datasource.oracleucp",
"Oracle UCP specific settings bound to an instance of Oracle UCP's PoolDataSource")
.addOverride("spring.datasource.dbcp2",
"Commons DBCP2 specific settings bound to an instance of DBCP2's BasicDataSource")
.addOverride("spring.datasource.tomcat",

@ -24,6 +24,8 @@ dependencies {
optional("com.hazelcast:hazelcast-spring")
optional("com.h2database:h2")
optional("com.nimbusds:oauth2-oidc-sdk")
optional("com.oracle.database.jdbc:ojdbc8")
optional("com.oracle.database.jdbc:ucp")
optional("com.samskivert:jmustache")
optional("com.sun.mail:jakarta.mail")
optional("de.flapdoodle.embed:de.flapdoodle.embed.mongo")

@ -69,8 +69,8 @@ public class DataSourceAutoConfiguration {
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class })
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,9 +16,13 @@
package org.springframework.boot.autoconfigure.jdbc;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource;
import oracle.jdbc.OracleConnection;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -35,6 +39,7 @@ import org.springframework.util.StringUtils;
* @author Dave Syer
* @author Phillip Webb
* @author Stephane Nicoll
* @author Fabio Grassi
*/
abstract class DataSourceConfiguration {
@ -109,6 +114,29 @@ abstract class DataSourceConfiguration {
}
/**
* Oracle UCP DataSource configuration.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ PoolDataSourceImpl.class, OracleConnection.class })
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "oracle.ucp.jdbc.PoolDataSource",
matchIfMissing = true)
static class OracleUcp {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.oracleucp")
PoolDataSourceImpl dataSource(DataSourceProperties properties) throws SQLException {
PoolDataSourceImpl dataSource = createDataSource(properties, PoolDataSourceImpl.class);
dataSource.setValidateConnectionOnBorrow(true);
if (StringUtils.hasText(properties.getName())) {
dataSource.setConnectionPoolName(properties.getName());
}
return dataSource;
}
}
/**
* Generic DataSource configuration.
*/

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,8 @@
package org.springframework.boot.autoconfigure.jdbc.metadata;
import com.zaxxer.hikari.HikariDataSource;
import oracle.jdbc.OracleConnection;
import oracle.ucp.jdbc.PoolDataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -24,6 +26,7 @@ import org.springframework.boot.jdbc.DataSourceUnwrapper;
import org.springframework.boot.jdbc.metadata.CommonsDbcp2DataSourcePoolMetadata;
import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider;
import org.springframework.boot.jdbc.metadata.HikariDataSourcePoolMetadata;
import org.springframework.boot.jdbc.metadata.OracleUcpDataSourcePoolMetadata;
import org.springframework.boot.jdbc.metadata.TomcatDataSourcePoolMetadata;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -33,6 +36,7 @@ import org.springframework.context.annotation.Configuration;
* sources.
*
* @author Stephane Nicoll
* @author Fabio Grassi
* @since 1.2.0
*/
@Configuration(proxyBeanMethods = false)
@ -90,4 +94,21 @@ public class DataSourcePoolMetadataProvidersConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ PoolDataSource.class, OracleConnection.class })
static class OracleUcpPoolDataSourceMetadataProviderConfiguration {
@Bean
DataSourcePoolMetadataProvider oracleUcpPoolDataSourceMetadataProvider() {
return (dataSource) -> {
PoolDataSource ucpDataSource = DataSourceUnwrapper.unwrap(dataSource, PoolDataSource.class);
if (ucpDataSource != null) {
return new OracleUcpDataSourcePoolMetadata(ucpDataSource);
}
return null;
};
}
}
}

@ -34,6 +34,7 @@ import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource;
import io.r2dbc.spi.ConnectionFactory;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.Test;
@ -135,8 +136,25 @@ class DataSourceAutoConfigurationTests {
assertDataSource(org.apache.commons.dbcp2.BasicDataSource.class,
Arrays.asList("com.zaxxer.hikari", "org.apache.tomcat"), (dataSource) -> {
assertThat(dataSource.getTestOnBorrow()).isTrue();
assertThat(dataSource.getValidationQuery()).isNull(); // Use
// Connection#isValid()
// Use Connection#isValid()
assertThat(dataSource.getValidationQuery()).isNull();
});
}
@Test
void oracleUcpIsFallback() {
assertDataSource(PoolDataSourceImpl.class,
Arrays.asList("com.zaxxer.hikari", "org.apache.tomcat", "org.apache.commons.dbcp2"),
(dataSource) -> assertThat(dataSource.getURL()).startsWith("jdbc:hsqldb:mem:testdb"));
}
@Test
void oracleUcpValidatesConnectionByDefault() {
assertDataSource(PoolDataSourceImpl.class,
Arrays.asList("com.zaxxer.hikari", "org.apache.tomcat", "org.apache.commons.dbcp2"), (dataSource) -> {
assertThat(dataSource.getValidateConnectionOnBorrow()).isTrue();
// Use an internal ping when using an Oracle JDBC driver
assertThat(dataSource.getSQLForValidateConnection()).isNull();
});
}
@ -225,8 +243,8 @@ class DataSourceAutoConfigurationTests {
}
private static Function<ApplicationContextRunner, ApplicationContextRunner> hideConnectionPools() {
return (runner) -> runner.withClassLoader(
new FilteredClassLoader("org.apache.tomcat", "com.zaxxer.hikari", "org.apache.commons.dbcp2"));
return (runner) -> runner.withClassLoader(new FilteredClassLoader("org.apache.tomcat", "com.zaxxer.hikari",
"org.apache.commons.dbcp2", "oracle.ucp.jdbc"));
}
private <T extends DataSource> void assertDataSource(Class<T> expectedType, List<String> hiddenPackages,

@ -0,0 +1,108 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* 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
*
* https://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.
*/
package org.springframework.boot.autoconfigure.jdbc;
import java.sql.Connection;
import javax.sql.DataSource;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DataSourceAutoConfiguration} with Oracle UCP.
*
* @author Fabio Grassi
* @author Stephane Nicoll
*/
class OracleUcpDataSourceConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.type=" + PoolDataSource.class.getName());
@Test
void testDataSourceExists() {
this.contextRunner.run((context) -> {
assertThat(context.getBeansOfType(DataSource.class)).hasSize(1);
assertThat(context.getBeansOfType(PoolDataSourceImpl.class)).hasSize(1);
try (Connection connection = context.getBean(DataSource.class).getConnection()) {
assertThat(connection.isValid(1000)).isTrue();
}
});
}
@Test
void testDataSourcePropertiesOverridden() {
this.contextRunner.withPropertyValues("spring.datasource.oracleucp.url=jdbc:foo//bar/spam",
"spring.datasource.oracleucp.max-idle-time=1234").run((context) -> {
PoolDataSourceImpl ds = context.getBean(PoolDataSourceImpl.class);
assertThat(ds.getURL()).isEqualTo("jdbc:foo//bar/spam");
assertThat(ds.getMaxIdleTime()).isEqualTo(1234);
});
}
@Test
void testDataSourceConnectionPropertiesOverridden() {
this.contextRunner.withPropertyValues("spring.datasource.oracleucp.connection-properties.autoCommit=false")
.run((context) -> {
PoolDataSourceImpl ds = context.getBean(PoolDataSourceImpl.class);
assertThat(ds.getConnectionProperty("autoCommit")).isEqualTo("false");
});
}
@Test
void testDataSourceDefaultsPreserved() {
this.contextRunner.run((context) -> {
PoolDataSourceImpl ds = context.getBean(PoolDataSourceImpl.class);
assertThat(ds.getInitialPoolSize()).isEqualTo(0);
assertThat(ds.getMinPoolSize()).isEqualTo(0);
assertThat(ds.getMaxPoolSize()).isEqualTo(Integer.MAX_VALUE);
assertThat(ds.getInactiveConnectionTimeout()).isEqualTo(0);
assertThat(ds.getConnectionWaitTimeout()).isEqualTo(3);
assertThat(ds.getTimeToLiveConnectionTimeout()).isEqualTo(0);
assertThat(ds.getAbandonedConnectionTimeout()).isEqualTo(0);
assertThat(ds.getTimeoutCheckInterval()).isEqualTo(30);
assertThat(ds.getFastConnectionFailoverEnabled()).isFalse();
});
}
@Test
void nameIsAliasedToPoolName() {
this.contextRunner.withPropertyValues("spring.datasource.name=myDS").run((context) -> {
PoolDataSourceImpl ds = context.getBean(PoolDataSourceImpl.class);
assertThat(ds.getConnectionPoolName()).isEqualTo("myDS");
});
}
@Test
void poolNameTakesPrecedenceOverName() {
this.contextRunner.withPropertyValues("spring.datasource.name=myDS",
"spring.datasource.oracleucp.connection-pool-name=myOracleUcpDS").run((context) -> {
PoolDataSourceImpl ds = context.getBean(PoolDataSourceImpl.class);
assertThat(ds.getConnectionPoolName()).isEqualTo("myOracleUcpDS");
});
}
}

@ -105,8 +105,8 @@ class LiquibaseAutoConfigurationTests {
@Test
void createsDataSourceWhenSpringJdbcOnlyAvailableWithNoDataSourceBeanAndLiquibaseUrl() {
this.contextRunner.withPropertyValues("spring.liquibase.url:jdbc:hsqldb:mem:liquibase")
.withClassLoader(
new FilteredClassLoader("org.apache.tomcat", "com.zaxxer.hikari", "org.apache.commons.dbcp2"))
.withClassLoader(new FilteredClassLoader("org.apache.tomcat", "com.zaxxer.hikari",
"org.apache.commons.dbcp2", "oracle.ucp.jdbc"))
.run(assertLiquibase((liquibase) -> {
DataSource dataSource = liquibase.getDataSource();
assertThat(dataSource).isInstanceOf(SimpleDriverDataSource.class);

@ -3826,7 +3826,8 @@ Spring Boot uses the following algorithm for choosing a specific implementation:
. We prefer https://github.com/brettwooldridge/HikariCP[HikariCP] for its performance and concurrency.
If HikariCP is available, we always choose it.
. Otherwise, if the Tomcat pooling `DataSource` is available, we use it.
. If neither HikariCP nor the Tomcat pooling datasource are available and if https://commons.apache.org/proper/commons-dbcp/[Commons DBCP2] is available, we use it.
. Otherwise, if https://commons.apache.org/proper/commons-dbcp/[Commons DBCP2] is available, we use it.
. If none of HikariCP, Tomcat, and DBCP2 are available and if Oracle UCP is available, we use it.
If you use the `spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa` "`starters`", you automatically get a dependency to `HikariCP`.
@ -3857,7 +3858,7 @@ In other words, if you set `spring.datasource.driver-class-name=com.mysql.jdbc.D
See {spring-boot-autoconfigure-module-code}/jdbc/DataSourceProperties.java[`DataSourceProperties`] for more of the supported options.
These are the standard options that work regardless of the actual implementation.
It is also possible to fine-tune implementation-specific settings by using their respective prefix (`+spring.datasource.hikari.*+`, `+spring.datasource.tomcat.*+`, and `+spring.datasource.dbcp2.*+`).
It is also possible to fine-tune implementation-specific settings by using their respective prefix (`+spring.datasource.hikari.*+`, `+spring.datasource.tomcat.*+`, `+spring.datasource.dbcp2.*+`, and `+spring.datasource.oracleucp.*+`).
Refer to the documentation of the connection pool implementation you are using for more details.
For instance, if you use the {tomcat-docs}/jdbc-pool.html#Common_Attributes[Tomcat connection pool], you could customize many additional settings, as shown in the following example:

@ -21,6 +21,7 @@ dependencies {
optional("com.atomikos:transactions-jta")
optional("com.fasterxml.jackson.core:jackson-databind")
optional("com.google.code.gson:gson")
optional("com.oracle.database.jdbc:ucp")
optional("com.samskivert:jmustache")
optional("com.zaxxer:HikariCP")
optional("io.netty:netty-tcnative-boringssl-static")
@ -77,7 +78,7 @@ dependencies {
testImplementation("com.ibm.db2:jcc")
testImplementation("com.jayway.jsonpath:json-path")
testImplementation("com.microsoft.sqlserver:mssql-jdbc")
testImplementation("com.oracle.ojdbc:ojdbc8")
testImplementation("com.oracle.database.jdbc:ojdbc8")
testImplementation("com.squareup.okhttp3:okhttp")
testImplementation("com.sun.xml.messaging.saaj:saaj-impl")
testImplementation("io.projectreactor:reactor-test")

@ -37,16 +37,17 @@ import org.springframework.util.ClassUtils;
/**
* Convenience class for building a {@link DataSource} with common implementations and
* properties. If HikariCP, Tomcat or Commons DBCP are on the classpath one of them will
* be selected (in that order with Hikari first). In the interest of a uniform interface,
* and so that there can be a fallback to an embedded database if one can be detected on
* the classpath, only a small set of common configuration properties are supported. To
* inject additional properties into the result you can downcast it, or use
* properties. If HikariCP, Tomcat, Commons DBCP or Oracle UCP are on the classpath one of
* them will be selected (in that order with Hikari first). In the interest of a uniform
* interface, and so that there can be a fallback to an embedded database if one can be
* detected on the classpath, only a small set of common configuration properties are
* supported. To inject additional properties into the result you can downcast it, or use
* {@code @ConfigurationProperties}.
*
* @param <T> type of DataSource produced by the builder
* @author Dave Syer
* @author Madhura Bhave
* @author Fabio Grassi
* @since 2.0.0
*/
public final class DataSourceBuilder<T extends DataSource> {
@ -166,9 +167,9 @@ public final class DataSourceBuilder<T extends DataSource> {
}
private static class OracleDataSourceSettings extends DataSourceSettings {
private static class OracleCommonDataSourceSettings extends DataSourceSettings {
OracleDataSourceSettings(Class<? extends DataSource> type) {
OracleCommonDataSourceSettings(Class<? extends DataSource> type) {
super(type, (aliases) -> aliases.addAliases("username", "user"));
}
@ -194,7 +195,7 @@ public final class DataSourceBuilder<T extends DataSource> {
(type) -> new DataSourceSettings(type,
(aliases) -> aliases.addAliases("driver-class-name", "driver-class"))));
addIfAvailable(this.allDataSourceSettings, create(classLoader,
"oracle.jdbc.datasource.OracleCommonDataSource", OracleDataSourceSettings::new));
"oracle.jdbc.datasource.OracleCommonDataSource", OracleCommonDataSourceSettings::new));
}
private static List<DataSourceSettings> resolveAvailableDataSourceSettings(ClassLoader classLoader) {
@ -205,6 +206,16 @@ public final class DataSourceBuilder<T extends DataSource> {
create(classLoader, "org.apache.tomcat.jdbc.pool.DataSource", DataSourceSettings::new));
addIfAvailable(providers,
create(classLoader, "org.apache.commons.dbcp2.BasicDataSource", DataSourceSettings::new));
addIfAvailable(providers, create(classLoader, "oracle.ucp.jdbc.PoolDataSourceImpl", (type) -> {
// Unfortunately Oracle UCP has an import on the Oracle driver itself
if (ClassUtils.isPresent("oracle.jdbc.OracleConnection", classLoader)) {
return new DataSourceSettings(type, (aliases) -> {
aliases.addAliases("username", "user");
aliases.addAliases("driver-class-name", "connection-factory-class-name");
});
}
return null;
}));
return providers;
}

@ -0,0 +1,80 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* 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
*
* https://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.
*/
package org.springframework.boot.jdbc.metadata;
import java.sql.SQLException;
import javax.sql.DataSource;
import oracle.ucp.jdbc.PoolDataSource;
import org.springframework.util.StringUtils;
/**
* {@link DataSourcePoolMetadata} for an Oracle UCP {@link DataSource}.
*
* @author Fabio Grassi
* @since 2.4.0
*/
public class OracleUcpDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<PoolDataSource> {
public OracleUcpDataSourcePoolMetadata(PoolDataSource dataSource) {
super(dataSource);
}
@Override
public Integer getActive() {
try {
return getDataSource().getBorrowedConnectionsCount();
}
catch (SQLException ex) {
return null;
}
}
@Override
public Integer getIdle() {
try {
return getDataSource().getAvailableConnectionsCount();
}
catch (SQLException ex) {
return null;
}
}
@Override
public Integer getMax() {
return getDataSource().getMaxPoolSize();
}
@Override
public Integer getMin() {
return getDataSource().getMinPoolSize();
}
@Override
public String getValidationQuery() {
return getDataSource().getSQLForValidateConnection();
}
@Override
public Boolean getDefaultAutoCommit() {
String autoCommit = getDataSource().getConnectionProperty("autoCommit");
return StringUtils.hasText(autoCommit) ? Boolean.valueOf(autoCommit) : null;
}
}

@ -27,6 +27,7 @@ import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource;
import oracle.jdbc.pool.OracleDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import org.apache.commons.dbcp2.BasicDataSource;
import org.h2.Driver;
import org.junit.jupiter.api.AfterEach;
@ -40,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link DataSourceBuilder}.
*
* @author Stephane Nicoll
* @author Fabio Grassi
*/
class DataSourceBuilderTests {
@ -68,13 +70,20 @@ class DataSourceBuilderTests {
}
@Test
void defaultToCommonsDbcp2AsLastResort() {
void defaultToCommonsDbcp2IfNeitherHikariNorTomcatIsNotAvailable() {
this.dataSource = DataSourceBuilder
.create(new HidePackagesClassLoader("com.zaxxer.hikari", "org.apache.tomcat.jdbc.pool"))
.url("jdbc:h2:test").build();
assertThat(this.dataSource).isInstanceOf(BasicDataSource.class);
}
@Test
void defaultToOracleUcpAsLastResort() {
this.dataSource = DataSourceBuilder.create(new HidePackagesClassLoader("com.zaxxer.hikari",
"org.apache.tomcat.jdbc.pool", "org.apache.commons.dbcp2")).url("jdbc:h2:test").build();
assertThat(this.dataSource).isInstanceOf(PoolDataSourceImpl.class);
}
@Test
void specificTypeOfDataSource() {
HikariDataSource hikariDataSource = DataSourceBuilder.create().type(HikariDataSource.class).build();
@ -100,6 +109,16 @@ class DataSourceBuilderTests {
assertThat(oracleDataSource.getUser()).isEqualTo("test");
}
@Test
void dataSourceCanBeCreatedWithOracleUcpDataSource() {
this.dataSource = DataSourceBuilder.create().driverClassName("org.hsqldb.jdbc.JDBCDriver")
.type(PoolDataSourceImpl.class).username("test").build();
assertThat(this.dataSource).isInstanceOf(PoolDataSourceImpl.class);
PoolDataSourceImpl upcDataSource = (PoolDataSourceImpl) this.dataSource;
assertThat(upcDataSource.getConnectionFactoryClassName()).isEqualTo("org.hsqldb.jdbc.JDBCDriver");
assertThat(upcDataSource.getUser()).isEqualTo("test");
}
@Test
void dataSourceAliasesAreOnlyAppliedToRelevantDataSource() {
this.dataSource = DataSourceBuilder.create().url("jdbc:h2:test").type(TestDataSource.class).username("test")

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -90,10 +90,10 @@ abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourceP
}
@Test
abstract void getValidationQuery();
abstract void getValidationQuery() throws Exception;
@Test
abstract void getDefaultAutoCommit();
abstract void getDefaultAutoCommit() throws Exception;
protected DataSourceBuilder<?> initializeBuilder() {
return DataSourceBuilder.create().driverClassName("org.hsqldb.jdbc.JDBCDriver").url("jdbc:hsqldb:mem:test")

@ -0,0 +1,70 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* 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
*
* https://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.
*/
package org.springframework.boot.jdbc.metadata;
import java.sql.SQLException;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OracleUcpDataSourcePoolMetadata}.
*
* @author Fabio Grassi
*/
class OracleUcpDataSourcePoolMetadataTests
extends AbstractDataSourcePoolMetadataTests<OracleUcpDataSourcePoolMetadata> {
private final OracleUcpDataSourcePoolMetadata dataSourceMetadata = new OracleUcpDataSourcePoolMetadata(
createDataSource(0, 2));
@Override
protected OracleUcpDataSourcePoolMetadata getDataSourceMetadata() {
return this.dataSourceMetadata;
}
@Override
void getValidationQuery() throws SQLException {
PoolDataSource dataSource = createDataSource(0, 4);
dataSource.setSQLForValidateConnection("SELECT NULL FROM DUAL");
assertThat(new OracleUcpDataSourcePoolMetadata(dataSource).getValidationQuery())
.isEqualTo("SELECT NULL FROM DUAL");
}
@Override
void getDefaultAutoCommit() throws SQLException {
PoolDataSource dataSource = createDataSource(0, 4);
dataSource.setConnectionProperty("autoCommit", "false");
assertThat(new OracleUcpDataSourcePoolMetadata(dataSource).getDefaultAutoCommit()).isFalse();
}
private PoolDataSource createDataSource(int minSize, int maxSize) {
try {
PoolDataSource dataSource = initializeBuilder().type(PoolDataSourceImpl.class).build();
dataSource.setInitialPoolSize(minSize);
dataSource.setMinPoolSize(minSize);
dataSource.setMaxPoolSize(maxSize);
return dataSource;
}
catch (SQLException ex) {
throw new IllegalStateException("Error while configuring PoolDataSource", ex);
}
}
}
Loading…
Cancel
Save