| /******************************************************************************* |
| * Copyright (c) 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.stem.ui.headless; |
| |
| import java.io.File; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.stem.core.Utility; |
| import org.eclipse.stem.core.model.Decorator; |
| import org.eclipse.stem.core.model.IntegrationDecorator; |
| import org.eclipse.stem.core.scenario.Scenario; |
| import org.eclipse.stem.core.sequencer.Sequencer; |
| import org.eclipse.stem.jobs.simulation.ISimulation; |
| import org.eclipse.stem.jobs.simulation.ISimulationListenerSync; |
| import org.eclipse.stem.jobs.simulation.SimulationEvent; |
| import org.eclipse.stem.jobs.simulation.SimulationManager; |
| import org.eclipse.stem.util.loggers.util.Util; |
| import org.eclipse.stem.util.loggers.views.CustomCSVLogger; |
| |
| /** |
| * Runs simulations for scenarios passed in as command line options. The run |
| * method find the correct scenarios, creates simulations for the scenarios, |
| * runs the simulations, and attempts to wait for them to finish. |
| * |
| */ |
| public class HeadlessSimulationRunner { |
| private static final String PROJECT_SCENARIOS_FOLDER_NAME = "scenarios"; |
| |
| private static final String SCENARIO_FILE_EXTENSION = ".scenario"; |
| |
| private static final SimulationManager MANAGER = SimulationManager |
| .getManager(); |
| |
| private final HeadlessSimulationStatusLogger logger = new HeadlessSimulationStatusLogger(); |
| |
| private final Set<URI> scenariosUrisToRun = new HashSet<URI>(); |
| |
| private boolean log = false; |
| |
| private String logDirectory = null; |
| |
| /** |
| * |
| */ |
| public HeadlessSimulationRunner(boolean log, String logDirectory) |
| { |
| this.log = log; |
| this.logDirectory = logDirectory; |
| |
| refreshWorkspace(); |
| } |
| |
| /** |
| * Refreshes the workspace, loading external resources |
| */ |
| private void refreshWorkspace() |
| { |
| WorkspaceImporter.importProjects(); |
| } |
| |
| /** |
| * Collects the scenarios based on command line options, creates and runs a |
| * simulation for each scenario, and waits for the simulations to finish. |
| * |
| * @param args |
| */ |
| public void run(Map<String, List<String>> args) |
| { |
| collectScenariosToRun(args); |
| runScenarios(); |
| waitForSimulations(); |
| } |
| |
| private void collectScenariosToRun(Map<String, List<String>> args) |
| { |
| if (args.containsKey("uri")) { |
| addScenariosForUris(args.get("uri")); |
| } |
| if (args.containsKey("project") && args.get("project").size() > 0) { |
| if (args.containsKey("scenario")) { |
| addScenarios(args.get("project").get(0), args.get("scenario")); |
| } else { |
| addScenariosForProject(args.get("project").get(0)); |
| } |
| } |
| |
| } |
| |
| private void addScenarios(String projectName, List<String> scenarioNames) { |
| for (String scenarioName : scenarioNames) { |
| if (!scenarioName.endsWith(SCENARIO_FILE_EXTENSION)) { |
| scenarioName = scenarioName.concat(SCENARIO_FILE_EXTENSION); |
| } |
| |
| scenariosUrisToRun.add(createUriForScenario(projectName, |
| scenarioName)); |
| } |
| } |
| |
| private void addScenariosForUris(List<String> uris) { |
| for (String uri : uris) { |
| try { |
| scenariosUrisToRun.add(URI.createURI(uri)); |
| } catch (IllegalArgumentException iae) { |
| System.err.println("URI " + uri + " is invalid"); |
| } |
| } |
| } |
| |
| /** |
| * Attach a logger to the simulation |
| * |
| * @param sim |
| * Simulation to attach logger to |
| */ |
| private void addLogger(ISimulation sim) { |
| String logDir = this.logDirectory; |
| if (logDir == null) { |
| logDir = Util.getLoggingFolder(sim.getScenario().getURI() |
| .toString()); |
| } |
| |
| String uniqueID = null; |
| |
| if (sim != null) uniqueID = sim.getUniqueIDString(); |
| String directoryName = logDir + File.separator+uniqueID + File.separator; |
| |
| File dir = new File(directoryName); |
| if(!dir.exists()) |
| dir.mkdirs(); |
| |
| EList<Decorator> decorators = sim.getScenario().getCanonicalGraph() |
| .getDecorators(); |
| for (Decorator dec : decorators) { |
| if (dec instanceof IntegrationDecorator) { |
| @SuppressWarnings("unused") |
| CustomCSVLogger logger = new CustomCSVLogger(directoryName, sim, |
| (IntegrationDecorator) dec); |
| } |
| } |
| } |
| |
| private void runScenarios() { |
| System.out.println("Scenarios selected: " + scenariosUrisToRun); |
| |
| // Loop through the list of scenario URIs found |
| for (URI scenarioUri : scenariosUrisToRun) { |
| try { |
| // Attempt to load the scenario by its URI |
| System.out.println("Creating simulation for " + scenarioUri); |
| Scenario simulationScenario = (Scenario) Utility |
| .getIdentifiable(scenarioUri); |
| if (simulationScenario != null) { |
| // Create the simulation from the scenario |
| ISimulation sim = MANAGER.createSimulation( |
| simulationScenario, new NullProgressMonitor()); |
| if (log) { |
| addLogger(sim); |
| } |
| |
| System.out.println("Running simulation " |
| + sim.getUniqueIDString() + " for " + scenarioUri); |
| |
| // Add the local simulation logger |
| sim.addSimulationListenerSync(logger); |
| |
| // Run the simulation |
| sim.run(); |
| } else { |
| System.err.println("Scenario " + scenarioUri + " not fond"); |
| } |
| } catch (Exception e) { |
| System.err.println("Error creating simulation for URI " |
| + scenarioUri); |
| e.printStackTrace(System.err); |
| } |
| } |
| } |
| |
| private static URI createUriForScenario(String projectName, |
| String scenarioName) { |
| return URI.createURI("platform:/resource/" + projectName + "/" |
| + PROJECT_SCENARIOS_FOLDER_NAME + "/" + scenarioName); |
| } |
| |
| private void addScenariosForProject(String projectName) { |
| // Get the project from the workspace |
| IProject project = getProjectForName(projectName); |
| |
| try { |
| // Get the "scenarios" folder and check existence |
| IFolder scneariosFolder = project |
| .getFolder(PROJECT_SCENARIOS_FOLDER_NAME); |
| if (scneariosFolder.exists()) { |
| // Get the members of the "scenarios" folder and |
| IResource[] folderMembers = scneariosFolder.members(); |
| for (IResource r : folderMembers) { |
| // If is a file that ends with ".scenario", then add to the |
| // list of URIs to run |
| if (r.getName().endsWith(SCENARIO_FILE_EXTENSION)) { |
| // Found a scenario |
| scenariosUrisToRun.add(createUriForScenario( |
| projectName, r.getName())); |
| } |
| } |
| } else { |
| System.err.println("Project " + projectName |
| + " is not a valid STEM project"); |
| } |
| } catch (CoreException ce) { |
| ce.printStackTrace(System.err); |
| } |
| } |
| |
| private static IProject getProjectForName(String projectName) { |
| return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| } |
| |
| private void waitForSimulations() { |
| while (MANAGER.getActiveSimulations().size() > 0) { |
| ISimulation sim = MANAGER.getActiveSimulations().get(0); |
| try { |
| sim.join(); |
| sim.stop(); |
| } catch (InterruptedException e) { |
| System.err.println("Simulation interrupted."); |
| } |
| } |
| } |
| |
| /** |
| * Simulation listener that logs the output of simulations to standard out |
| * at the end of each cycle and at the end of the sequence. |
| * |
| */ |
| private class HeadlessSimulationStatusLogger implements |
| ISimulationListenerSync { |
| |
| long initialTime; |
| long lastTime; |
| |
| HeadlessSimulationStatusLogger() { |
| // nothing |
| initialTime = lastTime = System.currentTimeMillis(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.stem.jobs.simulation.ISimulationListenerSync# |
| * simulationChangedSync |
| * (org.eclipse.stem.jobs.simulation.SimulationEvent) |
| */ |
| public void simulationChangedSync(SimulationEvent event) { |
| Sequencer sequencer = event.getSimulation().getScenario() |
| .getSequencer(); |
| |
| switch (event.getSimulationState()) { |
| case COMPLETED_CYCLE: |
| long time = System.currentTimeMillis();; |
| System.out.println("[" |
| + event.getSimulation().getUniqueIDString() + "] " |
| + sequencer.getWorkComplete() + "% " |
| + sequencer.getCurrentTime() + "/" |
| + sequencer.getEndTime() + " " |
| + "("+ (time - lastTime) +" ms)"); |
| lastTime = time; |
| break; |
| case COMPLETED_SEQUENCE: |
| System.out.println("[" |
| + event.getSimulation().getUniqueIDString() |
| + "] Finished ("+ (lastTime - initialTime) +" ms)"); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| } |