The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

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 {
String json = IOUtils.readTextFile(scenarioFilePath); JsonNode node;
JsonNode node = StateJsonConverter.deserializeToNode(json); 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(); 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);
} }
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 { 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,