org.fcrepo.utilities.install.InstallOptions Maven / Gradle / Ivy
/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.utilities.install;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
public class InstallOptions {
public static final String INSTALL_TYPE = "install.type";
public static final String FEDORA_HOME = "fedora.home";
public static final String FEDORA_SERVERHOST = "fedora.serverHost";
public static final String FEDORA_APP_SERVER_CONTEXT = "fedora.serverContext";
public static final String APIA_AUTH_REQUIRED = "apia.auth.required";
public static final String UPSTREAM_AUTH_ENABLED = "upstream.auth.enabled";
public static final String SSL_AVAILABLE = "ssl.available";
public static final String APIA_SSL_REQUIRED = "apia.ssl.required";
public static final String APIM_SSL_REQUIRED = "apim.ssl.required";
public static final String SERVLET_ENGINE = "servlet.engine";
public static final String TOMCAT_HOME = "tomcat.home";
public static final String FEDORA_ADMIN_PASS = "fedora.admin.pass";
public static final String TOMCAT_SHUTDOWN_PORT = "tomcat.shutdown.port";
public static final String TOMCAT_HTTP_PORT = "tomcat.http.port";
public static final String TOMCAT_SSL_PORT = "tomcat.ssl.port";
public static final String KEYSTORE_FILE = "keystore.file";
public static final String KEYSTORE_PASSWORD = "keystore.password";
public static final String KEYSTORE_TYPE = "keystore.type";
public static final String DATABASE = "database";
public static final String DATABASE_DRIVER = "database.driver";
public static final String DATABASE_JDBCURL = "database.jdbcURL";
public static final String DATABASE_DRIVERCLASS =
"database.jdbcDriverClass";
public static final String EMBEDDED_DATABASE_DRIVERCLASSNAME =
"org.apache.derby.jdbc.EmbeddedDriver";
public static final String DATABASE_USERNAME = "database.username";
public static final String DATABASE_PASSWORD = "database.password";
public static final String XACML_ENABLED = "xacml.enabled";
public static final String FESL_AUTHN_ENABLED = "fesl.authn.enabled";
public static final String FESL_AUTHZ_ENABLED = "fesl.authz.enabled";
public static final String LLSTORE_TYPE = "llstore.type";
public static final String RI_ENABLED = "ri.enabled";
public static final String MESSAGING_ENABLED = "messaging.enabled";
public static final String MESSAGING_URI = "messaging.uri";
public static final String DEPLOY_LOCAL_SERVICES = "deploy.local.services";
public static final String TEST_SPRING_CONFIGS = "test.spring.configs";
public static final String UNATTENDED = "unattended";
public static final String DATABASE_UPDATE = "database.update";
public static final String DEFAULT = "default";
public static final String INSTALL_QUICK = "quick";
public static final String INSTALL_CLIENT = "client";
public static final String INCLUDED = "included";
public static final String DERBY = "derby";
public static final String MYSQL = "mysql";
public static final String ORACLE = "oracle";
public static final String POSTGRESQL = "postgresql";
public static final String OTHER = "other";
public static final String EXISTING_TOMCAT = "existingTomcat";
private final Map _map;
private final Distribution _dist;
/**
* Initialize options from the given map of String values, keyed by option
* id.
*/
public InstallOptions(Distribution dist, Map map)
throws OptionValidationException {
_dist = dist;
_map = map;
applyDefaults();
validateAll();
}
/**
* Initialize options interactively, via input from the console.
*/
public InstallOptions(Distribution dist)
throws InstallationCancelledException {
_dist = dist;
_map = new HashMap();
System.out.println();
System.out.println("***********************");
System.out.println(" Fedora Installation ");
System.out.println("***********************");
checkJavaVersion();
System.out.println();
System.out.println("To install Fedora, please answer the following questions.");
System.out.println("Enter CANCEL at any time to abort the installation.");
System.out.println("Detailed installation instructions are available online:\n");
System.out.println(" https://wiki.duraspace.org/display/FEDORA/All+Documentation\n");
inputOption(INSTALL_TYPE);
inputOption(FEDORA_HOME);
if (getValue(INSTALL_TYPE).equals(INSTALL_CLIENT)) {
return;
}
inputOption(FEDORA_ADMIN_PASS);
String fedoraHome =
new File(getValue(InstallOptions.FEDORA_HOME))
.getAbsolutePath();
String includedJDBCURL =
"jdbc:derby:" + fedoraHome + File.separator
+ "derby/fedora3;create=true";
if (getValue(INSTALL_TYPE).equals(INSTALL_QUICK)) {
// See the defaultValues defined in OptionDefinition.properties
// for the null values below
_map.put(FEDORA_SERVERHOST, null); // localhost
_map.put(FEDORA_APP_SERVER_CONTEXT, null);
_map.put(APIA_AUTH_REQUIRED, null); // false
_map.put(SSL_AVAILABLE, Boolean.toString(false));
_map.put(APIM_SSL_REQUIRED, Boolean.toString(false));
_map.put(SERVLET_ENGINE, null); // included
_map.put(TOMCAT_HOME, fedoraHome + File.separator + "tomcat");
_map.put(TOMCAT_HTTP_PORT, null); // 8080
_map.put(TOMCAT_SHUTDOWN_PORT, null); // 8005
_map.put(DATABASE, INCLUDED);
_map.put(DATABASE_DRIVER, INCLUDED);
_map.put(DATABASE_USERNAME, "fedoraAdmin");
_map.put(DATABASE_PASSWORD, "fedoraAdmin");
_map.put(DATABASE_JDBCURL, includedJDBCURL);
_map.put(DATABASE_DRIVERCLASS, EMBEDDED_DATABASE_DRIVERCLASSNAME);
_map.put(XACML_ENABLED, Boolean.toString(false));
_map.put(UPSTREAM_AUTH_ENABLED, Boolean.toString(false));
_map.put(FESL_AUTHN_ENABLED, Boolean.toString(true));
_map.put(FESL_AUTHZ_ENABLED, Boolean.toString(false));
_map.put(LLSTORE_TYPE, null); // akubra-fs
_map.put(RI_ENABLED, null); // false
_map.put(MESSAGING_ENABLED, null); // false
_map.put(DEPLOY_LOCAL_SERVICES, null); // true
applyDefaults();
return;
}
inputOption(FEDORA_SERVERHOST);
inputOption(FEDORA_APP_SERVER_CONTEXT);
inputOption(APIA_AUTH_REQUIRED);
inputOption(SSL_AVAILABLE);
boolean sslAvailable = getBooleanValue(SSL_AVAILABLE, true);
if (sslAvailable) {
inputOption(APIA_SSL_REQUIRED);
inputOption(APIM_SSL_REQUIRED);
}
inputOption(SERVLET_ENGINE);
if (!getValue(SERVLET_ENGINE).equals(OTHER)) {
inputOption(TOMCAT_HOME);
inputOption(TOMCAT_HTTP_PORT);
inputOption(TOMCAT_SHUTDOWN_PORT);
if (sslAvailable) {
inputOption(TOMCAT_SSL_PORT);
if (getValue(SERVLET_ENGINE).equals(INCLUDED)
|| getValue(SERVLET_ENGINE).equals(EXISTING_TOMCAT)) {
inputOption(KEYSTORE_FILE);
if (!getValue(KEYSTORE_FILE).equals(INCLUDED)) {
inputOption(KEYSTORE_PASSWORD);
inputOption(KEYSTORE_TYPE);
}
}
}
}
// Database selection
// Ultimately we want to provide the following properties:
// database, database.username, database.password,
// database.driver, database.jdbcURL, database.jdbcDriverClass
inputOption(DATABASE);
String db = DATABASE + "." + getValue(DATABASE);
// The following lets us use the database-specific OptionDefinition.properties
// for the user prompts and defaults
String driver = db + ".driver";
String jdbcURL = db + ".jdbcURL";
String jdbcDriverClass = db + ".jdbcDriverClass";
if (getValue(DATABASE).equals(INCLUDED)) {
_map.put(DATABASE_USERNAME, "fedoraAdmin");
_map.put(DATABASE_PASSWORD, "fedoraAdmin");
_map.put(DATABASE_DRIVER, INCLUDED);
_map.put(DATABASE_JDBCURL, includedJDBCURL);
_map.put(DATABASE_DRIVERCLASS, EMBEDDED_DATABASE_DRIVERCLASSNAME);
} else {
boolean dbValidated = false;
while (!dbValidated) {
inputOption(driver);
_map.put(DATABASE_DRIVER, getValue(driver));
inputOption(DATABASE_USERNAME);
inputOption(DATABASE_PASSWORD);
inputOption(jdbcURL);
_map.put(DATABASE_JDBCURL, getValue(jdbcURL));
inputOption(jdbcDriverClass);
_map.put(DATABASE_DRIVERCLASS, getValue(jdbcDriverClass));
dbValidated = validateDatabaseConnection();
}
}
inputOption(UPSTREAM_AUTH_ENABLED);
if (getBooleanValue(UPSTREAM_AUTH_ENABLED,false)) {
// disable FESL authN if upstream authN is enabled
_map.put(FESL_AUTHN_ENABLED, Boolean.toString(false));
}
inputOption(FESL_AUTHZ_ENABLED);
if (getValue(FESL_AUTHZ_ENABLED).equals(Boolean.toString(true))) {
// Disable legacy authz if FeSL is enabled
_map.put(XACML_ENABLED, Boolean.toString(false));
} else {
inputOption(XACML_ENABLED);
}
inputOption(LLSTORE_TYPE);
inputOption(RI_ENABLED);
inputOption(MESSAGING_ENABLED);
if (getValue(MESSAGING_ENABLED).equals(Boolean.toString(true))) {
inputOption(MESSAGING_URI);
}
inputOption(DEPLOY_LOCAL_SERVICES);
}
private static void checkJavaVersion() throws InstallationCancelledException {
String v = System.getProperty("java.version");
if (v.startsWith("1.3") || v.startsWith("1.4") || v.startsWith("1.5")) {
System.err.println("ERROR: Java " + v + " is too old; This version"
+ " of Fedora requires Java 1.6 or above.");
throw new InstallationCancelledException();
}
}
private String dashes(int len) {
StringBuffer out = new StringBuffer();
for (int i = 0; i < len; i++) {
out.append('-');
}
return out.toString();
}
/**
* Get the indicated option from the console. Continue prompting until the
* value is valid, or the user has indicated they want to cancel the
* installation.
*/
private void inputOption(String optionId)
throws InstallationCancelledException {
OptionDefinition opt = OptionDefinition.get(optionId, this);
if (opt.getLabel() == null || opt.getLabel().length() == 0) {
throw new InstallationCancelledException(optionId
+ " is missing label (check OptionDefinition.properties?)");
}
System.out.println(opt.getLabel());
System.out.println(dashes(opt.getLabel().length()));
System.out.println(opt.getDescription());
System.out.println();
String[] valids = opt.getValidValues();
if (valids != null) {
System.out.print("Options : ");
for (int i = 0; i < valids.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(valids[i]);
}
System.out.println();
}
String defaultVal = opt.getDefaultValue();
if (valids != null || defaultVal != null) {
System.out.println();
}
boolean gotValidValue = false;
while (!gotValidValue) {
System.out.print("Enter a value ");
if (defaultVal != null) {
System.out.print("[default is " + defaultVal + "] ");
}
System.out.print("==> ");
String value = readLine().trim();
if (value.length() == 0 && defaultVal != null) {
value = defaultVal;
}
System.out.println();
if (value.equalsIgnoreCase("cancel")) {
throw new InstallationCancelledException("Cancelled by user.");
}
try {
opt.validateValue(value);
gotValidValue = true;
_map.put(optionId, value);
System.out.println();
} catch (OptionValidationException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
private String readLine() {
try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
} catch (Exception e) {
throw new RuntimeException("Error: Unable to read from STDIN");
}
}
/**
* Dump all options (including any defaults that were applied) to the given
* stream, in java properties file format. The output stream remains open
* after this method returns.
*/
public void dump(OutputStream out) throws IOException {
Properties props = new Properties();
Iterator iter = _map.keySet().iterator();
while (iter.hasNext()) {
String key = iter.next();
props.setProperty(key, getValue(key));
}
props.store(out, "Install Options");
}
/**
* Get the value of the given option, or null
if it doesn't
* exist.
*/
public String getValue(String name) {
return System.getProperty(name, _map.get(name));
}
public String getValue(String name, String defaultVal) {
String value = getValue(name);
if (value == null) {
return defaultVal;
} else {
return value;
}
}
/**
* Get the value of the given option as an integer, or the given default
* value if unspecified.
*
* @throws NumberFormatException
* if the value is specified, but cannot be parsed as an integer.
*/
public int getIntValue(String name, int defaultValue)
throws NumberFormatException {
String value = getValue(name);
if (value == null) {
return defaultValue;
} else {
return Integer.parseInt(value);
}
}
/**
* Get the value of the given option as a boolean, or the given default
* value if unspecified. If specified, the value is assumed to be
* true
if given as "true", regardless of case. All other
* values are assumed to be false
.
*/
public boolean getBooleanValue(String name, boolean defaultValue) {
String value = getValue(name);
if (value == null) {
return defaultValue;
} else {
return value.equals("true");
}
}
/**
* Get an iterator of the names of all specified options.
*/
public Collection getOptionNames() {
return _map.keySet();
}
/**
* Apply defaults to the options, where possible.
*/
private void applyDefaults() {
for (String name : getOptionNames()) {
String val = _map.get(name);
if (val == null || val.length() == 0) {
OptionDefinition opt = OptionDefinition.get(name, this);
_map.put(name, opt.getDefaultValue());
}
}
}
/**
* Validate the options, assuming defaults have already been applied.
* Validation for a given option might entail more than a syntax check. It
* might check whether a given directory exists, for example.
*
*/
private void validateAll() throws OptionValidationException {
boolean unattended = getBooleanValue(UNATTENDED, false);
for (String optionId : getOptionNames()) {
OptionDefinition opt = OptionDefinition.get(optionId, this);
if (opt == null) {
throw new OptionValidationException("Option is not defined", optionId);
}
opt.validateValue(getValue(optionId), unattended);
}
}
private boolean validateDatabaseConnection() {
String database = getValue(DATABASE);
if (database.equals(InstallOptions.INCLUDED)) {
return true;
}
Database db = new Database(_dist, this);
try {
// validate the user input by attempting a database connection
System.out.print("Validating database connection...");
db.test();
// check if we need to update old table
if (db.usesDOTable()) {
inputOption(DATABASE_UPDATE);
}
db.close();
System.out.println("OK\n");
return true;
} catch (Exception e) {
System.out.println("FAILED\n");
e.printStackTrace();
System.out.println(e.getClass().getName() + ": " + e.getMessage() + "\n");
System.out.println("ERROR validating database connection; see above.\n");
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy