From 6eba33758beb69fffaa8bbc03fe6de990fbfb4ce Mon Sep 17 00:00:00 2001 From: taskain7 Date: Wed, 12 Apr 2023 06:55:50 +0200 Subject: [PATCH] [FINERACT-1678] Exclude loan IDs from execution context --- .../cob/loan/ApplyLoanLockTasklet.java | 5 +-- .../fineract/cob/loan/LoanCOBConstant.java | 2 ++ .../cob/loan/LoanCOBManagerConfiguration.java | 4 +-- .../fineract/cob/loan/LoanCOBPartitioner.java | 33 ++++++++----------- .../cob/loan/LoanIdParameterTasklet.java | 5 ++- .../fineract/cob/loan/LoanItemReader.java | 7 ++-- .../loanaccount/domain/LoanRepository.java | 9 +++-- .../ApplyLoanLockTaskletStepDefinitions.java | 2 +- .../LoanCOBPartitionerStepDefinitions.java | 3 +- .../loan/LoanItemReaderStepDefinitions.java | 4 +-- 10 files changed, 35 insertions(+), 39 deletions(-) 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 06a23060b..10a686a6e 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 @@ -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> loanIdPartitions = Lists.partition(loanIds, fineractProperties.getQuery().getInClauseParameterSizeLimit()); List accountLocks = new ArrayList<>(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBConstant.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBConstant.java index d7e5fedd7..fdd3647ce 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBConstant.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBConstant.java @@ -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() { } 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 bb944c509..ac086dca8 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 @@ -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 diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBPartitioner.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBPartitioner.java index 25733d7cd..cc8da931a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBPartitioner.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanCOBPartitioner.java @@ -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 loanIdsInRange = LongStream.rangeClosed(minAndMaxLoanId.getMinLoanId(), minAndMaxLoanId.getMaxLoanId()).boxed() + .toList(); + List> 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 partitions, int partitionIndex, - Set cobBusinessSteps) { + Set cobBusinessSteps, List 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); } 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 a463503b9..78e73253e 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 @@ -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, 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 8dd6b3b2d..8d9464b42 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 @@ -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 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)); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java index 7fdcc8707..de3de3bef 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java @@ -91,8 +91,7 @@ public interface LoanRepository extends JpaRepository, 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, JpaSpecificat List findAllNonClosedLoansBehindOrNullByLoanIds(@Param("cobBusinessDate") LocalDate cobBusinessDate, @Param("loanIds") List loanIds); - @Query(FIND_ALL_NON_CLOSED_LOANS_BEHIND_OR_NULL_BY_MIN_AND_MAX_LOAN_ID) - List 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 findAllNonClosedLoansByLastClosedBusinessDateAndMinAndMaxLoanId(@Param("minLoanId") Long minLoanId, + @Param("maxLoanId") Long maxLoanId, @Param("cobBusinessDate") LocalDate cobBusinessDate); @Query(FIND_OLDEST_COB_PROCESSED_LOAN) List findOldestCOBProcessedLoan(@Param("cobBusinessDate") LocalDate cobBusinessDate); 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 47165937e..7e9c7f641 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 @@ -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); diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanCOBPartitionerStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanCOBPartitionerStepDefinitions.java index 012dbd317..91b5fbb0f 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanCOBPartitionerStepDefinitions.java +++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanCOBPartitionerStepDefinitions.java @@ -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()); } }); } 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 b35b0ec38..292a8e463 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 @@ -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 businessDates = new HashMap<>();