/* * 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.helpers; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.ow2.proactive.db.DatabaseManagerException; import org.ow2.proactive.scheduler.common.exception.UnknownTaskException; import org.ow2.proactive.scheduler.common.job.JobType; import org.ow2.proactive.scheduler.common.task.TaskId; import org.ow2.proactive.scheduler.common.task.TaskLogs; import org.ow2.proactive.scheduler.common.task.TaskResult; import org.ow2.proactive.scheduler.core.db.SchedulerDBManager; import org.ow2.proactive.scheduler.descriptor.EligibleTaskDescriptor; import org.ow2.proactive.scheduler.descriptor.JobDescriptor; import org.ow2.proactive.scheduler.job.InternalJob; import org.ow2.proactive.scheduler.task.TaskResultImpl; import org.ow2.proactive.scheduler.task.internal.InternalTask; import org.ow2.proactive.scheduler.util.TaskLogger; public class TaskResultCreator { private static TaskResultCreator instance = null; private static final TaskLogger tlogger = TaskLogger.getInstance(); public TaskResultCreator() { } public static synchronized TaskResultCreator getInstance() { if (instance == null) { instance = new TaskResultCreator(); } return instance; } public TaskResultImpl getTaskResult(SchedulerDBManager dbManager, InternalJob job, InternalTask task) throws UnknownTaskException { return getTaskResult(dbManager, job, task, null, null); } public TaskResultImpl getTaskResult(SchedulerDBManager dbManager, InternalJob job, InternalTask task, Throwable exception, TaskLogs output) throws UnknownTaskException { if (task == null) { throw new UnknownTaskException(); } JobDescriptor jobDescriptor = job.getJobDescriptor(); EligibleTaskDescriptor eligibleTaskDescriptor = null; if (jobDescriptor.getPausedTasks().get(task.getId()) != null) { eligibleTaskDescriptor = (EligibleTaskDescriptor) jobDescriptor.getPausedTasks().get(task.getId()); } else if (jobDescriptor.getRunningTasks().get(task.getId()) != null) { eligibleTaskDescriptor = (EligibleTaskDescriptor) jobDescriptor.getRunningTasks().get(task.getId()); } TaskResultImpl taskResult = getEmptyTaskResult(task, exception, output); taskResult.setPropagatedVariables(getPropagatedVariables(dbManager, eligibleTaskDescriptor, job, task)); return taskResult; } public TaskResultImpl getEmptyTaskResult(InternalTask task, Throwable exception, TaskLogs output) { return new TaskResultImpl(task.getId(), exception, output, System.currentTimeMillis() - task.getStartTime()); } private Map<String, byte[]> getPropagatedVariables(SchedulerDBManager dbManager, EligibleTaskDescriptor eligibleTaskDescriptor, InternalJob job, InternalTask task) throws UnknownTaskException { Map<String, byte[]> variables = new HashMap<>(); if (job.getType() == JobType.TASKSFLOW && eligibleTaskDescriptor != null) { TaskResultImpl taskResult = null; try { taskResult = (TaskResultImpl) dbManager.loadLastTaskResult(task.getId()); } catch (DatabaseManagerException exception) { tlogger.error(task.getId(), exception.getMessage(), exception); } if (taskResult != null) { variables.putAll(taskResult.getPropagatedVariables()); } else { // retrieve from the database the previous task results if available int numberOfParentTasks = eligibleTaskDescriptor.getParents().size(); if ((numberOfParentTasks > 0) && task.handleResultsArguments()) { variables = extractTaskResultsAndMergeIntoMap(dbManager, eligibleTaskDescriptor, job); } else { variables = extractJobVariables(job); } } } return variables; } private Map<String, byte[]> extractJobVariables(InternalJob job) { Map<String, byte[]> jobVariables = new HashMap<>(); // otherwise use the default job variables for (Entry<String, String> entry : job.getVariablesAsReplacementMap().entrySet()) { jobVariables.put(entry.getKey(), entry.getValue().getBytes()); } return jobVariables; } private Map<String, byte[]> extractTaskResultsAndMergeIntoMap(SchedulerDBManager dbManager, EligibleTaskDescriptor eligibleTaskDescriptor, InternalJob job) { Map<String, byte[]> mergedVariables = new HashMap<>(); int numberOfParentTasks = eligibleTaskDescriptor.getParents().size(); List<TaskId> parentIds = new ArrayList<>(numberOfParentTasks); for (int i = 0; i < numberOfParentTasks; i++) { parentIds.add(eligibleTaskDescriptor.getParents().get(i).getTaskId()); } Map<TaskId, TaskResult> taskResults = dbManager.loadTasksResults(job.getId(), parentIds); for (TaskResult taskResult : taskResults.values()) { if (taskResult.getPropagatedVariables() != null) { mergedVariables.putAll(taskResult.getPropagatedVariables()); } } return mergedVariables; } }