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 5079203d57 FINERACT-2389: Fix for rounding mode not being initialized 
whenever a new tenant is added to the system without a restart
5079203d57 is described below

commit 5079203d57b7ab14368f7e19b286098439ff78c8
Author: Arnold Galovics <[email protected]>
AuthorDate: Thu Nov 6 11:30:56 2025 +0100

    FINERACT-2389: Fix for rounding mode not being initialized whenever a new 
tenant is added to the system without a restart
---
 .../domain/GlobalConfigurationProperty.java        |  0
 .../domain/GlobalConfigurationRepository.java      |  0
 .../GlobalConfigurationRepositoryWrapper.java      |  0
 ...obalConfigurationPropertyNotFoundException.java |  0
 .../service/MoneyHelperInitializationService.java  | 15 ++++++++++++---
 .../MoneyHelperStartupInitializationService.java   |  0
 .../TomcatJdbcDataSourcePerTenantService.java      | 22 ++++++++++++++++++++++
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepository.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepository.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepository.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepository.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepositoryWrapper.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepositoryWrapper.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepositoryWrapper.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationRepositoryWrapper.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
similarity index 87%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
index 04eac2f3dc..34fea1c7d0 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
@@ -26,6 +26,8 @@ import 
org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurati
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 /**
@@ -40,7 +42,10 @@ import org.springframework.stereotype.Service;
 @RequiredArgsConstructor
 public class MoneyHelperInitializationService {
 
-    private final GlobalConfigurationRepositoryWrapper 
globalConfigurationRepository;
+    // TODO: this is preventing the circular dependency...
+    @Lazy
+    @Autowired
+    private GlobalConfigurationRepositoryWrapper globalConfigurationRepository;
 
     /**
      * Initialize MoneyHelper for a specific tenant. This method should be 
called during tenant setup and whenever
@@ -56,6 +61,7 @@ public class MoneyHelperInitializationService {
 
         String tenantIdentifier = tenant.getTenantIdentifier();
 
+        FineractPlatformTenant originalTenant = 
ThreadLocalContextUtil.getTenant();
         try {
             // Set tenant context to read configuration
             ThreadLocalContextUtil.setTenant(tenant);
@@ -69,8 +75,7 @@ public class MoneyHelperInitializationService {
             log.error("Failed to initialize MoneyHelper for tenant '{}'", 
tenantIdentifier, e);
             throw new RuntimeException("Failed to initialize MoneyHelper for 
tenant: " + tenantIdentifier, e);
         } finally {
-            // Clear tenant context
-            ThreadLocalContextUtil.clearTenant();
+            ThreadLocalContextUtil.setTenant(originalTenant);
         }
     }
 
@@ -85,6 +90,10 @@ public class MoneyHelperInitializationService {
         return MoneyHelper.isTenantInitialized(tenantIdentifier);
     }
 
+    public boolean isTenantInitialized(FineractPlatformTenant tenant) {
+        return isTenantInitialized(tenant.getTenantIdentifier());
+    }
+
     /**
      * Get the rounding mode from configuration with fallback to default.
      *
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
rename to 
fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
index e3b792e1b1..a6c1889dd8 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
@@ -18,14 +18,17 @@
  */
 package org.apache.fineract.infrastructure.core.service.database;
 
+import com.google.common.collect.Sets;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import javax.sql.DataSource;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import 
org.apache.fineract.infrastructure.configuration.service.MoneyHelperInitializationService;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import 
org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
@@ -53,6 +56,9 @@ public class TomcatJdbcDataSourcePerTenantService implements 
RoutingDataSourceSe
 
     private final DataSourcePerTenantServiceFactory 
dataSourcePerTenantServiceFactory;
 
+    private final MoneyHelperInitializationService 
moneyHelperInitializationService;
+    private final Set<Long> tenantMoneyInitializingSet = 
Sets.newConcurrentHashSet();
+
     @Override
     public DataSource retrieveDataSource() {
         // default to tenant database datasource
@@ -66,7 +72,23 @@ public class TomcatJdbcDataSourcePerTenantService implements 
RoutingDataSourceSe
             // appropriate datasource for that tenant.
             actualDataSource = 
TENANT_TO_DATA_SOURCE_MAP.computeIfAbsent(tenantConnectionKey,
                     (key) -> 
dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenant, 
tenantConnection));
+        }
 
+        // TODO: This is definitely not the optimal place to initialize the 
rounding modes
+        // Preferably nothing should use a statically referenced context and 
the initialization
+        // should happen within the rounding mode retrieval
+        if (tenant != null) {
+            Long connectionId = tenant.getConnection().getConnectionId();
+            if (!tenantMoneyInitializingSet.contains(connectionId) && 
!moneyHelperInitializationService.isTenantInitialized(tenant)) {
+                // Double check to prevent visibility and race-condition issues
+                synchronized (tenantMoneyInitializingSet) {
+                    if (!tenantMoneyInitializingSet.contains(connectionId)) {
+                        tenantMoneyInitializingSet.add(connectionId);
+                        
moneyHelperInitializationService.initializeTenantRoundingMode(tenant);
+                        tenantMoneyInitializingSet.remove(connectionId);
+                    }
+                }
+            }
         }
 
         return actualDataSource;

Reply via email to