Skip to content

Commit

Permalink
Merge pull request opentripplanner#5603 from entur/filter_access_path…
Browse files Browse the repository at this point in the history
…s_raptor

Add options to turn logging on/off and debug Raptor
  • Loading branch information
t2gran authored Jan 16, 2024
2 parents 288f7d2 + 5069194 commit af54699
Show file tree
Hide file tree
Showing 43 changed files with 1,175 additions and 709 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static org.opentripplanner.transit.model.basic.TransitMode.CARPOOL;

import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.opentripplanner.api.parameter.ApiRequestMode;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package org.opentripplanner.ext.interactivelauncher;

import static org.opentripplanner.ext.interactivelauncher.DebugLoggingSupport.configureDebugLogging;

import org.opentripplanner.ext.interactivelauncher.views.MainView;
import org.opentripplanner.ext.interactivelauncher.configuration.InteractiveLauncherModule;
import org.opentripplanner.ext.interactivelauncher.debug.OtpDebugController;
import org.opentripplanner.ext.interactivelauncher.startup.MainView;
import org.opentripplanner.standalone.OTPMain;

/**
* This class provide a main method to start a GUI which can start OTPMain.
* This class provides a main method to start a GUI which can start OTPMain.
* <p>
* The UI allow the user to select a OTP configuration data set. The list of data location is
* created by searching the a root data source directory.
* The UI allows the user to select the OTP configuration dataset. The list of data locations is
* created by searching the root data source directory.
* <p>
* The user then select what he/she want OTP to do. The settings are stored in the
* <code>.interactive_otp_main.json</code> file in the folder InteractiveOtpMain is started. The
* settings from the last run is loaded next time InteractiveOtpMain is started.
* The user then selects what he/she wants OTP to do.
* The settings are stored in the
* <code>.interactive_otp_main.json</code> file in the folder InteractiveOtpMain is started.
* The settings from the last run are loaded the next time InteractiveOtpMain is started.
*/
public class InteractiveOtpMain {

Expand All @@ -25,16 +26,19 @@ public static void main(String[] args) {

private void run() {
this.model = Model.load();
MainView frame = new MainView(new Thread(this::startOtp)::start, model);
MainView frame = new MainView(new Thread(this::startOtp)::start, model.getStartupModel());
frame.start();
}

private void startOtp() {
model.save();

configureDebugLogging(model.getDebugLogging());
startDebugControllerAndSetupRequestInterceptor();

System.out.println("Start OTP: " + model + "\n");
OTPMain.main(model.asOtpArgs());
OTPMain.main(model.getStartupModel().asOtpArgs());
}

private void startDebugControllerAndSetupRequestInterceptor() {
new OtpDebugController(model).start();
InteractiveLauncherModule.setRequestInterceptor(model.getRaptorDebugModel());
}
}
244 changes: 40 additions & 204 deletions src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java
Original file line number Diff line number Diff line change
@@ -1,245 +1,81 @@
package org.opentripplanner.ext.interactivelauncher;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel;
import org.opentripplanner.ext.interactivelauncher.debug.raptor.RaptorDebugModel;
import org.opentripplanner.ext.interactivelauncher.startup.StartupModel;

public class Model implements Serializable {

private static final Logger LOG = LoggerFactory.getLogger(Model.class);

private static final File MODEL_FILE = new File("interactive_otp_main.json");

private final Map<String, Boolean> debugLogging = new HashMap<>();

@JsonIgnore
private transient Consumer<String> commandLineChange;
private StartupModel startupModel;
private LogModel logModel;
private RaptorDebugModel raptorDebugModel;

private String rootDirectory = null;
private String dataSource = null;
private boolean buildStreet = false;
private boolean buildTransit = true;
private boolean saveGraph = false;
private boolean serveGraph = true;
private boolean visualizer = false;

public Model() {
setupListOfDebugLoggers();
}
public Model() {}

public static Model load() {
return MODEL_FILE.exists() ? readFromFile() : new Model();
}

public void subscribeCmdLineUpdates(Consumer<String> commandLineChange) {
this.commandLineChange = commandLineChange;
}

@SuppressWarnings("AccessOfSystemProperties")
public String getRootDirectory() {
return rootDirectory == null ? System.getProperty("user.dir") : rootDirectory;
}

public void setRootDirectory(String rootDirectory) {
// If the persisted JSON do not contain the rootDirectory, then avoid setting it
if (rootDirectory != null) {
this.rootDirectory = rootDirectory;
}
notifyChangeListener();
}

public String getDataSource() {
return dataSource;
}

public void setDataSource(String dataSource) {
this.dataSource = dataSource;
notifyChangeListener();
}

@JsonIgnore
public List<String> getDataSourceOptions() {
List<String> dataSourceOptions = new ArrayList<>();
File rootDir = new File(getRootDirectory());
List<File> dirs = SearchForOtpConfig.search(rootDir);
// Add 1 char for the path-separator-character
int length = rootDir.getAbsolutePath().length() + 1;

for (File dir : dirs) {
var path = dir.getAbsolutePath();
if (path.length() <= length) {
LOG.warn(
"The root directory contains a config file, choose " +
"the parent directory or delete the config file."
);
continue;
}
dataSourceOptions.add(path.substring(length));
}
return dataSourceOptions;
}

public boolean isBuildStreet() {
return buildStreet;
}

public void setBuildStreet(boolean buildStreet) {
this.buildStreet = buildStreet;
notifyChangeListener();
}

public boolean isBuildTransit() {
return buildTransit;
}

public void setBuildTransit(boolean buildTransit) {
this.buildTransit = buildTransit;
notifyChangeListener();
}

public boolean isSaveGraph() {
return saveGraph;
}

public void setSaveGraph(boolean saveGraph) {
this.saveGraph = saveGraph;
notifyChangeListener();
}

public boolean isServeGraph() {
return serveGraph;
}

public void setServeGraph(boolean serveGraph) {
this.serveGraph = serveGraph;
notifyChangeListener();
}

public boolean isVisualizer() {
return visualizer;
return MODEL_FILE.exists() ? readFromFile() : createNew();
}

public void setVisualizer(boolean visualizer) {
this.visualizer = visualizer;
notifyChangeListener();
public StartupModel getStartupModel() {
return startupModel;
}

public Map<String, Boolean> getDebugLogging() {
return debugLogging;
public LogModel getLogModel() {
return logModel;
}

public void setDebugLogging(Map<String, Boolean> map) {
for (Entry<String, Boolean> e : map.entrySet()) {
// Only keep entries that exist in the log config
if (debugLogging.containsKey(e.getKey())) {
debugLogging.put(e.getKey(), e.getValue());
}
}
}

@Override
public String toString() {
return (
"(" +
"data-source-dir: " +
getDataSourceDirectory() +
(buildStreet ? ", buildStreet" : "") +
(buildTransit ? ", buildTransit" : "") +
(saveGraph ? ", saveGraph" : "") +
(serveGraph ? ", serveGraph" : "") +
(visualizer ? ", visualizer" : "") +
')'
);
}

public String toCliString() {
return String.join(" ", asOtpArgs());
}

public void save() {
try {
new ObjectMapper().writeValue(MODEL_FILE, this);
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}

@JsonIgnore
String getDataSourceDirectory() {
if (dataSource == null) {
return "DATA_SOURCE_NOT_SET";
}
return rootDirectory + File.separatorChar + dataSource;
public RaptorDebugModel getRaptorDebugModel() {
return raptorDebugModel;
}

String[] asOtpArgs() {
List<String> args = new ArrayList<>();

if (buildAll()) {
args.add("--build");
} else if (buildStreet) {
args.add("--buildStreet");
} else if (buildTransit) {
args.add("--loadStreet");
} else {
args.add("--load");
}

if (saveGraph && (buildTransit || buildStreet)) {
args.add("--save");
}
if (serveGraph && !buildStreetOnly()) {
args.add("--serve");
}
if (serveGraph && !buildStreetOnly() && visualizer) {
args.add("--visualize");
}

args.add(getDataSourceDirectory());

return args.toArray(new String[0]);
private static Model createNew() {
return new Model().initSubModels();
}

private static Model readFromFile() {
try {
return new ObjectMapper().readValue(MODEL_FILE, Model.class);
var mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.readValue(MODEL_FILE, Model.class).initSubModels();
} catch (IOException e) {
System.err.println(
"Unable to read the InteractiveOtpMain state cache. If the model changed this " +
"is expected, and it will work next time. Cause: " +
e.getMessage()
);
return new Model();
return createNew();
}
}

private void notifyChangeListener() {
if (commandLineChange != null) {
commandLineChange.accept(toCliString());
private void save() {
try {
var mapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.writeValue(MODEL_FILE, this);
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}

private boolean buildAll() {
return buildStreet && buildTransit;
}

private boolean buildStreetOnly() {
return buildStreet && !buildTransit;
}

private void setupListOfDebugLoggers() {
for (String log : DebugLoggingSupport.getLogs()) {
debugLogging.put(log, Boolean.FALSE);
private Model initSubModels() {
if (startupModel == null) {
startupModel = new StartupModel();
}
if (logModel == null) {
logModel = LogModel.createFromConfig();
}
if (raptorDebugModel == null) {
raptorDebugModel = new RaptorDebugModel();
}
logModel.init(this::save);
raptorDebugModel.init(this::save);
return this;
}
}
Loading

0 comments on commit af54699

Please sign in to comment.