/*
* Copyright 2010 LinkedIn, Inc
*
* 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 azkaban.scheduler;
import org.joda.time.DateTime;
import org.joda.time.ReadablePeriod;
import azkaban.user.User;
import azkaban.utils.Utils;
/**
* Schedule for a job instance. This is decoupled from the execution.
*
* @author Richard Park
*
*/
public class ScheduledFlow {
//use projectId.flowId to form a unique scheduleId
private final String scheduleId;
private final ReadablePeriod period;
private DateTime nextExecTime;
private final String user;
private final String userSubmit;
private final DateTime submitTime;
private final DateTime firstSchedTime;
// private SchedStatus schedStatus;
public enum SchedStatus {
LASTSUCCESS ("lastsuccess"),
LASTFAILED ("lastfailed"),
LASTPAUSED ("lastpaused");
private final String status;
SchedStatus(String status){
this.status = status;
}
private String status(){
return this.status;
}
}
/**
* Constructor
*
* @param jobName Unique job name
* @param nextExecution The next execution time
* @param ignoreDependency
*/
public ScheduledFlow(String scheduleId,
String user,
String userSubmit,
DateTime submitTime,
DateTime firstSchedTime,
DateTime nextExecution) {
this(scheduleId, user, userSubmit, submitTime, firstSchedTime, nextExecution, null);
}
/**
* Constructor
*
* @param jobId
* @param nextExecution
* @param period
* @param ignoreDependency
*/
public ScheduledFlow(String scheduleId,
String user,
String userSubmit,
DateTime submitTime,
DateTime firstSchedTime,
DateTime nextExecution,
ReadablePeriod period) {
super();
this.scheduleId = Utils.nonNull(scheduleId);
this.user = user;
this.userSubmit = userSubmit;
this.submitTime = submitTime;
this.firstSchedTime = firstSchedTime;
this.period = period;
this.nextExecTime = Utils.nonNull(nextExecution);
// this.schedStatus = SchedStatus.LASTSUCCESS;
}
public ScheduledFlow(String scheduleId,
String user,
String userSubmit,
DateTime submitTime,
DateTime firstSchedTime,
ReadablePeriod period) {
super();
this.scheduleId = Utils.nonNull(scheduleId);
this.user = user;
this.userSubmit = userSubmit;
this.submitTime = submitTime;
this.firstSchedTime = firstSchedTime;
this.period = period;
this.nextExecTime = new DateTime(firstSchedTime);
// this.schedStatus = SchedStatus.LASTSUCCESS;
}
public ScheduledFlow(String scheduleId,
String user,
String userSubmit,
DateTime submitTime,
DateTime firstSchedTime) {
super();
this.scheduleId = Utils.nonNull(scheduleId);
this.user = user;
this.userSubmit = userSubmit;
this.submitTime = submitTime;
this.firstSchedTime = firstSchedTime;
this.period = null;
this.nextExecTime = new DateTime();
// this.schedStatus = SchedStatus.LASTSUCCESS;
}
// public SchedStatus getSchedStatus() {
// return this.schedStatus;
// }
//
// public void setSchedStatus(SchedStatus schedStatus) {
// this.schedStatus = schedStatus;
// }
/**
* Updates the time to a future time after 'now' that matches the period description.
*
* @return
*/
public boolean updateTime() {
if (nextExecTime.isAfterNow()) {
return true;
}
if (period != null) {
DateTime other = getNextRuntime(nextExecTime, period);
this.nextExecTime = other;
return true;
}
return false;
}
/**
* Calculates the next runtime by adding the period.
*
* @param scheduledDate
* @param period
* @return
*/
private DateTime getNextRuntime(DateTime scheduledDate, ReadablePeriod period)
{
DateTime now = new DateTime();
DateTime date = new DateTime(scheduledDate);
int count = 0;
while (!now.isBefore(date)) {
if (count > 100000) {
throw new IllegalStateException("100000 increments of period did not get to present time.");
}
if (period == null) {
break;
}
else {
date = date.plus(period);
}
count += 1;
}
return date;
}
/**
* Returns the unique id of the job to be run.
* @return
*/
/**
* Returns true if the job recurrs in the future
* @return
*/
public boolean isRecurring() {
return this.period != null;
}
/**
* Returns the recurrance period. Or null if not applicable
* @return
*/
public ReadablePeriod getPeriod() {
return period;
}
public DateTime getFirstSchedTime() {
return firstSchedTime;
}
/**
* Returns the next scheduled execution
* @return
*/
public DateTime getNextExecTime() {
return nextExecTime;
}
public String getUserSubmit() {
return userSubmit;
}
public DateTime getSubmitTime() {
return submitTime;
}
@Override
public String toString()
{
return "ScheduledFlow{" +
// "scheduleStatus=" + schedStatus +
"nextExecTime=" + nextExecTime +
", period=" + period.toString() +
", firstSchedTime=" + firstSchedTime +
", submitTime=" + submitTime +
", userSubmit=" + userSubmit +
", user=" + user +
", scheduleId='" + scheduleId + '\'' +
'}';
}
public String getUser() {
return user;
}
public String getScheduleId() {
return scheduleId;
}
public String getFlowId(){
return this.scheduleId.split("\\.")[1];
}
public String getProjectId(){
return this.scheduleId.split("\\.")[0];
}
}