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 8184b11c2 [FINERACT-1678] execution order for Loan COB
8184b11c2 is described below
commit 8184b11c29eb2b1b5378365025be965026f67427
Author: taskain7 <[email protected]>
AuthorDate: Wed Aug 3 19:41:52 2022 +0200
[FINERACT-1678] execution order for Loan COB
---
.../fineract/cob/COBBusinessStepService.java | 32 +++++++++++
.../fineract/cob/COBBusinessStepServiceImpl.java | 66 ++++++++++++++++++++++
.../fineract/cob/domain/BatchBusinessStep.java | 43 ++++++++++++++
.../cob/domain/BatchBusinessStepRepository.java | 28 +++++++++
.../cob/loan/LoanCOBManagerConfiguration.java | 11 +++-
.../fineract/cob/loan/LoanCOBPartitioner.java | 42 ++++++++++++++
.../cob/loan/LoanCOBWorkerConfiguration.java | 5 +-
.../fineract/cob/loan/LoanItemProcessor.java | 55 ++++++++++++++++++
8 files changed, 280 insertions(+), 2 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepService.java
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepService.java
new file mode 100644
index 000000000..ade540adc
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepService.java
@@ -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);
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
new file mode 100644
index 000000000..03fdbf195
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/cob/COBBusinessStepServiceImpl.java
@@ -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;
+ }
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStep.java
b/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStep.java
new file mode 100644
index 000000000..7876e56fb
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStep.java
@@ -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;
+
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStepRepository.java
b/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStepRepository.java
new file mode 100644
index 000000000..76475e2a3
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/cob/domain/BatchBusinessStepRepository.java
@@ -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);
+}
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 077602c74..30a91ee59 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
@@ -18,12 +18,15 @@
*/
package org.apache.fineract.cob.loan;
+import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.cob.COBPropertyService;
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.Step;
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.integration.config.annotation.EnableBatchIntegration;
import
org.springframework.batch.integration.partition.RemotePartitioningManagerStepBuilderFactory;
@@ -49,10 +52,16 @@ public class LoanCOBManagerConfiguration {
private COBPropertyService cobPropertyService;
@Autowired
private DirectChannel outboundRequests;
+ @Autowired
+ private COBBusinessStepService cobBusinessStepService;
+ @Autowired
+ private JobOperator jobOperator;
+ @Autowired
+ private JobExplorer jobExplorer;
@Bean
public LoanCOBPartitioner partitioner() {
- return new LoanCOBPartitioner(loanRepository, cobPropertyService);
+ return new LoanCOBPartitioner(loanRepository, cobPropertyService,
cobBusinessStepService, jobOperator, jobExplorer);
}
@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 49ed65d0b..0857b6a01 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
@@ -22,28 +22,56 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.cob.COBPropertyService;
+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.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.item.ExecutionContext;
+@Slf4j
@RequiredArgsConstructor
public class LoanCOBPartitioner implements Partitioner {
private final LoanRepository loanRepository;
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 JOB_NAME = "LOAN_COB";
+ private static final String LOAN_COB_JOB_NAME = "LOAN_CLOSE_OF_BUSINESS";
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
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<>();
for (int i = 0; i < partitionCount; i++) {
ExecutionContext executionContext = new ExecutionContext();
executionContext.put("loanIds", new ArrayList<Integer>());
+ executionContext.put("BusinessStepMap", cobBusinessStepMap);
partitions.put(PARTITION_PREFIX + i, executionContext);
}
@@ -56,4 +84,18 @@ public class LoanCOBPartitioner implements Partitioner {
}
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;
+ }
}
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 18527eb63..ddee35820 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
@@ -20,6 +20,7 @@ package org.apache.fineract.cob.loan;
import java.util.ArrayList;
import java.util.List;
+import org.apache.fineract.cob.COBBusinessStepService;
import org.apache.fineract.cob.COBPropertyService;
import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
@@ -54,6 +55,8 @@ public class LoanCOBWorkerConfiguration {
private LoanRepository loanRepository;
@Autowired
private QueueChannel inboundRequests;
+ @Autowired
+ private COBBusinessStepService cobBusinessStepService;
@Bean(name = "Loan COB worker")
public Step loanCOBWorkerStep() {
@@ -81,7 +84,7 @@ public class LoanCOBWorkerConfiguration {
@Bean
public ItemProcessor<Loan, Loan> itemProcessor() {
- return null;
+ return new LoanItemProcessor(cobBusinessStepService);
}
@Bean
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemProcessor.java
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemProcessor.java
new file mode 100644
index 000000000..537a3f415
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanItemProcessor.java
@@ -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;
+ }
+}