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 ac1aeea12 - [x] Move from JobParameter to CustomJobParameter - [x] 
Improve CustomJobParameterResolver to raise custom exception and work with 
StepExecution - [x] Improve tests
ac1aeea12 is described below

commit ac1aeea12dd9558d102c5f6242ac6e0e8ad31a25
Author: Janos Haber <[email protected]>
AuthorDate: Thu May 4 22:45:42 2023 +0200

    - [x] Move from JobParameter to CustomJobParameter
    - [x] Improve CustomJobParameterResolver to raise custom exception and work 
with StepExecution
    - [x] Improve tests
---
 .../cob/common/CustomJobParameterResolver.java     | 49 ++++++++++++++++++----
 .../fineract/cob/loan/ApplyLoanLockTasklet.java    | 11 +++--
 .../InlineLoanCOBBuildExecutionContextTasklet.java | 11 +++--
 .../cob/loan/LoanCOBManagerConfiguration.java      |  4 +-
 .../cob/loan/LoanCOBWorkerConfiguration.java       |  8 +++-
 .../fineract/cob/loan/LoanIdParameterTasklet.java  |  7 +++-
 .../fineract/cob/loan/LoanInlineCOBConfig.java     |  9 +++-
 .../apache/fineract/cob/loan/LoanItemReader.java   | 11 +++--
 .../apache/fineract/cob/loan/LockLoanTasklet.java  |  9 +++-
 .../cob/service/LoanCOBCatchUpServiceImpl.java     | 21 ++++++----
 .../jobs/domain/JobExecutionRepository.java        | 32 --------------
 .../domain/RunningJobWithCustomParameters.java}    | 17 +++-----
 .../loan/ApplyLoanLockTaskletStepDefinitions.java  |  8 +++-
 .../cob/loan/FetchAndLockLoanStepDefinitions.java  |  8 +++-
 .../cob/loan/LoanItemReaderStepDefinitions.java    |  8 +++-
 15 files changed, 127 insertions(+), 86 deletions(-)

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<JobParameterDTO> jobParameterDTOList = 
getCustomJobParameterSet(chunkContext);
+        Set<JobParameterDTO> 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<JobParameterDTO> 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<HashSet<JobParameterDTO>>() {}.getType());
+    /**
+     * Get parameter set from custom job parameter table
+     *
+     * @param stepExecution
+     * @return
+     */
+    public Optional<Set<JobParameterDTO>> 
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<HashSet<JobParameterDTO>>() {}.getType()));
     }
+
+    public Optional<String> 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<String, Object> getJobParameters(StepExecution stepExecution) {
+        Map<String, Object> result = new HashMap<>();
+        for (Map.Entry<String, JobParameter> 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<List<Long>> loanIdPartitions = Lists.partition(loanIds, 
getInClauseParameterSizeLimit());
         List<LoanAccountLock> 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<Long> 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<JobParameterDTO> jobParameters = gson.fromJson(parameterJson, new 
TypeToken<HashSet<JobParameterDTO>>() {}.getType());
+        Set<JobParameterDTO> 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<Long> 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<Long> 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<Long> 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", () -> {


Reply via email to