FINERACT-1787: Fineract using wrong business date due to lack of resetting the ActionContext
This commit is contained in:
committed by
Arnold Gálovics
parent
a293dee55c
commit
e76adfbe56
+1
@@ -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) {
|
||||
|
||||
+3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
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.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;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ResetContextTasklet implements Tasklet {
|
||||
|
||||
@Override
|
||||
public RepeatStatus execute(@NotNull StepContribution contribution, @NotNull ChunkContext chunkContext) throws Exception {
|
||||
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
}
|
||||
+3
@@ -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));
|
||||
|
||||
+13
-1
@@ -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() {
|
||||
|
||||
+12
-1
@@ -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();
|
||||
|
||||
+8
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -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());
|
||||
|
||||
+2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -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();
|
||||
|
||||
+2
-1
@@ -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));
|
||||
|
||||
+2
-1
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user