Conditional ad hoc job service
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ import java.util.Set;
|
|||||||
* Enum of all parameters passed in while creating/updating a AdHocQuery
|
* Enum of all parameters passed in while creating/updating a AdHocQuery
|
||||||
***/
|
***/
|
||||||
public enum AdHocJsonInputParams {
|
public enum AdHocJsonInputParams {
|
||||||
ID("id"), NAME("name"),QUERY("query"),TABLENAME("tableName"),TABLEFIELD("tableFields"), ISACTIVE("isActive"),
|
ID("id"), NAME("name"),QUERY("query"),TABLENAME("tableName"), TABLEFIELDS("tableFields"), ISACTIVE("isActive"),
|
||||||
REPORT_RUN_FREQUENCY("reportRunFrequency"),
|
REPORT_RUN_FREQUENCY("reportRunFrequency"),
|
||||||
REPORT_RUN_EVERY("reportRunEvery"),
|
REPORT_RUN_EVERY("reportRunEvery"),
|
||||||
EMAIL("email");
|
EMAIL("email");
|
||||||
|
|||||||
@@ -18,14 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.adhocquery.data;
|
package org.apache.fineract.adhocquery.data;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.apache.fineract.adhocquery.domain.ReportRunFrequency;
|
import org.apache.fineract.adhocquery.domain.ReportRunFrequency;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable data object represent note or case information AdHocData
|
* Immutable data object represent note or case information AdHocData
|
||||||
*
|
*
|
||||||
@@ -65,10 +65,13 @@ public class AdHocData {
|
|||||||
|
|
||||||
private final Long reportRunEvery;
|
private final Long reportRunEvery;
|
||||||
|
|
||||||
|
private final DateTime lastRun;
|
||||||
|
|
||||||
public AdHocData(final Long id, final String name, final String query, final String tableName, final String tableFields,
|
public AdHocData(final Long id, final String name, final String query, final String tableName, final String tableFields,
|
||||||
final boolean isActive, final DateTime createdOn, final Long createdById, final Long updatedById,
|
final boolean isActive, final DateTime createdOn, final Long createdById, final Long updatedById,
|
||||||
final DateTime updatedOn, final String createdBy, final String email,
|
final DateTime updatedOn, final String createdBy, final String email,
|
||||||
final List<EnumOptionData> reportRunFrequencies, final Long reportRunFrequency, final Long reportRunEvery) {
|
final List<EnumOptionData> reportRunFrequencies, final Long reportRunFrequency, final Long reportRunEvery,
|
||||||
|
final DateTime lastRun) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.query=query;
|
this.query=query;
|
||||||
@@ -84,13 +87,14 @@ public class AdHocData {
|
|||||||
this.reportRunFrequencies = reportRunFrequencies;
|
this.reportRunFrequencies = reportRunFrequencies;
|
||||||
this.reportRunFrequency = reportRunFrequency;
|
this.reportRunFrequency = reportRunFrequency;
|
||||||
this.reportRunEvery = reportRunEvery;
|
this.reportRunEvery = reportRunEvery;
|
||||||
|
this.lastRun = lastRun;
|
||||||
}
|
}
|
||||||
public static AdHocData template() {
|
public static AdHocData template() {
|
||||||
List<EnumOptionData> reportRunFrequencies = Arrays.stream(ReportRunFrequency.values()).map(rrf -> new EnumOptionData(
|
List<EnumOptionData> reportRunFrequencies = Arrays.stream(ReportRunFrequency.values()).map(rrf -> new EnumOptionData(
|
||||||
(long) rrf.getValue(), rrf.getCode(), rrf.getCode()
|
(long) rrf.getValue(), rrf.getCode(), rrf.getCode()
|
||||||
)).collect(Collectors.toList());
|
)).collect(Collectors.toList());
|
||||||
|
|
||||||
AdHocData adHocData = new AdHocData(null,null,null,null,null,false,null,null,null,null,null,null, reportRunFrequencies, null, null);
|
AdHocData adHocData = new AdHocData(null,null,null,null,null,false,null,null,null,null,null,null, reportRunFrequencies, null, null, null);
|
||||||
return adHocData;
|
return adHocData;
|
||||||
}
|
}
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -138,4 +142,7 @@ public class AdHocData {
|
|||||||
public Long getReportRunEvery() {
|
public Long getReportRunEvery() {
|
||||||
return this.reportRunEvery;
|
return this.reportRunEvery;
|
||||||
}
|
}
|
||||||
|
public DateTime getLastRun() {
|
||||||
|
return this.lastRun;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ public class AdHoc extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
SQLInjectionValidator.validateAdhocQuery(commandQuery);
|
SQLInjectionValidator.validateAdhocQuery(commandQuery);
|
||||||
final String query = commandQuery;
|
final String query = commandQuery;
|
||||||
final String tableName = command.stringValueOfParameterNamed(AdHocJsonInputParams.TABLENAME.getValue());
|
final String tableName = command.stringValueOfParameterNamed(AdHocJsonInputParams.TABLENAME.getValue());
|
||||||
final String tableFields = command.stringValueOfParameterNamed(AdHocJsonInputParams.TABLEFIELD.getValue());
|
final String tableFields = command.stringValueOfParameterNamed(AdHocJsonInputParams.TABLEFIELDS.getValue());
|
||||||
final String email = command.stringValueOfParameterNamed(AdHocJsonInputParams.EMAIL.getValue());
|
final String email = command.stringValueOfParameterNamed(AdHocJsonInputParams.EMAIL.getValue());
|
||||||
final Long reportRunFrequency = command.longValueOfParameterNamed(AdHocJsonInputParams.REPORT_RUN_FREQUENCY.getValue());
|
final Long reportRunFrequency = command.longValueOfParameterNamed(AdHocJsonInputParams.REPORT_RUN_FREQUENCY.getValue());
|
||||||
final Long reportRunEvery = command.longValueOfParameterNamed(AdHocJsonInputParams.REPORT_RUN_EVERY.getValue());
|
final Long reportRunEvery = command.longValueOfParameterNamed(AdHocJsonInputParams.REPORT_RUN_EVERY.getValue());
|
||||||
@@ -113,7 +113,7 @@ public class AdHoc extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
actualChanges.put(tableName, newValue);
|
actualChanges.put(tableName, newValue);
|
||||||
this.tableName = newValue;
|
this.tableName = newValue;
|
||||||
}
|
}
|
||||||
final String tableField = "tableField";
|
final String tableField = "tableFields";
|
||||||
if (command.isChangeInStringParameterNamed(tableField, this.tableFields)) {
|
if (command.isChangeInStringParameterNamed(tableField, this.tableFields)) {
|
||||||
final String newValue = command.stringValueOfParameterNamed(tableField);
|
final String newValue = command.stringValueOfParameterNamed(tableField);
|
||||||
actualChanges.put(tableField, newValue);
|
actualChanges.put(tableField, newValue);
|
||||||
|
|||||||
+15
-3
@@ -18,6 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.adhocquery.domain;
|
package org.apache.fineract.adhocquery.domain;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public enum ReportRunFrequency {
|
public enum ReportRunFrequency {
|
||||||
DAILY(1, "reportRunFrequency.daily"),
|
DAILY(1, "reportRunFrequency.daily"),
|
||||||
WEEKLY(2, "reportRunFrequency.weekly"),
|
WEEKLY(2, "reportRunFrequency.weekly"),
|
||||||
@@ -25,19 +29,27 @@ public enum ReportRunFrequency {
|
|||||||
YEARLY(4, "reportRunFrequency.yearly"),
|
YEARLY(4, "reportRunFrequency.yearly"),
|
||||||
CUSTOM(5, "reportRunFrequency.custom");
|
CUSTOM(5, "reportRunFrequency.custom");
|
||||||
|
|
||||||
private final int value;
|
private static final Map<Long, ReportRunFrequency> MAP = Arrays.stream(ReportRunFrequency.values()).collect(Collectors.toMap(
|
||||||
|
ReportRunFrequency::getValue, e -> e
|
||||||
|
));
|
||||||
|
|
||||||
|
private final long value;
|
||||||
private final String code;
|
private final String code;
|
||||||
|
|
||||||
private ReportRunFrequency(final int value, final String code) {
|
private ReportRunFrequency(final long value, final String code) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getValue() {
|
public long getValue() {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return this.code;
|
return this.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReportRunFrequency fromId(final long id) {
|
||||||
|
return ReportRunFrequency.MAP.get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -85,7 +85,7 @@ public final class AdHocDataValidator {
|
|||||||
final Long reportRunFrequencyCode = this.fromApiJsonHelper.extractLongNamed("reportRunFrequency", element);
|
final Long reportRunFrequencyCode = this.fromApiJsonHelper.extractLongNamed("reportRunFrequency", element);
|
||||||
if (reportRunFrequencyCode != null) {
|
if (reportRunFrequencyCode != null) {
|
||||||
baseDataValidator.reset().parameter("reportRunFrequency").value(reportRunFrequencyCode)
|
baseDataValidator.reset().parameter("reportRunFrequency").value(reportRunFrequencyCode)
|
||||||
.inMinMaxRange(ReportRunFrequency.DAILY.getValue(), ReportRunFrequency.CUSTOM.getValue());
|
.inMinMaxRange((int) ReportRunFrequency.DAILY.getValue(), (int) ReportRunFrequency.CUSTOM.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
final Long reportRunEvery = this.fromApiJsonHelper.extractLongNamed("reportRunEvery", element);
|
final Long reportRunEvery = this.fromApiJsonHelper.extractLongNamed("reportRunEvery", element);
|
||||||
@@ -131,7 +131,7 @@ public final class AdHocDataValidator {
|
|||||||
if (this.fromApiJsonHelper.parameterExists("reportRunFrequency", element)) {
|
if (this.fromApiJsonHelper.parameterExists("reportRunFrequency", element)) {
|
||||||
final Long reportRunFrequencyCode = this.fromApiJsonHelper.extractLongNamed("reportRunFrequency", element);
|
final Long reportRunFrequencyCode = this.fromApiJsonHelper.extractLongNamed("reportRunFrequency", element);
|
||||||
baseDataValidator.reset().parameter("reportRunFrequency").value(reportRunFrequencyCode)
|
baseDataValidator.reset().parameter("reportRunFrequency").value(reportRunFrequencyCode)
|
||||||
.inMinMaxRange(ReportRunFrequency.DAILY.getValue(), ReportRunFrequency.CUSTOM.getValue());
|
.inMinMaxRange((int) ReportRunFrequency.DAILY.getValue(), (int) ReportRunFrequency.CUSTOM.getValue());
|
||||||
}
|
}
|
||||||
if (this.fromApiJsonHelper.parameterExists("reportRunEvery", element)) {
|
if (this.fromApiJsonHelper.parameterExists("reportRunEvery", element)) {
|
||||||
final Long reportRunEvery = this.fromApiJsonHelper.extractLongNamed("reportRunEvery", element);
|
final Long reportRunEvery = this.fromApiJsonHelper.extractLongNamed("reportRunEvery", element);
|
||||||
|
|||||||
+3
-2
@@ -90,13 +90,14 @@ public class AdHocReadPlatformServiceImpl implements AdHocReadPlatformService {
|
|||||||
final String email=rs.getString("email");
|
final String email=rs.getString("email");
|
||||||
final Long reportRunFrequency=JdbcSupport.getLong(rs, "report_run_frequency_code");
|
final Long reportRunFrequency=JdbcSupport.getLong(rs, "report_run_frequency_code");
|
||||||
final Long reportRunEvery=JdbcSupport.getLong(rs, "report_run_every");
|
final Long reportRunEvery=JdbcSupport.getLong(rs, "report_run_every");
|
||||||
|
final DateTime lastRun = JdbcSupport.getDateTime(rs, "last_run");
|
||||||
|
|
||||||
return new AdHocData(id,name,query, tableName,tableFields,isActive,createdDate,createdById,updatedById,updatedOn,createdByUsername,email, AdHocData.template().getReportRunFrequencies(), reportRunFrequency, reportRunEvery);
|
return new AdHocData(id,name,query, tableName,tableFields,isActive,createdDate,createdById,updatedById,updatedOn,createdByUsername,email, AdHocData.template().getReportRunFrequencies(), reportRunFrequency, reportRunEvery, lastRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " r.id as id, r.name as name, r.query as query, r.table_name as tableName,r.table_fields as tableField ,r.IsActive as isActive ,r.email as email ,"
|
return " r.id as id, r.name as name, r.query as query, r.table_name as tableName,r.table_fields as tableField ,r.IsActive as isActive ,r.email as email ,"
|
||||||
+ " r.report_run_frequency_code, r.report_run_every, "
|
+ " r.report_run_frequency_code, r.report_run_every, r.last_run, "
|
||||||
+ " r.created_date as createdDate, r.createdby_id as createdById,cb.username as createdBy,r.lastmodifiedby_id as updatedById ,r.lastmodified_date as updatedOn "
|
+ " r.created_date as createdDate, r.createdby_id as createdById,cb.username as createdBy,r.lastmodifiedby_id as updatedById ,r.lastmodified_date as updatedOn "
|
||||||
+ " from m_adhoc r left join m_appuser cb on cb.id=r.createdby_id left join m_appuser mb on mb.id=r.lastmodifiedby_id";
|
+ " from m_adhoc r left join m_appuser cb on cb.id=r.createdby_id left join m_appuser mb on mb.id=r.lastmodifiedby_id";
|
||||||
|
|
||||||
|
|||||||
+60
-12
@@ -18,13 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.adhocquery.service;
|
package org.apache.fineract.adhocquery.service;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.fineract.adhocquery.data.AdHocData;
|
import org.apache.fineract.adhocquery.data.AdHocData;
|
||||||
|
import org.apache.fineract.adhocquery.domain.ReportRunFrequency;
|
||||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
|
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
|
||||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.Days;
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.joda.time.Months;
|
||||||
|
import org.joda.time.Years;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -32,6 +36,9 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@Service(value = "adHocScheduledJobRunnerService")
|
@Service(value = "adHocScheduledJobRunnerService")
|
||||||
public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunnerService {
|
public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunnerService {
|
||||||
|
|
||||||
@@ -47,6 +54,7 @@ public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunn
|
|||||||
this.adHocReadPlatformService = adHocReadPlatformService;
|
this.adHocReadPlatformService = adHocReadPlatformService;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
@CronTarget(jobName = JobName.GENERATE_ADHOCCLIENT_SCEHDULE)
|
@CronTarget(jobName = JobName.GENERATE_ADHOCCLIENT_SCEHDULE)
|
||||||
@@ -54,16 +62,56 @@ public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunn
|
|||||||
final Collection<AdHocData> adhocs = this.adHocReadPlatformService.retrieveAllActiveAdHocQuery();
|
final Collection<AdHocData> adhocs = this.adHocReadPlatformService.retrieveAllActiveAdHocQuery();
|
||||||
if(adhocs.size()>0){
|
if(adhocs.size()>0){
|
||||||
adhocs.forEach(adhoc->{
|
adhocs.forEach(adhoc->{
|
||||||
//jdbcTemplate.execute("truncate table "+adhoc.getTableName());
|
boolean run = true;
|
||||||
final StringBuilder insertSqlBuilder = new StringBuilder(900);
|
LocalDate next = null;
|
||||||
insertSqlBuilder
|
if (adhoc.getReportRunFrequency() != null) {
|
||||||
.append("INSERT INTO ")
|
if (adhoc.getLastRun() != null) {
|
||||||
.append(adhoc.getTableName()+"(")
|
LocalDate start = adhoc.getLastRun().toLocalDate();
|
||||||
.append(adhoc.getTableFields()+") ")
|
LocalDate end = new DateTime().toLocalDate();
|
||||||
.append(adhoc.getQuery());
|
switch (ReportRunFrequency.fromId(adhoc.getReportRunFrequency())) {
|
||||||
if (insertSqlBuilder.length() > 0) {
|
case DAILY:
|
||||||
final int result = this.jdbcTemplate.update(insertSqlBuilder.toString());
|
next = start.plusDays(1);
|
||||||
logger.info(ThreadLocalContextUtil.getTenant().getName() + ": Results affected by inserted: " + result);
|
run = Days.daysBetween(start, end).getDays() >= 1;
|
||||||
|
break;
|
||||||
|
case WEEKLY:
|
||||||
|
next = start.plusDays(7);
|
||||||
|
run = Days.daysBetween(start, end).getDays() >= 7;
|
||||||
|
break;
|
||||||
|
case MONTHLY:
|
||||||
|
next = start.plusMonths(1);
|
||||||
|
run = Months.monthsBetween(start, end).getMonths() >= 1;
|
||||||
|
break;
|
||||||
|
case YEARLY:
|
||||||
|
next = start.plusYears(1);
|
||||||
|
run = Years.yearsBetween(start, end).getYears() >= 1;
|
||||||
|
break;
|
||||||
|
case CUSTOM:
|
||||||
|
next = start.plusDays((int) (long) adhoc.getReportRunEvery());
|
||||||
|
run = Days.daysBetween(start, end).getDays() >= adhoc.getReportRunEvery();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (run) {
|
||||||
|
//jdbcTemplate.execute("truncate table "+adhoc.getTableName());
|
||||||
|
final StringBuilder insertSqlBuilder = new StringBuilder(900);
|
||||||
|
insertSqlBuilder
|
||||||
|
.append("INSERT INTO ")
|
||||||
|
.append(adhoc.getTableName()+"(")
|
||||||
|
.append(adhoc.getTableFields()+") ")
|
||||||
|
.append(adhoc.getQuery());
|
||||||
|
if (insertSqlBuilder.length() > 0) {
|
||||||
|
final int result = this.jdbcTemplate.update(insertSqlBuilder.toString());
|
||||||
|
logger.info(ThreadLocalContextUtil.getTenant().getName() + ": Results affected by inserted: " + result);
|
||||||
|
|
||||||
|
this.jdbcTemplate.update("UPDATE m_adhoc SET last_run=? WHERE id=?", new Date(), adhoc.getId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info(ThreadLocalContextUtil.getTenant().getName() + ": Skipping execution of " + adhoc.getName() + ", scheduled for execution on " + next);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
Reference in New Issue
Block a user