1

I want to configure the properties of the Tomcat JDBC Pool with custom parameter values. The pool is bootstrapped by the spring-cloud (Spring Cloud Connector) environment (Cloud Foundry) and connected to a PostgreSQL database. In particular, I want to set the minIdle, maxIdle and initialSize properties for the given pool.

In a "spring-vanilla" environment (non-cloud) the properties can be easily set by using

  • application.properties / .yaml files with environment properties,
  • @ConfigurationProperties annotation.

However, this approach doesn't transfer to my Cloud environment, where the URL (and other parameters) are injected from the environment variable VCAP_SERVICES (via the ServiceInfo instances). I don't want to re-implement the logic which Spring Cloud already did with its connectors.

After some searching I also stumbled over some tutorials / guides, which suggest to make use of the PoolConfig object (e.g. http://cloud.spring.io/spring-cloud-connectors/spring-cloud-spring-service-connector.html#_relational_database_db2_mysql_oracle_postgresql_sql_server). However, that way one cannot set the properties I need but merely the following three:

  • minPoolSize,
  • maxPoolSize,
  • maxWaitTime.

Note that I don't want to set connection-related properties (such as charset), but the properties are associated with the pool itself.

In essence, I would like to do the configuration similarly to https://www.baeldung.com/spring-boot-tomcat-connection-pool (using spring.datasource.tomcat.* properties). The problem with that approach is that the properties are not considered if the datasource was created by Spring Cloud. The article https://dzone.com/articles/binding-data-services-spring, section "Using a CloudFactory to create a DataSource", claims that the following code snippet makes it so that the configuration "can be tweaked using application.properties via spring.datasource.* properties":

@Bean
@ConfigurationProperties(DataSourceProperties.PREFIX)
public DataSource dataSource() {
  return cloud().getSingletonServiceConnector(DataSource.class, null);
}

However, my own local test (with spring-cloud:Greenwich.RELEASE and spring-boot-starter-parent:2.1.3.RELEASE) showed that those property values are simply ignored.

I found an ugly way to solve my problem but I think it's not appropriate:

  • Let spring-cloud create the DataSource, which is not the pooled DataSource directly,
  • check that the reference is a descendant of a DelegatingDataSource,
  • resolve the delegate, which is then the pool itself,
  • change the properties programmatically directly at the pool itself.

I do not believe that this is the right way as I am using internal knowledge (on the layering of datasources). Additionally, this approach does not work for the property initialSize, which is only considered when the pool is created.

EagleRainbow
  • 931
  • 5
  • 22

0 Answers0