Commit bbe6bc97 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

add migration revert option to console, move migration logic from console code

* add helper methods to crate backup files with suffix
* add migration revert function to MigrationAssistant
* move migration logic from VadereConsole back to MigrationAssistant
* add Test for MigrationSubCommand
parent c7e0538c
......@@ -5,6 +5,7 @@ import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.migration.MigrationAssistant;
import org.vadere.simulator.projects.migration.MigrationException;
import org.vadere.simulator.projects.migration.MigrationOptions;
import org.vadere.util.io.IOUtils;
......@@ -16,17 +17,32 @@ import java.nio.file.StandardCopyOption;
public class MigrationSubCommand implements SubCommandRunner{
private final static Logger logger = Logger.getLogger(MigrationSubCommand.class);
@Override
public void run(Namespace ns, ArgumentParser parser) {
public void run(Namespace ns, ArgumentParser parser) throws Exception {
Path scenarioFile = Paths.get(ns.getString("scenario-file"));
if (!scenarioFile.toFile().exists() || !scenarioFile.toFile().isFile()){
logger.error("scenario-file does not exist, is not a regular file or you do not have read permissions:" +
scenarioFile.toFile().toString());
System.exit(-1);
}
String outputPathString = ns.getString("output-file");
String outputPathString = ns.getString("output-file");
Version targetVersion = Version.fromString(ns.getString("target-version"));
boolean revertMode = ns.getBoolean("revert-migration");
if (revertMode){
revert(scenarioFile);
} else {
migrate(scenarioFile, targetVersion, outputPathString);
}
}
private void revert(Path scenarioFile) throws MigrationException {
MigrationAssistant ma = MigrationAssistant.getNewInstance(MigrationOptions.defaultOptions());
ma.revertFile(scenarioFile);
}
private void migrate(Path scenarioFile, Version targetVersion, String outputPathString){
MigrationAssistant ma = MigrationAssistant.getNewInstance(MigrationOptions.defaultOptions());
String out;
try{
......@@ -46,7 +62,6 @@ public class MigrationSubCommand implements SubCommandRunner{
} catch (Exception e) {
logger.error("Migration failed", e);
}
}
private Path addSuffix(Path p, String suffix){
......
package org.vadere.simulator.entrypoints;
public enum SubCommand {
PROJECT_RUN("project-run"),
SCENARO_RUN("scenario-run"),
SUQ("suq"),
MIGRATE("migrate");
private String cmdName;
SubCommand(String s) {
this.cmdName = s;
}
public String getCmdName(){
return this.cmdName;
}
}
......@@ -9,6 +9,6 @@ import net.sourceforge.argparse4j.inf.Namespace;
*/
public interface SubCommandRunner {
void run(Namespace ns, ArgumentParser parser);
void run(Namespace ns, ArgumentParser parser) throws Exception;
}
package org.vadere.simulator.entrypoints;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.ScenarioRun;
import org.vadere.simulator.projects.migration.incidents.VersionBumpIncident;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import org.vadere.simulator.entrypoints.Version;
import org.apache.log4j.Logger;
/**
* Provides the possibility to start VADERE in console mode.
*
......@@ -24,20 +17,20 @@ public class VadereConsole {
private final static Logger logger = Logger.getLogger(VadereConsole.class);
/**
* @param args
*/
public static void main(String[] args) throws ArgumentParserException {
public static void main(String[] args) {
ArgumentParser parser = createArgumentParser();
// args = new String[]{"migrate", "-f", "/home/lphex/hm.d/vadere/VadereSimulator/testResources/data/simpleProject/output/test_postvis_2018-01-17_16-56-37.307/test_postvis.scenario"};
try {
Namespace ns = parser.parseArgs(args);
SubCommandRunner sRunner = (SubCommandRunner) ns.get("func");
SubCommandRunner sRunner = ns.get("func");
sRunner.run(ns, parser);
} catch (ArgumentParserException e) {
parser.handleError(e);
System.exit(1);
} catch (Exception e) {
logger.error("error in command:" + e.getMessage());
System.exit(1);
}
}
......@@ -53,7 +46,7 @@ public class VadereConsole {
// Run Project
Subparser projectRun = subparsers
.addParser("project-run")
.addParser(SubCommand.PROJECT_RUN.getCmdName())
.help("This command uses a Vadere Project and runs selected scenario.")
.setDefault("func", new ProjectRunSubCommand());
projectRun.addArgument("--project-dir", "-p")
......@@ -69,7 +62,7 @@ public class VadereConsole {
// Run Scenario
Subparser scenarioRun = subparsers
.addParser("scenario-run")
.addParser(SubCommand.SCENARO_RUN.getCmdName())
.help("Run scenario without a project")
.setDefault("func", new ScenarioRunSubCommand());
scenarioRun.addArgument("--output-dir", "-o")
......@@ -87,7 +80,7 @@ public class VadereConsole {
// Run SUQ
Subparser suqRun = subparsers
.addParser("suq")
.addParser(SubCommand.SUQ.getCmdName())
.help("Run a single scenario file to specify to fully controll folder structure for input and output.")
.setDefault("func", new SuqSubCommand());
......@@ -107,7 +100,7 @@ public class VadereConsole {
// Run Migration Assistant
Subparser migrationAssistant = subparsers
.addParser("migrate")
.addParser(SubCommand.MIGRATE.getCmdName())
.help("Run migration assistant on single sceanrio file")
.setDefault("func", new MigrationSubCommand());
......@@ -133,6 +126,13 @@ public class VadereConsole {
.choices(versions)
.help("Write new version to this file. If not specified backup input file and overwrite it.");
migrationAssistant.addArgument("--revert-migration")
.required(false)
.action(Arguments.storeTrue())
.dest("revert-migration")
.help("if set vadere will search for a <scenario-file>.legacy and will replace the current version with this backup." +
" The Backup must be in the same directory");
return parser;
}
......
......@@ -26,8 +26,8 @@ public enum Version {
return label;
}
public String label(char repalce) {
return label.replace(' ', repalce);
public String label(char replaceSpaceWith) {
return label.replace(' ', replaceSpaceWith);
}
public static Version fromString(String versionStr) {
......
......@@ -72,7 +72,12 @@ public class IncidentMigrationAssistant extends MigrationAssistant {
}
@Override
public String convertFile(Path scenarioFilePath, Version targetVersion) throws IOException, MigrationException {
public String convertFile(Path scenarioFilePath, Version targetVersion) {
throw new NotImplementedException();
}
@Override
public void revertFile(Path scenarioFile) {
throw new NotImplementedException();
}
......
package org.vadere.simulator.projects.migration;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.log4j.Logger;
......@@ -67,9 +68,15 @@ public class JoltMigrationAssistant extends MigrationAssistant {
}
@Override
public String convertFile(Path scenarioFilePath, Version targetVersion) throws IOException, MigrationException {
String json = IOUtils.readTextFile(scenarioFilePath);
JsonNode node = StateJsonConverter.deserializeToNode(json);
public String convertFile(Path scenarioFilePath, Version targetVersion) throws MigrationException {
JsonNode node;
try {
String json = IOUtils.readTextFile(scenarioFilePath);
node = StateJsonConverter.deserializeToNode(json);
} catch (IOException e){
logger.error("Error converting File: " + e.getMessage());
throw new MigrationException("Could not read JsonFile or create Json representation" + e.getMessage());
}
restLog();
logger.info(">> analyzing JSON tree of scenario <" + node.get("name").asText() + ">");
Version version = Version.UNDEFINED;
......@@ -94,9 +101,37 @@ public class JoltMigrationAssistant extends MigrationAssistant {
transformedNode = transform(transformedNode, v);
}
return StateJsonConverter.serializeJsonNode(transformedNode);
try {
return StateJsonConverter.serializeJsonNode(transformedNode);
} catch (JsonProcessingException e) {
logger.error("could not serializeJsonNode after Transformation: " + e.getMessage());
throw new MigrationException("could not serializeJsonNode after Transformation: " + e.getMessage());
}
}
@Override
public void revertFile(Path scenarioFile) throws MigrationException {
Path backupFile = MigrationAssistant.getBackupPath(scenarioFile);
if (!backupFile.toFile().exists()){
logger.error("There does not exist a Backup for the given file");
logger.error("File: " + scenarioFile.toString());
logger.error("Backup does not exist: " + backupFile.toString());
}
try {
Files.copy(backupFile, scenarioFile, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
logger.error("Could not copy legacy backup to current version: " + e.getMessage(), e);
throw new MigrationException("Could not copy legacy backup to current version: " + e.getMessage(), e);
}
try {
Files.deleteIfExists(backupFile);
} catch (IOException e) {
logger.error("Cold not delete old legacy file after reverting File: " + e.getMessage(), e);
}
}
public MigrationResult analyzeDirectory(Path dir, String dirName) throws IOException {
Path legacyDir = dir.getParent().resolve(LEGACY_DIR).resolve(dirName);
......@@ -150,7 +185,7 @@ public class JoltMigrationAssistant extends MigrationAssistant {
logger.info(">> analyzing JSON tree of scenario <" + parentPath + node.get("name").asText() + ">");
Version version = Version.UNDEFINED;
Version version;
if (node.get("release") != null) {
version = Version.fromString(node.get("release").asText());
......
package org.vadere.simulator.projects.migration;
import org.vadere.simulator.entrypoints.Version;
import org.vadere.util.io.IOUtils;
import java.io.IOException;
import java.nio.file.Path;
......@@ -24,6 +25,10 @@ public abstract class MigrationAssistant {
}
}
public static Path getBackupPath(Path scenarioFile){
return IOUtils.addSuffix(scenarioFile, "." + IOUtils.LEGACY_DIR, false);
}
public abstract String getLog();
public abstract void restLog();
......@@ -36,5 +41,7 @@ public abstract class MigrationAssistant {
return new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
}
public abstract String convertFile(Path scenarioFilePath, Version targetVersion) throws IOException, MigrationException;
public abstract String convertFile(Path scenarioFilePath, Version targetVersion) throws MigrationException;
public abstract void revertFile(Path scenarioFile) throws MigrationException;
}
package org.vadere.simulator.projects.migration.helper;
public class Util {
public static void main(String[] args){
}
private void listScenarioFiles(){
}
}
{
"name" : "basic_2_density_osm1",
"description" : "",
"release" : "0.1",
"topographyhash" : "033539da8c31611622e76d2566fc5b54d18870fa",
"attributeshash" : "75778572f188cffcdedc74a7a9b60ddbe42359fc",
"processWriters" : [ {
"formatString" : "%s",
"columnNames" : [ "densityTest" ],
"attributes" : {
"startTime" : 0.0,
"endTime" : 1.7976931348623157E308
},
"processor" : {
"pedestrianDensityProcessor" : {
"densityProcessor" : {
"attributes" : {
"radius" : 1.5
},
"columnNames" : [ "x", "y", "circleDensity", "step", "time" ],
"clazz" : "DensityCountingProcessor"
},
"columnNames" : [ "circleDensity" ],
"clazz" : "PedestrianDensityProcessor"
},
"attributes" : {
"maxDensity" : 10.0,
"minDensity" : 0.0,
"maxMeanDensity" : 6.0,
"minMeanDensity" : 0.0,
"expectFailure" : false
},
"errorTime" : -1.0,
"columnNames" : [ ],
"clazz" : "PedestrianDensityTest"
}
}, {
"formatString" : "%s",
"columnNames" : [ "evacuationTimeTest" ],
"attributes" : {
"startTime" : 0.0,
"endTime" : 1.7976931348623157E308
},
"processor" : {
"attributes" : {
"maxEvacuationTime" : 100.0,
"maxEvacuationTimeMean" : 100.0,
"minEvacuationTime" : 0.0,
"minEvacuationTimeMean" : 0.0,
"expectFailure" : false
},
"errorTime" : -1.0,
"columnNames" : [ ],
"clazz" : "PedestrianEvacuationTimeTest"
}
} ],
"vadere" : {
"mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel",
"attributesModel" : {
"org.vadere.state.attributes.models.AttributesPotentialCompact" : {
"pedPotentialWidth" : 0.5,
"pedPotentialHeight" : 12.6,
"obstPotentialWidth" : 0.25,
"obstPotentialHeight" : 20.1,
"useHardBodyShell" : false,
"obstDistanceDeviation" : 0.0,
"visionFieldRadius" : 5.0
},
"org.vadere.state.attributes.models.AttributesOSM" : {
"stepCircleResolution" : 18,
"numberOfCircles" : 1,
"varyStepDirection" : false,
"stepLengthIntercept" : 0.4625,
"stepLengthSlopeSpeed" : 0.2345,
"stepLengthSD" : 0.036,
"movementThreshold" : 0.0,
"optimizationType" : "DISCRETE",
"movementType" : "ARBITRARY",
"dynamicStepLength" : false,
"updateType" : "EVENT_DRIVEN",
"seeSmallWalls" : false,
"minimumStepLength" : false,
"targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid",
"pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompact",
"obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompact",
"submodels" : [ ]
},
"org.vadere.state.attributes.models.AttributesFloorField" : {
"createMethod" : "HIGH_ACCURACY_FAST_MARCHING",
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"timeCostAttributes" : {
"standardDerivation" : 0.7,
"type" : "UNIT",
"obstacleDensityWeight" : 3.5,
"pedestrianSameTargetDensityWeight" : 3.5,
"pedestrianOtherTargetDensityWeight" : 3.5,
"pedestrianWeight" : 3.5,
"queueWidthLoading" : 1.0,
"pedestrianDynamicWeight" : 6.0,
"loadingType" : "CONSTANT"
}
}
},
"attributesSimulation" : {
"finishTime" : 200.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.0,
"writeSimulationData" : true,
"visualizationEnabled" : true,
"printFPS" : false,
"needsBoundary" : false,
"digitsPerCoordinate" : 2,
"useRandomSeed" : true,
"randomSeed" : 1
},
"topography" : {
"attributes" : {
"bounds" : {
"x" : 0.0,
"y" : 0.0,
"width" : 38.0,
"height" : 12.0
},
"boundingBoxWidth" : 0.5,
"bounded" : true
},
"obstacles" : [ {
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 9.0,
"y" : 12.0
}, {
"x" : 9.0,
"y" : 10.0
}, {
"x" : 30.0,
"y" : 7.0
}, {
"x" : 30.0,
"y" : 12.0
} ]
},
"id" : -1
}, {
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 9.0,
"y" : 0.0
}, {
"x" : 9.0,
"y" : 2.0
}, {
"x" : 30.0,
"y" : 5.0
}, {
"x" : 30.0,
"y" : 0.0
} ]
},
"id" : -1
} ],
"stairs" : [ ],
"targets" : [ {
"id" : 1,
"absorbing" : true,
"shape" : {
"x" : 35.0,
"y" : 5.0,
"width" : 2.0,
"height" : 2.0,
"type" : "RECTANGLE"
},
"waitingTime" : 0.0,
"waitingTimeYellowPhase" : 0.0,
"parallelWaiters" : 0,
"individualWaiting" : true,
"deletionDistance" : 0.1,
"startingWithRedLight" : false,
"nextSpeed" : -1.0
} ],
"sources" : [ {
"id" : -1,
"shape" : {
"x" : 1.0,
"y" : 1.0,
"width" : 3.0,
"height" : 10.0,
"type" : "RECTANGLE"
},
"spawnDelay" : 1.0,
"interSpawnTimeDistribution" : "org.vadere.state.scenario.ConstantDistribution",
"distributionParameters" : [ 1.0 ],
"spawnNumber" : 200,
"startTime" : 0.0,
"endTime" : 0.0,
"spawnAtRandomPositions" : true,
"useFreeSpaceOnly" : false,
"targetIds" : [ 1 ],
"dynamicElementType" : "PEDESTRIAN"
} ],
"dynamicElements" : [ ],
"attributesPedestrian" : {
"radius" : 0.195,
"densityDependentSpeed" : false,
"speedDistributionMean" : 1.34,
"speedDistributionStandardDeviation" : 0.26,
"minimumSpeed" : 0.3,
"maximumSpeed" : 3.0,
"acceleration" : 2.0
},
"attributesCar" : null
}
}
}
\ No newline at end of file
package org.vadere.simulator.entrypoints;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import org.hamcrest.core.StringContains;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.vadere.simulator.projects.migration.MigrationAssistant;
import org.vadere.util.io.IOUtils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class MigrationSubCommandTest {
private Path baseScenario;
private Path baseScenarioBackup;
private StringContains v01 = new StringContains("\"release\" : \"0.1\"");
// StringContains v02 = new StringContains("\"release\" : \"0.2\"");
private StringContains vlatest = new StringContains("\"release\" : \"" + Version.latest().label() + "\"");
@Before
public void init() throws URISyntaxException, IOException {
baseScenario = Paths.get(getClass()
.getResource("/migration/VadererConsole/v0.1_to_LATEST_Test1.scenario").toURI());
baseScenarioBackup = IOUtils.makeBackup(baseScenario, ".bak", true);
}
@After
public void clenaup() throws IOException {
if (baseScenario != null && baseScenarioBackup != null){
Files.copy(baseScenarioBackup, baseScenario, StandardCopyOption.REPLACE_EXISTING);
Files.deleteIfExists(baseScenarioBackup);
}
Path legacyFile = MigrationAssistant.getBackupPath(baseScenario);
Files.deleteIfExists(legacyFile);
}