You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2023/04/15 08:40:58 UTC
[fineract] branch develop updated: FINERACT-1913-Initializing-db-connection-pool-at-startup
This is an automated email from the ASF dual-hosted git repository.
arnold 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 c18e50683 FINERACT-1913-Initializing-db-connection-pool-at-startup
c18e50683 is described below
commit c18e5068320dd08c0d8860ccaef483cf9a045cd0
Author: Ruchi Dhamankar <ru...@gmail.com>
AuthorDate: Thu Apr 13 20:11:08 2023 +0530
FINERACT-1913-Initializing-db-connection-pool-at-startup
---
.../TomcatJdbcDataSourcePerTenantService.java | 62 ++++++++++++++++------
1 file changed, 47 insertions(+), 15 deletions(-)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
index b01d6999d..fb829d664 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
@@ -18,14 +18,21 @@
*/
package org.apache.fineract.infrastructure.core.service.database;
-import java.util.HashMap;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
+import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
/**
@@ -34,19 +41,22 @@ import org.springframework.stereotype.Service;
*
* {@link ThreadLocalContextUtil} is used to retrieve the {@link FineractPlatformTenant} for the request.
*/
+@Slf4j
@Service
-public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceService {
+public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceService, ApplicationListener<ContextRefreshedEvent> {
- private static final Map<Long, DataSource> TENANT_TO_DATA_SOURCE_MAP = new HashMap<>(1);
+ private static final Map<Long, DataSource> TENANT_TO_DATA_SOURCE_MAP = new ConcurrentHashMap<>();
private final DataSource tenantDataSource;
+ private final TenantDetailsService tenantDetailsService;
private final DataSourcePerTenantServiceFactory dataSourcePerTenantServiceFactory;
@Autowired
public TomcatJdbcDataSourcePerTenantService(final @Qualifier("hikariTenantDataSource") DataSource tenantDataSource,
- final DataSourcePerTenantServiceFactory dataSourcePerTenantServiceFactory) {
+ final DataSourcePerTenantServiceFactory dataSourcePerTenantServiceFactory, final TenantDetailsService tenantDetailsService) {
this.tenantDataSource = tenantDataSource;
this.dataSourcePerTenantServiceFactory = dataSourcePerTenantServiceFactory;
+ this.tenantDetailsService = tenantDetailsService;
}
@Override
@@ -57,20 +67,42 @@ public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceSe
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
if (tenant != null) {
final FineractPlatformTenantConnection tenantConnection = tenant.getConnection();
+ Long tenantConnectionKey = tenantConnection.getConnectionId();
+ // if tenantConnection information available switch to the
+ // appropriate datasource for that tenant.
+ actualDataSource = TENANT_TO_DATA_SOURCE_MAP.computeIfAbsent(tenantConnectionKey, (key) -> {
+ DataSource tenantSpecificDataSource = dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection);
+ return tenantSpecificDataSource;
+ });
- synchronized (TENANT_TO_DATA_SOURCE_MAP) {
- // if tenantConnection information available switch to the
- // appropriate datasource for that tenant.
- DataSource possibleDS = TENANT_TO_DATA_SOURCE_MAP.get(tenantConnection.getConnectionId());
- if (possibleDS != null) {
- actualDataSource = possibleDS;
- } else {
- actualDataSource = dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection);
- TENANT_TO_DATA_SOURCE_MAP.put(tenantConnection.getConnectionId(), actualDataSource);
- }
- }
}
return actualDataSource;
}
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ final List<FineractPlatformTenant> allTenants = tenantDetailsService.findAllTenants();
+ for (final FineractPlatformTenant tenant : allTenants) {
+ initializeDataSourceConnection(tenant);
+ }
+ }
+
+ private void initializeDataSourceConnection(FineractPlatformTenant tenant) {
+ log.debug("Initializing database connection for {}", tenant.getName());
+ final FineractPlatformTenantConnection tenantConnection = tenant.getConnection();
+ Long tenantConnectionKey = tenantConnection.getConnectionId();
+ TENANT_TO_DATA_SOURCE_MAP.computeIfAbsent(tenantConnectionKey, (key) -> {
+ DataSource tenantSpecificDataSource = dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection);
+ try (Connection connection = tenantSpecificDataSource.getConnection()) {
+ String url = connection.getMetaData().getURL();
+ log.debug("Established database connection with URL {}", url);
+ } catch (SQLException e) {
+ log.error("Error while initializing database connection for {}", tenant.getName(), e);
+ }
+ return tenantSpecificDataSource;
+ });
+ log.debug("Database connection for {} initialized", tenant.getName());
+
+ }
}