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; ...@@ -5,6 +5,7 @@ import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.vadere.simulator.projects.migration.MigrationAssistant; import org.vadere.simulator.projects.migration.MigrationAssistant;
import org.vadere.simulator.projects.migration.MigrationException;
import org.vadere.simulator.projects.migration.MigrationOptions; import org.vadere.simulator.projects.migration.MigrationOptions;
import org.vadere.util.io.IOUtils; import org.vadere.util.io.IOUtils;
...@@ -16,17 +17,32 @@ import java.nio.file.StandardCopyOption; ...@@ -16,17 +17,32 @@ import java.nio.file.StandardCopyOption;
public class MigrationSubCommand implements SubCommandRunner{ public class MigrationSubCommand implements SubCommandRunner{
private final static Logger logger = Logger.getLogger(MigrationSubCommand.class); private final static Logger logger = Logger.getLogger(MigrationSubCommand.class);
@Override @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")); Path scenarioFile = Paths.get(ns.getString("scenario-file"));
if (!scenarioFile.toFile().exists() || !scenarioFile.toFile().isFile()){ 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:" + logger.error("scenario-file does not exist, is not a regular file or you do not have read permissions:" +
scenarioFile.toFile().toString()); scenarioFile.toFile().toString());
System.exit(-1); System.exit(-1);
} }
String outputPathString = ns.getString("output-file");
String outputPathString = ns.getString("output-file");
Version targetVersion = Version.fromString(ns.getString("target-version")); 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()); MigrationAssistant ma = MigrationAssistant.getNewInstance(MigrationOptions.defaultOptions());
String out; String out;
try{ try{
...@@ -46,7 +62,6 @@ public class MigrationSubCommand implements SubCommandRunner{ ...@@ -46,7 +62,6 @@ public class MigrationSubCommand implements SubCommandRunner{
} catch (Exception e) { } catch (Exception e) {
logger.error("Migration failed", e); logger.error("Migration failed", e);
} }
} }
private Path addSuffix(Path p, String suffix){ 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; ...@@ -9,6 +9,6 @@ import net.sourceforge.argparse4j.inf.Namespace;
*/ */
public interface SubCommandRunner { public interface SubCommandRunner {
void run(Namespace ns, ArgumentParser parser); void run(Namespace ns, ArgumentParser parser) throws Exception;
} }
package org.vadere.simulator.entrypoints; 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.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers; import net.sourceforge.argparse4j.inf.Subparsers;
import java.nio.file.Files; import org.apache.log4j.Logger;
import java.nio.file.Paths;
import java.util.Locale;
import org.vadere.simulator.entrypoints.Version;
/** /**
* Provides the possibility to start VADERE in console mode. * Provides the possibility to start VADERE in console mode.
* *
...@@ -24,20 +17,20 @@ public class VadereConsole { ...@@ -24,20 +17,20 @@ public class VadereConsole {
private final static Logger logger = Logger.getLogger(VadereConsole.class); private final static Logger logger = Logger.getLogger(VadereConsole.class);
/** public static void main(String[] args) {
* @param args
*/
public static void main(String[] args) throws ArgumentParserException {
ArgumentParser parser = createArgumentParser(); 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"}; // 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 { try {
Namespace ns = parser.parseArgs(args); Namespace ns = parser.parseArgs(args);
SubCommandRunner sRunner = (SubCommandRunner) ns.get("func"); SubCommandRunner sRunner = ns.get("func");
sRunner.run(ns, parser); sRunner.run(ns, parser);
} catch (ArgumentParserException e) { } catch (ArgumentParserException e) {
parser.handleError(e); parser.handleError(e);
System.exit(1); System.exit(1);
} catch (Exception e) {
logger.error("error in command:" + e.getMessage());
System.exit(1);
} }
} }
...@@ -53,7 +46,7 @@ public class VadereConsole { ...@@ -53,7 +46,7 @@ public class VadereConsole {
// Run Project // Run Project
Subparser projectRun = subparsers Subparser projectRun = subparsers
.addParser("project-run") .addParser(SubCommand.PROJECT_RUN.getCmdName())
.help("This command uses a Vadere Project and runs selected scenario.") .help("This command uses a Vadere Project and runs selected scenario.")
.setDefault("func", new ProjectRunSubCommand()); .setDefault("func", new ProjectRunSubCommand());
projectRun.addArgument("--project-dir", "-p") projectRun.addArgument("--project-dir", "-p")
...@@ -69,7 +62,7 @@ public class VadereConsole { ...@@ -69,7 +62,7 @@ public class VadereConsole {
// Run Scenario // Run Scenario
Subparser scenarioRun = subparsers Subparser scenarioRun = subparsers
.addParser("scenario-run") .addParser(SubCommand.SCENARO_RUN.getCmdName())
.help("Run scenario without a project") .help("Run scenario without a project")
.setDefault("func", new ScenarioRunSubCommand()); .setDefault("func", new ScenarioRunSubCommand());
scenarioRun.addArgument("--output-dir", "-o") scenarioRun.addArgument("--output-dir", "-o")
...@@ -87,7 +80,7 @@ public class VadereConsole { ...@@ -87,7 +80,7 @@ public class VadereConsole {
// Run SUQ // Run SUQ
Subparser suqRun = subparsers 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.") .help("Run a single scenario file to specify to fully controll folder structure for input and output.")
.setDefault("func", new SuqSubCommand()); .setDefault("func", new SuqSubCommand());
...@@ -107,7 +100,7 @@ public class VadereConsole { ...@@ -107,7 +100,7 @@ public class VadereConsole {
// Run Migration Assistant // Run Migration Assistant
Subparser migrationAssistant = subparsers Subparser migrationAssistant = subparsers
.addParser("migrate") .addParser(SubCommand.MIGRATE.getCmdName())
.help("Run migration assistant on single sceanrio file") .help("Run migration assistant on single sceanrio file")
.setDefault("func", new MigrationSubCommand()); .setDefault("func", new MigrationSubCommand());
...@@ -133,6 +126,13 @@ public class VadereConsole { ...@@ -133,6 +126,13 @@ public class VadereConsole {
.choices(versions) .choices(versions)
.help("Write new version to this file. If not specified backup input file and overwrite it."); .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; return parser;
} }
......
...@@ -26,8 +26,8 @@ public enum Version { ...@@ -26,8 +26,8 @@ public enum Version {
return label; return label;
} }
public String label(char repalce) { public String label(char replaceSpaceWith) {
return label.replace(' ', repalce); return label.replace(' ', replaceSpaceWith);
} }
public static Version fromString(String versionStr) { public static Version fromString(String versionStr) {
......
...@@ -72,7 +72,12 @@ public class IncidentMigrationAssistant extends MigrationAssistant { ...@@ -72,7 +72,12 @@ public class IncidentMigrationAssistant extends MigrationAssistant {
} }
@Override @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(); throw new NotImplementedException();
} }
......
package org.vadere.simulator.projects.migration; package org.vadere.simulator.projects.migration;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
...@@ -67,9 +68,15 @@ public class JoltMigrationAssistant extends MigrationAssistant { ...@@ -67,9 +68,15 @@ public class JoltMigrationAssistant extends MigrationAssistant {
} }
@Override @Override
public String convertFile(Path scenarioFilePath, Version targetVersion) throws IOException, MigrationException { public String convertFile(Path scenarioFilePath, Version targetVersion) throws MigrationException {
JsonNode node;
try {
String json = IOUtils.readTextFile(scenarioFilePath); String json = IOUtils.readTextFile(scenarioFilePath);
JsonNode node = StateJsonConverter.deserializeToNode(json); 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(); restLog();
logger.info(">> analyzing JSON tree of scenario <" + node.get("name").asText() + ">"); logger.info(">> analyzing JSON tree of scenario <" + node.get("name").asText() + ">");
Version version = Version.UNDEFINED; Version version = Version.UNDEFINED;
...@@ -94,9 +101,37 @@ public class JoltMigrationAssistant extends MigrationAssistant { ...@@ -94,9 +101,37 @@ public class JoltMigrationAssistant extends MigrationAssistant {
transformedNode = transform(transformedNode, v); transformedNode = transform(transformedNode, v);
} }
try {
return StateJsonConverter.serializeJsonNode(transformedNode); 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 { public MigrationResult analyzeDirectory(Path dir, String dirName) throws IOException {
Path legacyDir = dir.getParent().resolve(LEGACY_DIR).resolve(dirName); Path legacyDir = dir.getParent().resolve(LEGACY_DIR).resolve(dirName);
...@@ -150,7 +185,7 @@ public class JoltMigrationAssistant extends MigrationAssistant { ...@@ -150,7 +185,7 @@ public class JoltMigrationAssistant extends MigrationAssistant {
logger.info(">> analyzing JSON tree of scenario <" + parentPath + node.get("name").asText() + ">"); logger.info(">> analyzing JSON tree of scenario <" + parentPath + node.get("name").asText() + ">");
Version version = Version.UNDEFINED; Version version;
if (node.get("release") != null) { if (node.get("release") != null) {
version = Version.fromString(node.get("release").asText()); version = Version.fromString(node.get("release").asText());
......
package org.vadere.simulator.projects.migration; package org.vadere.simulator.projects.migration;
import org.vadere.simulator.entrypoints.Version; import org.vadere.simulator.entrypoints.Version;
import org.vadere.util.io.IOUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
...@@ -24,6 +25,10 @@ public abstract class MigrationAssistant { ...@@ -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 String getLog();
public abstract void restLog(); public abstract void restLog();
...@@ -36,5 +41,7 @@ public abstract class MigrationAssistant { ...@@ -36,5 +41,7 @@ public abstract class MigrationAssistant {
return new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()); 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,