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 e76adfbe5 FINERACT-1787: Fineract using wrong business date due to 
lack of resetting the ActionContext
e76adfbe5 is described below

commit e76adfbe564ce6d712e325f8af20646b07e332f1
Author: Adam Saghy <[email protected]>
AuthorDate: Thu Oct 27 14:13:38 2022 +0200

    FINERACT-1787: Fineract using wrong business date due to lack of resetting 
the ActionContext
---
 .../apache/fineract/cob/COBBusinessStepServiceImpl.java  |  1 +
 .../fineract/cob/common/InitialisationTasklet.java       |  3 +++
 ...itialisationTasklet.java => ResetContextTasklet.java} | 16 ++++------------
 .../loan/InlineLoanCOBBuildExecutionContextTasklet.java  |  3 +++
 .../fineract/cob/loan/LoanCOBWorkerConfiguration.java    | 14 +++++++++++++-
 .../apache/fineract/cob/loan/LoanInlineCOBConfig.java    | 13 ++++++++++++-
 .../core/service/ThreadLocalContextUtil.java             |  8 ++++++++
 .../jobs/service/JobSchedulerServiceImpl.java            |  2 ++
 .../jobs/service/SchedulerJobListener.java               |  2 ++
 .../jobs/service/SchedulerTriggerListener.java           |  2 ++
 .../filter/TenantAwareBasicAuthenticationFilter.java     |  3 ++-
 .../filter/TenantAwareTenantIdentifierFilter.java        |  3 ++-
 12 files changed, 54 insertions(+), 16 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
