/* * 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.common.task; import java.io.IOException; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.objectweb.proactive.annotation.PublicAPI; import org.ow2.proactive.scheduler.common.job.TaskFlowJob; import org.ow2.proactive.scheduler.common.util.Object2ByteConverter; /** * Use this class to build a java task that will use a * {@link org.ow2.proactive.scheduler.common.task.executable.JavaExecutable} and be integrated in a * {@link TaskFlowJob}. * <p> * A java task includes an {@link org.ow2.proactive.scheduler.common.task.executable.JavaExecutable} that can be set * as a .class file or instance. * <p> * It also provides method to personalize it. * * @author The ProActive Team * @since ProActive Scheduling 0.9 */ @PublicAPI public class JavaTask extends Task { /** Classname of the executable */ protected String executableClassName = null; /** Arguments of the task as a map */ // WARNING: this field is accessed by reflection from InternalJobFactory private final HashMap<String, byte[]> serializedArguments = new HashMap<>(); /** For internal use: name of the field that stores task arguments */ public static final String ARGS_FIELD_NAME = "serializedArguments"; /** * Empty constructor. */ public JavaTask() { } /** * To get the executable task classname. * * @return the task Class name. */ public String getExecutableClassName() { return executableClassName; } /** * To set the executable task class name. * It must be a class that extends {@link org.ow2.proactive.scheduler.common.task.executable.JavaExecutable}. * * @param executableClassName the task Class to set. */ public void setExecutableClassName(String executableClassName) { if (executableClassName == null) { throw new IllegalArgumentException("Executable class name must be set for JavaTask: " + this.name); } if (executableClassName.length() > 255) { throw new IllegalArgumentException("Class name is too long, it must have 255 chars length max: " + executableClassName); } this.executableClassName = executableClassName; } /** * Return an unmodifiable copy of all the task arguments as a hash map. * * @return an unmodifiable copy of the arguments list. * @throws IOException if the copy of the value cannot be performed. * @throws ClassNotFoundException if the value's class cannot be loaded. */ public Map<String, Serializable> getArguments() throws IOException, ClassNotFoundException { final Set<String> allNames = this.serializedArguments.keySet(); final Map<String, Serializable> deserialized = new HashMap<String, Serializable>(allNames.size()); for (String name : allNames) { deserialized.put(name, this.getArgument(name)); } return Collections.unmodifiableMap(deserialized); } public HashMap<String, byte[]> getSerializedArguments() { return new HashMap<>(serializedArguments); } /** * Add an argument to the list of arguments. Note that the value is serialized and stored * in the JavaTask. * * @param name the name of the argument to add. * @param value the associated value to add. * @throws IllegalArgumentException if the value cannot be serialized and stored in the task. */ public void addArgument(String name, Serializable value) { if (name != null && name.length() > 255) { throw new IllegalArgumentException("Key is too long, it must have 255 chars length max: " + name); } else { byte[] serialized = null; try { serialized = Object2ByteConverter.convertObject2Byte(value); this.serializedArguments.put(name, serialized); } catch (IOException e) { throw new IllegalArgumentException("Cannot add argument " + name + " in task " + this.name, e); } } } /** * Return a copy of the value of the specified argument. * @param name the name of the specified argument. * @return a copy of the value of the specified argument. * @throws IOException if the copy of the value cannot be performed. * @throws ClassNotFoundException if the value's class cannot be loaded. */ public Serializable getArgument(String name) throws IOException, ClassNotFoundException { byte[] serializedValue = this.serializedArguments.get(name); if (serializedValue != null) { return (Serializable) Object2ByteConverter.convertByte2Object(serializedValue); } else { return null; } } /** * Remove the specified argument from the argument map. * @param name the name of the specified argument. * @return a copy of the value of the specified argument. * @throws IOException if the copy of the value cannot be performed. * @throws ClassNotFoundException if the value's class cannot be loaded. */ public Serializable removeArgument(String name) throws IOException, ClassNotFoundException { byte[] serializedValue = this.serializedArguments.remove(name); if (serializedValue != null) { return (Serializable) Object2ByteConverter.convertByte2Object(serializedValue); } else { return null; } } /** * @return true if the task will be executed in a separate JVM */ public boolean isFork() { return this.forkEnvironment != null || super.isWallTimeSet() || super.isRunAsMe(); } @Override public String display() { String nl = System.lineSeparator(); String answer = super.display(); return answer + nl + "\tExecutableClassName = '" + executableClassName + '\'' + nl + "\tArguments = " + serializedArguments.keySet() + nl + "\tForkEnvironment = " + forkEnvironment; } }