Scheduler changes is a combination of 2 commits.
update API changes for scheduler jobs added scheduler job update API added pagination for job history
This commit is contained in:
@@ -0,0 +1 @@
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('jobs', 'UPDATE_SCHEDULER', 'SCHEDULER', 'UPDATE', 0);
|
||||
+6
-2
@@ -512,7 +512,7 @@ public class CommandWrapper {
|
||||
public boolean isAccountingRuleResource() {
|
||||
return this.entityName.equalsIgnoreCase("ACCOUNTINGRULE");
|
||||
}
|
||||
|
||||
|
||||
public boolean isClientUnassignStaff() {
|
||||
return this.actionName.equalsIgnoreCase("UNASSIGNSTAFF") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
@@ -532,8 +532,12 @@ public class CommandWrapper {
|
||||
public boolean isClientAssignStaff() {
|
||||
return this.actionName.equalsIgnoreCase("ASSIGNSTAFF") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
|
||||
public boolean isClientClose() {
|
||||
return this.actionName.equalsIgnoreCase("CLOSE") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
public boolean isSchedulerResource() {
|
||||
return this.entityName.equalsIgnoreCase("SCHEDULER");
|
||||
}
|
||||
}
|
||||
+9
@@ -1116,4 +1116,13 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/clients/" + clientId + "?command=assignStaff";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateJobDetail(final Long jobId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "SCHEDULER";
|
||||
this.entityId = jobId;
|
||||
this.href = "/updateJobDetail/" + jobId+"/updateJobDetail";
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -491,6 +491,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
if (wrapper.isCreate()) {
|
||||
handler = this.applicationContext.getBean("createHolidayCommandHandler", NewCommandSourceHandler.class);
|
||||
}
|
||||
} else if(wrapper.isSchedulerResource()){
|
||||
if (wrapper.isUpdate()) {
|
||||
handler = this.applicationContext.getBean("updateJobDetailCommandhandler", NewCommandSourceHandler.class);
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+15
@@ -16,6 +16,7 @@ import net.fortuna.ical4j.model.ValidationException;
|
||||
import net.fortuna.ical4j.model.property.RRule;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
@@ -684,4 +685,18 @@ public class DataValidatorBuilder {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValidatorBuilder validateCronExpression() {
|
||||
if (value != null && !CronExpression.isValidExpression(this.value.toString().trim())) {
|
||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter)
|
||||
.append(".invalid");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter).append(
|
||||
" value is not a valid cron expression");
|
||||
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
|
||||
defaultEnglishMessage.toString(), parameter, this.value);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
-10
@@ -64,16 +64,6 @@ public class CronMethodParser {
|
||||
Map<String, Object> attributes = metadata.getAnnotationAttributes(annotationClass.getName());
|
||||
JobName attributeValue = (JobName) attributes.get(attributeName);
|
||||
String className = metadata.getDeclaringClassName();
|
||||
/**
|
||||
* TODO: Vishwas, have commented out this piece of code,
|
||||
* check its need with Pramod
|
||||
**/
|
||||
/**
|
||||
* if (attributeValue == null ||
|
||||
* attributeValue.trim().length() < 1) { attributeValue
|
||||
* = className.substring(className.lastIndexOf(".") +
|
||||
* 1); }
|
||||
**/
|
||||
String[] mapVal = { className, metadata.getMethodName() };
|
||||
targetMethosMap.put(attributeValue.toString(), mapVal);
|
||||
}
|
||||
|
||||
+6
@@ -6,6 +6,8 @@ import java.util.Set;
|
||||
|
||||
public class SchedulerJobApiConstants {
|
||||
|
||||
|
||||
public static final String JOB_RESOURCE_NAME = "schedulerjob";
|
||||
// response parameters
|
||||
public static final String jobIdentifierParamName = "jobId";
|
||||
public static final String displayNameParamName = "displayName";
|
||||
@@ -23,6 +25,8 @@ public class SchedulerJobApiConstants {
|
||||
public static final String jobRunErrorMessageParamName = "jobRunErrorMessage";
|
||||
public static final String triggerTypeParamName = "triggerType";
|
||||
public static final String jobRunErrorLogParamName = "jobRunErrorLog";
|
||||
|
||||
public static final String cronExpressionParamName = "cronExpression";
|
||||
|
||||
public static final Set<String> JOB_DETAIL_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(jobIdentifierParamName,
|
||||
displayNameParamName, nextRunTimeParamName, initializingErrorParamName, jobActiveStatusParamName,currentlyRunningParamName, lastRunHistoryObjParamName));
|
||||
@@ -30,5 +34,7 @@ public class SchedulerJobApiConstants {
|
||||
public static final Set<String> JOB_HISTORY_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(versionParamName,
|
||||
jobRunStartTimeParamName, jobRunEndTimeParamName, statusParamName, jobRunErrorMessageParamName, triggerTypeParamName,
|
||||
jobRunErrorLogParamName));
|
||||
|
||||
public static final Set<String> JOB_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(displayNameParamName,jobActiveStatusParamName,cronExpressionParamName));
|
||||
|
||||
}
|
||||
|
||||
+35
-3
@@ -5,15 +5,21 @@ import java.util.List;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
@@ -21,6 +27,7 @@ import org.mifosplatform.infrastructure.jobs.data.JobDetailData;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailHistoryData;
|
||||
import org.mifosplatform.infrastructure.jobs.service.JobRegisterService;
|
||||
import org.mifosplatform.infrastructure.jobs.service.SchedulerJobRunnerReadService;
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -33,17 +40,20 @@ public class SchedulerJobApiResource {
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final ToApiJsonSerializer<JobDetailData> toApiJsonSerializer;
|
||||
private final ToApiJsonSerializer<JobDetailHistoryData> jobHistoryToApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public SchedulerJobApiResource(final SchedulerJobRunnerReadService schedulerJobRunnerReadService,
|
||||
final JobRegisterService jobRegisterService, final ToApiJsonSerializer<JobDetailData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final ToApiJsonSerializer<JobDetailHistoryData> jobHistoryToApiJsonSerializer) {
|
||||
final ToApiJsonSerializer<JobDetailHistoryData> jobHistoryToApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.schedulerJobRunnerReadService = schedulerJobRunnerReadService;
|
||||
this.jobRegisterService = jobRegisterService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.jobHistoryToApiJsonSerializer = jobHistoryToApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -69,8 +79,11 @@ public class SchedulerJobApiResource {
|
||||
@Path("{jobId}/history")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveHistory(@Context final UriInfo uriInfo, @PathParam("jobId") final Long jobId) {
|
||||
Page<JobDetailHistoryData> jobhistoryDetailData = this.schedulerJobRunnerReadService.retrieveJobHistory(jobId);
|
||||
public String retrieveHistory(@Context final UriInfo uriInfo, @PathParam("jobId") final Long jobId,
|
||||
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
|
||||
final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit, orderBy, sortOrder);
|
||||
Page<JobDetailHistoryData> jobhistoryDetailData = this.schedulerJobRunnerReadService.retrieveJobHistory(jobId, searchParameters);
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.jobHistoryToApiJsonSerializer.serialize(settings, jobhistoryDetailData,
|
||||
SchedulerJobApiConstants.JOB_HISTORY_RESPONSE_DATA_PARAMETERS);
|
||||
@@ -86,4 +99,23 @@ public class SchedulerJobApiResource {
|
||||
response = Response.status(202).build();
|
||||
return response;
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{jobId}/updateJobDetail")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateJobDetail(@PathParam("jobId") final Long jobId, final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.updateJobDetail(jobId) //
|
||||
.withJson(jsonRequestBody) //
|
||||
.build(); //
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
if (result.getChanges() != null
|
||||
&& (result.getChanges().containsKey(SchedulerJobApiConstants.jobActiveStatusParamName) || result.getChanges().containsKey(
|
||||
SchedulerJobApiConstants.cronExpressionParamName))) {
|
||||
jobRegisterService.rescheduleJob(jobId);
|
||||
}
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,4 +35,4 @@ public class JobDetailData {
|
||||
this.lastRunHistory = lastRunHistory;
|
||||
this.currentlyRunning = currentlyRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.mifosplatform.infrastructure.jobs.data;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.jobs.api.SchedulerJobApiConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class JobDetailDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public JobDetailDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
boolean atLeastOneParameterPassedForUpdate = false;
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SchedulerJobApiConstants.JOB_UPDATE_REQUEST_DATA_PARAMETERS);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SchedulerJobApiConstants.JOB_RESOURCE_NAME);
|
||||
if (this.fromApiJsonHelper.parameterExists(SchedulerJobApiConstants.displayNameParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String displayName = this.fromApiJsonHelper.extractStringNamed(SchedulerJobApiConstants.displayNameParamName, element);
|
||||
baseDataValidator.reset().parameter(SchedulerJobApiConstants.displayNameParamName).value(displayName).notBlank();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(SchedulerJobApiConstants.cronExpressionParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String cronExpression = this.fromApiJsonHelper.extractStringNamed(SchedulerJobApiConstants.cronExpressionParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SchedulerJobApiConstants.cronExpressionParamName).value(cronExpression).notBlank()
|
||||
.validateCronExpression();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(SchedulerJobApiConstants.jobActiveStatusParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String status = this.fromApiJsonHelper.extractStringNamed(SchedulerJobApiConstants.jobActiveStatusParamName, element);
|
||||
baseDataValidator.reset().parameter(SchedulerJobApiConstants.jobActiveStatusParamName).value(status).notBlank()
|
||||
.validateForBooleanValue();
|
||||
}
|
||||
|
||||
if (!atLeastOneParameterPassedForUpdate) {
|
||||
final Object forceError = null;
|
||||
baseDataValidator.reset().anyOfNotNull(forceError);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -6,16 +6,22 @@ public class JobDetailHistoryData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long version;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Date jobRunStartTime;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Date jobRunEndTime;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String status;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String jobRunErrorMessage;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String triggerType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String jobRunErrorLog;
|
||||
|
||||
|
||||
+34
-24
@@ -1,6 +1,8 @@
|
||||
package org.mifosplatform.infrastructure.jobs.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@@ -8,6 +10,9 @@ import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.jobs.api.SchedulerJobApiConstants;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@@ -17,12 +22,11 @@ public class ScheduledJobDetail extends AbstractPersistable<Long> {
|
||||
@Column(name = "name")
|
||||
private String jobName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "display_name")
|
||||
private String jobDisplayName;
|
||||
|
||||
@Column(name = "cron_expression")
|
||||
private String croneExpression;
|
||||
private String cronExpression;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "create_time")
|
||||
@@ -58,33 +62,16 @@ public class ScheduledJobDetail extends AbstractPersistable<Long> {
|
||||
@Column(name = "currently_running")
|
||||
private boolean currentlyRunning;
|
||||
|
||||
public ScheduledJobDetail() {
|
||||
protected ScheduledJobDetail() {
|
||||
|
||||
}
|
||||
|
||||
public ScheduledJobDetail(final String jobName, final String jobDisplayName, final String croneExpression, Date createTime,
|
||||
final Short taskPriority, final String groupName, final Date previousRunStartTime, final Date nextRunTime, final String jobKey,
|
||||
final String errorLog, final boolean activeSchedular, final boolean currentlyRunning) {
|
||||
this.jobName = jobName;
|
||||
this.jobDisplayName = jobDisplayName;
|
||||
this.croneExpression = croneExpression;
|
||||
this.createTime = createTime;
|
||||
this.taskPriority = taskPriority;
|
||||
this.groupName = groupName;
|
||||
this.previousRunStartTime = previousRunStartTime;
|
||||
this.nextRunTime = nextRunTime;
|
||||
this.jobKey = jobKey;
|
||||
this.errorLog = errorLog;
|
||||
this.activeSchedular = activeSchedular;
|
||||
this.currentlyRunning = currentlyRunning;
|
||||
}
|
||||
|
||||
public String getJobName() {
|
||||
return this.jobName;
|
||||
}
|
||||
|
||||
public String getCroneExpression() {
|
||||
return this.croneExpression;
|
||||
public String getCronExpression() {
|
||||
return this.cronExpression;
|
||||
}
|
||||
|
||||
public Short getTaskPriority() {
|
||||
@@ -103,8 +90,8 @@ public class ScheduledJobDetail extends AbstractPersistable<Long> {
|
||||
return this.activeSchedular;
|
||||
}
|
||||
|
||||
public void updateCroneExpression(final String croneExpression) {
|
||||
this.croneExpression = croneExpression;
|
||||
public void updateCronExpression(final String cronExpression) {
|
||||
this.cronExpression = cronExpression;
|
||||
}
|
||||
|
||||
public void updatePreviousRunStartTime(final Date previousRunStartTime) {
|
||||
@@ -131,4 +118,27 @@ public class ScheduledJobDetail extends AbstractPersistable<Long> {
|
||||
this.currentlyRunning = currentlyRunning;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
|
||||
|
||||
if (command.isChangeInStringParameterNamed(SchedulerJobApiConstants.displayNameParamName, this.jobDisplayName)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(SchedulerJobApiConstants.displayNameParamName).trim();
|
||||
actualChanges.put(SchedulerJobApiConstants.displayNameParamName, newValue);
|
||||
this.jobDisplayName = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(SchedulerJobApiConstants.cronExpressionParamName, this.cronExpression)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(SchedulerJobApiConstants.cronExpressionParamName).trim();
|
||||
actualChanges.put(SchedulerJobApiConstants.cronExpressionParamName, newValue);
|
||||
this.cronExpression = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(SchedulerJobApiConstants.jobActiveStatusParamName, this.activeSchedular)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(SchedulerJobApiConstants.jobActiveStatusParamName);
|
||||
actualChanges.put(SchedulerJobApiConstants.jobActiveStatusParamName, newValue);
|
||||
this.activeSchedular = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package org.mifosplatform.infrastructure.jobs.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.jobs.service.SchedularWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UpdateJobDetailCommandhandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SchedularWritePlatformService schedularWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateJobDetailCommandhandler(final SchedularWritePlatformService schedularWritePlatformService) {
|
||||
this.schedularWritePlatformService = schedularWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.schedularWritePlatformService.updateJobDetail(command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-3
@@ -1,11 +1,9 @@
|
||||
package org.mifosplatform.infrastructure.jobs.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
|
||||
|
||||
public interface JobRegisterService {
|
||||
|
||||
public void executeJob(Long jobId);
|
||||
|
||||
public void rescheduleJob(ScheduledJobDetail scheduledJobDetails);
|
||||
public void rescheduleJob(Long jobId);
|
||||
|
||||
}
|
||||
|
||||
+25
-32
@@ -40,15 +40,15 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
|
||||
private final SchedulerFactoryBean schedulerFactoryBean;
|
||||
|
||||
private final SchedularService schedularService;
|
||||
private final SchedularWritePlatformService schedularWritePlatformService;
|
||||
|
||||
private final TenantDetailsService tenantDetailsService;
|
||||
|
||||
@Autowired
|
||||
public JobRegisterServiceImpl(final ApplicationContext applicationContext, final SchedulerFactoryBean schedulerFactoryBean,
|
||||
final SchedularService schedularService, final TenantDetailsService tenantDetailsService) {
|
||||
final SchedularWritePlatformService schedularService, final TenantDetailsService tenantDetailsService) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.schedularService = schedularService;
|
||||
this.schedularWritePlatformService = schedularService;
|
||||
this.schedulerFactoryBean = schedulerFactoryBean;
|
||||
this.tenantDetailsService = tenantDetailsService;
|
||||
}
|
||||
@@ -58,15 +58,10 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
List<MifosPlatformTenant> allTenants = this.tenantDetailsService.findAllTenants();
|
||||
for (MifosPlatformTenant tenant : allTenants) {
|
||||
ThreadLocalContextUtil.setTenant(tenant);
|
||||
List<ScheduledJobDetail> scheduledJobDetails = this.schedularService.retrieveAllJobs();
|
||||
List<ScheduledJobDetail> scheduledJobDetails = this.schedularWritePlatformService.retrieveAllJobs();
|
||||
for (ScheduledJobDetail jobDetails : scheduledJobDetails) {
|
||||
if (jobDetails.isActiveSchedular()) {
|
||||
scheduleJob(jobDetails);
|
||||
}else{
|
||||
jobDetails.updateNextRunTime(null);
|
||||
}
|
||||
|
||||
this.schedularService.saveOrUpdate(jobDetails);
|
||||
scheduleJob(jobDetails);
|
||||
this.schedularWritePlatformService.saveOrUpdate(jobDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,21 +72,11 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
jobDataMap.put(SchedularServiceConstants.TRIGGER_TYPE_REFERENCE, SchedularServiceConstants.TRIGGER_TYPE_APPLICATION);
|
||||
jobDataMap.put(SchedularServiceConstants.TENANT_IDENTIFIER, ThreadLocalContextUtil.getTenant().getTenantIdentifier());
|
||||
if (schedulerFactoryBean.getScheduler().checkExists(jobKey)) {
|
||||
Thread newThread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final JobKey threadLocalJobKey = jobKey;
|
||||
final JobDataMap threadLocalJobDataMap = jobDataMap;
|
||||
try {
|
||||
schedulerFactoryBean.getScheduler().triggerJob(threadLocalJobKey, threadLocalJobDataMap);
|
||||
} catch (SchedulerException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
newThread.run();
|
||||
try {
|
||||
schedulerFactoryBean.getScheduler().triggerJob(jobKey, jobDataMap);
|
||||
} catch (SchedulerException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
throw new JobNotFoundException(jobKey.toString());
|
||||
}
|
||||
@@ -101,25 +86,30 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rescheduleJob(ScheduledJobDetail scheduledJobDetails) {
|
||||
try {
|
||||
String jobIdentity = scheduledJobDetails.getJobKey();
|
||||
JobKey jobKey = constructJobKey(jobIdentity);
|
||||
schedulerFactoryBean.getScheduler().deleteJob(jobKey);
|
||||
scheduleJob(scheduledJobDetails);
|
||||
this.schedularService.saveOrUpdate(scheduledJobDetails);
|
||||
this.schedularWritePlatformService.saveOrUpdate(scheduledJobDetails);
|
||||
} catch (Throwable throwable) {
|
||||
String stackTrace = getStackTraceAsString(throwable);
|
||||
scheduledJobDetails.updateErrorLog(stackTrace);
|
||||
this.schedularService.saveOrUpdate(scheduledJobDetails);
|
||||
this.schedularWritePlatformService.saveOrUpdate(scheduledJobDetails);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rescheduleJob(Long jobId) {
|
||||
ScheduledJobDetail scheduledJobDetail = this.schedularWritePlatformService.findByJobId(jobId);
|
||||
rescheduleJob(scheduledJobDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeJob(Long jobId) {
|
||||
try {
|
||||
ScheduledJobDetail scheduledJobDetail = this.schedularService.findByJobId(jobId);
|
||||
ScheduledJobDetail scheduledJobDetail = this.schedularWritePlatformService.findByJobId(jobId);
|
||||
if (scheduledJobDetail != null) {
|
||||
String key = scheduledJobDetail.getJobKey();
|
||||
JobKey jobKey = constructJobKey(key);
|
||||
@@ -133,6 +123,10 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
}
|
||||
|
||||
private void scheduleJob(ScheduledJobDetail scheduledJobDetails) {
|
||||
if (!scheduledJobDetails.isActiveSchedular()) {
|
||||
scheduledJobDetails.updateNextRunTime(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
JobDetail jobDetail = createJobDetail(scheduledJobDetails);
|
||||
Trigger trigger = createTrigger(scheduledJobDetails, jobDetail);
|
||||
@@ -184,7 +178,7 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
TimeZone timeZone = TimeZone.getTimeZone(tenant.getTimezoneId());
|
||||
cronTriggerFactoryBean.setTimeZone(timeZone);
|
||||
cronTriggerFactoryBean.setGroup(scheduledJobDetails.getGroupName());
|
||||
cronTriggerFactoryBean.setCronExpression(scheduledJobDetails.getCroneExpression());
|
||||
cronTriggerFactoryBean.setCronExpression(scheduledJobDetails.getCronExpression());
|
||||
cronTriggerFactoryBean.setPriority(scheduledJobDetails.getTaskPriority());
|
||||
cronTriggerFactoryBean.afterPropertiesSet();
|
||||
return cronTriggerFactoryBean.getObject();
|
||||
@@ -213,5 +207,4 @@ public class JobRegisterServiceImpl implements JobRegisterService {
|
||||
JobKey JobKey = new JobKey(keyParams[0], keyParams[1]);
|
||||
return JobKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-1
@@ -2,10 +2,12 @@ package org.mifosplatform.infrastructure.jobs.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistory;
|
||||
|
||||
public interface SchedularService {
|
||||
public interface SchedularWritePlatformService {
|
||||
|
||||
public List<ScheduledJobDetail> retrieveAllJobs();
|
||||
|
||||
@@ -19,4 +21,6 @@ public interface SchedularService {
|
||||
|
||||
public ScheduledJobDetail findByJobId(Long jobId);
|
||||
|
||||
CommandProcessingResult updateJobDetail(Long jobId, JsonCommand command);
|
||||
|
||||
}
|
||||
+30
-3
@@ -1,27 +1,36 @@
|
||||
package org.mifosplatform.infrastructure.jobs.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailDataValidator;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetail;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobDetailRepository;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistory;
|
||||
import org.mifosplatform.infrastructure.jobs.domain.ScheduledJobRunHistoryRepository;
|
||||
import org.mifosplatform.infrastructure.jobs.exception.JobNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class SchedularServiceJpaRepositoryImpl implements SchedularService {
|
||||
public class SchedularWritePlatformServiceJpaRepositoryImpl implements SchedularWritePlatformService {
|
||||
|
||||
private final ScheduledJobDetailRepository scheduledJobDetailsRepository;
|
||||
|
||||
private final ScheduledJobRunHistoryRepository scheduledJobRunHistoryRepository;
|
||||
|
||||
private final JobDetailDataValidator dataValidator;
|
||||
|
||||
@Autowired
|
||||
public SchedularServiceJpaRepositoryImpl(final ScheduledJobDetailRepository scheduledJobDetailsRepository,
|
||||
final ScheduledJobRunHistoryRepository scheduledJobRunHistoryRepository) {
|
||||
public SchedularWritePlatformServiceJpaRepositoryImpl(final ScheduledJobDetailRepository scheduledJobDetailsRepository,
|
||||
final ScheduledJobRunHistoryRepository scheduledJobRunHistoryRepository, final JobDetailDataValidator dataValidator) {
|
||||
this.scheduledJobDetailsRepository = scheduledJobDetailsRepository;
|
||||
this.scheduledJobRunHistoryRepository = scheduledJobRunHistoryRepository;
|
||||
this.dataValidator = dataValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,4 +71,22 @@ public class SchedularServiceJpaRepositoryImpl implements SchedularService {
|
||||
return this.scheduledJobDetailsRepository.findByJobId(jobId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult updateJobDetail(final Long jobId, final JsonCommand command) {
|
||||
dataValidator.validateForUpdate(command.json());
|
||||
final ScheduledJobDetail scheduledJobDetail = findByJobId(jobId);
|
||||
if (scheduledJobDetail == null) { throw new JobNotFoundException(String.valueOf(jobId)); }
|
||||
final Map<String, Object> changes = scheduledJobDetail.update(command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.scheduledJobDetailsRepository.saveAndFlush(scheduledJobDetail);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(jobId) //
|
||||
.with(changes) //
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -29,12 +29,12 @@ public class SchedulerJobListener implements JobListener {
|
||||
|
||||
private final String name = SchedularServiceConstants.DEFAULT_LISTENER_NAME;
|
||||
|
||||
private final SchedularService schedularService;
|
||||
private final SchedularWritePlatformService schedularService;
|
||||
|
||||
private final TenantDetailsService tenantDetailsService;
|
||||
|
||||
@Autowired
|
||||
public SchedulerJobListener(final SchedularService schedularService, final TenantDetailsService tenantDetailsService) {
|
||||
public SchedulerJobListener(final SchedularWritePlatformService schedularService, final TenantDetailsService tenantDetailsService) {
|
||||
this.schedularService = schedularService;
|
||||
this.tenantDetailsService = tenantDetailsService;
|
||||
}
|
||||
|
||||
+6
-6
@@ -5,14 +5,14 @@ import java.util.List;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailData;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailHistoryData;
|
||||
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
|
||||
public interface SchedulerJobRunnerReadService {
|
||||
|
||||
public List<JobDetailData> findAllJobDeatils();
|
||||
|
||||
public List<JobDetailData> findAllJobDeatils();
|
||||
|
||||
public JobDetailData retrieveOne(Long jobId);
|
||||
|
||||
public Page<JobDetailHistoryData> retrieveJobHistory(Long jobId);
|
||||
|
||||
|
||||
public Page<JobDetailHistoryData> retrieveJobHistory(Long jobId, SearchParameters searchParameters);
|
||||
|
||||
}
|
||||
|
||||
+30
-10
@@ -11,6 +11,7 @@ import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailData;
|
||||
import org.mifosplatform.infrastructure.jobs.data.JobDetailHistoryData;
|
||||
import org.mifosplatform.infrastructure.jobs.exception.JobNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -50,12 +51,28 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<JobDetailHistoryData> retrieveJobHistory(Long jobId) {
|
||||
public Page<JobDetailHistoryData> retrieveJobHistory(Long jobId, SearchParameters searchParameters) {
|
||||
retrieveOne(jobId);
|
||||
JobHistoryMapper jobHistoryMapper = new JobHistoryMapper();
|
||||
String sql = jobHistoryMapper.schema() + " where job.id=?";
|
||||
StringBuilder sqlBuilder = new StringBuilder(jobHistoryMapper.schema());
|
||||
sqlBuilder.append(" where job.id=?");
|
||||
if (searchParameters.isOrderByRequested()) {
|
||||
sqlBuilder.append(" order by ").append(searchParameters.getOrderBy());
|
||||
|
||||
if (searchParameters.isSortOrderProvided()) {
|
||||
sqlBuilder.append(' ').append(searchParameters.getSortOrder());
|
||||
}
|
||||
}
|
||||
|
||||
if (searchParameters.isLimited()) {
|
||||
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
|
||||
if (searchParameters.isOffset()) {
|
||||
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sql, new Object[] { jobId }, jobHistoryMapper);
|
||||
return paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { jobId }, jobHistoryMapper);
|
||||
}
|
||||
|
||||
private static final class JobDetailMapper implements RowMapper<JobDetailData> {
|
||||
@@ -73,21 +90,24 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
|
||||
public JobDetailData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
|
||||
Long id = rs.getLong("id");
|
||||
String displayName = rs.getString("displayName");
|
||||
Date nextRunTime = rs.getDate("nextRunTime");
|
||||
Date nextRunTime = rs.getTimestamp("nextRunTime");
|
||||
String initializingError = rs.getString("initializingError");
|
||||
boolean active = rs.getBoolean("active");
|
||||
boolean currentlyRunning = rs.getBoolean("currentlyRunning");
|
||||
|
||||
Long version = rs.getLong("version");
|
||||
Date jobRunStartTime = rs.getDate("lastRunStartTime");
|
||||
Date jobRunEndTime = rs.getDate("lastRunEndTime");
|
||||
Date jobRunStartTime = rs.getTimestamp("lastRunStartTime");
|
||||
Date jobRunEndTime = rs.getTimestamp("lastRunEndTime");
|
||||
String status = rs.getString("status");
|
||||
String jobRunErrorMessage = rs.getString("jobRunErrorMessage");
|
||||
String triggerType = rs.getString("triggerType");
|
||||
String jobRunErrorLog = rs.getString("jobRunErrorLog");
|
||||
|
||||
JobDetailHistoryData lastRunHistory = new JobDetailHistoryData(version, jobRunStartTime, jobRunEndTime, status,
|
||||
jobRunErrorMessage, triggerType, jobRunErrorLog);
|
||||
JobDetailHistoryData lastRunHistory = null;
|
||||
if (version > 0) {
|
||||
lastRunHistory = new JobDetailHistoryData(version, jobRunStartTime, jobRunEndTime, status, jobRunErrorMessage, triggerType,
|
||||
jobRunErrorLog);
|
||||
}
|
||||
JobDetailData jobDetail = new JobDetailData(id, displayName, nextRunTime, initializingError, active, currentlyRunning,
|
||||
lastRunHistory);
|
||||
return jobDetail;
|
||||
@@ -108,8 +128,8 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
|
||||
@Override
|
||||
public JobDetailHistoryData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
|
||||
Long version = rs.getLong("version");
|
||||
Date jobRunStartTime = rs.getDate("runStartTime");
|
||||
Date jobRunEndTime = rs.getDate("runEndTime");
|
||||
Date jobRunStartTime = rs.getTimestamp("runStartTime");
|
||||
Date jobRunEndTime = rs.getTimestamp("runEndTime");
|
||||
String status = rs.getString("status");
|
||||
String jobRunErrorMessage = rs.getString("jobRunErrorMessage");
|
||||
String triggerType = rs.getString("triggerType");
|
||||
|
||||
+8
@@ -61,6 +61,14 @@ public final class SearchParameters {
|
||||
return new SearchParameters(null, officeId, null, null, null, null, null, offset, maxLimitAllowed, orderBy, sortOrder);
|
||||
}
|
||||
|
||||
public static SearchParameters forPagination(final Integer offset, final Integer limit, final String orderBy,
|
||||
final String sortOrder) {
|
||||
|
||||
Integer maxLimitAllowed = getCheckedLimit(limit);
|
||||
|
||||
return new SearchParameters(null, null, null, null, null, null, null, offset, maxLimitAllowed, orderBy, sortOrder);
|
||||
}
|
||||
|
||||
private SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
|
||||
final String hierarchy, final String firstname, final String lastname, final Integer offset, final Integer limit,
|
||||
final String orderBy, final String sortOrder) {
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
<jpa:repositories base-package="org.mifosplatform.useradministration.domain" />
|
||||
<jpa:repositories base-package="org.mifosplatform.organisation.*.domain" />
|
||||
<jpa:repositories base-package="org.mifosplatform.portfolio.*" />
|
||||
<jpa:repositories base-package="org.mifosplatform.scheduledjobs.domain" />
|
||||
|
||||
<import resource="infrastructure.xml" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user