[FINERACT-1678] Fix Inline COB execution

This commit is contained in:
taskain7
2022-11-30 08:52:36 +01:00
committed by Arnold Gálovics
parent 53b474b461
commit 47108e0ac9
5 changed files with 76 additions and 15 deletions
@@ -18,8 +18,14 @@
*/
package org.apache.fineract.cob.common;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.loan.LoanCOBConstant;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.ActionContext;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.useradministration.domain.AppUser;
@@ -41,11 +47,18 @@ public class InitialisationTasklet implements Tasklet {
@Override
public RepeatStatus execute(@NotNull StepContribution contribution, @NotNull ChunkContext chunkContext) throws Exception {
HashMap<BusinessDateType, LocalDate> businessDates = ThreadLocalContextUtil.getBusinessDates();
AppUser user = userRepository.fetchSystemUser();
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword(),
new NullAuthoritiesMapper().mapAuthorities(user.getAuthorities()));
SecurityContextHolder.getContext().setAuthentication(auth);
ThreadLocalContextUtil.setActionContext(ActionContext.COB);
String businessDateString = Objects.requireNonNull((String) chunkContext.getStepContext().getStepExecution().getJobExecution()
.getExecutionContext().get(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME));
LocalDate businessDate = LocalDate.parse(businessDateString, DateTimeFormatter.ISO_DATE);
businessDates.put(BusinessDateType.COB_DATE, businessDate);
businessDates.put(BusinessDateType.BUSINESS_DATE, businessDate.plusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
return RepeatStatus.FINISHED;
}
}
@@ -20,12 +20,16 @@ package org.apache.fineract.cob.loan;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.ActionContext;
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
@@ -37,14 +41,11 @@ 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.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
@Component
public class InlineLoanCOBBuildExecutionContextTasklet implements Tasklet {
private final GoogleGsonSerializerHelper gsonFactory;
private final COBBusinessStepService cobBusinessStepService;
private final CustomJobParameterRepository customJobParameterRepository;
@@ -52,15 +53,30 @@ public class InlineLoanCOBBuildExecutionContextTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
HashMap<BusinessDateType, LocalDate> businessDates = ThreadLocalContextUtil.getBusinessDates();
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));
contribution.getStepExecution().getExecutionContext().put(LoanCOBConstant.BUSINESS_STEP_MAP, cobBusinessStepMap);
String businessDateString = getBusinessDateFromJobParameters(chunkContext);
contribution.getStepExecution().getExecutionContext().put(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME, businessDateString);
LocalDate businessDate = LocalDate.parse(businessDateString, DateTimeFormatter.ISO_DATE);
businessDates.put(BusinessDateType.COB_DATE, businessDate);
businessDates.put(BusinessDateType.BUSINESS_DATE, businessDate.plusDays(1));
ThreadLocalContextUtil.setBusinessDates(businessDates);
return RepeatStatus.FINISHED;
}
private String getBusinessDateFromJobParameters(ChunkContext chunkContext) {
Long customJobParameterId = (Long) chunkContext.getStepContext().getJobParameters()
.get(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME);
CustomJobParameter customJobParameter = customJobParameterRepository.findById(customJobParameterId)
.orElseThrow(() -> new LoanNotFoundException(customJobParameterId));
String parameterJson = customJobParameter.getParameterJson();
return gson.fromJson(parameterJson, new TypeToken<String>() {}.getType());
}
private List<Long> getLoanIdsFromJobParameters(ChunkContext chunkContext) {
Long customJobParameterId = (Long) chunkContext.getStepContext().getJobParameters()
.get(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY);
@@ -22,7 +22,6 @@ 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;
import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository;
import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.infrastructure.springbatch.PropertyService;
@@ -60,12 +59,10 @@ public class LoanInlineCOBConfig {
private TransactionTemplate transactionTemplate;
@Autowired
private CustomJobParameterRepository loanIdListRepository;
@Autowired
private GoogleGsonSerializerHelper googleGsonSerializerHelper;
@Bean
public InlineLoanCOBBuildExecutionContextTasklet inlineLoanCOBBuildExecutionContextTasklet() {
return new InlineLoanCOBBuildExecutionContextTasklet(googleGsonSerializerHelper, cobBusinessStepService, loanIdListRepository);
return new InlineLoanCOBBuildExecutionContextTasklet(cobBusinessStepService, loanIdListRepository);
}
@Bean
@@ -124,7 +121,8 @@ public class LoanInlineCOBConfig {
@Bean
public ExecutionContextPromotionListener inlineCobPromotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[] { LoanCOBConstant.LOAN_IDS, LoanCOBConstant.BUSINESS_STEP_MAP });
listener.setKeys(
new String[] { LoanCOBConstant.LOAN_IDS, LoanCOBConstant.BUSINESS_STEP_MAP, LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME });
return listener;
}
}
@@ -21,6 +21,8 @@ package org.apache.fineract.cob.service;
import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW;
import com.google.gson.Gson;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -102,7 +104,9 @@ public class InlineLoanCOBExecutorServiceImpl implements InlineExecutorService<L
throw new JobNotFoundException(jobName, e);
}
JobParameters jobParameters = new JobParametersBuilder(jobExplorer).getNextJobParameters(inlineLoanCOBJob)
.addJobParameters(new JobParameters(getJobParametersMap(loanIds))).toJobParameters();
.addJobParameters(new JobParameters(
getJobParametersMap(loanIds, ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE))))
.toJobParameters();
JobExecution jobExecution;
try {
jobExecution = jobLauncher.run(inlineLoanCOBJob, jobParameters);
@@ -141,16 +145,18 @@ public class InlineLoanCOBExecutorServiceImpl implements InlineExecutorService<L
return loanAccountLocks;
}
private Map<String, JobParameter> getJobParametersMap(List<Long> loanIds) {
private Map<String, JobParameter> getJobParametersMap(List<Long> loanIds, LocalDate businessDate) {
// TODO: refactor for a more generic solution
String parameterJson = gson.toJson(loanIds);
CustomJobParameter loanIdsJobParameter = new CustomJobParameter();
loanIdsJobParameter.setParameterJson(parameterJson);
Long loanIdsJobParameterId = customJobParameterRepository.saveAndFlush(loanIdsJobParameter).getId();
CustomJobParameter businessDateJobParameter = new CustomJobParameter();
businessDateJobParameter.setParameterJson(gson.toJson(businessDate.format(DateTimeFormatter.ISO_DATE)));
Long businessDateJobParameterId = customJobParameterRepository.saveAndFlush(businessDateJobParameter).getId();
Map<String, JobParameter> jobParameterMap = new HashMap<>();
jobParameterMap.put(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY, new JobParameter(loanIdsJobParameterId));
String businessDate = ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE).toString();
jobParameterMap.put(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME, new JobParameter(businessDate));
jobParameterMap.put(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME, new JobParameter(businessDateJobParameterId));
return jobParameterMap;
}
@@ -24,21 +24,34 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import io.cucumber.java8.En;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import org.apache.fineract.cob.loan.LoanCOBConstant;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
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.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.scope.context.StepContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.security.core.context.SecurityContextHolder;
public class InitialisationTaskletStepDefinitions implements En {
private static final LocalDate TODAY = LocalDate.now(ZoneId.systemDefault());
private AppUserRepositoryWrapper userRepository = mock(AppUserRepositoryWrapper.class);
private InitialisationTasklet initialisationTasklet = new InitialisationTasklet(userRepository);
private AppUser appUser = mock(AppUser.class);
private RepeatStatus resultItem;
private ChunkContext chunkContext;
public InitialisationTaskletStepDefinitions() {
Given("/^The InitialisationTasklet.execute method with action (.*)$/", (String action) -> {
@@ -48,16 +61,29 @@ public class InitialisationTaskletStepDefinitions implements En {
} else {
lenient().when(this.userRepository.fetchSystemUser()).thenReturn(appUser);
}
HashMap<BusinessDateType, LocalDate> businessDates = new HashMap<>();
LocalDate businessDate = TODAY;
LocalDate cobBusinessDate = businessDate.minusDays(1);
businessDates.put(BusinessDateType.BUSINESS_DATE, businessDate);
businessDates.put(BusinessDateType.COB_DATE, cobBusinessDate);
ThreadLocalContextUtil.setBusinessDates(businessDates);
JobExecution jobExecution = new JobExecution(1L);
jobExecution.getExecutionContext().put(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME,
cobBusinessDate.format(DateTimeFormatter.ISO_DATE));
StepExecution stepExecution = new StepExecution("step", jobExecution);
StepContext stepContext = new StepContext(stepExecution);
chunkContext = new ChunkContext(stepContext);
});
When("InitialisationTasklet.execute method executed", () -> {
resultItem = this.initialisationTasklet.execute(null, null);
resultItem = this.initialisationTasklet.execute(null, chunkContext);
});
Then("InitialisationTasklet.execute result should match", () -> {
assertEquals(RepeatStatus.FINISHED, resultItem);
assertEquals(appUser, SecurityContextHolder.getContext().getAuthentication().getPrincipal());
assertEquals(TODAY, ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.BUSINESS_DATE));
assertEquals(TODAY.minusDays(1), ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE));
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
});
@@ -65,6 +91,8 @@ public class InitialisationTaskletStepDefinitions implements En {
assertThrows(RuntimeException.class, () -> {
resultItem = this.initialisationTasklet.execute(null, null);
});
assertEquals(TODAY, ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.BUSINESS_DATE));
assertEquals(TODAY.minusDays(1), ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE));
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
});
}