[FINERACT-1678] execution order for Loan COB
This commit is contained in:
committed by
Arnold Gálovics
parent
f821841a80
commit
8184b11c29
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface COBBusinessStepService {
|
||||||
|
|
||||||
|
<T extends COBBusinessStep<S>, S extends AbstractPersistableCustom> S run(TreeMap<Long, String> executionMap, S item);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
<T extends COBBusinessStep<S>, S extends AbstractPersistableCustom> TreeMap<Long, String> getCOBBusinessStepMap(
|
||||||
|
Class<T> businessStepClass, String cobJobName);
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.cob.domain.BatchBusinessStep;
|
||||||
|
import org.apache.fineract.cob.domain.BatchBusinessStepRepository;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.beans.factory.ListableBeanFactory;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class COBBusinessStepServiceImpl implements COBBusinessStepService {
|
||||||
|
|
||||||
|
private final BatchBusinessStepRepository batchBusinessStepRepository;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
private final ListableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends COBBusinessStep<S>, S extends AbstractPersistableCustom> S run(TreeMap<Long, String> executionMap, S item) {
|
||||||
|
for (String businessStep : executionMap.values()) {
|
||||||
|
COBBusinessStep<S> businessStepBean = (COBBusinessStep<S>) applicationContext.getBean(businessStep);
|
||||||
|
item = businessStepBean.execute(item);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public <T extends COBBusinessStep<S>, S extends AbstractPersistableCustom> TreeMap<Long, String> getCOBBusinessStepMap(
|
||||||
|
Class<T> businessStepClass, String cobJobName) {
|
||||||
|
List<BatchBusinessStep> cobStepConfigs = batchBusinessStepRepository.findAllByJobName(cobJobName);
|
||||||
|
List<String> businessSteps = Arrays.stream(beanFactory.getBeanNamesForType(businessStepClass)).toList();
|
||||||
|
TreeMap<Long, String> executionMap = new TreeMap<>();
|
||||||
|
for (String businessStep : businessSteps) {
|
||||||
|
COBBusinessStep<S> businessStepBean = (COBBusinessStep<S>) applicationContext.getBean(businessStep);
|
||||||
|
Optional<BatchBusinessStep> businessStepConfig = cobStepConfigs.stream()
|
||||||
|
.filter(stepConfig -> businessStepBean.getEnumStyledName().equals(stepConfig.getStepName())).findFirst();
|
||||||
|
businessStepConfig.ifPresent(batchBusinessStep -> executionMap.put(batchBusinessStep.getStepOrder(), businessStep));
|
||||||
|
}
|
||||||
|
return executionMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* 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.domain;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_batch_business_steps")
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class BatchBusinessStep extends AbstractPersistableCustom {
|
||||||
|
|
||||||
|
@Column(name = "job_name", nullable = false)
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Column(name = "step_name", nullable = false)
|
||||||
|
private String stepName;
|
||||||
|
|
||||||
|
@Column(name = "step_order", nullable = false)
|
||||||
|
private Long stepOrder;
|
||||||
|
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
public interface BatchBusinessStepRepository extends JpaRepository<BatchBusinessStep, Long>, JpaSpecificationExecutor<BatchBusinessStep> {
|
||||||
|
|
||||||
|
List<BatchBusinessStep> findAllByJobName(String jobName);
|
||||||
|
}
|
||||||
+10
-1
@@ -18,12 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.cob.loan;
|
package org.apache.fineract.cob.loan;
|
||||||
|
|
||||||
|
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.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;
|
||||||
|
import org.springframework.batch.core.explore.JobExplorer;
|
||||||
|
import org.springframework.batch.core.launch.JobOperator;
|
||||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
||||||
import org.springframework.batch.integration.config.annotation.EnableBatchIntegration;
|
import org.springframework.batch.integration.config.annotation.EnableBatchIntegration;
|
||||||
import org.springframework.batch.integration.partition.RemotePartitioningManagerStepBuilderFactory;
|
import org.springframework.batch.integration.partition.RemotePartitioningManagerStepBuilderFactory;
|
||||||
@@ -49,10 +52,16 @@ public class LoanCOBManagerConfiguration {
|
|||||||
private COBPropertyService cobPropertyService;
|
private COBPropertyService cobPropertyService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DirectChannel outboundRequests;
|
private DirectChannel outboundRequests;
|
||||||
|
@Autowired
|
||||||
|
private COBBusinessStepService cobBusinessStepService;
|
||||||
|
@Autowired
|
||||||
|
private JobOperator jobOperator;
|
||||||
|
@Autowired
|
||||||
|
private JobExplorer jobExplorer;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public LoanCOBPartitioner partitioner() {
|
public LoanCOBPartitioner partitioner() {
|
||||||
return new LoanCOBPartitioner(loanRepository, cobPropertyService);
|
return new LoanCOBPartitioner(loanRepository, cobPropertyService, cobBusinessStepService, jobOperator, jobExplorer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -22,28 +22,56 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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.portfolio.loanaccount.domain.LoanRepository;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.springframework.batch.core.JobExecution;
|
||||||
|
import org.springframework.batch.core.explore.JobExplorer;
|
||||||
|
import org.springframework.batch.core.launch.JobExecutionNotRunningException;
|
||||||
|
import org.springframework.batch.core.launch.JobOperator;
|
||||||
|
import org.springframework.batch.core.launch.NoSuchJobExecutionException;
|
||||||
import org.springframework.batch.core.partition.support.Partitioner;
|
import org.springframework.batch.core.partition.support.Partitioner;
|
||||||
import org.springframework.batch.item.ExecutionContext;
|
import org.springframework.batch.item.ExecutionContext;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LoanCOBPartitioner implements Partitioner {
|
public class LoanCOBPartitioner implements Partitioner {
|
||||||
|
|
||||||
private final LoanRepository loanRepository;
|
private final LoanRepository loanRepository;
|
||||||
private final COBPropertyService cobPropertyService;
|
private final COBPropertyService cobPropertyService;
|
||||||
|
private final COBBusinessStepService cobBusinessStepService;
|
||||||
|
private final JobOperator jobOperator;
|
||||||
|
private final JobExplorer jobExplorer;
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, ExecutionContext> partition(int gridSize) {
|
public Map<String, ExecutionContext> partition(int gridSize) {
|
||||||
int partitionCount = cobPropertyService.getPartitionSize(JOB_NAME);
|
int partitionCount = cobPropertyService.getPartitionSize(JOB_NAME);
|
||||||
|
TreeMap<Long, String> cobBusinessStepMap = cobBusinessStepService.getCOBBusinessStepMap(LoanCOBBusinessStep.class,
|
||||||
|
LOAN_COB_JOB_NAME);
|
||||||
|
if (cobBusinessStepMap.isEmpty()) {
|
||||||
|
return stopJobExecution();
|
||||||
|
}
|
||||||
|
return getPartitions(partitionCount, cobBusinessStepMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
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++) {
|
for (int i = 0; i < partitionCount; i++) {
|
||||||
ExecutionContext executionContext = new ExecutionContext();
|
ExecutionContext executionContext = new ExecutionContext();
|
||||||
executionContext.put("loanIds", new ArrayList<Integer>());
|
executionContext.put("loanIds", new ArrayList<Integer>());
|
||||||
|
executionContext.put("BusinessStepMap", cobBusinessStepMap);
|
||||||
partitions.put(PARTITION_PREFIX + i, executionContext);
|
partitions.put(PARTITION_PREFIX + i, executionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,4 +84,18 @@ public class LoanCOBPartitioner implements Partitioner {
|
|||||||
}
|
}
|
||||||
return partitions;
|
return partitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Map<String, ExecutionContext> stopJobExecution() {
|
||||||
|
Set<JobExecution> runningJobExecutions = jobExplorer.findRunningJobExecutions(JobName.LOAN_COB.name());
|
||||||
|
for (JobExecution jobExecution : runningJobExecutions) {
|
||||||
|
try {
|
||||||
|
jobOperator.stop(jobExecution.getId());
|
||||||
|
} catch (NoSuchJobExecutionException | JobExecutionNotRunningException e) {
|
||||||
|
log.error("There is no running execution for the given execution ID. Execution ID: {}", jobExecution.getId());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.cob.loan;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
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.Loan;
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
@@ -54,6 +55,8 @@ public class LoanCOBWorkerConfiguration {
|
|||||||
private LoanRepository loanRepository;
|
private LoanRepository loanRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private QueueChannel inboundRequests;
|
private QueueChannel inboundRequests;
|
||||||
|
@Autowired
|
||||||
|
private COBBusinessStepService cobBusinessStepService;
|
||||||
|
|
||||||
@Bean(name = "Loan COB worker")
|
@Bean(name = "Loan COB worker")
|
||||||
public Step loanCOBWorkerStep() {
|
public Step loanCOBWorkerStep() {
|
||||||
@@ -81,7 +84,7 @@ public class LoanCOBWorkerConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ItemProcessor<Loan, Loan> itemProcessor() {
|
public ItemProcessor<Loan, Loan> itemProcessor() {
|
||||||
return null;
|
return new LoanItemProcessor(cobBusinessStepService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.TreeMap;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.cob.COBBusinessStepService;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.springframework.batch.core.ExitStatus;
|
||||||
|
import org.springframework.batch.core.StepExecution;
|
||||||
|
import org.springframework.batch.core.StepExecutionListener;
|
||||||
|
import org.springframework.batch.item.ExecutionContext;
|
||||||
|
import org.springframework.batch.item.ItemProcessor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LoanItemProcessor implements ItemProcessor<Loan, Loan>, StepExecutionListener {
|
||||||
|
|
||||||
|
private final COBBusinessStepService cobBusinessStepService;
|
||||||
|
private StepExecution stepExecution;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeStep(StepExecution stepExecution) {
|
||||||
|
this.stepExecution = stepExecution;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loan process(Loan item) throws Exception {
|
||||||
|
ExecutionContext executionContext = stepExecution.getJobExecution().getExecutionContext();
|
||||||
|
TreeMap<Long, String> businessStepMap = (TreeMap<Long, String>) executionContext.get("BusinessStepMap");
|
||||||
|
return cobBusinessStepService.run(businessStepMap, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||||
|
return ExitStatus.COMPLETED;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user