
org.opentripplanner.standalone.CommandLineParameters Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.standalone;
import com.beust.jcommander.IParameterValidator;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import jersey.repackaged.com.google.common.collect.Lists;
import org.opentripplanner.routing.services.GraphService;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
/**
* This is a JCommander-annotated class that holds parameters for OTP stand-alone mode.
* These parameters can be parsed from the command line, or provided in a file using Jcommander's
* at-symbol syntax (see http://jcommander.org/#Syntax). When stand-alone OTP is started as a
* daemon, parameters are loaded from such a file, located by default in '/etc/opentripplanner.cfg'.
*
* Note that JCommander-annotated parameters can be any type that can be constructed from a string.
* This module also contains classes for validating parameters.
* See: http://jcommander.org/#Parameter_validation
*
* Some parameter fields are not initialized so when inferring other parameters, we can check for
* null and see whether they were specified on the command line.
*
* @author abyrd
*/
public class CommandLineParameters implements Cloneable {
private static final int DEFAULT_PORT = 8080;
private static final int DEFAULT_SECURE_PORT = 8081;
private static final String DEFAULT_BASE_PATH = "/var/otp";
/* Options for the command itself, rather than build or server sub-tasks. */
@Parameter(names = {"--help"}, help = true,
description = "Print this help message and exit.")
public boolean help;
@Parameter(names = {"--verbose"},
description = "Verbose output.")
public boolean verbose;
@Parameter(names = {"--basePath"}, validateWith = ReadWriteDirectory.class,
description = "Set the path under which graphs, caches, etc. are stored by default.")
public String basePath = DEFAULT_BASE_PATH;
/* Options for the graph builder sub-task. */
@Parameter(names = {"--build"}, validateWith = ReadableDirectory.class,
description = "Build graphs at specified paths.", variableArity = true)
public File build;
@Parameter(names = {"--cache"}, validateWith = ReadWriteDirectory.class,
description = "The directory under which to cache OSM and NED tiles. Default is BASE_PATH/cache.")
public File cacheDirectory;
@Parameter(names = {"--inMemory"},
description = "Pass the graph to the server in-memory after building it, without saving to disk.")
public boolean inMemory;
@Parameter(names = {"--preFlight"},
description = "Pass the graph to the server in-memory after building it, and saving to disk.")
public boolean preFlight;
@Parameter(names = { "--version", },
description = "Print the version, and then exit.")
public boolean version = false;
/* Options for the server sub-task. */
@Parameter(names = {"--analyst"},
description = "Enable OTP Analyst extensions.")
public boolean analyst;
@Parameter(names = {"--bindAddress"},
description = "Specify which network interface to bind to by address. 0.0.0.0 means all interfaces.")
public String bindAddress = "0.0.0.0";
@Parameter(names = {"--securePort"}, validateWith = AvailablePort.class,
description = "Server port for HTTPS.")
public Integer securePort;
@Parameter(names = {"--autoScan"}, description = "Auto-scan for graphs to register in graph directory.")
public boolean autoScan = false;
@Parameter(names = {"--autoReload"}, description = "Auto-reload registered graphs when source data is modified.")
public boolean autoReload = false;
@Parameter(names = {"--port"}, validateWith = AvailablePort.class,
description = "Server port for plain HTTP.")
public Integer port;
@Parameter(names = {"--maxThreads"}, description = "The maximum number of HTTP handler threads in the pool.")
public Integer maxThreads;
@Parameter(names = {"--graphs"}, validateWith = ReadableDirectory.class,
description = "Path to directory containing graphs. Defaults to BASE_PATH/graphs.")
public File graphDirectory;
@Parameter(names = {"--pointSets"}, validateWith = ReadableDirectory.class,
description = "Path to directory containing PointSets. Defaults to BASE_PATH/pointsets.")
public File pointSetDirectory;
@Parameter(names = {"--clientFiles"}, validateWith = ReadableDirectory.class,
description = "Path to directory containing local client files to serve.")
public File clientDirectory = null;
@Parameter(names = {"--disableFileCache"}, description = "Disable http server static file cache. Handy for development.")
public boolean disableFileCache = false;
@Parameter(names = {"--router"}, validateWith = RouterId.class,
description = "One or more router IDs to build and/or serve, first one being the default.")
public List routerIds;
@Parameter(names = {"--server"},
description = "Run an OTP API server.")
public boolean server = false;
@Parameter(names = {"--visualize"},
description = "Open a graph visualizer window for debugging.")
public boolean visualize;
// TODO should these replace the files auto-discovered in the router directory?
@Parameter(validateWith = ReadableFile.class, // the remaining parameters in one array
description = "Files for graph build.")
public List files = new ArrayList();
@Parameter(names = {"--insecure"},
description = "Allow unauthenticated access to sensitive API resources, e.g. /routers")
public boolean insecure = false;
@Parameter(names = { "--script" }, description = "run the specified OTP script (groovy, python)")
public File scriptFile = null;
@Parameter(names = { "--enableScriptingWebService" }, description = "enable scripting through a web-service (Warning! Very unsafe for public facing servers)")
boolean enableScriptingWebService = false;
/** Set some convenience parameters based on other parameters' values. */
public void infer() {
server |= (inMemory || preFlight || port != null);
if (basePath == null) basePath = DEFAULT_BASE_PATH;
/* If user has not overridden these paths, use default locations under the base path. */
if (cacheDirectory == null) cacheDirectory = new File(basePath, "cache");
if (graphDirectory == null) graphDirectory = new File(basePath, "graphs");
if (pointSetDirectory == null) pointSetDirectory = new File(basePath, "pointsets");
if (server && port == null) {
port = DEFAULT_PORT;
new AvailablePort().validate(port);
}
if (server && securePort == null) {
securePort = DEFAULT_SECURE_PORT;
new AvailablePort().validate(securePort);
}
}
public CommandLineParameters clone() {
CommandLineParameters ret;
try {
ret = (CommandLineParameters) super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
if (this.routerIds != null) {
ret.routerIds = Lists.newArrayList();
ret.routerIds.addAll(this.routerIds);
}
return ret;
}
public static class ReadableFile implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
File file = new File(value);
if ( ! file.isFile()) {
String msg = String.format("%s: '%s' is not a file.", name, value);
throw new ParameterException(msg);
}
if ( ! file.canRead()) {
String msg = String.format("%s: file '%s' is not readable.", name, value);
throw new ParameterException(msg);
}
}
}
public static class ReadableDirectory implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
File file = new File(value);
if ( ! file.isDirectory()) {
String msg = String.format("%s: '%s' is not a directory.", name, value);
throw new ParameterException(msg);
}
if ( ! file.canRead()) {
String msg = String.format("%s: directory '%s' is not readable.", name, value);
throw new ParameterException(msg);
}
}
}
public static class ReadWriteDirectory implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
new ReadableDirectory().validate(name, value);
File file = new File(value);
if ( ! file.canWrite()) {
String msg = String.format("%s: directory '%s' is not writable.", name, value);
throw new ParameterException(msg);
}
}
}
public static class PositiveInteger implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
Integer i = Integer.parseInt(value);
if ( i <= 0 ) {
String msg = String.format("%s must be a positive integer.", name);
throw new ParameterException(msg);
}
}
}
public static class AvailablePort implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
new PositiveInteger().validate(name, value);
int port = Integer.parseInt(value);
this.validate(port);
}
public void validate(int port) throws ParameterException {
ServerSocket socket = null;
boolean portUnavailable = false;
String reason = null;
try {
socket = new ServerSocket(port);
} catch (IOException e) {
portUnavailable = true;
reason = e.getMessage();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// will not be thrown
}
}
}
if ( portUnavailable ) {
String msg = String.format(": port %d is not available. %s.", port, reason);
throw new ParameterException(msg);
}
}
}
public static class RouterId implements IParameterValidator {
@Override
public void validate(String name, String value) throws ParameterException {
if (!GraphService.routerIdLegal(value)) {
String msg = String.format("%s: '%s' is not a valid router ID.", name, value);
throw new ParameterException(msg);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy