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;
+    }
+}

Reply via email to