This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 7f5b87694 FINERACT-1724: Ability to override tenant datasource min/max
configuration from env variables
7f5b87694 is described below
commit 7f5b87694b5a882c7507d810712fd9ee42cd5b06
Author: Arnold Galovics <[email protected]>
AuthorDate: Mon May 8 13:52:54 2023 +0200
FINERACT-1724: Ability to override tenant datasource min/max configuration
from env variables
---
.../core/config/FineractProperties.java | 21 +++++
.../DataSourcePerTenantServiceFactory.java | 26 ++++-
.../migration/TenantDatabaseUpgradeService.java | 27 +++---
.../src/main/resources/application.properties | 3 +
.../DataSourcePerTenantServiceFactoryTest.java | 105 +++++++++++++++++++++
5 files changed, 168 insertions(+), 14 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
index 2a38776f0..41c05d1f7 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
@@ -86,6 +86,27 @@ public class FineractProperties {
private String readOnlyPassword;
private String readOnlyParameters;
private String readOnlyName;
+
+ private FineractConfigProperties config;
+ }
+
+ /**
+ * Configuration properties to override configurations stored in the
tenants database
+ */
+ @Getter
+ @Setter
+ public static class FineractConfigProperties {
+
+ private int minPoolSize;
+ private int maxPoolSize;
+
+ public boolean isMinPoolSizeSet() {
+ return minPoolSize != -1;
+ }
+
+ public boolean isMaxPoolSizeSet() {
+ return maxPoolSize != -1;
+ }
}
@Getter
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
index e3e6bfc1b..410b3db96 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
@@ -92,8 +92,8 @@ public class DataSourcePerTenantServiceFactory {
config.setPoolName(schemaName + "_pool");
config.setUsername(schemaUsername);
config.setPassword(databasePasswordEncryptor.decrypt(schemaPassword));
- config.setMinimumIdle(tenantConnection.getInitialSize());
- config.setMaximumPoolSize(tenantConnection.getMaxActive());
+ config.setMinimumIdle(getMinPoolSize(tenantConnection));
+ config.setMaximumPoolSize(getMaxPoolSize(tenantConnection));
config.setValidationTimeout(tenantConnection.getValidationInterval());
config.setDriverClassName(hikariConfig.getDriverClassName());
config.setConnectionTestQuery(hikariConfig.getConnectionTestQuery());
@@ -111,4 +111,26 @@ public class DataSourcePerTenantServiceFactory {
return hikariDataSourceFactory.create(config);
}
+ private int getMaxPoolSize(FineractPlatformTenantConnection
tenantConnection) {
+ FineractProperties.FineractConfigProperties configOverride =
fineractProperties.getTenant().getConfig();
+ if (configOverride.isMaxPoolSizeSet()) {
+ int maxPoolSize = configOverride.getMaxPoolSize();
+ log.info("Overriding tenant datasource maximum pool size
configuration to {}", maxPoolSize);
+ return maxPoolSize;
+ } else {
+ return tenantConnection.getMaxActive();
+ }
+ }
+
+ private int getMinPoolSize(FineractPlatformTenantConnection
tenantConnection) {
+ FineractProperties.FineractConfigProperties configOverride =
fineractProperties.getTenant().getConfig();
+ if (configOverride.isMinPoolSizeSet()) {
+ int minPoolSize = configOverride.getMinPoolSize();
+ log.info("Overriding tenant datasource minimum pool size
configuration to {}", minPoolSize);
+ return minPoolSize;
+ } else {
+ return tenantConnection.getInitialSize();
+ }
+ }
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java
index 2a19c12aa..c65b6b101 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDatabaseUpgradeService.java
@@ -19,6 +19,7 @@
package org.apache.fineract.infrastructure.core.service.migration;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.Arrays;
import java.util.List;
@@ -29,7 +30,6 @@ import liquibase.exception.LiquibaseException;
import liquibase.integration.spring.SpringLiquibase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
import org.apache.fineract.infrastructure.core.config.FineractProperties;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
@@ -102,19 +102,22 @@ public class TenantDatabaseUpgradeService implements
InitializingBean {
}
private void logTenantStoreDetails() {
- log.info("- fineract.tenant.username: {}",
fineractProperties.getTenant().getUsername());
+ FineractProperties.FineractTenantProperties tenant =
fineractProperties.getTenant();
+ log.info("- fineract.tenant.username: {}", tenant.getUsername());
log.info("- fineract.tenant.password: ****");
- log.info("- fineract.tenant.parameters: {}",
fineractProperties.getTenant().getParameters());
- log.info("- fineract.tenant.timezone: {}",
fineractProperties.getTenant().getTimezone());
- log.info("- fineract.tenant.description: {}",
fineractProperties.getTenant().getDescription());
- log.info("- fineract.tenant.identifier: {}",
fineractProperties.getTenant().getIdentifier());
- log.info("- fineract.tenant.name: {}",
fineractProperties.getTenant().getName());
+ log.info("- fineract.tenant.parameters: {}", tenant.getParameters());
+ log.info("- fineract.tenant.timezone: {}", tenant.getTimezone());
+ log.info("- fineract.tenant.description: {}", tenant.getDescription());
+ log.info("- fineract.tenant.identifier: {}", tenant.getIdentifier());
+ log.info("- fineract.tenant.name: {}", tenant.getName());
- log.info("- fineract.tenant.readonly.username: {}",
fineractProperties.getTenant().getReadOnlyUsername());
- log.info("- fineract.tenant.readonly.password: {}",
-
StringUtils.isNotBlank(fineractProperties.getTenant().getReadOnlyPassword()) ?
"****" : "");
- log.info("- fineract.tenant.readonly.parameters: {}",
fineractProperties.getTenant().getReadOnlyParameters());
- log.info("- fineract.tenant.readonly.name: {}",
fineractProperties.getTenant().getReadOnlyName());
+ String readOnlyUsername = tenant.getReadOnlyUsername();
+ if (isNotBlank(readOnlyUsername)) {
+ log.info("- fineract.tenant.readonly.username: {}",
readOnlyUsername);
+ log.info("- fineract.tenant.readonly.password: {}",
isNotBlank(tenant.getReadOnlyPassword()) ? "****" : "");
+ log.info("- fineract.tenant.readonly.parameters: {}",
tenant.getReadOnlyParameters());
+ log.info("- fineract.tenant.readonly.name: {}",
tenant.getReadOnlyName());
+ }
}
diff --git a/fineract-provider/src/main/resources/application.properties
b/fineract-provider/src/main/resources/application.properties
index 24252be91..009b11daf 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -44,6 +44,9 @@
fineract.tenant.read-only-password=${FINERACT_DEFAULT_TENANTDB_RO_PWD:}
fineract.tenant.read-only-parameters=${FINERACT_DEFAULT_TENANTDB_RO_CONN_PARAMS:}
fineract.tenant.read-only-name=${FINERACT_DEFAULT_TENANTDB_RO_NAME:}
+fineract.tenant.config.min-pool-size=${FINERACT_CONFIG_MIN_POOL_SIZE:-1}
+fineract.tenant.config.max-pool-size=${FINERACT_CONFIG_MAX_POOL_SIZE:-1}
+
fineract.mode.read-enabled=${FINERACT_MODE_READ_ENABLED:true}
fineract.mode.write-enabled=${FINERACT_MODE_WRITE_ENABLED:true}
fineract.mode.batch-worker-enabled=${FINERACT_MODE_BATCH_WORKER_ENABLED:true}
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
index b099cd397..5ead9f5f0 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/DataSourcePerTenantServiceFactoryTest.java
@@ -155,9 +155,16 @@ public class DataSourcePerTenantServiceFactoryTest {
given(tenantHikariConfig.isAutoCommit()).willReturn(MASTER_DB_AUTO_COMMIT_ENABLED);
given(hikariDataSourceFactory.create(any())).willReturn(mock(HikariDataSource.class));
+
+ FineractProperties.FineractConfigProperties configProperties = new
FineractProperties.FineractConfigProperties();
+ configProperties.setMinPoolSize(-1);
+ configProperties.setMaxPoolSize(-1);
+
FineractProperties.FineractTenantProperties tenantPropertiesMock =
mock(FineractProperties.FineractTenantProperties.class);
given(tenantPropertiesMock.getEncryption()).willReturn(MASTER_ENCRYPTION);
given(tenantPropertiesMock.getMasterPassword()).willReturn(MASTER_MASTER_PASSWORD);
+
+ given(tenantPropertiesMock.getConfig()).willReturn(configProperties);
given(fineractProperties.getTenant()).willReturn(tenantPropertiesMock);
given(databasePasswordEncryptor.isMasterPasswordHashValid(any())).willReturn(true);
@@ -195,6 +202,104 @@ public class DataSourcePerTenantServiceFactoryTest {
assertEquals(MASTER_DB_AUTO_COMMIT_ENABLED,
hikariConfig.isAutoCommit());
}
+ @Test
+ void
testCreateNewDataSourceFor_ShouldOverridesMinPoolConfiguration_WhenConfigured()
{
+ // given
+ FineractProperties.FineractModeProperties modeProperties =
createModeProps(MASTER_DB_AUTO_COMMIT_ENABLED,
+ MASTER_DB_AUTO_COMMIT_ENABLED, MASTER_DB_AUTO_COMMIT_ENABLED,
MASTER_DB_AUTO_COMMIT_ENABLED);
+ given(fineractProperties.getMode()).willReturn(modeProperties);
+
+ int minPoolSize = 10;
+
+ FineractProperties.FineractConfigProperties config =
fineractProperties.getTenant().getConfig();
+ config.setMinPoolSize(minPoolSize);
+
+ // when
+ DataSource dataSource =
underTest.createNewDataSourceFor(defaultTenant.getConnection());
+
+ // then
+ assertNotNull(dataSource);
+ verify(hikariDataSourceFactory).create(hikariConfigCaptor.capture());
+ HikariConfig hikariConfig = hikariConfigCaptor.getValue();
+ assertFalse(hikariConfig.isReadOnly());
+ assertEquals(MASTER_DB_JDBC_URL, hikariConfig.getJdbcUrl());
+ assertEquals(MASTER_DB_SCHEMA_NAME + "_pool",
hikariConfig.getPoolName());
+ assertEquals(MASTER_DB_USERNAME, hikariConfig.getUsername());
+ assertEquals(MASTER_DB_PASSWORD, hikariConfig.getPassword());
+ assertEquals(minPoolSize, hikariConfig.getMinimumIdle());
+ assertEquals(MASTER_DB_MAX_ACTIVE, hikariConfig.getMaximumPoolSize());
+ assertEquals(MASTER_DB_VALIDATION_INTERVAL,
hikariConfig.getValidationTimeout());
+ assertEquals(MASTER_DB_DRIVER_CLASS_NAME,
hikariConfig.getDriverClassName());
+ assertEquals(MASTER_DB_CONN_TEST_QUERY,
hikariConfig.getConnectionTestQuery());
+ assertEquals(MASTER_DB_AUTO_COMMIT_ENABLED,
hikariConfig.isAutoCommit());
+ }
+
+ @Test
+ void
testCreateNewDataSourceFor_ShouldOverridesMaxPoolConfiguration_WhenConfigured()
{
+ // given
+ FineractProperties.FineractModeProperties modeProperties =
createModeProps(MASTER_DB_AUTO_COMMIT_ENABLED,
+ MASTER_DB_AUTO_COMMIT_ENABLED, MASTER_DB_AUTO_COMMIT_ENABLED,
MASTER_DB_AUTO_COMMIT_ENABLED);
+ given(fineractProperties.getMode()).willReturn(modeProperties);
+
+ int maxPoolSize = 10;
+
+ FineractProperties.FineractConfigProperties config =
fineractProperties.getTenant().getConfig();
+ config.setMaxPoolSize(maxPoolSize);
+
+ // when
+ DataSource dataSource =
underTest.createNewDataSourceFor(defaultTenant.getConnection());
+
+ // then
+ assertNotNull(dataSource);
+ verify(hikariDataSourceFactory).create(hikariConfigCaptor.capture());
+ HikariConfig hikariConfig = hikariConfigCaptor.getValue();
+ assertFalse(hikariConfig.isReadOnly());
+ assertEquals(MASTER_DB_JDBC_URL, hikariConfig.getJdbcUrl());
+ assertEquals(MASTER_DB_SCHEMA_NAME + "_pool",
hikariConfig.getPoolName());
+ assertEquals(MASTER_DB_USERNAME, hikariConfig.getUsername());
+ assertEquals(MASTER_DB_PASSWORD, hikariConfig.getPassword());
+ assertEquals(MASTER_DB_INITIAL_SIZE, hikariConfig.getMinimumIdle());
+ assertEquals(maxPoolSize, hikariConfig.getMaximumPoolSize());
+ assertEquals(MASTER_DB_VALIDATION_INTERVAL,
hikariConfig.getValidationTimeout());
+ assertEquals(MASTER_DB_DRIVER_CLASS_NAME,
hikariConfig.getDriverClassName());
+ assertEquals(MASTER_DB_CONN_TEST_QUERY,
hikariConfig.getConnectionTestQuery());
+ assertEquals(MASTER_DB_AUTO_COMMIT_ENABLED,
hikariConfig.isAutoCommit());
+ }
+
+ @Test
+ void
testCreateNewDataSourceFor_ShouldOverridesMinAndMaxPoolConfiguration_WhenBothConfigured()
{
+ // given
+ FineractProperties.FineractModeProperties modeProperties =
createModeProps(MASTER_DB_AUTO_COMMIT_ENABLED,
+ MASTER_DB_AUTO_COMMIT_ENABLED, MASTER_DB_AUTO_COMMIT_ENABLED,
MASTER_DB_AUTO_COMMIT_ENABLED);
+ given(fineractProperties.getMode()).willReturn(modeProperties);
+
+ int minPoolSize = 10;
+ int maxPoolSize = 10;
+
+ FineractProperties.FineractConfigProperties config =
fineractProperties.getTenant().getConfig();
+ config.setMinPoolSize(minPoolSize);
+ config.setMaxPoolSize(maxPoolSize);
+
+ // when
+ DataSource dataSource =
underTest.createNewDataSourceFor(defaultTenant.getConnection());
+
+ // then
+ assertNotNull(dataSource);
+ verify(hikariDataSourceFactory).create(hikariConfigCaptor.capture());
+ HikariConfig hikariConfig = hikariConfigCaptor.getValue();
+ assertFalse(hikariConfig.isReadOnly());
+ assertEquals(MASTER_DB_JDBC_URL, hikariConfig.getJdbcUrl());
+ assertEquals(MASTER_DB_SCHEMA_NAME + "_pool",
hikariConfig.getPoolName());
+ assertEquals(MASTER_DB_USERNAME, hikariConfig.getUsername());
+ assertEquals(MASTER_DB_PASSWORD, hikariConfig.getPassword());
+ assertEquals(minPoolSize, hikariConfig.getMinimumIdle());
+ assertEquals(maxPoolSize, hikariConfig.getMaximumPoolSize());
+ assertEquals(MASTER_DB_VALIDATION_INTERVAL,
hikariConfig.getValidationTimeout());
+ assertEquals(MASTER_DB_DRIVER_CLASS_NAME,
hikariConfig.getDriverClassName());
+ assertEquals(MASTER_DB_CONN_TEST_QUERY,
hikariConfig.getConnectionTestQuery());
+ assertEquals(MASTER_DB_AUTO_COMMIT_ENABLED,
hikariConfig.isAutoCommit());
+ }
+
@Test
void
testCreateNewDataSourceFor_ShouldUseReadOnlyConfiguration_WhenInReadOnlyMode() {
// given