index 33361c4cc..e716c1ac3 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
@@ -54,6 +54,7 @@ public class COBBusinessStepServiceImpl implements 
COBBusinessStepService {
         businessEventNotifierService.startExternalEventRecording();
         for (String businessStep : executionMap.values()) {
             try {
+                ThreadLocalContextUtil.setActionContext(ActionContext.COB);
                 COBBusinessStep<S> businessStepBean = (COBBusinessStep<S>) 
applicationContext.getBean(businessStep);
                 item = businessStepBean.execute(item);
             } catch (Exception e) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
index 20be30778..160eee62f 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
@@ -20,6 +20,8 @@ package org.apache.fineract.cob.common;
 
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
 import org.jetbrains.annotations.NotNull;
@@ -43,6 +45,7 @@ public class InitialisationTasklet implements Tasklet {
         UsernamePasswordAuthenticationToken auth = new 
UsernamePasswordAuthenticationToken(user, user.getPassword(),
                 new 
NullAuthoritiesMapper().mapAuthorities(user.getAuthorities()));
         SecurityContextHolder.getContext().setAuthentication(auth);
+        ThreadLocalContextUtil.setActionContext(ActionContext.COB);
         return RepeatStatus.FINISHED;
     }
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/common/ResetContextTasklet.java
similarity index 63%
copy from 
fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
copy to 
fineract-provider/src/main/java/org/apache/fineract/cob/common/ResetContextTasklet.java
index 20be30778..60f51f2ea 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/common/InitialisationTasklet.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/common/ResetContextTasklet.java
@@ -20,29 +20,21 @@ package org.apache.fineract.cob.common;
 
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.fineract.useradministration.domain.AppUser;
-import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.batch.core.StepContribution;
 import org.springframework.batch.core.scope.context.ChunkContext;
 import org.springframework.batch.core.step.tasklet.Tasklet;
 import org.springframework.batch.repeat.RepeatStatus;
-import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import 
org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
-import org.springframework.security.core.context.SecurityContextHolder;
 
 @Slf4j
 @RequiredArgsConstructor
-public class InitialisationTasklet implements Tasklet {
-
-    private final AppUserRepositoryWrapper userRepository;
+public class ResetContextTasklet implements Tasklet {
 
     @Override
     public RepeatStatus execute(@NotNull StepContribution contribution, 
@NotNull ChunkContext chunkContext) throws Exception {
-        AppUser user = userRepository.fetchSystemUser();
-        UsernamePasswordAuthenticationToken auth = new 
UsernamePasswordAuthenticationToken(user, user.getPassword(),
-                new 
NullAuthoritiesMapper().mapAuthorities(user.getAuthorities()));
-        SecurityContextHolder.getContext().setAuthentication(auth);
+        ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
         return RepeatStatus.FINISHED;
     }
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/InlineLoanCOBBuildExecutionContextTasklet.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/InlineLoanCOBBuildExecutionContextTasklet.java
index 37bf40e51..e3856fd05 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/InlineLoanCOBBuildExecutionContextTasklet.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/InlineLoanCOBBuildExecutionContextTasklet.java
@@ -26,7 +26,9 @@ import java.util.TreeMap;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.cob.COBBusinessStepService;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import 
org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameter;
 import 
org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository;
 import org.apache.fineract.infrastructure.springbatch.SpringBatchJobConstants;
@@ -54,6 +56,7 @@ public class InlineLoanCOBBuildExecutionContextTasklet 
implements Tasklet, Initi
 
     @Override
     public RepeatStatus execute(StepContribution contribution, ChunkContext 
chunkContext) throws Exception {
+        ThreadLocalContextUtil.setActionContext(ActionContext.COB);
         TreeMap<Long, String> cobBusinessStepMap = 
cobBusinessStepService.getCOBBusinessStepMap(LoanCOBBusinessStep.class,
                 LoanCOBConstant.LOAN_COB_JOB_NAME);
         
contribution.getStepExecution().getExecutionContext().put(LoanCOBConstant.LOAN_IDS,
 getLoanIdsFromJobParameters(chunkContext));
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBWorkerConfiguration.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBWorkerConfiguration.java
index 0a3bd5a33..823675a31 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBWorkerConfiguration.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBWorkerConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.fineract.cob.loan;
 
 import org.apache.fineract.cob.COBBusinessStepService;
 import org.apache.fineract.cob.common.InitialisationTasklet;
+import org.apache.fineract.cob.common.ResetContextTasklet;
 import org.apache.fineract.cob.domain.LoanAccountLockRepository;
 import org.apache.fineract.cob.listener.ChunkProcessingLoanItemListener;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
@@ -74,7 +75,7 @@ public class LoanCOBWorkerConfiguration {
     @Bean
     public Flow flow() {
         return new 
FlowBuilder<Flow>("cobFlow").start(initialisationStep(null)).next(applyLockStep(null)).next(loanBusinessStep(null))
-                .build();
+                .next(resetContextStep(null)).build();
     }
 
     @Bean
@@ -99,6 +100,12 @@ public class LoanCOBWorkerConfiguration {
         return localStepBuilderFactory.get("Apply lock - Step:" + 
partitionName).tasklet(applyLock()).listener(promotionListener()).build();
     }
 
+    @Bean
+    @StepScope
+    public Step 
resetContextStep(@Value("#{stepExecutionContext['partition']}") String 
partitionName) {
+        return localStepBuilderFactory.get("Reset context - Step:" + 
partitionName).tasklet(resetContext()).build();
+    }
+
     @Bean
     public InitialisationTasklet initialiseContext() {
         return new InitialisationTasklet(userRepository);
@@ -114,6 +121,11 @@ public class LoanCOBWorkerConfiguration {
         return new ApplyLoanLockTasklet(accountLockRepository);
     }
 
+    @Bean
+    public ResetContextTasklet resetContext() {
+        return new ResetContextTasklet();
+    }
+
     @Bean
     @StepScope
     public LoanItemReader cobWorkerItemReader() {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInlineCOBConfig.java
 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInlineCOBConfig.java
index cbaa5bc0d..71bf56714 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInlineCOBConfig.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInlineCOBConfig.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.cob.loan;
 
 import org.apache.fineract.cob.COBBusinessStepService;
+import org.apache.fineract.cob.common.ResetContextTasklet;
 import org.apache.fineract.cob.domain.LoanAccountLockRepository;
 import org.apache.fineract.cob.listener.InlineCOBLoanItemListener;
 import 
org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
@@ -83,7 +84,7 @@ public class LoanInlineCOBConfig {
     @Bean(name = "loanInlineCOBJob")
     public Job loanInlineCOBJob() {
         return jobBuilderFactory.get(LoanCOBConstant.INLINE_LOAN_COB_JOB_NAME) 
//
-                
.start(inlineCOBBuildExecutionContextStep()).next(inlineLoanCOBStep()) //
+                
.start(inlineCOBBuildExecutionContextStep()).next(inlineLoanCOBStep()).next(inlineCOBResetContextStep())
 //
                 .incrementer(new RunIdIncrementer()) //
                 .build();
     }
@@ -98,6 +99,11 @@ public class LoanInlineCOBConfig {
         return new InlineCOBLoanItemProcessor(cobBusinessStepService);
     }
 
+    @Bean
+    public Step inlineCOBResetContextStep() {
+        return stepBuilderFactory.get("Reset context - 
Step").tasklet(inlineCOBResetContext()).build();
+    }
+
     @Bean
     public InlineCOBLoanItemWriter inlineCobWorkerItemWriter() {
         InlineCOBLoanItemWriter repositoryItemWriter = new 
InlineCOBLoanItemWriter(accountLockRepository);
@@ -110,6 +116,11 @@ public class LoanInlineCOBConfig {
         return new InlineCOBLoanItemListener(accountLockRepository, 
transactionTemplate);
     }
 
+    @Bean
+    public ResetContextTasklet inlineCOBResetContext() {
+        return new ResetContextTasklet();
+    }
+
     @Bean
     public ExecutionContextPromotionListener inlineCobPromotionListener() {
         ExecutionContextPromotionListener listener = new 
ExecutionContextPromotionListener();
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java
index fad559f15..fe3f10d54 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java
@@ -116,4 +116,12 @@ public final class ThreadLocalContextUtil {
         setBusinessDates(fineractContext.getBusinessDateContext());
         setActionContext(fineractContext.getActionContext());
     }
+
+    public static void reset() {
+        contextHolder.remove();
+        tenantContext.remove();
+        authTokenContext.remove();
+        businessDateContext.remove();
+        actionContext.remove();
+    }
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
index 654efc063..54bdcd437 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobSchedulerServiceImpl.java
@@ -26,6 +26,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
 import 
org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
@@ -57,6 +58,7 @@ public class JobSchedulerServiceImpl implements 
ApplicationListener<ContextRefre
         for (final FineractPlatformTenant tenant : allTenants) {
             ThreadLocalContextUtil.setTenant(tenant);
             HashMap<BusinessDateType, LocalDate> businessDates = 
businessDateReadPlatformService.getBusinessDates();
+            ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
             ThreadLocalContextUtil.setBusinessDates(businessDates);
             final List<ScheduledJobDetail> scheduledJobDetails = 
schedularWritePlatformService
                     .retrieveAllJobs(fineractProperties.getNodeId());
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
index 8fa314ac1..6f1e412cf 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
 import 
org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
 import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobRunHistory;
@@ -67,6 +68,7 @@ public class SchedulerJobListener implements JobListener {
                 authoritiesMapper.mapAuthorities(user.getAuthorities()));
         SecurityContextHolder.getContext().setAuthentication(auth);
         HashMap<BusinessDateType, LocalDate> businessDates = 
businessDateReadPlatformService.getBusinessDates();
+        ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
         ThreadLocalContextUtil.setBusinessDates(businessDates);
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
index 5952f5503..a48910de9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerTriggerListener.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
 import 
org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
+import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import 
org.apache.fineract.infrastructure.security.service.TenantDetailsService;
@@ -69,6 +70,7 @@ public class SchedulerTriggerListener implements 
TriggerListener {
         final String tenantIdentifier = 
trigger.getJobDataMap().getString(SchedulerServiceConstants.TENANT_IDENTIFIER);
         final FineractPlatformTenant tenant = 
this.tenantDetailsService.loadTenantById(tenantIdentifier);
         ThreadLocalContextUtil.setTenant(tenant);
+        ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
         HashMap<BusinessDateType, LocalDate> businessDates = 
businessDateReadPlatformService.getBusinessDates();
         ThreadLocalContextUtil.setBusinessDates(businessDates);
         final JobKey key = trigger.getJobKey();
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
index 4a8c0d494..d9a43c437 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java
@@ -103,7 +103,7 @@ public class TenantAwareBasicAuthenticationFilter extends 
BasicAuthenticationFil
         task.start();
 
         try {
-
+            ThreadLocalContextUtil.reset();
             if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
                 // ignore to allow 'preflight' requests from AJAX applications
                 // in different origin (domain name)
@@ -157,6 +157,7 @@ public class TenantAwareBasicAuthenticationFilter extends 
BasicAuthenticationFil
             response.addHeader("WWW-Authenticate", "Basic realm=\"" + 
"Fineract Platform API" + "\"");
             response.sendError(HttpServletResponse.SC_BAD_REQUEST, 
e.getMessage());
         } finally {
+            ThreadLocalContextUtil.reset();
             task.stop();
             final PlatformRequestLog log = PlatformRequestLog.from(task, 
request);
             LOG.debug("{}", this.toApiJsonSerializer.serialize(log));
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
index 82f6abab8..193538773 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/filter/TenantAwareTenantIdentifierFilter.java
@@ -88,7 +88,7 @@ public class TenantAwareTenantIdentifierFilter extends 
GenericFilterBean {
         task.start();
 
         try {
-
+            ThreadLocalContextUtil.reset();
             // allows for Cross-Origin
             // Requests (CORs) to be performed against the platform API.
             response.setHeader("Access-Control-Allow-Origin", "*"); // NOSONAR
@@ -148,6 +148,7 @@ public class TenantAwareTenantIdentifierFilter extends 
GenericFilterBean {
             response.addHeader("WWW-Authenticate", "Basic realm=\"" + 
"Fineract Platform API" + "\"");
             response.sendError(HttpServletResponse.SC_BAD_REQUEST, 
e.getMessage());
         } finally {
+            ThreadLocalContextUtil.reset();
             task.stop();
             final PlatformRequestLog logRequest = 
PlatformRequestLog.from(task, request);
             log.debug("{}", this.toApiJsonSerializer.serialize(logRequest));

Reply via email to