diff --git a/docker-compose.yml b/docker-compose.yml index 45b290fba..3724c3404 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,6 +54,7 @@ services: - FINERACT_DEFAULT_TENANTDB_PORT=3306 - FINERACT_DEFAULT_TENANTDB_UID=root - FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca + - FINERACT_DEFAULT_TENANTDB_CONN_PARAMS= # Frontend service community-app: diff --git a/fineract-db/mifospltaform-tenants-first-time-install.sql b/fineract-db/mifospltaform-tenants-first-time-install.sql index 37d26d091..aa298cef3 100644 --- a/fineract-db/mifospltaform-tenants-first-time-install.sql +++ b/fineract-db/mifospltaform-tenants-first-time-install.sql @@ -90,6 +90,7 @@ CREATE TABLE `tenants` ( `lastmodified_date` datetime DEFAULT NULL, `schema_server` varchar(100) NOT NULL DEFAULT 'localhost', `schema_server_port` varchar(10) NOT NULL DEFAULT '3306', + `schema_connection_parameters` text DEFAULT NULL, `schema_username` varchar(100) NOT NULL DEFAULT 'root', `schema_password` varchar(100) NOT NULL DEFAULT 'mysql', `auto_update` tinyint NOT NULL DEFAULT '1', @@ -117,7 +118,7 @@ CREATE TABLE `tenants` ( LOCK TABLES `tenants` WRITE; /*!40000 ALTER TABLE `tenants` DISABLE KEYS */; INSERT INTO `tenants` VALUES -(1,'default','default','fineract_default','Asia/Kolkata',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1,5,30000,1,60,1,50,1,40,20,10,60,34000,60000); +(1,'default','default','fineract_default','Asia/Kolkata',NULL,NULL,NULL,NULL,'localhost','3306',NULL,'root','mysql',1,5,30000,1,60,1,50,1,40,20,10,60,34000,60000); /*!40000 ALTER TABLE `tenants` ENABLE KEYS */; UNLOCK TABLES; diff --git a/fineract-provider/dependencies.gradle b/fineract-provider/dependencies.gradle index a11c8b63a..a0626a284 100644 --- a/fineract-provider/dependencies.gradle +++ b/fineract-provider/dependencies.gradle @@ -80,7 +80,9 @@ dependencies { 'com.github.spotbugs:spotbugs-annotations', 'io.swagger.core.v3:swagger-annotations', - 'org.webjars:webjars-locator-core' + 'org.webjars:webjars-locator-core', + + 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.1.0' ) implementation ('org.apache.activemq:activemq-broker') { exclude group: 'org.apache.geronimo.specs' diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/JDBCDriverConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/JDBCDriverConfig.java index 37b11ae49..91a5f794a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/JDBCDriverConfig.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/JDBCDriverConfig.java @@ -50,9 +50,12 @@ public class JDBCDriverConfig { return this.driverClassName; } - public String constructProtocol(String schemaServer, String schemaServerPort, String schemaName) { - final String url = new StringBuilder(protocol).append(":").append(subProtocol).append("://").append(schemaServer).append(':') - .append(schemaServerPort).append('/').append(schemaName).toString(); - return url; + public String constructProtocol(String schemaServer, String schemaServerPort, String schemaName, String schemaConnectionParameters) { + StringBuilder sb = new StringBuilder(protocol).append(":").append(subProtocol).append("://").append(schemaServer).append(":") + .append(schemaServerPort).append('/').append(schemaName); + if (schemaConnectionParameters != null && !schemaConnectionParameters.isEmpty()) { + sb.append('?').append(schemaConnectionParameters); + } + return sb.toString(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java index fac355480..b07f5ca39 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java @@ -26,6 +26,7 @@ public class FineractPlatformTenantConnection { private final Long connectionId; private final String schemaServer; private final String schemaServerPort; + private final String schemaConnectionParameters; private final String schemaUsername; private final String schemaPassword; private final String schemaName; @@ -47,16 +48,18 @@ public class FineractPlatformTenantConnection { private final boolean testOnBorrow; public FineractPlatformTenantConnection(final Long connectionId, final String schemaName, String schemaServer, - final String schemaServerPort, final String schemaUsername, final String schemaPassword, final boolean autoUpdateEnabled, - final int initialSize, final long validationInterval, final boolean removeAbandoned, final int removeAbandonedTimeout, - final boolean logAbandoned, final int abandonWhenPercentageFull, final int maxActive, final int minIdle, final int maxIdle, - final int suspectTimeout, final int timeBetweenEvictionRunsMillis, final int minEvictableIdleTimeMillis, - final int maxRetriesOnDeadlock, final int maxIntervalBetweenRetries, final boolean tesOnBorrow) { + final String schemaServerPort, final String schemaConnectionParameters, final String schemaUsername, + final String schemaPassword, final boolean autoUpdateEnabled, final int initialSize, final long validationInterval, + final boolean removeAbandoned, final int removeAbandonedTimeout, final boolean logAbandoned, + final int abandonWhenPercentageFull, final int maxActive, final int minIdle, final int maxIdle, final int suspectTimeout, + final int timeBetweenEvictionRunsMillis, final int minEvictableIdleTimeMillis, final int maxRetriesOnDeadlock, + final int maxIntervalBetweenRetries, final boolean tesOnBorrow) { this.connectionId = connectionId; this.schemaName = schemaName; this.schemaServer = schemaServer; this.schemaServerPort = schemaServerPort; + this.schemaConnectionParameters = schemaConnectionParameters; this.schemaUsername = schemaUsername; this.schemaPassword = schemaPassword; this.autoUpdateEnabled = autoUpdateEnabled; @@ -85,6 +88,10 @@ public class FineractPlatformTenantConnection { return this.schemaServerPort; } + public String getSchemaConnectionParameters() { + return this.schemaConnectionParameters; + } + public String getSchemaUsername() { return this.schemaUsername; } @@ -167,6 +174,11 @@ public class FineractPlatformTenantConnection { @Override public String toString() { - return this.schemaName + ":" + this.schemaServer + ":" + this.schemaServerPort; + StringBuilder sb = new StringBuilder(this.schemaName).append(":").append(this.schemaServer).append(":") + .append(this.schemaServerPort); + if (this.schemaConnectionParameters != null && !this.schemaConnectionParameters.isEmpty()) { + sb.append('?').append(this.schemaConnectionParameters); + } + return sb.toString(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/Tenant.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/Tenant.java index 79e85130e..297aec6f5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/Tenant.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/Tenant.java @@ -25,17 +25,19 @@ public class Tenant { private final String schemaName; private final String schemaServer; private final String schemaServerPort; + private final String schemaConnectionParameters; private final String schemaUsername; private final String schemaPassword; private final String timezoneId; public Tenant(final Long id, final String name, final String schemaName, final String schemaServer, final String schemaServerPort, - final String schemaUsername, final String schemaPassword, final String timezoneId) { + final String schemaConnectionParameters, final String schemaUsername, final String schemaPassword, final String timezoneId) { this.id = id; this.name = name; this.schemaName = schemaName; this.schemaServer = schemaServer; this.schemaServerPort = schemaServerPort; + this.schemaConnectionParameters = schemaConnectionParameters; this.schemaUsername = schemaUsername; this.schemaPassword = schemaPassword; this.timezoneId = timezoneId; @@ -62,6 +64,10 @@ public class Tenant { return this.schemaServerPort; } + public String getSchemaConnectionParameters() { + return this.schemaConnectionParameters; + } + public String getSchemaUsername() { return this.schemaUsername; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TenantDatabaseUpgradeService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TenantDatabaseUpgradeService.java index b59e80bd5..877d2717d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TenantDatabaseUpgradeService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TenantDatabaseUpgradeService.java @@ -67,7 +67,7 @@ public class TenantDatabaseUpgradeService { if (connection.isAutoUpdateEnabled()) { String connectionProtocol = driverConfig.constructProtocol(connection.getSchemaServer(), connection.getSchemaServerPort(), - connection.getSchemaName()); + connection.getSchemaName(), connection.getSchemaConnectionParameters()); DriverDataSource source = new DriverDataSource(Thread.currentThread().getContextClassLoader(), driverConfig.getDriverClassName(), connectionProtocol, connection.getSchemaUsername(), connection.getSchemaPassword()); @@ -100,12 +100,14 @@ public class TenantDatabaseUpgradeService { String dbPort = getEnvVar("FINERACT_DEFAULT_TENANTDB_PORT", "3306"); String dbUid = getEnvVar("FINERACT_DEFAULT_TENANTDB_UID", "root"); String dbPwd = getEnvVar("FINERACT_DEFAULT_TENANTDB_PWD", "mysql"); + String dbConnParams = getEnvVar("FINERACT_DEFAULT_TENANTDB_CONN_PARAMS", ""); LOG.info("upgradeTenantDB: FINERACT_DEFAULT_TENANTDB_HOSTNAME = {}, FINERACT_DEFAULT_TENANTDB_PORT = {}", dbHostname, dbPort); final Flyway flyway = Flyway.configure().dataSource(tenantDataSource).locations("sql/migrations/list_db").outOfOrder(true) // FINERACT-773 .placeholders(Map.of("fineract_default_tenantdb_hostname", dbHostname, "fineract_default_tenantdb_port", dbPort, - "fineract_default_tenantdb_uid", dbUid, "fineract_default_tenantdb_pwd", dbPwd)) + "fineract_default_tenantdb_uid", dbUid, "fineract_default_tenantdb_pwd", dbPwd, + "fineract_default_tenantdb_conn_params", dbConnParams)) .configuration(Map.of("flyway.table", "schema_version")) // FINERACT-979 .load(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java index d9e941b07..99a5b5ab5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java @@ -78,7 +78,8 @@ public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceSe // creates the tenant data source for the oltp and report database private DataSource createNewDataSourceFor(final FineractPlatformTenantConnection tenantConnectionObj) { String jdbcUrl = this.driverConfig.constructProtocol(tenantConnectionObj.getSchemaServer(), - tenantConnectionObj.getSchemaServerPort(), tenantConnectionObj.getSchemaName()); + tenantConnectionObj.getSchemaServerPort(), tenantConnectionObj.getSchemaName(), + tenantConnectionObj.getSchemaConnectionParameters()); HikariConfig config = new HikariConfig(); config.setDriverClassName(this.driverConfig.getDriverClassName()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java index 07d1180e8..c0783d6aa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/BasicAuthTenantDetailsServiceJdbc.java @@ -51,7 +51,7 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails private final boolean isReport; private final StringBuilder sqlBuilder = new StringBuilder(" t.id, ts.id as connectionId , ")// .append(" t.timezone_id as timezoneId , t.name,t.identifier, ts.schema_name as schemaName, ts.schema_server as schemaServer,")// - .append(" ts.schema_server_port as schemaServerPort, ts.auto_update as autoUpdate,")// + .append(" ts.schema_server_port as schemaServerPort, ts.schema_connection_parameters as schemaConnectionParameters, ts.auto_update as autoUpdate,")// .append(" ts.schema_username as schemaUsername, ts.schema_password as schemaPassword , ts.pool_initial_size as initialSize,")// .append(" ts.pool_validation_interval as validationInterval, ts.pool_remove_abandoned as removeAbandoned, ts.pool_remove_abandoned_timeout as removeAbandonedTimeout,")// .append(" ts.pool_log_abandoned as logAbandoned, ts.pool_abandon_when_percentage_full as abandonedWhenPercentageFull, ts.pool_test_on_borrow as testOnBorrow,")// @@ -92,6 +92,7 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails final String schemaName = rs.getString("schemaName"); final String schemaServer = rs.getString("schemaServer"); final String schemaServerPort = rs.getString("schemaServerPort"); + final String schemaConnectionParameters = rs.getString("schemaConnectionParameters"); final String schemaUsername = rs.getString("schemaUsername"); final String schemaPassword = rs.getString("schemaPassword"); final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate"); @@ -114,10 +115,11 @@ public class BasicAuthTenantDetailsServiceJdbc implements BasicAuthTenantDetails maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15); maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15); - return new FineractPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, schemaUsername, - schemaPassword, autoUpdateEnabled, initialSize, validationInterval, removeAbandoned, removeAbandonedTimeout, - logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, timeBetweenEvictionRunsMillis, - minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries, testOnBorrow); + return new FineractPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, + schemaConnectionParameters, schemaUsername, schemaPassword, autoUpdateEnabled, initialSize, validationInterval, + removeAbandoned, removeAbandonedTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, + suspectTimeout, timeBetweenEvictionRunsMillis, minEvictableIdleTimeMillis, maxRetriesOnDeadlock, + maxIntervalBetweenRetries, testOnBorrow); } private int bindValueInMinMaxRange(final int value, int min, int max) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java index f2987696b..dd1551a14 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/JdbcTenantDetailsService.java @@ -51,7 +51,7 @@ public class JdbcTenantDetailsService implements TenantDetailsService { private final StringBuilder sqlBuilder = new StringBuilder("t.id, ts.id as connectionId , ")// .append(" t.timezone_id as timezoneId , t.name,t.identifier, ts.schema_name as schemaName, ts.schema_server as schemaServer,")// - .append(" ts.schema_server_port as schemaServerPort, ts.auto_update as autoUpdate,")// + .append(" ts.schema_server_port as schemaServerPort, ts.schema_connection_parameters as schemaConnectionParameters, ts.auto_update as autoUpdate,")// .append(" ts.schema_username as schemaUsername, ts.schema_password as schemaPassword , ts.pool_initial_size as initialSize,")// .append(" ts.pool_validation_interval as validationInterval, ts.pool_remove_abandoned as removeAbandoned, ts.pool_remove_abandoned_timeout as removeAbandonedTimeout,")// .append(" ts.pool_log_abandoned as logAbandoned, ts.pool_abandon_when_percentage_full as abandonedWhenPercentageFull, ts.pool_test_on_borrow as testOnBorrow,")// @@ -84,6 +84,7 @@ public class JdbcTenantDetailsService implements TenantDetailsService { final String schemaName = rs.getString("schemaName"); final String schemaServer = rs.getString("schemaServer"); final String schemaServerPort = rs.getString("schemaServerPort"); + final String schemaConnectionParameters = rs.getString("schemaConnectionParameters"); final String schemaUsername = rs.getString("schemaUsername"); final String schemaPassword = rs.getString("schemaPassword"); final boolean autoUpdateEnabled = rs.getBoolean("autoUpdate"); @@ -106,10 +107,11 @@ public class JdbcTenantDetailsService implements TenantDetailsService { maxRetriesOnDeadlock = bindValueInMinMaxRange(maxRetriesOnDeadlock, 0, 15); maxIntervalBetweenRetries = bindValueInMinMaxRange(maxIntervalBetweenRetries, 1, 15); - return new FineractPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, schemaUsername, - schemaPassword, autoUpdateEnabled, initialSize, validationInterval, removeAbandoned, removeAbandonedTimeout, - logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, suspectTimeout, timeBetweenEvictionRunsMillis, - minEvictableIdleTimeMillis, maxRetriesOnDeadlock, maxIntervalBetweenRetries, testOnBorrow); + return new FineractPlatformTenantConnection(connectionId, schemaName, schemaServer, schemaServerPort, + schemaConnectionParameters, schemaUsername, schemaPassword, autoUpdateEnabled, initialSize, validationInterval, + removeAbandoned, removeAbandonedTimeout, logAbandoned, abandonWhenPercentageFull, maxActive, minIdle, maxIdle, + suspectTimeout, timeBetweenEvictionRunsMillis, minEvictableIdleTimeMillis, maxRetriesOnDeadlock, + maxIntervalBetweenRetries, testOnBorrow); } diff --git a/fineract-provider/src/main/resources/sql/migrations/list_db/V5__add_schema_connection_parameters.sql b/fineract-provider/src/main/resources/sql/migrations/list_db/V5__add_schema_connection_parameters.sql new file mode 100644 index 000000000..021b9fba7 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/list_db/V5__add_schema_connection_parameters.sql @@ -0,0 +1,24 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you 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 +-- +-- http://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. +-- + +ALTER TABLE `tenant_server_connections` + ADD COLUMN `schema_connection_parameters` TEXT NULL DEFAULT NULL; +UPDATE `tenant_server_connections` + SET `schema_connection_parameters`='${fineract_default_tenantdb_conn_params}' + WHERE `id`=1; diff --git a/kubernetes/fineract-server-deployment.yml b/kubernetes/fineract-server-deployment.yml index 6f5c1992c..77d9c9b31 100644 --- a/kubernetes/fineract-server-deployment.yml +++ b/kubernetes/fineract-server-deployment.yml @@ -92,6 +92,8 @@ spec: secretKeyRef: name: fineract-tenants-db-secret key: password + - name: FINERACT_DEFAULT_TENANTDB_CONN_PARAMS + value: '' ports: - containerPort: 8443 name: fineract-server