/* * Eoulsan development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public License version 2.1 or * later and CeCILL-C. This should be distributed with the code. * If you do not have a copy, see: * * http://www.gnu.org/licenses/lgpl-2.1.txt * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt * * Copyright for this code is held jointly by the Genomic platform * of the Institut de Biologie de l'École normale supérieure and * the individual authors. These should be listed in @author doc * comments. * * For more information on the Eoulsan project and its aims, * or to join the Eoulsan Google group, visit the home page * at: * * http://outils.genomique.biologie.ens.fr/eoulsan * */ package fr.ens.biologie.genomique.eoulsan.core.workflow; import static com.google.common.base.Preconditions.checkNotNull; import static fr.ens.biologie.genomique.eoulsan.EoulsanLogger.getLogger; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; import fr.ens.biologie.genomique.eoulsan.EoulsanException; import fr.ens.biologie.genomique.eoulsan.EoulsanRuntime; import fr.ens.biologie.genomique.eoulsan.core.Module; import fr.ens.biologie.genomique.eoulsan.core.Workflow; import fr.ens.biologie.genomique.eoulsan.design.Design; import fr.ens.biologie.genomique.eoulsan.design.io.DefaultDesignReader; import fr.ens.biologie.genomique.eoulsan.ui.UI; import fr.ens.biologie.genomique.eoulsan.ui.UIService; import fr.ens.biologie.genomique.eoulsan.util.hadoop.HadoopInfo; /** * This class is the executor for running all the steps of an analysis. * @since 1.0 * @author Laurent Jourdren */ public class Executor { private final ExecutorArguments arguments; private final CommandWorkflowModel command; private final Design design; // // Check methods // /** * Check design. * @throws EoulsanException if there is an issue with the design */ private void checkDesign() throws EoulsanException { if (this.design == null) { throw new EoulsanException("The design is null"); } // Check samples count if (this.design.getSamples().isEmpty()) { throw new EoulsanException( "Nothing to do, no samples found in design file"); } getLogger().info("Found " + this.design.getSamples().size() + " sample(s) in design file"); } // // Execute methods // /** * run Eoulsan. * @throws EoulsanException if an error occurs while creating of executing * steps */ public void execute() throws EoulsanException { execute(null, null); } /** * run Eoulsan. * @param firstSteps steps to add at the begin the workflow * @param lastSteps steps to add at the end the workflow * @throws EoulsanException if an error occurs while creating of executing * steps */ public void execute(final List<Module> firstSteps, final List<Module> lastSteps) throws EoulsanException { // Add general executor info logInfo(this.arguments, this.command); // Add Hadoop info in Hadoop mode if (EoulsanRuntime.getRuntime().getMode().isHadoopMode()) { HadoopInfo.logHadoopSysInfo(); } // Check base path if (this.arguments.getLocalWorkingPathname() == null) { throw new EoulsanException("The base path is null"); } // Check design checkDesign(); // Create Workflow final CommandWorkflow workflow = new CommandWorkflow(this.arguments, this.command, firstSteps, lastSteps, this.design); // Check directories (log, working, output, temporary...) workflow.checkDirectories(); // Get UI final UI ui = startUI(workflow); // Enable listen workflow events by ui StepObserverRegistry.getInstance().addObserver(ui); getLogger() .info("Start analysis at " + new Date(System.currentTimeMillis())); // Execute Workflow workflow.execute(); } // // Utility methods // /** * Start the UI. * @param workflow the workflow * @return the UI object * @throws EoulsanException if an error occurs while stating the UI */ private UI startUI(final Workflow workflow) throws EoulsanException { // Get the UI name final String uiName = EoulsanRuntime.getSettings().getUIName(); if (uiName == null) { throw new EoulsanException("No UI name defined."); } // Get the UIService final UIService uiService = UIService.getInstance(); // Test the UI exists if (!uiService.isService(uiName)) { throw new EoulsanException("Unknown UI name: " + uiName); } // Get the UI final UI ui = uiService.newService(uiName); // Initialize UI ui.init(workflow); return ui; } /** * Log some information about the current execution. * @param execArgs execution information * @param command workflow file content */ private static void logInfo(final ExecutorArguments execArgs, final CommandWorkflowModel command) { getLogger().info("Design file path: " + execArgs.getDesignPathname()); getLogger().info("Workflow file path: " + execArgs.getWorkflowPathname()); getLogger().info("Workflow Author: " + command.getAuthor()); getLogger().info("Workflow Description: " + command.getDescription()); getLogger().info("Workflow Name: " + command.getName()); getLogger().info("Job Id: " + execArgs.getJobId()); getLogger().info("Job UUID: " + execArgs.getJobUUID()); getLogger().info("Job Description: " + execArgs.getJobDescription()); getLogger().info("Job Environment: " + execArgs.getJobEnvironment()); getLogger().info("Job Base path: " + execArgs.getLocalWorkingPathname()); getLogger().info("Job Output path: " + execArgs.getOutputPathname()); getLogger().info("Job Log path: " + execArgs.getJobPathname()); } private static Design loadDesign(final ExecutorArguments arguments) throws EoulsanException { try { // Load design getLogger().info("Read design file"); // Get input stream of design file from arguments object final InputStream is = arguments.openDesignFile(); checkNotNull(is, "The input stream for design file is null"); // Read design file and return the design object return new DefaultDesignReader(is).read(); } catch (IOException e) { throw new EoulsanException(e); } } private static CommandWorkflowModel loadCommand( final ExecutorArguments arguments) throws EoulsanException { try { // Get input stream of workflow file from arguments object final InputStream is = arguments.openParamFile(); checkNotNull(is, "The input stream for workflow file is null"); // Parse workflow file final CommandWorkflowParser pp = new CommandWorkflowParser(is); pp.addConstants(arguments); return pp.parse(); } catch (IOException e) { throw new EoulsanException(e); } } // // Constructor // /** * Constructor. * @param arguments arguments for the Executor * @throws EoulsanException if an error occurs while loading and parsing * design and workflow files */ public Executor(final ExecutorArguments arguments) throws EoulsanException { checkNotNull(arguments, "The arguments of the executor is null"); this.arguments = arguments; this.design = loadDesign(arguments); this.command = loadCommand(arguments); } }