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 <[email protected]>
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());
+
+ }
}