[FINERACT-1678] Exclude loan IDs from execution context

This commit is contained in:
taskain7
2023-04-13 10:36:19 +02:00
committed by Adam Saghy
parent fbd0bb91c0
commit 6eba33758b
10 changed files with 35 additions and 39 deletions
@@ -64,8 +64,9 @@ public class ApplyLoanLockTasklet implements Tasklet {
|| (loanCOBParameter.getMinLoanId().equals(0L) && loanCOBParameter.getMaxLoanId().equals(0L))) {
loanIds = Collections.emptyList();
} else {
loanIds = new ArrayList<>(loanRepository.findAllNonClosedLoansBehindOrNullByMinAndMaxLoanId(loanCOBParameter.getMinLoanId(),
loanCOBParameter.getMaxLoanId(), ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE)));
loanIds = new ArrayList<>(loanRepository.findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(
loanCOBParameter.getMinLoanId(), loanCOBParameter.getMaxLoanId(), ThreadLocalContextUtil
.getBusinessDateByType(BusinessDateType.COB_DATE).minusDays(LoanCOBConstant.NUMBER_OF_DAYS_BEHIND)));
}
List<List<Long>> loanIdPartitions = Lists.partition(loanIds, fineractProperties.getQuery().getInClauseParameterSizeLimit());
List<LoanAccountLock> accountLocks = new ArrayList<>();
@@ -34,6 +34,8 @@ public final class LoanCOBConstant {
public static final String LOAN_COB_PARTITIONER_STEP = "Loan COB partition - Step";
public static final String LOAN_COB_CUSTOM_JOB_PARAMETER_KEY = "CUSTOM_JOB_PARAMETER_ID";
public static final Long NUMBER_OF_DAYS_BEHIND = 1L;
private LoanCOBConstant() {
}
@@ -83,8 +83,8 @@ public class LoanCOBManagerConfiguration {
@Bean
@JobScope
public LoanCOBPartitioner partitioner(@Value("#{jobExecutionContext['loanIds']}") LoanCOBParameter minAndMaxLoanId) {
return new LoanCOBPartitioner(propertyService, cobBusinessStepService, jobOperator, jobExplorer, minAndMaxLoanId);
public LoanCOBPartitioner partitioner(@Value("#{jobExecutionContext['loanCobParameter']}") LoanCOBParameter loanCOBParameter) {
return new LoanCOBPartitioner(propertyService, cobBusinessStepService, jobOperator, jobExplorer, loanCOBParameter);
}
@Bean
@@ -18,10 +18,13 @@
*/
package org.apache.fineract.cob.loan;
import com.google.common.collect.Lists;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.LongStream;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.COBBusinessStepService;
@@ -66,34 +69,24 @@ public class LoanCOBPartitioner implements Partitioner {
stopJobExecution();
return Map.of();
}
int partitionIndex = 1;
createNewPartition(partitions, partitionIndex, cobBusinessSteps);
if (!Objects.isNull(minAndMaxLoanId)) {
long remainingLoanIdCount = minAndMaxLoanId.getMaxLoanId() - minAndMaxLoanId.getMinLoanId() + 1;
long startLoanId = minAndMaxLoanId.getMinLoanId();
long endLoanId;
do {
String key = PARTITION_PREFIX + partitionIndex;
ExecutionContext executionContext = partitions.get(key);
if (remainingLoanIdCount > partitionSize) {
endLoanId = startLoanId + partitionSize - 1;
partitionIndex++;
createNewPartition(partitions, partitionIndex, cobBusinessSteps);
} else {
endLoanId = minAndMaxLoanId.getMaxLoanId();
}
executionContext.put(LoanCOBConstant.LOAN_COB_PARAMETER, new LoanCOBParameter(startLoanId, endLoanId));
startLoanId = startLoanId + partitionSize;
remainingLoanIdCount = minAndMaxLoanId.getMaxLoanId() - endLoanId;
} while (remainingLoanIdCount > 0);
List<Long> loanIdsInRange = LongStream.rangeClosed(minAndMaxLoanId.getMinLoanId(), minAndMaxLoanId.getMaxLoanId()).boxed()
.toList();
List<List<Long>> loanIdPartitions = Lists.partition(loanIdsInRange, partitionSize);
for (int i = 0; i < loanIdPartitions.size(); i++) {
createNewPartition(partitions, i + 1, cobBusinessSteps, loanIdPartitions.get(i));
}
} else {
createNewPartition(partitions, 1, cobBusinessSteps, List.of(0L));
}
return partitions;
}
private void createNewPartition(Map<String, ExecutionContext> partitions, int partitionIndex,
Set<BusinessStepNameAndOrder> cobBusinessSteps) {
Set<BusinessStepNameAndOrder> cobBusinessSteps, List<Long> loanIds) {
ExecutionContext executionContext = new ExecutionContext();
executionContext.put(LoanCOBConstant.BUSINESS_STEPS, cobBusinessSteps);
executionContext.put(LoanCOBConstant.LOAN_COB_PARAMETER, new LoanCOBParameter(loanIds.get(0), loanIds.get(loanIds.size() - 1)));
executionContext.put("partition", PARTITION_PREFIX + partitionIndex);
partitions.put(PARTITION_PREFIX + partitionIndex, executionContext);
}
@@ -32,8 +32,6 @@ import org.springframework.batch.repeat.RepeatStatus;
@RequiredArgsConstructor
public class LoanIdParameterTasklet implements Tasklet {
private static final Long NUMBER_OF_DAYS_BEHIND = 1L;
private final RetrieveLoanIdService retrieveLoanIdService;
@Override
@@ -41,7 +39,8 @@ public class LoanIdParameterTasklet implements Tasklet {
String businessDateParameter = (String) contribution.getStepExecution().getJobExecution().getExecutionContext()
.get(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME);
LocalDate businessDate = LocalDate.parse(Objects.requireNonNull(businessDateParameter));
LoanCOBParameter minAndMaxLoanId = retrieveLoanIdService.retrieveMinAndMaxLoanIdsNDaysBehind(NUMBER_OF_DAYS_BEHIND, businessDate);
LoanCOBParameter minAndMaxLoanId = retrieveLoanIdService.retrieveMinAndMaxLoanIdsNDaysBehind(LoanCOBConstant.NUMBER_OF_DAYS_BEHIND,
businessDate);
if (Objects.isNull(minAndMaxLoanId)
|| (Objects.isNull(minAndMaxLoanId.getMinLoanId()) && Objects.isNull(minAndMaxLoanId.getMaxLoanId()))) {
contribution.getStepExecution().getJobExecution().getExecutionContext().put(LoanCOBConstant.LOAN_COB_PARAMETER,
@@ -40,7 +40,7 @@ public class LoanItemReader extends AbstractLoanItemReader {
@BeforeStep
@SuppressWarnings({ "unchecked" })
public void beforeStep(@NotNull StepExecution stepExecution) {
ExecutionContext executionContext = stepExecution.getJobExecution().getExecutionContext();
ExecutionContext executionContext = stepExecution.getExecutionContext();
LoanCOBParameter loanCOBParameter = (LoanCOBParameter) executionContext.get(LoanCOBConstant.LOAN_COB_PARAMETER);
List<Long> loanIds;
if (Objects.isNull(loanCOBParameter)
@@ -48,8 +48,9 @@ public class LoanItemReader extends AbstractLoanItemReader {
|| (loanCOBParameter.getMinLoanId().equals(0L) && loanCOBParameter.getMaxLoanId().equals(0L))) {
loanIds = Collections.emptyList();
} else {
loanIds = loanRepository.findAllNonClosedLoansBehindOrNullByMinAndMaxLoanId(loanCOBParameter.getMinLoanId(),
loanCOBParameter.getMaxLoanId(), ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE));
loanIds = loanRepository.findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(loanCOBParameter.getMinLoanId(),
loanCOBParameter.getMaxLoanId(), ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE)
.minusDays(LoanCOBConstant.NUMBER_OF_DAYS_BEHIND));
}
setRemainingData(new ArrayList<>(loanIds));
}
@@ -91,8 +91,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
String FIND_ALL_NON_CLOSED_LOANS_BEHIND_OR_NULL_BY_LOAN_IDS = "select loan.id, loan.lastClosedBusinessDate from Loan loan where loan.id IN :loanIds and loan.loanStatus in (100,200,300,303,304) and (loan.lastClosedBusinessDate < :cobBusinessDate or "
+ "loan.lastClosedBusinessDate is null)";
String FIND_ALL_NON_CLOSED_LOANS_BEHIND_OR_NULL_BY_MIN_AND_MAX_LOAN_ID = "select loan.id from Loan loan where loan.id BETWEEN :minLoanId and :maxLoanId and loan.loanStatus in (100,200,300,303,304) and (loan.lastClosedBusinessDate < "
+ ":cobBusinessDate or loan.lastClosedBusinessDate is null)";
String FIND_ALL_NON_CLOSED_LOANS_BY_LAST_CLOSED_BUSINESS_DATE_AND_MIN_AND_MAX_LOAN_ID = "select loan.id from Loan loan where loan.id BETWEEN :minLoanId and :maxLoanId and loan.loanStatus in (100,200,300,303,304) and (:cobBusinessDate = loan.lastClosedBusinessDate or loan.lastClosedBusinessDate is NULL)";
String FIND_ALL_NON_CLOSED_LOANS_BEHIND_BY_LOAN_IDS = "select loan.id, loan.lastClosedBusinessDate from Loan loan where loan.id IN :loanIds and loan.loanStatus in (100,200,300,303,304) and loan.lastClosedBusinessDate < :cobBusinessDate";
@@ -207,9 +206,9 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
List<LoanIdAndLastClosedBusinessDate> findAllNonClosedLoansBehindOrNullByLoanIds(@Param("cobBusinessDate") LocalDate cobBusinessDate,
@Param("loanIds") List<Long> loanIds);
@Query(FIND_ALL_NON_CLOSED_LOANS_BEHIND_OR_NULL_BY_MIN_AND_MAX_LOAN_ID)
List<Long> findAllNonClosedLoansBehindOrNullByMinAndMaxLoanId(@Param("minLoanId") Long minLoanId, @Param("maxLoanId") Long maxLoanId,
@Param("cobBusinessDate") LocalDate cobBusinessDate);
@Query(FIND_ALL_NON_CLOSED_LOANS_BY_LAST_CLOSED_BUSINESS_DATE_AND_MIN_AND_MAX_LOAN_ID)
List<Long> findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(@Param("minLoanId") Long minLoanId,
@Param("maxLoanId") Long maxLoanId, @Param("cobBusinessDate") LocalDate cobBusinessDate);
@Query(FIND_OLDEST_COB_PROCESSED_LOAN)
List<LoanIdAndLastClosedBusinessDate> findOldestCOBProcessedLoan(@Param("cobBusinessDate") LocalDate cobBusinessDate);
@@ -71,7 +71,7 @@ public class ApplyLoanLockTaskletStepDefinitions implements En {
StepExecution stepExecution = new StepExecution("test", null);
ExecutionContext executionContext = new ExecutionContext();
executionContext.put(LoanCOBConstant.LOAN_COB_PARAMETER, new LoanCOBParameter(1L, 4L));
lenient().when(this.loanRepository.findAllNonClosedLoansBehindOrNullByMinAndMaxLoanId(anyLong(), anyLong(), any()))
lenient().when(this.loanRepository.findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(anyLong(), anyLong(), any()))
.thenReturn(List.of(1L, 2L, 3L, 4L));
stepExecution.setExecutionContext(executionContext);
this.stepContribution = new StepContribution(stepExecution);
@@ -128,7 +128,8 @@ public class LoanCOBPartitionerStepDefinitions implements En {
businessSteps.stream().findFirst().get().getStepName());
LoanCOBParameter loanCOBParameter = (LoanCOBParameter) resultItem.get(LoanCOBPartitioner.PARTITION_PREFIX + "1")
.get(LoanCOBConstant.LOAN_COB_PARAMETER);
assertEquals(null, loanCOBParameter);
assertEquals(0L, loanCOBParameter.getMinLoanId());
assertEquals(0L, loanCOBParameter.getMaxLoanId());
}
});
}
@@ -71,9 +71,9 @@ public class LoanItemReaderStepDefinitions implements En {
maxLoanId = splitAccounts.get(splitAccounts.size() - 1);
}
stepExecutionContext.put(LoanCOBConstant.LOAN_COB_PARAMETER, new LoanCOBParameter(minLoanId, maxLoanId));
jobExecution.setExecutionContext(stepExecutionContext);
stepExecution.setExecutionContext(stepExecutionContext);
lenient().when(this.loanRepository.findAllNonClosedLoansBehindOrNullByMinAndMaxLoanId(anyLong(), anyLong(), any()))
lenient().when(this.loanRepository.findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(anyLong(), anyLong(), any()))
.thenReturn(splitAccounts);
HashMap<BusinessDateType, LocalDate> businessDates = new HashMap<>();