Skip to content

Commit 0da4cdd

Browse files
wkk91193vorburger
authored andcommitted
Parallelization of Jobs: Parallelizing and paging of recalculate interest for loans (PR #524 for FINERACT-428)
1 parent cc181b5 commit 0da4cdd

9 files changed

Lines changed: 672 additions & 142 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.infrastructure.jobs.domain;
20+
21+
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
22+
23+
import javax.persistence.Column;
24+
import javax.persistence.Entity;
25+
import javax.persistence.Table;
26+
import java.util.Objects;
27+
28+
@Entity
29+
@Table(name = "job_parameters")
30+
public class JobParameter extends AbstractPersistableCustom<Long> {
31+
32+
@Column(name = "job_id", nullable = false)
33+
private Long jobId;
34+
35+
@Column(name = "parameter_name",nullable = true)
36+
private String parameterName;
37+
38+
@Column(name = "parameter_value",nullable = true)
39+
private String parameterValue;
40+
41+
42+
public JobParameter(final Long jobId, final String parameterName, final String parameterValue) {
43+
this.jobId = jobId;
44+
this.parameterName = parameterName;
45+
this.parameterValue = parameterValue;
46+
}
47+
48+
public static JobParameter getInstance(final Long jobId, final String parameterName, final String parameterValue){
49+
return new JobParameter(jobId,parameterName,parameterValue);
50+
}
51+
52+
public Long getJobId() {
53+
return jobId;
54+
}
55+
56+
public void setJobId(final Long jobId) {
57+
this.jobId = jobId;
58+
}
59+
60+
public String getParameterName() {
61+
return parameterName;
62+
}
63+
64+
public void setParameterName(final String parameterName) {
65+
this.parameterName = parameterName;
66+
}
67+
68+
public String getParameterValue() {
69+
return parameterValue;
70+
}
71+
72+
public void setParameterValue(final String parameterValue) {
73+
this.parameterValue = parameterValue;
74+
}
75+
76+
77+
@Override
78+
public boolean equals(Object obj) {
79+
if (!obj.getClass().equals(getClass())) return false;
80+
JobParameter jobParameter = (JobParameter) obj;
81+
return jobParameter.getJobId().equals(this.getJobId())
82+
&& jobParameter.getParameterName().equals(this.getParameterName())
83+
&& jobParameter.getParameterValue().equals(this.getParameterValue());
84+
}
85+
86+
@Override
87+
public int hashCode() {
88+
return Objects.hash(jobId,parameterName,parameterValue);
89+
}
90+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.infrastructure.jobs.domain;
20+
21+
import org.springframework.data.jpa.repository.JpaRepository;
22+
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
23+
import org.springframework.data.jpa.repository.Query;
24+
import org.springframework.data.repository.query.Param;
25+
26+
import java.util.List;
27+
28+
public interface JobParameterRepository extends JpaRepository<JobParameter, Long>, JpaSpecificationExecutor<JobParameter> {
29+
30+
@Query("select jobParameter from JobParameter jobParameter where jobParameter.jobId=:jobId")
31+
List<JobParameter> findJobParametersByJobId(@Param("jobId") Long jobId);
32+
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobRegisterServiceImpl.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,24 @@
1818
*/
1919
package org.apache.fineract.infrastructure.jobs.service;
2020

21+
2122
import java.text.ParseException;
2223
import java.util.ArrayList;
2324
import java.util.Arrays;
2425
import java.util.HashMap;
2526
import java.util.List;
2627
import java.util.Properties;
2728
import java.util.TimeZone;
28-
29+
import java.util.Map;
2930
import javax.annotation.PostConstruct;
3031

3132
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
3233
import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
3334
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
3435
import org.apache.fineract.infrastructure.jobs.annotation.CronMethodParser;
3536
import org.apache.fineract.infrastructure.jobs.annotation.CronMethodParser.ClassMethodNamesPair;
37+
import org.apache.fineract.infrastructure.jobs.domain.JobParameter;
38+
import org.apache.fineract.infrastructure.jobs.domain.JobParameterRepository;
3639
import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
3740
import org.apache.fineract.infrastructure.jobs.domain.SchedulerDetail;
3841
import org.apache.fineract.infrastructure.jobs.exception.JobNotFoundException;
@@ -78,6 +81,7 @@ public class JobRegisterServiceImpl implements JobRegisterService, ApplicationLi
7881
private SchedulerJobListener schedulerJobListener;
7982
private SchedulerStopListener schedulerStopListener;
8083
private SchedulerTriggerListener globalSchedulerTriggerListener;
84+
private JobParameterRepository jobParameterRepository;
8185

8286
private final HashMap<String, Scheduler> schedulers = new HashMap<>(4);
8387

@@ -111,6 +115,11 @@ public void setGlobalTriggerListener(SchedulerTriggerListener globalTriggerListe
111115
this.globalSchedulerTriggerListener = globalTriggerListener;
112116
}
113117

118+
@Autowired
119+
public void setJobParameterRepository(JobParameterRepository jobParameterRepository){
120+
this.jobParameterRepository=jobParameterRepository;
121+
}
122+
114123
@PostConstruct
115124
public void loadAllJobs() {
116125
final List<FineractPlatformTenant> allTenants = this.tenantDetailsService.findAllTenants();
@@ -354,6 +363,14 @@ private JobDetail createJobDetail(final ScheduledJobDetail scheduledJobDetail) t
354363
return jobDetailFactoryBean.getObject();
355364
}
356365

366+
public Map<String,String> getJobParameter(ScheduledJobDetail scheduledJobDetail){
367+
List<JobParameter> jobParameterList= jobParameterRepository.findJobParametersByJobId(scheduledJobDetail.getId());
368+
Map<String,String> jobParameterMap=new HashMap<>();
369+
for (JobParameter jobparameter:jobParameterList) {
370+
jobParameterMap.put(jobparameter.getParameterName(),jobparameter.getParameterValue());
371+
}
372+
return jobParameterMap;
373+
}
357374
private Object getBeanObject(final Class<?> classType) throws ClassNotFoundException {
358375
final List<Class<?>> typesList = new ArrayList<>();
359376
final Class<?>[] interfaceType = classType.getInterfaces();
@@ -419,4 +436,4 @@ private JobKey constructJobKey(final String Key) {
419436
final JobKey JobKey = new JobKey(keyParams[0], keyParams[1]);
420437
return JobKey;
421438
}
422-
}
439+
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java

100755100644
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.math.BigDecimal;
2222
import java.util.Collection;
2323
import java.util.Date;
24+
import java.util.List;
2425

2526
import org.apache.fineract.infrastructure.core.service.Page;
2627
import org.apache.fineract.infrastructure.core.service.SearchParameters;
@@ -45,7 +46,7 @@ public interface LoanReadPlatformService {
4546
LoanAccountData retrieveOne(Long loanId);
4647

4748
LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData,
48-
Collection<DisbursementData> disbursementData, boolean isInterestRecalculationEnabled, BigDecimal totalPaidFeeCharges);
49+
Collection<DisbursementData> disbursementData, boolean isInterestRecalculationEnabled, BigDecimal totalPaidFeeCharges);
4950

5051
Collection<LoanTransactionData> retrieveLoanTransactions(Long loanId);
5152

@@ -84,7 +85,7 @@ LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelated
8485
/*
8586
* musoni-specific at present - will find overdue scheduled installments
8687
* that have a special 'overdue charge' associated with the loan product.
87-
*
88+
*
8889
* The 'overdue-charge' is only ever applied once to an installment and as a
8990
* result overdue installments with this charge already applied are not
9091
* returned.
@@ -111,6 +112,8 @@ LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelated
111112

112113
Collection<Long> fetchLoansForInterestRecalculation();
113114

115+
List<Long> fetchLoansForInterestRecalculation(Integer pageSize, Long maxLoanIdInList, String officeHierarchy);
116+
114117
LoanTransactionData retrieveLoanPrePaymentTemplate(Long loanId, LocalDate onDate);
115118

116119
Collection<LoanTransactionData> retrieveWaiverLoanTransactions(Long loanId);
@@ -124,17 +127,20 @@ LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelated
124127
PaidInAdvanceData retrieveTotalPaidInAdvance(Long loanId);
125128

126129
LoanTransactionData retrieveRefundByCashTemplate(Long loanId);
127-
130+
128131
Collection<InterestRatePeriodData> retrieveLoanInterestRatePeriodData(LoanAccountData loan);
129132

130133
Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions();
131134

132135
LoanTransactionData retrieveLoanForeclosureTemplate(final Long loanId, final LocalDate transactionDate);
133136

137+
134138
LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber);
135139

136140
Long retrieveLoanIdByAccountNumber(String loanAccountNumber);
137141

138142
String retrieveAccountNumberByAccountId(Long accountId);
139143

144+
Integer retrieveNumberOfActiveLoans();
145+
140146
}

0 commit comments

Comments
 (0)