/* * Copyright 2013-2015 the original author or authors. * * Licensed 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.springframework.batch.admin.domain; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; import javax.xml.bind.annotation.XmlRootElement; import com.fasterxml.jackson.annotation.JsonProperty; import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameters; import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.ResourceSupport; /** * Represents job execution info resource. * * @author Dave Syer * @author Ilayaperumal Gopinathan * @author Michael Minella * @since 2.0 */ @XmlRootElement public class JobExecutionInfoResource extends ResourceSupport { private DateTimeFormatter dateFormat = ISODateTimeFormat.dateTime(); private Long executionId; private int stepExecutionCount; private Long jobId; private Integer version; @JsonProperty("name") private String jobName; private String startTime = ""; private String endTime = ""; private String createDate = ""; private String lastUpdated = ""; private JobParameters jobParameters; private boolean restartable = false; private boolean abandonable = false; private boolean stoppable = false; private final TimeZone timeZone; private BatchStatus status; private ExitStatus exitStatus; private String jobConfigurationName; private List<Throwable> failureExceptions; private Map<String, Object> executionContext; private Collection<StepExecutionInfoResource> stepExecutions; public JobExecutionInfoResource() { this.timeZone = TimeZone.getTimeZone("UTC"); } public JobExecutionInfoResource(JobExecution jobExecution, TimeZone timeZone) { if(timeZone != null) { this.timeZone = timeZone; } else { this.timeZone = TimeZone.getTimeZone("UTC"); } this.executionId = jobExecution.getId(); this.jobId = jobExecution.getJobId(); this.stepExecutionCount = jobExecution.getStepExecutions().size(); this.jobParameters = jobExecution.getJobParameters(); this.status = jobExecution.getStatus(); this.exitStatus = jobExecution.getExitStatus(); this.jobConfigurationName = jobExecution.getJobConfigurationName(); this.failureExceptions = jobExecution.getFailureExceptions(); Map<String, Object> executionContextEntires = new HashMap<String, Object>(jobExecution.getExecutionContext().size()); for (Map.Entry<String, Object> stringObjectEntry : jobExecution.getExecutionContext().entrySet()) { executionContextEntires.put(stringObjectEntry.getKey(), stringObjectEntry.getValue()); } this.executionContext = executionContextEntires; this.version = jobExecution.getVersion(); JobInstance jobInstance = jobExecution.getJobInstance(); if (jobInstance != null) { this.jobName = jobInstance.getJobName(); BatchStatus status = jobExecution.getStatus(); this.restartable = status.isGreaterThan(BatchStatus.STOPPING) && status.isLessThan(BatchStatus.ABANDONED); this.abandonable = status.isGreaterThan(BatchStatus.STARTED) && status != BatchStatus.ABANDONED; this.stoppable = status.isLessThan(BatchStatus.STOPPING) && status != BatchStatus.COMPLETED; } else { this.jobName = "?"; } this.dateFormat = this.dateFormat.withZone(DateTimeZone.forTimeZone(timeZone)); this.createDate = dateFormat.print(jobExecution.getCreateTime().getTime()); this.lastUpdated = dateFormat.print(jobExecution.getLastUpdated().getTime()); if (jobExecution.getStartTime() != null) { this.startTime = dateFormat.print(jobExecution.getStartTime().getTime()); if(!jobExecution.isRunning()) { this.endTime = dateFormat.print(jobExecution.getEndTime().getTime()); } else { this.endTime = "N/A"; } } } public void setStepExecutions(Collection<StepExecutionInfoResource> stepExecutions) { this.stepExecutions = stepExecutions; } public TimeZone getTimeZone() { return timeZone; } @JsonProperty public String getName() { return (jobName.endsWith(".job") ? jobName.substring(0, jobName.lastIndexOf(".job")) : jobName); } public Long getExecutionId() { return executionId; } public int getStepExecutionCount() { return stepExecutionCount; } public Long getJobId() { return jobId; } public String getStartTime() { return startTime; } public boolean isRestartable() { return restartable; } public boolean isAbandonable() { return abandonable; } public boolean isStoppable() { return stoppable; } public JobParameters getJobParameters() { return jobParameters; } public Map<String, Object> getExecutionContext() { return executionContext; } public List<Throwable> getFailureExceptions() { return failureExceptions; } public String getJobConfigurationName() { return jobConfigurationName; } public ExitStatus getExitStatus() { return exitStatus; } public BatchStatus getStatus() { return status; } public String getLastUpdated() { return lastUpdated; } public String getCreateDate() { return createDate; } public Collection<StepExecutionInfoResource> getStepExecutions() { return stepExecutions; } public Integer getVersion() { return version; } public String getEndTime() { return endTime; } /** * Set restartable flag explicitly based on the job executions status of the same job instance. * * @param restartable flag to identify if the job execution can be restarted */ public void setRestartable(boolean restartable) { this.restartable = restartable; } /** * Dedicated subclass to workaround type erasure. * * @author Gunnar Hillert */ public static class Page extends PagedResources<JobExecutionInfoResource> { } }