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));