From ac1aeea12dd9558d102c5f6242ac6e0e8ad31a25 Mon Sep 17 00:00:00 2001 From: Janos Haber Date: Thu, 4 May 2023 22:45:42 +0200 Subject: [PATCH] - [x] Move from JobParameter to CustomJobParameter - [x] Improve CustomJobParameterResolver to raise custom exception and work with StepExecution - [x] Improve tests --- .../common/CustomJobParameterResolver.java | 49 ++++++++++++++++--- .../cob/loan/ApplyLoanLockTasklet.java | 11 +++-- ...neLoanCOBBuildExecutionContextTasklet.java | 11 ++--- .../cob/loan/LoanCOBManagerConfiguration.java | 4 +- .../cob/loan/LoanCOBWorkerConfiguration.java | 8 ++- .../cob/loan/LoanIdParameterTasklet.java | 7 ++- .../cob/loan/LoanInlineCOBConfig.java | 9 +++- .../fineract/cob/loan/LoanItemReader.java | 11 +++-- .../fineract/cob/loan/LockLoanTasklet.java | 9 +++- .../service/LoanCOBCatchUpServiceImpl.java | 21 +++++--- .../jobs/domain/JobExecutionRepository.java | 32 ------------ .../RunningJobWithCustomParameters.java} | 17 +++---- .../ApplyLoanLockTaskletStepDefinitions.java | 8 ++- .../loan/FetchAndLockLoanStepDefinitions.java | 8 ++- .../loan/LoanItemReaderStepDefinitions.java | 8 ++- 15 files changed, 127 insertions(+), 86 deletions(-) rename fineract-provider/src/main/java/org/apache/fineract/{cob/loan/LoanCatchUpSupport.java => infrastructure/jobs/domain/RunningJobWithCustomParameters.java} (61%) diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/common/CustomJobParameterResolver.java b/fineract-provider/src/main/java/org/apache/fineract/cob/common/CustomJobParameterResolver.java index 9e156856c..9de07c736 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/common/CustomJobParameterResolver.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/common/CustomJobParameterResolver.java @@ -20,7 +20,11 @@ package org.apache.fineract.cob.common; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; +import java.util.Optional; import java.util.Set; import lombok.RequiredArgsConstructor; import org.apache.fineract.cob.exceptions.CustomJobParameterNotFoundException; @@ -29,7 +33,9 @@ import org.apache.fineract.infrastructure.jobs.data.JobParameterDTO; import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameter; import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository; import org.apache.fineract.infrastructure.springbatch.SpringBatchJobConstants; +import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @@ -50,7 +56,8 @@ public class CustomJobParameterResolver implements InitializingBean { public void resolve(StepContribution contribution, ChunkContext chunkContext, String customJobParameterKey, String parameterNameInExecutionContext) { - Set jobParameterDTOList = getCustomJobParameterSet(chunkContext); + Set jobParameterDTOList = getCustomJobParameterSet(chunkContext.getStepContext().getStepExecution()) + .orElseThrow(() -> new CustomJobParameterNotFoundException(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY)); JobParameterDTO businessDateParameter = jobParameterDTOList.stream() .filter(jobParameterDTO -> customJobParameterKey.equals(jobParameterDTO.getParameterName())) // .findFirst().orElseThrow(() -> new CustomJobParameterNotFoundException(customJobParameterKey)); @@ -58,12 +65,38 @@ public class CustomJobParameterResolver implements InitializingBean { businessDateParameter.getParameterValue()); } - private Set getCustomJobParameterSet(ChunkContext chunkContext) { - Long customJobParameterId = (Long) chunkContext.getStepContext().getJobParameters() - .get(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY); - CustomJobParameter customJobParameter = customJobParameterRepository.findById(customJobParameterId) - .orElseThrow(() -> new CustomJobParameterNotFoundException(customJobParameterId)); - String parameterJson = customJobParameter.getParameterJson(); - return gson.fromJson(parameterJson, new TypeToken>() {}.getType()); + /** + * Get parameter set from custom job parameter table + * + * @param stepExecution + * @return + */ + public Optional> getCustomJobParameterSet(StepExecution stepExecution) { + Long customJobParameterId = (Long) getJobParameters(stepExecution).get(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY); + return customJobParameterRepository.findById(customJobParameterId).map(CustomJobParameter::getParameterJson) + .map(json -> gson.fromJson(json, new TypeToken>() {}.getType())); } + + public Optional getCustomJobParameterById(StepExecution stepExecution, String key) { + return getCustomJobParameterSet(stepExecution) + .flatMap(paramterList -> paramterList.stream().filter(dto -> dto.getParameterName().equals(key)).findFirst()) + .map(JobParameterDTO::getParameterValue); + } + + /** + * Resolve job parameters from step execution context, + * like @org.springframework.batch.core.scope.context.StepContext#getJobParameters() + * + * @param stepExecution + * StepExecution context + * @return + */ + private Map getJobParameters(StepExecution stepExecution) { + Map result = new HashMap<>(); + for (Map.Entry entry : stepExecution.getJobParameters().getParameters().entrySet()) { + result.put(entry.getKey(), entry.getValue().getValue()); + } + return Collections.unmodifiableMap(result); + } + } diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/ApplyLoanLockTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/ApplyLoanLockTasklet.java index 6efb01bb2..013c9ebae 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/ApplyLoanLockTasklet.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/ApplyLoanLockTasklet.java @@ -28,6 +28,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.apache.fineract.cob.domain.LoanAccountLock; import org.apache.fineract.cob.domain.LockOwner; @@ -41,11 +42,12 @@ import org.springframework.batch.repeat.RepeatStatus; @Slf4j @RequiredArgsConstructor -public class ApplyLoanLockTasklet implements Tasklet, LoanCatchUpSupport { +public class ApplyLoanLockTasklet implements Tasklet { private final FineractProperties fineractProperties; private final LoanLockingService loanLockingService; private final RetrieveLoanIdService retrieveLoanIdService; + private final CustomJobParameterResolver customJobParameterResolver; @Override public RepeatStatus execute(@NotNull StepContribution contribution, @NotNull ChunkContext chunkContext) throws Exception { @@ -57,8 +59,11 @@ public class ApplyLoanLockTasklet implements Tasklet, LoanCatchUpSupport { || (loanCOBParameter.getMinLoanId().equals(0L) && loanCOBParameter.getMaxLoanId().equals(0L))) { loanIds = Collections.emptyList(); } else { - loanIds = new ArrayList<>(retrieveLoanIdService - .retrieveAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(loanCOBParameter, isCatchUp(contribution))); + loanIds = new ArrayList<>( + retrieveLoanIdService.retrieveAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(loanCOBParameter, + customJobParameterResolver + .getCustomJobParameterById(contribution.getStepExecution(), LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME) + .map(Boolean::parseBoolean).orElse(false))); } List> loanIdPartitions = Lists.partition(loanIds, getInClauseParameterSizeLimit()); List accountLocks = new ArrayList<>(); 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 79868b76c..400a35893 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 @@ -30,6 +30,7 @@ import java.util.Set; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.fineract.cob.COBBusinessStepService; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.BusinessStepNameAndOrder; import org.apache.fineract.cob.exceptions.CustomJobParameterNotFoundException; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; @@ -52,6 +53,7 @@ public class InlineLoanCOBBuildExecutionContextTasklet implements Tasklet { private final COBBusinessStepService cobBusinessStepService; private final CustomJobParameterRepository customJobParameterRepository; + private final CustomJobParameterResolver customJobParameterResolver; private final Gson gson = GoogleGsonSerializerHelper.createSimpleGson(); @@ -87,12 +89,9 @@ public class InlineLoanCOBBuildExecutionContextTasklet implements Tasklet { } private List getLoanIdsFromJobParameters(ChunkContext chunkContext) { - Long customJobParameterId = (Long) chunkContext.getStepContext().getJobParameters() - .get(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY); - CustomJobParameter customJobParameter = customJobParameterRepository.findById(customJobParameterId) - .orElseThrow(() -> new LoanNotFoundException(customJobParameterId)); - String parameterJson = customJobParameter.getParameterJson(); - Set jobParameters = gson.fromJson(parameterJson, new TypeToken>() {}.getType()); + Set jobParameters = customJobParameterResolver + .getCustomJobParameterSet(chunkContext.getStepContext().getStepExecution()) + .orElseThrow(() -> new LoanNotFoundException(SpringBatchJobConstants.CUSTOM_JOB_PARAMETER_ID_KEY)); JobParameterDTO loanIdsParameter = jobParameters.stream() .filter(jobParameterDTO -> jobParameterDTO.getParameterName().equals(LoanCOBConstant.LOAN_IDS_PARAMETER_NAME)).findFirst() .orElseThrow(() -> new CustomJobParameterNotFoundException(LoanCOBConstant.LOAN_IDS_PARAMETER_NAME)); diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBManagerConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBManagerConfiguration.java index 07c9e962d..4d6a04cb7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBManagerConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBManagerConfiguration.java @@ -112,13 +112,13 @@ public class LoanCOBManagerConfiguration { @Bean @JobScope public LoanIdParameterTasklet loanIdParameterTasklet() { - return new LoanIdParameterTasklet(retrieveLoanIdService); + return new LoanIdParameterTasklet(retrieveLoanIdService, customJobParameterResolver); } @Bean @JobScope public LockLoanTasklet lockLoanTasklet() { - return new LockLoanTasklet(loanLockingService); + return new LockLoanTasklet(loanLockingService, customJobParameterResolver); } @Bean 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 71437256a..94f39596b 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 @@ -19,6 +19,7 @@ package org.apache.fineract.cob.loan; import org.apache.fineract.cob.COBBusinessStepService; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.common.InitialisationTasklet; import org.apache.fineract.cob.common.ResetContextTasklet; import org.apache.fineract.cob.listener.ChunkProcessingLoanItemListener; @@ -71,6 +72,9 @@ public class LoanCOBWorkerConfiguration { @Autowired private LoanLockingService loanLockingService; + @Autowired + private CustomJobParameterResolver customJobParameterResolver; + @Bean(name = LoanCOBConstant.LOAN_COB_WORKER_STEP) public Step loanCOBWorkerStep() { return stepBuilderFactory.get("Loan COB worker - Step").inputChannel(inboundRequests).flow(flow()).build(); @@ -122,7 +126,7 @@ public class LoanCOBWorkerConfiguration { @Bean public ApplyLoanLockTasklet applyLock() { - return new ApplyLoanLockTasklet(fineractProperties, loanLockingService, retrieveLoanIdService); + return new ApplyLoanLockTasklet(fineractProperties, loanLockingService, retrieveLoanIdService, customJobParameterResolver); } @Bean @@ -133,7 +137,7 @@ public class LoanCOBWorkerConfiguration { @Bean @StepScope public LoanItemReader cobWorkerItemReader() { - return new LoanItemReader(loanRepository, retrieveLoanIdService); + return new LoanItemReader(loanRepository, retrieveLoanIdService, customJobParameterResolver); } @Bean diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanIdParameterTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanIdParameterTasklet.java index 75b6ed6f2..781bb051a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanIdParameterTasklet.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanIdParameterTasklet.java @@ -22,6 +22,7 @@ import java.time.LocalDate; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; @@ -30,9 +31,10 @@ import org.springframework.batch.repeat.RepeatStatus; @Slf4j @RequiredArgsConstructor -public class LoanIdParameterTasklet implements Tasklet, LoanCatchUpSupport { +public class LoanIdParameterTasklet implements Tasklet { private final RetrieveLoanIdService retrieveLoanIdService; + private final CustomJobParameterResolver customJobParameterResolver; @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { @@ -40,7 +42,8 @@ public class LoanIdParameterTasklet implements Tasklet, LoanCatchUpSupport { .get(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME); LocalDate businessDate = LocalDate.parse(Objects.requireNonNull(businessDateParameter)); LoanCOBParameter minAndMaxLoanId = retrieveLoanIdService.retrieveMinAndMaxLoanIdsNDaysBehind(LoanCOBConstant.NUMBER_OF_DAYS_BEHIND, - businessDate, isCatchUp(contribution)); + businessDate, customJobParameterResolver.getCustomJobParameterById(chunkContext.getStepContext().getStepExecution(), + LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME).map(Boolean::parseBoolean).orElse(false)); if (Objects.isNull(minAndMaxLoanId) || (Objects.isNull(minAndMaxLoanId.getMinLoanId()) && Objects.isNull(minAndMaxLoanId.getMaxLoanId()))) { contribution.getStepExecution().getJobExecution().getExecutionContext().put(LoanCOBConstant.LOAN_COB_PARAMETER, 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 9e92cd61a..1ff72a5a6 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.CustomJobParameterResolver; import org.apache.fineract.cob.common.ResetContextTasklet; import org.apache.fineract.cob.domain.LoanAccountLockRepository; import org.apache.fineract.cob.listener.InlineCOBLoanItemListener; @@ -58,13 +59,17 @@ public class LoanInlineCOBConfig { @Autowired private TransactionTemplate transactionTemplate; @Autowired - private CustomJobParameterRepository loanIdListRepository; + private CustomJobParameterRepository customJobParameterRepository; + @Autowired + private CustomJobParameterResolver customJobParameterResolver; + @Autowired private LoanLockingService loanLockingService; @Bean public InlineLoanCOBBuildExecutionContextTasklet inlineLoanCOBBuildExecutionContextTasklet() { - return new InlineLoanCOBBuildExecutionContextTasklet(cobBusinessStepService, loanIdListRepository); + return new InlineLoanCOBBuildExecutionContextTasklet(cobBusinessStepService, customJobParameterRepository, + customJobParameterResolver); } @Bean diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemReader.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemReader.java index def3ab969..4dd4df780 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemReader.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemReader.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository; import org.jetbrains.annotations.NotNull; @@ -29,13 +30,16 @@ import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.annotation.BeforeStep; import org.springframework.batch.item.ExecutionContext; -public class LoanItemReader extends AbstractLoanItemReader implements LoanCatchUpSupport { +public class LoanItemReader extends AbstractLoanItemReader { private final RetrieveLoanIdService retrieveLoanIdService; + private final CustomJobParameterResolver customJobParameterResolver; - public LoanItemReader(LoanRepository loanRepository, RetrieveLoanIdService retrieveLoanIdService) { + public LoanItemReader(LoanRepository loanRepository, RetrieveLoanIdService retrieveLoanIdService, + CustomJobParameterResolver customJobParameterResolver) { super(loanRepository); this.retrieveLoanIdService = retrieveLoanIdService; + this.customJobParameterResolver = customJobParameterResolver; } @BeforeStep @@ -50,7 +54,8 @@ public class LoanItemReader extends AbstractLoanItemReader implements LoanCatchU loanIds = Collections.emptyList(); } else { loanIds = retrieveLoanIdService.retrieveAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(loanCOBParameter, - isCatchUp(stepExecution)); + customJobParameterResolver.getCustomJobParameterById(stepExecution, LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME) + .map(Boolean::parseBoolean).orElse(false)); } setRemainingData(new ArrayList<>(loanIds)); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LockLoanTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LockLoanTasklet.java index e0768c488..d2d503974 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LockLoanTasklet.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LockLoanTasklet.java @@ -22,6 +22,7 @@ import java.time.LocalDate; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.jetbrains.annotations.NotNull; import org.springframework.batch.core.StepContribution; @@ -31,9 +32,10 @@ import org.springframework.batch.repeat.RepeatStatus; @Slf4j @RequiredArgsConstructor -public class LockLoanTasklet implements Tasklet, LoanCatchUpSupport { +public class LockLoanTasklet implements Tasklet { private final LoanLockingService loanLockingService; + private final CustomJobParameterResolver customJobParameterResolver; @Override public RepeatStatus execute(@NotNull StepContribution contribution, @NotNull ChunkContext chunkContext) throws Exception { @@ -47,7 +49,10 @@ public class LockLoanTasklet implements Tasklet, LoanCatchUpSupport { || (Objects.isNull(loanCOBParameter.getMinLoanId()) && Objects.isNull(loanCOBParameter.getMaxLoanId()))) { loanCOBParameter = new LoanCOBParameter(0L, 0L); } - loanLockingService.applySoftLock(lastClosedBusinessDate, loanCOBParameter, isCatchUp(contribution)); + loanLockingService.applySoftLock(lastClosedBusinessDate, loanCOBParameter, + customJobParameterResolver + .getCustomJobParameterById(contribution.getStepExecution(), LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME) + .map(Boolean::parseBoolean).orElse(false)); return RepeatStatus.FINISHED; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java index 2cc77d04f..30f214a80 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java @@ -18,11 +18,11 @@ */ package org.apache.fineract.cob.service; +import com.google.gson.Gson; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.List; import lombok.RequiredArgsConstructor; -import org.apache.commons.collections4.CollectionUtils; import org.apache.fineract.cob.data.IsCatchUpRunningDTO; import org.apache.fineract.cob.data.LoanIdAndLastClosedBusinessDate; import org.apache.fineract.cob.data.OldestCOBProcessedLoanDTO; @@ -30,7 +30,9 @@ import org.apache.fineract.cob.loan.LoanCOBConstant; import org.apache.fineract.cob.loan.RetrieveLoanIdService; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.core.domain.FineractContext; +import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; +import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository; import org.apache.fineract.infrastructure.jobs.domain.JobExecutionRepository; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.explore.JobExplorer; @@ -46,6 +48,8 @@ public class LoanCOBCatchUpServiceImpl implements LoanCOBCatchUpService { private final RetrieveLoanIdService retrieveLoanIdService; private final LoanAccountLockService accountLockService; + private final CustomJobParameterRepository customJobParameterRepository; + protected Gson gson = GoogleGsonSerializerHelper.createSimpleGson(); @Override public void unlockHardLockedLoans() { @@ -75,12 +79,13 @@ public class LoanCOBCatchUpServiceImpl implements LoanCOBCatchUpService { public IsCatchUpRunningDTO isCatchUpRunning() { List runningCatchUpExecutionIds = jobExecutionRepository.getRunningJobsIdsByExecutionParameter(LoanCOBConstant.JOB_NAME, LoanCOBConstant.LOAN_COB_CUSTOM_JOB_PARAMETER_KEY, LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME, "true"); - if (CollectionUtils.isNotEmpty(runningCatchUpExecutionIds)) { - JobExecution jobExecution = jobExplorer.getJobExecution(runningCatchUpExecutionIds.get(0)); - String executionDateString = (String) jobExecution.getExecutionContext().get(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME); - return new IsCatchUpRunningDTO(true, LocalDate.parse(executionDateString, DateTimeFormatter.ISO_DATE)); - } else { - return new IsCatchUpRunningDTO(false, null); - } + return runningCatchUpExecutionIds // + .stream() // + .findFirst() // + .map(jobExplorer::getJobExecution) // + .map(JobExecution::getExecutionContext) // + .map(executionContext -> executionContext.getString(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME)) // + .map(result -> new IsCatchUpRunningDTO(true, LocalDate.parse(result, DateTimeFormatter.ISO_DATE))) // + .orElse(new IsCatchUpRunningDTO(false, null)); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/JobExecutionRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/JobExecutionRepository.java index b6f10b3e6..044b102b8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/JobExecutionRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/JobExecutionRepository.java @@ -163,37 +163,6 @@ public class JobExecutionRepository implements InitializingBean { """, Map.of("status", FAILED.name(), "jobExecutionId", stuckJobId)); } - public List getRunningJobsByExecutionParameter(String jobName, String parameterKeyName, String parameterValue) { - return namedParameterJdbcTemplate.queryForList(""" - SELECT bje.JOB_EXECUTION_ID - FROM BATCH_JOB_INSTANCE bji - INNER JOIN BATCH_JOB_EXECUTION bje - ON bji.JOB_INSTANCE_ID = bje.JOB_INSTANCE_ID - INNER JOIN BATCH_JOB_EXECUTION_PARAMS bjep - ON bje.JOB_EXECUTION_ID = bjep.JOB_EXECUTION_ID - WHERE - bje.STATUS IN (:statuses) - AND - bji.JOB_NAME = :jobName - AND - bjep.KEY_NAME = :parameterKeyName - AND - bjep.STRING_VAL = :parameterValue - AND - bje.JOB_INSTANCE_ID NOT IN ( - SELECT bje.JOB_INSTANCE_ID - FROM BATCH_JOB_INSTANCE bji - INNER JOIN BATCH_JOB_EXECUTION bje - ON bji.JOB_INSTANCE_ID = bje.JOB_INSTANCE_ID - WHERE - bje.STATUS = :completedStatus - AND - bji.JOB_NAME = :jobName - ) - """, Map.of("statuses", List.of(STARTED.name(), STARTING.name()), "jobName", jobName, "completedStatus", COMPLETED.name(), - "parameterKeyName", parameterKeyName, "parameterValue", parameterValue), Long.class); - } - public List getRunningJobsIdsByExecutionParameter(String jobName, String jobCustomParamKeyName, String parameterKeyName, String parameterValue) { final StringBuilder sqlStatementBuilder = new StringBuilder(); @@ -218,7 +187,6 @@ public class JobExecutionRepository implements InitializingBean { } else { throw new IllegalStateException("Database type is not supported for json query " + databaseTypeResolver.databaseType()); } - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCatchUpSupport.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/RunningJobWithCustomParameters.java similarity index 61% rename from fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCatchUpSupport.java rename to fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/RunningJobWithCustomParameters.java index ce382ca31..3ab15c4d2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCatchUpSupport.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/RunningJobWithCustomParameters.java @@ -16,18 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.cob.loan; +package org.apache.fineract.infrastructure.jobs.domain; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.StepExecution; +import lombok.Data; -public interface LoanCatchUpSupport { +@Data +public class RunningJobWithCustomParameters { - default boolean isCatchUp(StepContribution contribution) { - return isCatchUp(contribution.getStepExecution()); - } - - default boolean isCatchUp(StepExecution execution) { - return "true".equalsIgnoreCase(execution.getExecutionContext().getString(LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME, "false")); - } + private Long executionId; + private String parameter; } diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java index fe1060036..0b437e085 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java +++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java @@ -20,6 +20,7 @@ package org.apache.fineract.cob.loan; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,6 +30,8 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.HashMap; import java.util.List; +import java.util.Optional; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.apache.fineract.cob.domain.LoanAccountLock; import org.apache.fineract.cob.domain.LockOwner; @@ -51,8 +54,10 @@ public class ApplyLoanLockTaskletStepDefinitions implements En { private FineractProperties fineractProperties = mock(FineractProperties.class); private FineractProperties.FineractQueryProperties fineractQueryProperties = mock(FineractProperties.FineractQueryProperties.class); private RetrieveLoanIdService retrieveLoanIdService = mock(RetrieveLoanIdService.class); + + private CustomJobParameterResolver customJobParameterResolver = mock(CustomJobParameterResolver.class); private ApplyLoanLockTasklet applyLoanLockTasklet = new ApplyLoanLockTasklet(fineractProperties, loanLockingService, - retrieveLoanIdService); + retrieveLoanIdService, customJobParameterResolver); private RepeatStatus resultItem; private StepContribution stepContribution; @@ -86,6 +91,7 @@ public class ApplyLoanLockTaskletStepDefinitions implements En { lenient().when(fineractQueryProperties.getInClauseParameterSizeLimit()).thenReturn(65000); lenient().when(loanLockingService.findAllByLoanIdIn(Mockito.anyList())).thenReturn(accountLocks); } + lenient().when(customJobParameterResolver.getCustomJobParameterSet(any())).thenReturn(Optional.empty()); }); diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/FetchAndLockLoanStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/FetchAndLockLoanStepDefinitions.java index 147cb883d..b5cda2574 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/FetchAndLockLoanStepDefinitions.java +++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/FetchAndLockLoanStepDefinitions.java @@ -29,6 +29,8 @@ import java.time.ZoneId; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Optional; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.apache.fineract.cob.domain.LoanAccountLock; import org.apache.fineract.cob.domain.LoanAccountLockRepository; @@ -60,6 +62,8 @@ public class FetchAndLockLoanStepDefinitions implements En { private RepeatStatus result; private final LoanLockingService loanLockingService = mock(LoanLockingService.class); + private final CustomJobParameterResolver customJobParameterResolver = mock(CustomJobParameterResolver.class); + public FetchAndLockLoanStepDefinitions() { Given("/^The FetchAndLockLoanTasklet.execute method with action (.*)$/", (String action) -> { ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null)); @@ -73,7 +77,7 @@ public class FetchAndLockLoanStepDefinitions implements En { contribution = new StepContribution(stepExecution); contribution.getStepExecution().getJobExecution().getExecutionContext().put(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME, LocalDate.now(ZoneId.systemDefault()).toString()); - + lenient().when(customJobParameterResolver.getCustomJobParameterSet(Mockito.any())).thenReturn(Optional.empty()); if ("empty loanIds".equals(action)) { contribution.getStepExecution().getJobExecution().getExecutionContext().put(LoanCOBConstant.LOAN_COB_PARAMETER, new LoanCOBParameter(0L, 0L)); @@ -106,7 +110,7 @@ public class FetchAndLockLoanStepDefinitions implements En { List.of(new LoanAccountLock(3L, LockOwner.LOAN_COB_CHUNK_PROCESSING, LocalDate.now(ZoneId.systemDefault())))); } - lockLoanTasklet = new LockLoanTasklet(loanLockingService); + lockLoanTasklet = new LockLoanTasklet(loanLockingService, customJobParameterResolver); }); When("FetchAndLockLoanTasklet.execute method executed", () -> { diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java index 2792ef9e9..04b456a1c 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java +++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java @@ -21,6 +21,7 @@ package org.apache.fineract.cob.loan; import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Optional; +import org.apache.fineract.cob.common.CustomJobParameterResolver; import org.apache.fineract.cob.data.LoanCOBParameter; import org.apache.fineract.cob.exceptions.LoanReadException; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; @@ -48,7 +50,9 @@ public class LoanItemReaderStepDefinitions implements En { private RetrieveLoanIdService retrieveLoanIdService = mock(RetrieveLoanIdService.class); - private LoanItemReader loanItemReader = new LoanItemReader(loanRepository, retrieveLoanIdService); + private CustomJobParameterResolver customJobParameterResolver = mock(CustomJobParameterResolver.class); + + private LoanItemReader loanItemReader = new LoanItemReader(loanRepository, retrieveLoanIdService, customJobParameterResolver); private Loan loan = mock(Loan.class); @@ -83,12 +87,12 @@ public class LoanItemReaderStepDefinitions implements En { businessDates.put(BusinessDateType.BUSINESS_DATE, businessDate); businessDates.put(BusinessDateType.COB_DATE, businessDate.minusDays(1)); ThreadLocalContextUtil.setBusinessDates(businessDates); + lenient().when(customJobParameterResolver.getCustomJobParameterSet(any())).thenReturn(Optional.empty()); loanItemReader.beforeStep(stepExecution); lenient().when(this.loanRepository.findById(1L)).thenReturn(Optional.of(loan)); lenient().when(this.loanRepository.findById(-1L)).thenThrow(new RuntimeException("fail")); - }); When("LoanItemReader.read method executed", () -> {