[FINERACT-1678] Loan COB Partitioner strategy fix

This commit is contained in:
taskain7
2022-08-26 11:26:23 +02:00
committed by Arnold Gálovics
parent 48c353fb8f
commit 81b56fafa0
5 changed files with 126 additions and 23 deletions
@@ -22,7 +22,6 @@ import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.cob.COBPropertyService; import org.apache.fineract.cob.COBPropertyService;
import org.apache.fineract.cob.listener.COBExecutionListenerRunner; import org.apache.fineract.cob.listener.COBExecutionListenerRunner;
import org.apache.fineract.infrastructure.jobs.service.JobName; import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.springframework.batch.core.Job; import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step; import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
@@ -47,9 +46,6 @@ public class LoanCOBManagerConfiguration {
private JobBuilderFactory jobBuilderFactory; private JobBuilderFactory jobBuilderFactory;
@Autowired @Autowired
private RemotePartitioningManagerStepBuilderFactory stepBuilderFactory; private RemotePartitioningManagerStepBuilderFactory stepBuilderFactory;
@Autowired
private LoanRepository loanRepository;
@Autowired @Autowired
private COBPropertyService cobPropertyService; private COBPropertyService cobPropertyService;
@Autowired @Autowired
@@ -62,10 +58,12 @@ public class LoanCOBManagerConfiguration {
private JobExplorer jobExplorer; private JobExplorer jobExplorer;
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@Autowired(required = false)
private RetrieveLoanIdService retrieveLoanIdService;
@Bean @Bean
public LoanCOBPartitioner partitioner() { public LoanCOBPartitioner partitioner() {
return new LoanCOBPartitioner(loanRepository, cobPropertyService, cobBusinessStepService, jobOperator, jobExplorer); return new LoanCOBPartitioner(cobPropertyService, cobBusinessStepService, jobOperator, jobExplorer, retrieveLoanIdService);
} }
@Bean @Bean
@@ -29,8 +29,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.COBBusinessStepService; import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.cob.COBPropertyService; import org.apache.fineract.cob.COBPropertyService;
import org.apache.fineract.infrastructure.jobs.service.JobName; import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.explore.JobExplorer;
@@ -44,47 +42,56 @@ import org.springframework.batch.item.ExecutionContext;
@RequiredArgsConstructor @RequiredArgsConstructor
public class LoanCOBPartitioner implements Partitioner { public class LoanCOBPartitioner implements Partitioner {
private final LoanRepository loanRepository;
private final COBPropertyService cobPropertyService; private final COBPropertyService cobPropertyService;
private final COBBusinessStepService cobBusinessStepService; private final COBBusinessStepService cobBusinessStepService;
private final JobOperator jobOperator; private final JobOperator jobOperator;
private final JobExplorer jobExplorer; private final JobExplorer jobExplorer;
private final RetrieveLoanIdService retrieveLoanIdService;
private static final String PARTITION_PREFIX = "partition"; private static final String PARTITION_PREFIX = "partition_";
private static final String JOB_NAME = "LOAN_COB"; private static final String JOB_NAME = "LOAN_COB";
private static final String LOAN_COB_JOB_NAME = "LOAN_CLOSE_OF_BUSINESS"; private static final String LOAN_COB_JOB_NAME = "LOAN_CLOSE_OF_BUSINESS";
@Override @Override
public Map<String, ExecutionContext> partition(int gridSize) { public Map<String, ExecutionContext> partition(int gridSize) {
int partitionCount = cobPropertyService.getPartitionSize(JOB_NAME); int partitionSize = cobPropertyService.getPartitionSize(JOB_NAME);
TreeMap<Long, String> cobBusinessStepMap = cobBusinessStepService.getCOBBusinessStepMap(LoanCOBBusinessStep.class, TreeMap<Long, String> cobBusinessStepMap = cobBusinessStepService.getCOBBusinessStepMap(LoanCOBBusinessStep.class,
LOAN_COB_JOB_NAME); LOAN_COB_JOB_NAME);
if (cobBusinessStepMap.isEmpty()) { if (cobBusinessStepMap.isEmpty()) {
return stopJobExecution(); return stopJobExecution();
} }
return getPartitions(partitionCount, cobBusinessStepMap); return getPartitions(partitionSize, cobBusinessStepMap);
} }
@NotNull private Map<String, ExecutionContext> getPartitions(int partitionSize, TreeMap<Long, String> cobBusinessStepMap) {
private Map<String, ExecutionContext> getPartitions(int partitionCount, TreeMap<Long, String> cobBusinessStepMap) {
Map<String, ExecutionContext> partitions = new HashMap<>(); Map<String, ExecutionContext> partitions = new HashMap<>();
for (int i = 0; i < partitionCount; i++) { List<Integer> allNonClosedLoanIds = retrieveLoanIdService.retrieveLoanIds();
ExecutionContext executionContext = new ExecutionContext(); if (allNonClosedLoanIds.isEmpty()) {
executionContext.put("loanIds", new ArrayList<Integer>()); return stopJobExecution();
executionContext.put("BusinessStepMap", cobBusinessStepMap);
partitions.put(PARTITION_PREFIX + i, executionContext);
} }
int partitionIndex = 0;
List<Integer> allNonClosedLoanIds = loanRepository.findAllNonClosedLoanIds(); createNewPartition(partitions, partitionIndex, cobBusinessStepMap);
for (int i = 0; i < allNonClosedLoanIds.size(); i++) { for (Integer allNonClosedLoanId : allNonClosedLoanIds) {
String key = PARTITION_PREFIX + (i % partitionCount); if (partitions.get(PARTITION_PREFIX + partitionIndex).size() == partitionSize) {
partitionIndex++;
createNewPartition(partitions, partitionIndex, cobBusinessStepMap);
}
String key = PARTITION_PREFIX + partitionIndex;
ExecutionContext executionContext = partitions.get(key); ExecutionContext executionContext = partitions.get(key);
List<Integer> data = (List<Integer>) executionContext.get("loanIds"); List<Integer> data = (List<Integer>) executionContext.get("loanIds");
data.add(allNonClosedLoanIds.get(i)); data.add(allNonClosedLoanId);
} }
return partitions; return partitions;
} }
private void createNewPartition(Map<String, ExecutionContext> partitions, int partitionIndex,
TreeMap<Long, String> cobBusinessStepMap) {
ExecutionContext executionContext = new ExecutionContext();
executionContext.put("loanIds", new ArrayList<Integer>());
executionContext.put("BusinessStepMap", cobBusinessStepMap);
partitions.put(PARTITION_PREFIX + partitionIndex, executionContext);
}
@Nullable @Nullable
private Map<String, ExecutionContext> stopJobExecution() { private Map<String, ExecutionContext> stopJobExecution() {
Set<JobExecution> runningJobExecutions = jobExplorer.findRunningJobExecutions(JobName.LOAN_COB.name()); Set<JobExecution> runningJobExecutions = jobExplorer.findRunningJobExecutions(JobName.LOAN_COB.name());
@@ -0,0 +1,34 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.cob.loan;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
@RequiredArgsConstructor
public class RetrieveAllNonClosedLoanIdServiceImpl implements RetrieveLoanIdService {
private final LoanRepository loanRepository;
@Override
public List<Integer> retrieveLoanIds() {
return loanRepository.findAllNonClosedLoanIds();
}
}
@@ -0,0 +1,38 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.cob.loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RetrieveLoanIdConfiguration {
@Autowired
private LoanRepository loanRepository;
@Bean
@ConditionalOnMissingBean
public RetrieveLoanIdService retrieveLoanIdService() {
return new RetrieveAllNonClosedLoanIdServiceImpl(loanRepository);
}
}
@@ -0,0 +1,26 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.cob.loan;
import java.util.List;
public interface RetrieveLoanIdService {
List<Integer> retrieveLoanIds();
}