Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

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);