/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.scheduler.core.db; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ConstraintMode; import javax.persistence.ElementCollection; import javax.persistence.Embeddable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.ForeignKey; import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.MapKey; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.Parameter; import org.hibernate.annotations.Type; import org.hibernate.type.SerializableToBlobType; import org.ow2.proactive.scheduler.common.task.CommonAttribute; import org.ow2.proactive.scheduler.common.task.ForkEnvironment; import org.ow2.proactive.scheduler.common.task.OnTaskError; import org.ow2.proactive.scheduler.common.task.ParallelEnvironment; import org.ow2.proactive.scheduler.common.task.PropertyModifier; import org.ow2.proactive.scheduler.common.task.RestartMode; import org.ow2.proactive.scheduler.common.task.TaskId; import org.ow2.proactive.scheduler.common.task.TaskInfo; import org.ow2.proactive.scheduler.common.task.TaskState; import org.ow2.proactive.scheduler.common.task.TaskStatus; import org.ow2.proactive.scheduler.common.task.TaskVariable; import org.ow2.proactive.scheduler.common.task.dataspaces.InputSelector; import org.ow2.proactive.scheduler.common.task.dataspaces.OutputSelector; import org.ow2.proactive.scheduler.common.task.flow.FlowBlock; import org.ow2.proactive.scheduler.common.usage.TaskUsage; import org.ow2.proactive.scheduler.core.properties.PASchedulerProperties; import org.ow2.proactive.scheduler.job.InternalJob; import org.ow2.proactive.scheduler.job.JobIdImpl; import org.ow2.proactive.scheduler.task.TaskIdImpl; import org.ow2.proactive.scheduler.task.TaskInfoImpl; import org.ow2.proactive.scheduler.task.TaskStateImpl; import org.ow2.proactive.scheduler.task.containers.ExecutableContainer; import org.ow2.proactive.scheduler.task.containers.ScriptExecutableContainer; import org.ow2.proactive.scheduler.task.internal.InternalForkedScriptTask; import org.ow2.proactive.scheduler.task.internal.InternalScriptTask; import org.ow2.proactive.scheduler.task.internal.InternalTask; import org.ow2.proactive.scheduler.util.policy.ISO8601DateUtil; import org.ow2.proactive.scripting.InvalidScriptException; import org.ow2.proactive.scripting.SelectionScript; import org.ow2.proactive.scripting.TaskScript; import org.ow2.proactive.topology.descriptor.ArbitraryTopologyDescriptor; import org.ow2.proactive.topology.descriptor.BestProximityDescriptor; import org.ow2.proactive.topology.descriptor.DifferentHostsExclusiveDescriptor; import org.ow2.proactive.topology.descriptor.MultipleHostsExclusiveDescriptor; import org.ow2.proactive.topology.descriptor.SingleHostDescriptor; import org.ow2.proactive.topology.descriptor.SingleHostExclusiveDescriptor; import org.ow2.proactive.topology.descriptor.ThresholdProximityDescriptor; import org.ow2.proactive.topology.descriptor.TopologyDescriptor; @Entity @NamedQueries({ @NamedQuery(name = "deleteTaskDataInBulk", query = "delete from TaskData where jobData.id in :jobIdList"), @NamedQuery(name = "countTaskData", query = "select count (*) from TaskData"), @NamedQuery(name = "countTaskDataNotFinished", query = "select count (*) from TaskData where taskStatus <> org.ow2.proactive.scheduler.common.task.TaskStatus.FINISHED"), @NamedQuery(name = "getFinishedTasksCount", query = "select count(*) from TaskData task where taskStatus in (:taskStatus) and task.jobData.removedTime = -1"), @NamedQuery(name = "getMeanTaskPendingTime", query = "select avg(startTime - :jobSubmittedTime) from TaskData task where task.jobData.id = :id and task.startTime > 0"), @NamedQuery(name = "getMeanTaskRunningTime", query = "select avg(task.finishedTime - task.startTime) from TaskData task where task.startTime > 0 and task.finishedTime > 0 and task.jobData.id = :id"), @NamedQuery(name = "getPendingTasksCount", query = "select count(*) from TaskData task where taskStatus in (:taskStatus) and task.jobData.status in (:jobStatus) and task.jobData.removedTime = -1"), @NamedQuery(name = "getRunningTasksCount", query = "select count(*) from TaskData task where taskStatus in (:taskStatus) " + "and task.jobData.status in (:jobStatus) and task.jobData.removedTime = -1"), @NamedQuery(name = "findTaskData", query = "from TaskData where id in (:ids)"), @NamedQuery(name = "findTaskDataById", query = "from TaskData td where td.id = :taskId"), @NamedQuery(name = "getTotalNumberOfHostsUsed", query = "select count(distinct executionHostName) from TaskData task where task.jobData.id = :id"), @NamedQuery(name = "getTotalTasksCount", query = "select count(*) from TaskData task where task.jobData.removedTime = -1"), @NamedQuery(name = "loadJobsTasks", query = "from TaskData as task left outer join fetch task.dependentTasks where task.id.jobId in (:ids)"), @NamedQuery(name = "readAccountTasks", query = "select count(*), sum(task.finishedTime) - sum(task.startTime) from TaskData task " + "where task.finishedTime > 0 and task.jobData.owner = :username"), @NamedQuery(name = "updateTaskData", query = "update TaskData task set task.taskStatus = :taskStatus, " + "task.numberOfExecutionLeft = :numberOfExecutionLeft, " + "task.numberOfExecutionOnFailureLeft = :numberOfExecutionOnFailureLeft, " + "task.inErrorTime = :inErrorTime " + "where task.id = :taskId"), @NamedQuery(name = "updateTaskDataAfterJobFinished", query = "update TaskData task set task.taskStatus = :taskStatus, " + "task.numberOfExecutionLeft = :numberOfExecutionLeft, " + "task.numberOfExecutionOnFailureLeft = :numberOfExecutionOnFailureLeft, " + "task.finishedTime = :finishedTime, " + "task.executionDuration = :executionDuration " + "where task.id = :taskId"), @NamedQuery(name = "updateTaskDataJobScripts", query = "update TaskData set envScript = null, preScript = null, postScript = null,flowScript = null," + "cleanScript = null where id.jobId = :jobId"), @NamedQuery(name = "updateTaskDataJobScriptsInBulk", query = "update TaskData set envScript = null, preScript = null, postScript = null,flowScript = null," + "cleanScript = null where id.jobId in :jobIdList"), @NamedQuery(name = "updateTaskDataStatusToPending", query = "update TaskData task set task.taskStatus = :taskStatus " + "where task.jobData = :job"), @NamedQuery(name = "updateTaskDataTaskRestarted", query = "update TaskData set taskStatus = :taskStatus, " + "numberOfExecutionLeft = :numberOfExecutionLeft," + "numberOfExecutionOnFailureLeft = :numberOfExecutionOnFailureLeft" + " where id = :taskId"), @NamedQuery(name = "updateTaskDataTaskStarted", query = "update TaskData task set task.taskStatus = :taskStatus, " + "task.startTime = :startTime, task.finishedTime = :finishedTime, " + "task.executionHostName = :executionHostName where task.id = :taskId"), }) @Table(name = "TASK_DATA", indexes = { @Index(name = "TASK_DATA_CLEAN_SCRIPT_ID", columnList = "CLEAN_SCRIPT_ID"), @Index(name = "TASK_DATA_ENV_SCRIPT_ID", columnList = "ENV_SCRIPT_ID"), @Index(name = "TASK_DATA_FINISH_TIME", columnList = "FINISH_TIME"), @Index(name = "TASK_DATA_FLOW_SCRIPT_ID", columnList = "FLOW_SCRIPT_ID"), @Index(name = "TASK_DATA_IFBRANCH_JOB_ID", columnList = "IFBRANCH_TASK_ID_JOB"), @Index(name = "TASK_DATA_IFBRANCH_TASK_ID", columnList = "IFBRANCH_TASK_ID_TASK"), @Index(name = "TASK_DATA_JOB_ID", columnList = "JOB_ID"), @Index(name = "TASK_DATA_POST_SCRIPT_ID", columnList = "POST_SCRIPT_ID"), @Index(name = "TASK_DATA_PRE_SCRIPT_ID", columnList = "PRE_SCRIPT_ID"), @Index(name = "TASK_DATA_SCRIPT_ID", columnList = "SCRIPT_ID"), @Index(name = "TASK_DATA_START_TIME", columnList = "START_TIME"), @Index(name = "TASK_DATA_STATUS", columnList = "STATUS"), @Index(name = "TASK_DATA_TAG", columnList = "TAG"), @Index(name = "TASK_DATA_TASK_ID_JOB", columnList = "TASK_ID_JOB"), @Index(name = "TASK_DATA_TASK_ID_TASK", columnList = "TASK_ID_TASK"), @Index(name = "TASK_DATA_TASK_NAME", columnList = "TASK_NAME") }) public class TaskData { private static final String SCRIPT_TASK = "SCRIPT_TASK"; private static final String FORKED_SCRIPT_TASK = "FORKED_SCRIPT_TASK"; private DBTaskId id; private JobData jobData; private List<DBTaskId> dependentTasks; private List<DBTaskId> joinedBranches; private TaskData ifBranch; private Map<String, String> genericInformation; private Map<String, TaskDataVariable> variables; private List<SelectionScriptData> selectionScripts; private List<SelectorData> dataspaceSelectors; private ScriptData preScript; private ScriptData postScript; private ScriptData cleanScript; private ScriptData flowScript; private ScriptData script; private String taskName; private String tag; private String description; private long startTime; private long finishedTime; private long scheduledTime; // START_AT time // contains the timestamp at which the Task has been in-error for the last time (last attempt) private long inErrorTime = -1; private long executionDuration; private TaskStatus taskStatus; private String executionHostName; private int maxNumberOfExecution; private String onTaskErrorString; private int numberOfExecutionLeft; private int numberOfExecutionOnFailureLeft; private String resultPreview; private boolean preciousResult; private boolean preciousLogs; private boolean runAsMe; private long wallTime; private int iteration; private int replication; private String matchingBlock; private String taskType; private int restartModeId; private FlowBlock flowBlock; private int parallelEnvNodesNumber; private String topologyDescriptor; private long topologyDescriptorThreshold; /* Fork environment parameters */ private String javaHome; private List<String> jvmArguments; private List<String> additionalClasspath; private ScriptData envScript; private List<EnvironmentModifierData> envModifiers; private String workingDir; @Column(name = "JAVA_HOME", length = Integer.MAX_VALUE) @Lob public String getJavaHome() { return javaHome; } public void setJavaHome(String javaHome) { this.javaHome = javaHome; } @Column(name = "JVM_ARGUMENTS") @Type(type = "org.hibernate.type.SerializableToBlobType", parameters = @org.hibernate.annotations.Parameter(name = SerializableToBlobType.CLASS_NAME, value = "java.lang.Object")) public List<String> getJvmArguments() { return jvmArguments; } public void setJvmArguments(List<String> jvmArguments) { this.jvmArguments = jvmArguments; } @Column(name = "CLASSPATH") @Type(type = "org.hibernate.type.SerializableToBlobType", parameters = @org.hibernate.annotations.Parameter(name = SerializableToBlobType.CLASS_NAME, value = "java.lang.Object")) public List<String> getAdditionalClasspath() { return additionalClasspath; } public void setAdditionalClasspath(List<String> additionalClasspath) { this.additionalClasspath = additionalClasspath; } @Cascade(org.hibernate.annotations.CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "ENV_SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getEnvScript() { return envScript; } public void setEnvScript(ScriptData envScript) { this.envScript = envScript; } @Cascade(org.hibernate.annotations.CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getScript() { return script; } public void setScript(ScriptData script) { this.script = script; } @Cascade(CascadeType.ALL) @OneToMany(mappedBy = "taskData") @OnDelete(action = OnDeleteAction.CASCADE) public List<EnvironmentModifierData> getEnvModifiers() { return envModifiers; } public void setEnvModifiers(List<EnvironmentModifierData> envModifiers) { this.envModifiers = envModifiers; } @Column(name = "WORKING_DIR", length = Integer.MAX_VALUE) @Lob public String getWorkingDir() { return workingDir; } public void setWorkingDir(String workingDir) { this.workingDir = workingDir; } public ForkEnvironment createForkEnvironment() throws InvalidScriptException { ForkEnvironment forkEnv = new ForkEnvironment(); forkEnv.setJavaHome(javaHome); forkEnv.setWorkingDir(workingDir); List<String> additionalClasspath = getAdditionalClasspath(); if (additionalClasspath != null) { for (String classpath : additionalClasspath) { forkEnv.addAdditionalClasspath(classpath); } } List<String> jvmArguments = getJvmArguments(); if (jvmArguments != null) { for (String jvmArg : jvmArguments) { forkEnv.addJVMArgument(jvmArg); } } List<EnvironmentModifierData> envModifiers = getEnvModifiers(); if (envModifiers != null) { for (EnvironmentModifierData envModifier : envModifiers) { forkEnv.addSystemEnvironmentVariable(envModifier.getName(), envModifier.getValue()); } } if (envScript != null) { forkEnv.setEnvScript(envScript.createSimpleScript()); } return forkEnv; } public ExecutableContainer createExecutableContainer() throws InvalidScriptException { return new ScriptExecutableContainer(new TaskScript(script.createSimpleScript())); } @Embeddable public static class DBTaskId implements Serializable { private long jobId; private long taskId; @Column(name = "TASK_ID_JOB") public long getJobId() { return jobId; } public void setJobId(long jobId) { this.jobId = jobId; } @Column(name = "TASK_ID_TASK") public long getTaskId() { return taskId; } public void setTaskId(long taskId) { this.taskId = taskId; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DBTaskId dbTaskId = (DBTaskId) o; if (jobId != dbTaskId.jobId) return false; return taskId == dbTaskId.taskId; } @Override public int hashCode() { int result = (int) (jobId ^ (jobId >>> 32)); result = 31 * result + (int) (taskId ^ (taskId >>> 32)); return result; } } private static final Map<Class<? extends TopologyDescriptor>, String> topologyDescMapping; static { topologyDescMapping = new HashMap<>(); topologyDescMapping.put(ArbitraryTopologyDescriptor.class, "ARBITRARY"); topologyDescMapping.put(BestProximityDescriptor.class, "BEST_PROXIMITY"); topologyDescMapping.put(ThresholdProximityDescriptor.class, "THRESHOLD"); topologyDescMapping.put(DifferentHostsExclusiveDescriptor.class, "DIFFERENT_HOSTS_EXCLUSIVE"); topologyDescMapping.put(MultipleHostsExclusiveDescriptor.class, "MULTIPLE_HOSTS_EXCLUSIVE"); topologyDescMapping.put(SingleHostDescriptor.class, "SINGLE_HOST"); topologyDescMapping.put(SingleHostExclusiveDescriptor.class, "SINGLE_HOST_EXCLUSIVE"); } public TaskData() { } private void convertTopologyDescriptor(TopologyDescriptor desc) { if (desc == null) { topologyDescriptor = null; return; } if (!topologyDescMapping.containsKey(desc.getClass())) { throw new IllegalArgumentException("Unsupported topology descriptor: " + desc); } topologyDescriptor = topologyDescMapping.get(desc.getClass()); if (desc instanceof ThresholdProximityDescriptor) { topologyDescriptorThreshold = ((ThresholdProximityDescriptor) desc).getThreshold(); } } private TopologyDescriptor convertTopologyDescriptor() { if (topologyDescriptor == null) { return null; } if (topologyDescriptor.equals("ARBITRARY")) { return TopologyDescriptor.ARBITRARY; } else if (topologyDescriptor.equals("BEST_PROXIMITY")) { return TopologyDescriptor.BEST_PROXIMITY; } else if (topologyDescriptor.equals("SINGLE_HOST")) { return TopologyDescriptor.SINGLE_HOST; } else if (topologyDescriptor.equals("SINGLE_HOST_EXCLUSIVE")) { return TopologyDescriptor.SINGLE_HOST_EXCLUSIVE; } else if (topologyDescriptor.equals("MULTIPLE_HOSTS_EXCLUSIVE")) { return TopologyDescriptor.MULTIPLE_HOSTS_EXCLUSIVE; } else if (topologyDescriptor.equals("DIFFERENT_HOSTS_EXCLUSIVE")) { return TopologyDescriptor.DIFFERENT_HOSTS_EXCLUSIVE; } else if (topologyDescriptor.equals("THRESHOLD")) { return new ThresholdProximityDescriptor(topologyDescriptorThreshold); } else { throw new IllegalStateException("Invalid TopologyDescriptor: " + topologyDescriptor); } } void updateMutableAttributes(InternalTask task) { setTaskName(task.getName()); setStartTime(task.getStartTime()); setFinishedTime(task.getFinishedTime()); setScheduledTime(task.getScheduledTime()); setIteration(task.getIterationIndex()); setReplication(task.getReplicationIndex()); setMatchingBlock(task.getMatchingBlock()); setTaskStatus(task.getStatus()); setExecutionDuration(task.getExecutionDuration()); } static TaskData createTaskData(JobData jobRuntimeData, InternalScriptTask task) { TaskData taskData = new TaskData(); TaskData.DBTaskId taskId = new DBTaskId(); taskId.setJobId(jobRuntimeData.getId()); taskId.setTaskId(task.getTaskInfo().getTaskId().longValue()); taskData.setId(taskId); taskData.setDescription(task.getDescription()); taskData.setTag(task.getTag()); taskData.setParallelEnvironment(task.getParallelEnvironment()); taskData.setFlowBlock(task.getFlowBlock()); taskData.setRestartMode(task.getRestartTaskOnError()); taskData.setPreciousLogs(task.isPreciousLogs()); taskData.setPreciousResult(task.isPreciousResult()); taskData.setRunAsMe(task.isRunAsMe()); taskData.setWallTime(task.getWallTime()); taskData.setOnTaskErrorString(task.getOnTaskErrorProperty().getValue()); taskData.setMaxNumberOfExecution(task.getMaxNumberOfExecution()); taskData.setJobData(jobRuntimeData); taskData.setNumberOfExecutionOnFailureLeft(PASchedulerProperties.NUMBER_OF_EXECUTION_ON_FAILURE.getValueAsInt()); taskData.setNumberOfExecutionLeft(task.getMaxNumberOfExecution()); taskData.setGenericInformation(task.getGenericInformation()); HashMap<String, TaskDataVariable> variables = new HashMap<>(); for (Map.Entry<String, TaskVariable> entry : task.getVariables().entrySet()) { variables.put(entry.getKey(), TaskDataVariable.create(entry.getKey(), entry.getValue(), taskData)); } taskData.setVariables(variables); // set the scheduledTime if the START_AT property exists Map<String, String> genericInfos = taskData.getGenericInformation(); if (genericInfos != null && genericInfos.containsKey(CommonAttribute.GENERIC_INFO_START_AT_KEY)) { long scheduledTime = ISO8601DateUtil.toDate(genericInfos.get(CommonAttribute.GENERIC_INFO_START_AT_KEY)) .getTime(); taskData.setScheduledTime(scheduledTime); task.setScheduledTime(scheduledTime); } taskData.updateMutableAttributes(task); if (task.getSelectionScripts() != null) { List<SelectionScriptData> scripts = new ArrayList<>(task.getSelectionScripts().size()); for (SelectionScript selectionScript : task.getSelectionScripts()) { scripts.add(SelectionScriptData.createForSelectionScript(selectionScript, taskData)); } taskData.setSelectionScripts(scripts); } if (task.getExecutableContainer() != null) { taskData.setScript(ScriptData.createForScript(((ScriptExecutableContainer) task.getExecutableContainer()).getScript(), taskData)); } if (task.getPreScript() != null) { taskData.setPreScript(ScriptData.createForScript(task.getPreScript(), taskData)); } if (task.getPostScript() != null) { taskData.setPostScript(ScriptData.createForScript(task.getPostScript(), taskData)); } if (task.getCleaningScript() != null) { taskData.setCleanScript(ScriptData.createForScript(task.getCleaningScript(), taskData)); } if (task.getFlowScript() != null) { taskData.setFlowScript(ScriptData.createForFlowScript(task.getFlowScript(), taskData)); } List<SelectorData> selectorsData = new ArrayList<>(); if (task.getInputFilesList() != null) { for (InputSelector selector : task.getInputFilesList()) { selectorsData.add(SelectorData.createForInputSelector(selector, taskData)); } } if (task.getOutputFilesList() != null) { for (OutputSelector selector : task.getOutputFilesList()) { selectorsData.add(SelectorData.createForOutputSelector(selector, taskData)); } } taskData.setDataspaceSelectors(selectorsData); ForkEnvironment forkEnvironment = task.getForkEnvironment(); if (forkEnvironment != null) { taskData.setAdditionalClasspath(forkEnvironment.getAdditionalClasspath()); taskData.setJavaHome(forkEnvironment.getJavaHome()); taskData.setJvmArguments(forkEnvironment.getJVMArguments()); taskData.setWorkingDir(forkEnvironment.getWorkingDir()); if (forkEnvironment.getEnvScript() != null) { taskData.setEnvScript(ScriptData.createForScript(forkEnvironment.getEnvScript(), taskData)); } Map<String, String> systemEnvironment = forkEnvironment.getSystemEnvironment(); if (systemEnvironment != null) { List<EnvironmentModifierData> envModifiers = new ArrayList<>(systemEnvironment.size()); for (Map.Entry<String, String> entry : systemEnvironment.entrySet()) { envModifiers.add(EnvironmentModifierData.create(new PropertyModifier(entry.getKey(), entry.getValue()), taskData)); } taskData.setEnvModifiers(envModifiers); } } taskData.initTaskType(task); return taskData; } private Map<String, TaskVariable> variablesToTaskVariables() { Map<String, TaskVariable> taskVariables = new HashMap<>(); for (Map.Entry<String, TaskDataVariable> entry : getVariables().entrySet()) { taskVariables.put(entry.getKey(), taskDataVariableToTaskVariable(entry.getValue())); } return taskVariables; } private static TaskVariable taskDataVariableToTaskVariable(TaskDataVariable taskDataVariable) { if (taskDataVariable == null) { return null; } TaskVariable taskVariable = new TaskVariable(); taskVariable.setJobInherited(taskDataVariable.isJobInherited()); taskVariable.setModel(taskDataVariable.getModel()); taskVariable.setValue(taskDataVariable.getValue()); taskVariable.setName(taskDataVariable.getName()); return taskVariable; } TaskId createTaskId(InternalJob internalJob) { return TaskIdImpl.createTaskId(internalJob.getId(), getTaskName(), getId().getTaskId()); } InternalTask toInternalTask(InternalJob internalJob) throws InvalidScriptException { TaskId taskId = createTaskId(internalJob); InternalTask internalTask; if (taskType.equals(SCRIPT_TASK)) { internalTask = new InternalScriptTask(internalJob); } else if (taskType.equals(FORKED_SCRIPT_TASK)) { internalTask = new InternalForkedScriptTask(internalJob); } else { throw new IllegalStateException("Unexpected stored task type: " + taskType); } internalTask.setId(taskId); internalTask.setDescription(getDescription()); internalTask.setTag(this.getTag()); internalTask.setStatus(getTaskStatus()); internalTask.setJobInfo(internalJob.getJobInfo()); internalTask.setName(getTaskName()); internalTask.setExecutionDuration(getExecutionDuration()); internalTask.setFinishedTime(getFinishedTime()); internalTask.setInErrorTime(getInErrorTime()); internalTask.setStartTime(getStartTime()); internalTask.setScheduledTime(getScheduledTime()); internalTask.setExecutionHostName(getExecutionHostName()); internalTask.setOnTaskError(OnTaskError.getInstance(this.onTaskErrorString)); internalTask.setPreciousLogs(isPreciousLogs()); internalTask.setPreciousResult(isPreciousResult()); internalTask.setRunAsMe(isRunAsMe()); internalTask.setWallTime(getWallTime()); internalTask.setMaxNumberOfExecution(getMaxNumberOfExecution()); internalTask.setNumberOfExecutionLeft(getNumberOfExecutionLeft()); internalTask.setNumberOfExecutionOnFailureLeft(getNumberOfExecutionOnFailureLeft()); internalTask.setRestartTaskOnError(getRestartMode()); internalTask.setFlowBlock(getFlowBlock()); internalTask.setIterationIndex(getIteration()); internalTask.setReplicationIndex(getReplication()); internalTask.setMatchingBlock(getMatchingBlock()); internalTask.setVariables(variablesToTaskVariables()); ForkEnvironment forkEnv = createForkEnvironment(); internalTask.setForkEnvironment(forkEnv); return internalTask; } @EmbeddedId public DBTaskId getId() { return id; } public void setId(DBTaskId taskId) { this.id = taskId; } @Column(name = "GENERIC_INFO", updatable = false) @Type(type = "org.ow2.proactive.scheduler.core.db.types.NonEmptyMapToBlobType", parameters = @Parameter(name = SerializableToBlobType.CLASS_NAME, value = "java.lang.Object")) public Map<String, String> getGenericInformation() { return genericInformation; } public void setGenericInformation(Map<String, String> genericInformation) { this.genericInformation = genericInformation; } @Cascade(CascadeType.ALL) @OneToMany(fetch = FetchType.LAZY, mappedBy = "taskData") @OnDelete(action = OnDeleteAction.CASCADE) public Map<String, TaskDataVariable> getVariables() { return variables; } public void setVariables(Map<String, TaskDataVariable> variables) { this.variables = variables; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "JOB_ID", nullable = false, updatable = false) public JobData getJobData() { return jobData; } public void setJobData(JobData jobRuntimeData) { this.jobData = jobRuntimeData; } @ElementCollection(fetch = FetchType.LAZY) @CollectionTable(name = "TASK_DATA_DEPENDENCIES", joinColumns = { @JoinColumn(name = "JOB_ID", referencedColumnName = "TASK_ID_JOB"), @JoinColumn(name = "TASK_ID", referencedColumnName = "TASK_ID_TASK") }, indexes = { @Index(name = "TASK_DATA_DEP_JOB_ID", columnList = "JOB_ID"), @Index(name = "TASK_DATA_DEP_TASK_ID", columnList = "TASK_ID"), }) @BatchSize(size = 100) public List<DBTaskId> getDependentTasks() { return dependentTasks; } public void setDependentTasks(List<DBTaskId> dependentTasks) { this.dependentTasks = dependentTasks; } @ElementCollection(fetch = FetchType.LAZY) @CollectionTable(name = "TASK_DATA_JOINED_BRANCHES", joinColumns = { @JoinColumn(name = "JOB_ID", referencedColumnName = "TASK_ID_JOB"), @JoinColumn(name = "TASK_ID", referencedColumnName = "TASK_ID_TASK") }, indexes = { @Index(name = "TASK_DATA_JB_JOB_ID", columnList = "JOB_ID"), @Index(name = "TASK_DATA_JB_TASK_ID", columnList = "TASK_ID"), }) @BatchSize(size = 100) public List<DBTaskId> getJoinedBranches() { return joinedBranches; } public void setJoinedBranches(List<DBTaskId> joinedBranches) { this.joinedBranches = joinedBranches; } @OneToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) public TaskData getIfBranch() { return ifBranch; } public void setIfBranch(TaskData ifBranch) { this.ifBranch = ifBranch; } @Cascade(CascadeType.ALL) @OneToMany(fetch = FetchType.LAZY, mappedBy = "taskData") @OnDelete(action = OnDeleteAction.CASCADE) public List<SelectionScriptData> getSelectionScripts() { return selectionScripts; } public void setSelectionScripts(List<SelectionScriptData> selectionScripts) { this.selectionScripts = selectionScripts; } @Cascade(CascadeType.ALL) @OneToMany(fetch = FetchType.LAZY, mappedBy = "taskData") @OnDelete(action = OnDeleteAction.CASCADE) public List<SelectorData> getDataspaceSelectors() { return dataspaceSelectors; } public void setDataspaceSelectors(List<SelectorData> dataspaceSelectors) { this.dataspaceSelectors = dataspaceSelectors; } @Cascade(CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "PRE_SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getPreScript() { return preScript; } public void setPreScript(ScriptData preScript) { this.preScript = preScript; } @Cascade(CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "POST_SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getPostScript() { return postScript; } public void setPostScript(ScriptData postScript) { this.postScript = postScript; } @Cascade(CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "CLEAN_SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getCleanScript() { return cleanScript; } public void setCleanScript(ScriptData cleanScript) { this.cleanScript = cleanScript; } @Cascade(CascadeType.ALL) @OneToOne(fetch = FetchType.LAZY) // disable foreign key, to be able to remove runtime data @JoinColumn(name = "FLOW_SCRIPT_ID", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) public ScriptData getFlowScript() { return flowScript; } public void setFlowScript(ScriptData flowScript) { this.flowScript = flowScript; } @Column(nullable = false, name = "TASK_NAME") public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } @Column(name = "TYPE", nullable = false, updatable = false) public String getTaskType() { return taskType; } public void setTaskType(String taskType) { this.taskType = taskType; } void initTaskType(InternalTask task) { if (task.getClass().equals(InternalForkedScriptTask.class)) { taskType = FORKED_SCRIPT_TASK; } else if (task.getClass().equals(InternalScriptTask.class)) { taskType = SCRIPT_TASK; } else { throw new IllegalArgumentException("Unexpected task type: " + task.getClass()); } } @Column(name = "DESCRIPTION", updatable = false) public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Column(name = "TAG", updatable = false) public String getTag() { return this.tag; } public void setTag(String tag) { this.tag = tag; } @Column(name = "MAX_NUMBER_OF_EXEC", updatable = false) public int getMaxNumberOfExecution() { return maxNumberOfExecution; } public void setMaxNumberOfExecution(int maxNumberOfExecution) { this.maxNumberOfExecution = maxNumberOfExecution; } @Column(name = "ON_TASK_ERROR", updatable = false, nullable = false, length = 25) public String getOnTaskErrorString() { return this.onTaskErrorString; } public void setOnTaskErrorString(OnTaskError onTaskError) { this.onTaskErrorString = onTaskError.toString(); } public void setOnTaskErrorString(String onTaskError) { this.onTaskErrorString = onTaskError; } @Column(name = "RES_PREVIEW", length = 1000, updatable = false) public String getResultPreview() { return resultPreview; } public void setResultPreview(String resultPreview) { this.resultPreview = resultPreview; } @Column(name = "PRECIOUS_RES", updatable = false) public boolean isPreciousResult() { return preciousResult; } public void setPreciousResult(boolean preciousResult) { this.preciousResult = preciousResult; } @Column(name = "PRECIOUS_LOG", updatable = false) public boolean isPreciousLogs() { return preciousLogs; } public void setPreciousLogs(boolean preciousLogs) { this.preciousLogs = preciousLogs; } @Column(name = "RUN_AS_ME", updatable = false) public boolean isRunAsMe() { return runAsMe; } public void setRunAsMe(boolean runAsMe) { this.runAsMe = runAsMe; } @Column(name = "WALLTIME", updatable = false) public long getWallTime() { return wallTime; } public void setWallTime(long wallTime) { this.wallTime = wallTime; } @Column(name = "START_TIME") public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } @Column(name = "FINISH_TIME") public long getFinishedTime() { return finishedTime; } public void setFinishedTime(long finishedTime) { this.finishedTime = finishedTime; } @Column(name = "LAST_IN_ERROR_TIME") public long getInErrorTime() { return inErrorTime; } public void setInErrorTime(long inErrorTime) { this.inErrorTime = inErrorTime; } @Column(name = "SCHEDULED_TIME") public long getScheduledTime() { return scheduledTime; } public void setScheduledTime(long scheduledTime) { this.scheduledTime = scheduledTime; } @Column(name = "EXEC_DURATION") public long getExecutionDuration() { return executionDuration; } public void setExecutionDuration(long executionDuration) { this.executionDuration = executionDuration; } @Column(name = "STATUS", nullable = false) public TaskStatus getTaskStatus() { return taskStatus; } public void setTaskStatus(TaskStatus taskStatus) { this.taskStatus = taskStatus; } @Column(name = "EXEC_HOST_NAME") public String getExecutionHostName() { return executionHostName; } public void setExecutionHostName(String executionHostName) { this.executionHostName = executionHostName; } @Column(name = "NUMBER_OF_EXEC_LEFT") public int getNumberOfExecutionLeft() { return numberOfExecutionLeft; } public void setNumberOfExecutionLeft(int numberOfExecutionLeft) { this.numberOfExecutionLeft = numberOfExecutionLeft; } @Column(name = "NUMBER_OF_EXEC_ON_FAIL_LEFT") public int getNumberOfExecutionOnFailureLeft() { return numberOfExecutionOnFailureLeft; } public void setNumberOfExecutionOnFailureLeft(int numberOfExecutionOnFailureLeft) { this.numberOfExecutionOnFailureLeft = numberOfExecutionOnFailureLeft; } @Column(name = "ITERATION") public int getIteration() { return iteration; } public void setIteration(int iteration) { this.iteration = iteration; } @Column(name = "REPLICATION") public int getReplication() { return replication; } public void setReplication(int replication) { this.replication = replication; } @Column(name = "MATCH_BLOCK") public String getMatchingBlock() { return matchingBlock; } public void setMatchingBlock(String matchingBlock) { this.matchingBlock = matchingBlock; } @Column(name = "RESTART_MODE") public int getRestartModeId() { return restartModeId; } public void setRestartModeId(int restartModeId) { this.restartModeId = restartModeId; } @Column(name = "FLOW_BLOCK") public FlowBlock getFlowBlock() { return flowBlock; } public void setFlowBlock(FlowBlock flowBlock) { this.flowBlock = flowBlock; } @Column(name = "NODES_NUMBER") public int getParallelEnvNodesNumber() { return parallelEnvNodesNumber; } public void setParallelEnvNodesNumber(int parallelEnvNodesNumber) { this.parallelEnvNodesNumber = parallelEnvNodesNumber; } @Column(name = "TOPOLOGY") public String getTopologyDescriptor() { return topologyDescriptor; } public void setTopologyDescriptor(String topologyDescriptor) { this.topologyDescriptor = topologyDescriptor; } @Column(name = "TOPOLOGY_DESC_THRESHOLD") public long getTopologyDescriptorThreshold() { return topologyDescriptorThreshold; } public void setTopologyDescriptorThreshold(long topologyDescriptorThreshold) { this.topologyDescriptorThreshold = topologyDescriptorThreshold; } @Transient RestartMode getRestartMode() { return RestartMode.getMode(restartModeId); } void setRestartMode(RestartMode restartMode) { restartModeId = restartMode.getIndex(); } @Transient ParallelEnvironment getParallelEnvironment() { if (parallelEnvNodesNumber == 0) { return null; } return new ParallelEnvironment(parallelEnvNodesNumber, convertTopologyDescriptor()); } void setParallelEnvironment(ParallelEnvironment env) { if (env == null) { return; } parallelEnvNodesNumber = env.getNodesNumber(); convertTopologyDescriptor(env.getTopologyDescriptor()); } TaskUsage toTaskUsage(JobIdImpl jobId) { TaskId taskId = TaskIdImpl.createTaskId(jobId, getTaskName(), getId().getTaskId()); return new TaskUsage(taskId.value(), getTaskName(), getStartTime(), getFinishedTime(), getExecutionDuration(), getParallelEnvironment() == null ? 1 : getParallelEnvironment().getNodesNumber()); } TaskInfoImpl createTaskInfo(JobIdImpl jobId) { TaskId taskId = TaskIdImpl.createTaskId(jobId, getTaskName(), getId().getTaskId(), getTag()); TaskInfoImpl taskInfo = new TaskInfoImpl(); taskInfo.setTaskId(taskId); taskInfo.setStatus(getTaskStatus()); taskInfo.setStartTime(getStartTime()); taskInfo.setProgress(0); taskInfo.setInErrorTime(getInErrorTime()); taskInfo.setNumberOfExecutionOnFailureLeft(getNumberOfExecutionOnFailureLeft()); taskInfo.setNumberOfExecutionLeft(getNumberOfExecutionLeft()); taskInfo.setJobInfo(getJobData().toJobInfo()); taskInfo.setJobId(jobId); taskInfo.setFinishedTime(getFinishedTime()); taskInfo.setScheduledTime(getScheduledTime()); taskInfo.setExecutionHostName(getExecutionHostName()); taskInfo.setExecutionDuration(getExecutionDuration()); return taskInfo; } public TaskInfo toTaskInfo() { JobIdImpl jobId = new JobIdImpl(getJobData().getId(), getJobData().getJobName()); TaskInfoImpl taskInfo = createTaskInfo(jobId); return taskInfo; } public TaskState toTaskState() { TaskInfo taskInfo = toTaskInfo(); TaskStateImpl taskState = new TaskStateImpl(); taskState.update(taskInfo); taskState.setName(getTaskName()); taskState.setDescription(getDescription()); taskState.setTag(getTag()); taskState.setIterationIndex(getIteration()); taskState.setReplicationIndex(getReplication()); taskState.setMaxNumberOfExecution(getMaxNumberOfExecution()); taskState.setParallelEnvironment(getParallelEnvironment()); taskState.setGenericInformation(getGenericInformation()); taskState.setVariables(variablesToTaskVariables()); return taskState; } }