This reverts commit e4e0a7d061
.
This commit is contained in:
parent
e4e0a7d061
commit
eb61192d11
12 changed files with 409 additions and 135 deletions
|
@ -24,6 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel
|
|||
*/
|
||||
public class ApplicationSetup implements ServletContextListener {
|
||||
private static final String APPLICATION_SETUP_PATH = "config/applicationSetup.n3";
|
||||
private static final String APPLICATION_SETUP_DEFAULT_PATH = "config/default.applicationSetup.n3";
|
||||
|
||||
private ServletContext ctx;
|
||||
private StartupStatus ss;
|
||||
|
@ -45,6 +46,8 @@ public class ApplicationSetup implements ServletContextListener {
|
|||
this.vitroHomeDir = VitroHomeDirectory.find(ctx);
|
||||
ss.info(this, vitroHomeDir.getDiscoveryMessage());
|
||||
|
||||
this.vitroHomeDir.populate();
|
||||
|
||||
locateApplicationConfigFile();
|
||||
loadApplicationConfigFile();
|
||||
createConfigurationBeanLoader();
|
||||
|
@ -63,11 +66,19 @@ public class ApplicationSetup implements ServletContextListener {
|
|||
private void locateApplicationConfigFile() {
|
||||
Path path = this.vitroHomeDir.getPath().resolve(APPLICATION_SETUP_PATH);
|
||||
|
||||
if (!Files.exists(path) || !Files.isReadable(path)) {
|
||||
path = this.vitroHomeDir.getPath().resolve(APPLICATION_SETUP_DEFAULT_PATH);
|
||||
}
|
||||
|
||||
if (!Files.exists(path)) {
|
||||
throw new IllegalStateException("'" + path + "' does not exist.");
|
||||
throw new IllegalStateException("Neither '" + APPLICATION_SETUP_PATH + "' nor '" +
|
||||
APPLICATION_SETUP_DEFAULT_PATH + "' were found in " +
|
||||
this.vitroHomeDir.getPath());
|
||||
}
|
||||
if (!Files.isReadable(path)) {
|
||||
throw new IllegalStateException("Can't read '" + path + "'");
|
||||
throw new IllegalStateException("No readable '" + APPLICATION_SETUP_PATH + "' nor '" +
|
||||
APPLICATION_SETUP_DEFAULT_PATH + "' files were found in " +
|
||||
this.vitroHomeDir.getPath());
|
||||
}
|
||||
this.configFile = path;
|
||||
}
|
||||
|
|
|
@ -4,25 +4,46 @@ package edu.cornell.mannlib.vitro.webapp.application;
|
|||
|
||||
import static edu.cornell.mannlib.vitro.webapp.application.BuildProperties.WEBAPP_PATH_BUILD_PROPERTIES;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ContextProperties;
|
||||
|
||||
/**
|
||||
* Encapsulates some of the info relating to the Vitro home directory.
|
||||
* Encapsulates some of the info relating to and initializes the Vitro home directory.
|
||||
*/
|
||||
public class VitroHomeDirectory {
|
||||
private static final Log log = LogFactory.getLog(VitroHomeDirectory.class);
|
||||
|
||||
private static final String DIGEST_FILE_NAME = "digest.md5";
|
||||
|
||||
private static final Pattern CHECKSUM_PATTERN = Pattern.compile("^[a-f0-9]{32} \\*.+$");
|
||||
|
||||
public static VitroHomeDirectory find(ServletContext ctx) {
|
||||
HomeDirectoryFinder finder = new HomeDirectoryFinder(ctx);
|
||||
return new VitroHomeDirectory(ctx, finder.getPath(),
|
||||
|
@ -52,6 +73,219 @@ public class VitroHomeDirectory {
|
|||
return discoveryMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates VIVO home directory with files required to run.
|
||||
*
|
||||
* NOTE: Will not overwrite any modified files on redeploy.
|
||||
*/
|
||||
public void populate() {
|
||||
File vhdDir = getPath().toFile();
|
||||
|
||||
if (!vhdDir.isDirectory() || vhdDir.list() == null) {
|
||||
throw new RuntimeException("Application home dir is not a directory! " + vhdDir);
|
||||
}
|
||||
|
||||
Map<String, String> digest = untar(vhdDir);
|
||||
|
||||
writeDigest(digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-destructive untar process that returns checksum digest of tarred files.
|
||||
*
|
||||
* Checksum digest can be manually created with the following command.
|
||||
*
|
||||
* `find /vivo/home -type f | cut -c3- | grep -E '^bin/|^config/|^rdf/' | xargs md5sum > /vivo/home/digest.md5`
|
||||
*
|
||||
* @param destination VIVO home directory
|
||||
* @return digest of each files checksum
|
||||
*/
|
||||
private Map<String, String> untar(File destination) {
|
||||
log.info("Syncing VIVO home at: " + destination.getPath());
|
||||
|
||||
Map<String, String> digest = new HashMap<>();
|
||||
Map<String, String> storedDigest = loadDigest();
|
||||
|
||||
TarArchiveEntry tarEntry;
|
||||
try (
|
||||
InputStream homeDirTar = getHomeDirTar();
|
||||
TarArchiveInputStream tarInput = new TarArchiveInputStream(homeDirTar);
|
||||
) {
|
||||
while ((tarEntry = tarInput.getNextTarEntry()) != null) {
|
||||
|
||||
// Use the example configurations
|
||||
String outFilename = tarEntry.getName().replace("example.", "");
|
||||
File outFile = new File(destination, outFilename);
|
||||
|
||||
// Is the entry a directory?
|
||||
if (tarEntry.isDirectory()) {
|
||||
if (!outFile.exists()) {
|
||||
outFile.mkdirs();
|
||||
}
|
||||
} else {
|
||||
// Entry is a File
|
||||
boolean write = true;
|
||||
|
||||
// reading bytes into memory to avoid having to unreliably reset stream
|
||||
byte[] bytes = IOUtils.toByteArray(tarInput);
|
||||
String newFileChecksum = checksum(bytes);
|
||||
digest.put(outFilename, newFileChecksum);
|
||||
|
||||
// if file already exists and stored digest contains the file,
|
||||
// check to determine if it has changed
|
||||
if (outFile.exists() && storedDigest.containsKey(outFilename)) {
|
||||
String existingFileChecksum = checksum(outFile);
|
||||
// if file has not changed in home and is not the same as new file, overwrite
|
||||
write = storedDigest.get(outFilename).equals(existingFileChecksum)
|
||||
&& !existingFileChecksum.equals(newFileChecksum);
|
||||
}
|
||||
|
||||
if (write) {
|
||||
outFile.getParentFile().mkdirs();
|
||||
try (
|
||||
InputStream is = new ByteArrayInputStream(bytes);
|
||||
FileOutputStream fos = new FileOutputStream(outFile);
|
||||
) {
|
||||
IOUtils.copy(is, fos);
|
||||
log.info(outFile.getAbsolutePath() + " source has changed and has not been "
|
||||
+ "edited in home, updated file has been copied to home directory.");
|
||||
}
|
||||
} else {
|
||||
log.debug(outFile.getAbsolutePath() + " has been preserved.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("Error creating home directory!", e);
|
||||
}
|
||||
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load checksum digest of VIVO home directory.
|
||||
*
|
||||
* @return checksum digest
|
||||
*/
|
||||
private Map<String, String> loadDigest() {
|
||||
File storedDigest = new File(getPath().toFile(), DIGEST_FILE_NAME);
|
||||
if (storedDigest.exists() && storedDigest.isFile()) {
|
||||
log.info("Reading VIVO home digest: " + storedDigest.getPath());
|
||||
try {
|
||||
return FileUtils
|
||||
.readLines(storedDigest, StandardCharsets.UTF_8)
|
||||
.stream()
|
||||
.filter(CHECKSUM_PATTERN.asPredicate())
|
||||
.map(this::split)
|
||||
.collect(Collectors.toMap(this::checksumFile, this::checksumValue));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading VIVO home checksum digest!", e);
|
||||
}
|
||||
}
|
||||
log.info("VIVO home digest not found: " + storedDigest.getPath());
|
||||
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write VIVO home checksum digest following md5 format; `<checksum> *<file>`.
|
||||
*
|
||||
* @param digest checksum digest to write
|
||||
*/
|
||||
private void writeDigest(Map<String, String> digest) {
|
||||
File storedDigest = new File(getPath().toFile(), DIGEST_FILE_NAME);
|
||||
try (
|
||||
FileOutputStream fos = new FileOutputStream(storedDigest);
|
||||
OutputStreamWriter osw = new OutputStreamWriter(fos);
|
||||
) {
|
||||
for (Map.Entry<String, String> entry : digest.entrySet()) {
|
||||
String filename = entry.getKey();
|
||||
String checksum = entry.getValue();
|
||||
osw.write(String.format("%s *%s\n", checksum, filename));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error writing home directory checksum digest!", e);
|
||||
}
|
||||
log.info("VIVO home digest created: " + storedDigest.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Split checksum.
|
||||
*
|
||||
* @param checksum checksum delimited by space and asterisks `<checksum> *<file>`
|
||||
* @return split checksum
|
||||
*/
|
||||
private String[] split(String checksum) {
|
||||
return checksum.split("\\s+");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value from split checksum.
|
||||
*
|
||||
* @param checksum split checksum
|
||||
* @return checksum value
|
||||
*/
|
||||
private String checksumValue(String[] checksum) {
|
||||
return checksum[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file from split checksum.
|
||||
*
|
||||
* @param checksum split checksum
|
||||
* @return filename
|
||||
*/
|
||||
private String checksumFile(String[] checksum) {
|
||||
return checksum[1].substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get md5 checksum from file.
|
||||
*
|
||||
* @param file file
|
||||
* @return md5 checksum as string
|
||||
* @throws IOException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
private String checksum(File file) throws IOException, NoSuchAlgorithmException {
|
||||
return checksum(FileUtils.readFileToByteArray(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get md5 checksum from bytes.
|
||||
*
|
||||
* @param bytes bytes from file
|
||||
* @return md5 checksum as string
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
private String checksum(byte[] bytes) throws NoSuchAlgorithmException {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(bytes);
|
||||
// bytes to hex
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : md.digest()) {
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prepacked VIVO home tar file as input stream.
|
||||
*
|
||||
* @return input stream of VIVO home tar file
|
||||
*/
|
||||
private InputStream getHomeDirTar() {
|
||||
String tarLocation = "/WEB-INF/resources/home-files/vivo-home.tar";
|
||||
InputStream tar = ctx.getResourceAsStream(tarLocation);
|
||||
if (tar == null) {
|
||||
log.error("Application home tar not found in: " + tarLocation);
|
||||
throw new RuntimeException("Application home tar not found in: " + tarLocation);
|
||||
}
|
||||
|
||||
return tar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find something that specifies the location of the Vitro home directory.
|
||||
* Look in the JDNI environment, the system properties, and the
|
||||
|
@ -92,23 +326,12 @@ public class VitroHomeDirectory {
|
|||
}
|
||||
|
||||
public void getVhdFromJndi() {
|
||||
try {
|
||||
String vhdPath = (String) new InitialContext()
|
||||
.lookup(VHD_JNDI_PATH);
|
||||
if (vhdPath == null) {
|
||||
log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH
|
||||
+ "'.");
|
||||
} else {
|
||||
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: "
|
||||
+ vhdPath);
|
||||
String message = String.format(
|
||||
"JNDI environment '%s' was set to '%s'",
|
||||
VHD_JNDI_PATH, vhdPath);
|
||||
foundLocations.add(new Found(Paths.get(vhdPath), message));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("JNDI lookup failed. " + e);
|
||||
}
|
||||
String vhdPath = ContextProperties.findJndiProperty(VHD_JNDI_PATH);
|
||||
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: " + vhdPath);
|
||||
String message = String.format(
|
||||
"JNDI environment '%s' was set to '%s'",
|
||||
VHD_JNDI_PATH, vhdPath);
|
||||
foundLocations.add(new Found(Paths.get(vhdPath), message));
|
||||
}
|
||||
|
||||
private void getVhdFromSystemProperties() {
|
||||
|
|
|
@ -32,8 +32,10 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
|
|||
|
||||
public ConfigurationPropertiesImpl(InputStream stream,
|
||||
Map<String, String> preemptiveProperties,
|
||||
Map<String, String> buildProperties) throws IOException {
|
||||
Map<String, String> buildProperties,
|
||||
Map<String, String> contextProperties) throws IOException {
|
||||
Map<String, String> map = new HashMap<>(buildProperties);
|
||||
map.putAll(contextProperties);
|
||||
|
||||
Properties props = loadFromPropertiesFile(stream);
|
||||
for (String key: props.stringPropertyNames()) {
|
||||
|
|
|
@ -49,12 +49,12 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
|
|||
/** Name of the file that contains runtime properties. */
|
||||
private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties";
|
||||
|
||||
/** Fall-back name of the file that contains runtime properties. */
|
||||
private static final String FILE_DEFAULT_RUNTIME_PROPERTIES = "default.runtime.properties";
|
||||
|
||||
/** Configuration property to store the Vitro home directory */
|
||||
private static final String VHD_CONFIGURATION_PROPERTY = "vitro.home";
|
||||
|
||||
/** Configuration property used to determine if there are runtime.properties files in multiple locations **/
|
||||
static final String RP_MULTIPLE = "rp.multiple";
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
|
@ -69,18 +69,17 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
|
|||
File vitroHomeDirConfig = new File(vitroHomeDir.getPath()
|
||||
.concat(File.separator).concat("config"));
|
||||
|
||||
String rpfLocation = findMultipleRuntimePropertiesFiles(
|
||||
vitroHomeDir, vitroHomeDirConfig);
|
||||
|
||||
File runtimePropertiesFile = locateRuntimePropertiesFile(
|
||||
vitroHomeDir, vitroHomeDirConfig, ss);
|
||||
vitroHomeDirConfig, ss);
|
||||
stream = new FileInputStream(runtimePropertiesFile);
|
||||
|
||||
Map<String, String> preempts = createPreemptiveProperties(
|
||||
VHD_CONFIGURATION_PROPERTY, vitroHomeDir, RP_MULTIPLE, rpfLocation);
|
||||
VHD_CONFIGURATION_PROPERTY, vitroHomeDir);
|
||||
|
||||
ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl(
|
||||
stream, preempts, new BuildProperties(ctx).getMap());
|
||||
stream, preempts,
|
||||
new BuildProperties(ctx).getMap(),
|
||||
new ContextProperties().getMap());
|
||||
|
||||
ConfigurationProperties.setBean(ctx, bean);
|
||||
ss.info(this, "Loaded " + bean.getPropertyMap().size()
|
||||
|
@ -99,53 +98,36 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
|
|||
}
|
||||
}
|
||||
|
||||
private String findMultipleRuntimePropertiesFiles(File vitroHomeDir,
|
||||
File vitroHomeDirConfig) {
|
||||
private File locateRuntimePropertiesFile(File vitroHomeDirConfig, StartupStatus ss) {
|
||||
|
||||
File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES);
|
||||
File rpfc = new File(vitroHomeDirConfig, FILE_RUNTIME_PROPERTIES);
|
||||
// First look for the user-customized runtime.properties
|
||||
File rpf = new File(vitroHomeDirConfig, FILE_RUNTIME_PROPERTIES);
|
||||
|
||||
if (rpf.exists() && !rpfc.exists()) {
|
||||
return "home";
|
||||
} else if (rpf.exists() && rpfc.exists()) {
|
||||
return "both";
|
||||
} else if (rpfc.exists()) {
|
||||
return "config";
|
||||
} else {
|
||||
throw new IllegalStateException("Did not find '"
|
||||
+ FILE_RUNTIME_PROPERTIES + "' in vitro home directory '"
|
||||
+ vitroHomeDir + "' or config directory '" + vitroHomeDirConfig + "'");
|
||||
}
|
||||
}
|
||||
// Have we found a suitable runtime.properties file?
|
||||
if (!rpf.exists() || !rpf.isFile() || !rpf.canRead()) {
|
||||
|
||||
private File locateRuntimePropertiesFile(File vitroHomeDir,
|
||||
File vitroHomeDirConfig, StartupStatus ss) {
|
||||
|
||||
File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES);
|
||||
File rpfc = new File(vitroHomeDirConfig, FILE_RUNTIME_PROPERTIES);
|
||||
|
||||
if (!rpf.exists()) {
|
||||
rpf = rpfc;
|
||||
// If not... look for the default runtime.properties
|
||||
rpf = new File(vitroHomeDirConfig, FILE_DEFAULT_RUNTIME_PROPERTIES);
|
||||
}
|
||||
|
||||
if (!rpf.isFile()) {
|
||||
throw new IllegalStateException("'" + rpf.getPath()
|
||||
+ "' is not a file.");
|
||||
if (!rpf.exists() || !rpf.isFile()) {
|
||||
throw new IllegalStateException("Neither '" + FILE_RUNTIME_PROPERTIES + "' nor '" +
|
||||
FILE_DEFAULT_RUNTIME_PROPERTIES + "' were found in " +
|
||||
vitroHomeDirConfig.getAbsolutePath());
|
||||
}
|
||||
if (!rpf.canRead()) {
|
||||
throw new IllegalStateException("Cannot read '" + rpf.getPath()
|
||||
+ "'.");
|
||||
throw new IllegalStateException("No readable '" + FILE_RUNTIME_PROPERTIES + "' nor '" +
|
||||
FILE_DEFAULT_RUNTIME_PROPERTIES + "' files were found in " +
|
||||
vitroHomeDirConfig.getAbsolutePath());
|
||||
}
|
||||
ss.info(this, "Loading runtime properties from '" + rpf.getPath() + "'");
|
||||
return rpf;
|
||||
}
|
||||
|
||||
private Map<String, String> createPreemptiveProperties(
|
||||
String propertyVitroHome, File vitroHomeDir, String propertyRpfMultiple,
|
||||
String rpfLocation) {
|
||||
String propertyVitroHome, File vitroHomeDir) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(propertyVitroHome, vitroHomeDir.getAbsolutePath());
|
||||
map.put(propertyRpfMultiple, rpfLocation);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ public class ConfigurationPropertiesSmokeTests implements
|
|||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
checkDefaultNamespace(ctx, props, ss);
|
||||
checkMultipleRPFs(ctx, props, ss);
|
||||
checkLanguages(ctx, props, ss);
|
||||
checkEncryptionParameters(props, ss);
|
||||
|
||||
|
@ -86,32 +85,6 @@ public class ConfigurationPropertiesSmokeTests implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn if runtime.properties exists in multiple locations
|
||||
* or is located vivo.home instead of vivo.home/config
|
||||
*/
|
||||
private void checkMultipleRPFs(ServletContext ctx,
|
||||
ConfigurationProperties props, StartupStatus ss) {
|
||||
String rpfStatus = props.getProperty(ConfigurationPropertiesSetup.RP_MULTIPLE);
|
||||
|
||||
if (rpfStatus.equals("both")) {
|
||||
ss.warning(this,
|
||||
"Deprecation warning: Files matching the name 'runtime.properties' "
|
||||
+ "were found in both vivo.home and vivo.home/config. Using "
|
||||
+ "the file in vivo.home. Future releases may require "
|
||||
+ "runtime.properties be placed in vivo.home/config.");
|
||||
}
|
||||
|
||||
if (rpfStatus.equals("home")) {
|
||||
ss.warning(this,
|
||||
"Deprecation warning: runtime.properties was found in the "
|
||||
+ "vivo.home directory. The recommended directory for "
|
||||
+ "runtime.properties is now vivo.home/config. Future releases "
|
||||
+ "may require runtime.properties be placed in "
|
||||
+ "vivo.home/config.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn if we set up the languages incorrectly:
|
||||
*
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Obtains and provides the properties from the web application's context.xml
|
||||
*
|
||||
* @author awoods
|
||||
* @since 2020-10-23
|
||||
*/
|
||||
public class ContextProperties {
|
||||
private static final Log log = LogFactory.getLog(ContextProperties.class);
|
||||
|
||||
private static final String DEFAULT_NAMESPACE_JNDI_PATH = "java:comp/env/vitro/defaultNamespace";
|
||||
private static final String ROOT_USER_ADDRESS_JNDI_PATH = "java:comp/env/vitro/rootUserAddress";
|
||||
private static final String APP_NAME_JNDI_PATH = "java:comp/env/vitro/appName";
|
||||
|
||||
private static final String DEFAULT_NAMESPACE_KEY = "Vitro.defaultNamespace";
|
||||
private static final String ROOT_USER_ADDRESS_KEY = "rootUser.emailAddress";
|
||||
private static final String APP_NAME_KEY = "app-name";
|
||||
|
||||
private final Map<String, String> propertyMap;
|
||||
|
||||
public ContextProperties() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
// Find default namespace
|
||||
map.put(DEFAULT_NAMESPACE_KEY, findJndiProperty(DEFAULT_NAMESPACE_JNDI_PATH));
|
||||
|
||||
// Find root user email address
|
||||
map.put(ROOT_USER_ADDRESS_KEY, findJndiProperty(ROOT_USER_ADDRESS_JNDI_PATH));
|
||||
|
||||
// Find application name
|
||||
map.put(APP_NAME_KEY, findJndiProperty(APP_NAME_JNDI_PATH));
|
||||
|
||||
propertyMap = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
public static String findJndiProperty(String jndiProperty) {
|
||||
try {
|
||||
return (String) new InitialContext().lookup(jndiProperty);
|
||||
|
||||
} catch (NamingException e) {
|
||||
log.error("Unable to find name in JNDI: " + jndiProperty, e);
|
||||
|
||||
StringBuilder msg = new StringBuilder("\n====================\n");
|
||||
msg.append("Error loading JNDI property: ");
|
||||
msg.append(jndiProperty);
|
||||
msg.append("\n");
|
||||
msg.append("\tAn application context XML file (named after deployed war file, e.g. vivo.xml) ");
|
||||
msg.append("must be placed in servlet container.\n");
|
||||
msg.append("\tFor Tomcat, see documentation for location of file: \n");
|
||||
msg.append("\t\thttps://tomcat.apache.org/tomcat-9.0-doc/config/context.html#Defining_a_context \n");
|
||||
msg.append("\tThe common location on the server is: $CATALINA_BASE/conf/[enginename]/[hostname]/ \n");
|
||||
msg.append("\t\te.g. /var/lib/tomcat9/conf/Catalina/localhost/vivo.xml\n");
|
||||
msg.append("\tAn example 'context.xml' file is in the META-INF directory of this project.\n");
|
||||
msg.append("====================\n");
|
||||
throw new RuntimeException(msg.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getMap() {
|
||||
return this.propertyMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -202,18 +202,23 @@ public class DeveloperSettings {
|
|||
File dsFile = homeDir.resolve("config/developer.properties")
|
||||
.toFile();
|
||||
|
||||
if (!dsFile.exists()) {
|
||||
dsFile = homeDir.resolve("config/default.developer.properties").toFile();
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(dsFile)) {
|
||||
Properties dsProps = new Properties();
|
||||
dsProps.load(reader);
|
||||
devSettings.updateFromProperties(dsProps);
|
||||
log.info(devSettings);
|
||||
ss.info(this, "Loaded the 'developer.properties' file: "
|
||||
ss.info(this, "Loaded the '" + dsFile.getName() + "' file: "
|
||||
+ devSettings);
|
||||
} catch (FileNotFoundException e) {
|
||||
ss.info(this, "'developer.properties' file does not exist.");
|
||||
ss.info(this, "Neither 'developer.properties' nor 'default.developer.properties' " +
|
||||
"files exist.");
|
||||
} catch (Exception e) {
|
||||
ss.warning(this,
|
||||
"Failed to load the 'developer.properties' file.", e);
|
||||
"Failed to load the '" + dsFile.getAbsolutePath() + "' file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,19 +9,6 @@
|
|||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# This namespace will be used when generating URIs for objects created in the
|
||||
# editor. In order to serve linked data, the default namespace must be composed
|
||||
# as follows (optional elements in parentheses):
|
||||
#
|
||||
# scheme + server_name (+ port) (+ servlet_context) + "/individual/"
|
||||
#
|
||||
# For example, Cornell's default namespace is:
|
||||
#
|
||||
# http://vivo.cornell.edu/individual/
|
||||
#
|
||||
Vitro.defaultNamespace = http://vivo.mydomain.edu/individual/
|
||||
|
||||
#
|
||||
# URL of Solr context used in local Vitro search. This will usually consist of:
|
||||
# scheme + server_name + port + vitro_webapp_name + "solr"
|
||||
|
@ -70,13 +57,6 @@ VitroConnection.DataSource.dbtype = MySQL
|
|||
VitroConnection.DataSource.driver = com.mysql.jdbc.Driver
|
||||
VitroConnection.DataSource.validationQuery = SELECT 1
|
||||
|
||||
#
|
||||
# The email address of the root user for the VIVO application. The password
|
||||
# for this user is initially set to "rootPassword", but you will be asked to
|
||||
# change the password the first time you log in.
|
||||
#
|
||||
rootUser.emailAddress = root@myDomain.com
|
||||
|
||||
#
|
||||
# Argon2 password hashing parameters for time, memory and parallelism required to
|
||||
# compute a hash.
|
|
@ -1,21 +0,0 @@
|
|||
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>defaults</id>
|
||||
<properties>
|
||||
<app-name>vitro</app-name>
|
||||
|
||||
<vitro-dir>/usr/local/vitro/home</vitro-dir>
|
||||
<tomcat-dir>/usr/local/tomcat</tomcat-dir>
|
||||
|
||||
<default-theme>vitro</default-theme>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<activeProfiles>
|
||||
<activeProfile>defaults</activeProfile>
|
||||
</activeProfiles>
|
||||
</settings>
|
|
@ -1,8 +1,51 @@
|
|||
<Context> <!-- useHttpOnly="false" -->
|
||||
|
||||
<!--
|
||||
# The 'home' property specifies the location of Vitro HOME.
|
||||
# The system user used to run the Vitro web application must have write access
|
||||
# to the parent directory of the directory defined in this property, if Vitro HOME
|
||||
# does not already exist.
|
||||
# If this directory already exists, the system user used to run the Vitro web application
|
||||
# must have write access to this directory.
|
||||
-->
|
||||
<Environment
|
||||
type="java.lang.String"
|
||||
name="vitro/home"
|
||||
value="${vitro-dir}" override="true"/>
|
||||
value="${vivo-dir}" override="true"/>
|
||||
|
||||
<!--
|
||||
# The name of the application (possibly not used).
|
||||
-->
|
||||
<Environment
|
||||
type="java.lang.String"
|
||||
name="vitro/appName"
|
||||
value="vivo" override="true"/>
|
||||
|
||||
<!--
|
||||
# The email address of the root user for the Vitro application. The password
|
||||
# for this user is initially set to "rootPassword", but you will be asked to
|
||||
# change the password the first time you log in.
|
||||
-->
|
||||
<Environment
|
||||
type="java.lang.String"
|
||||
name="vitro/rootUserAddress"
|
||||
value="vivo_root@mydomain.edu" override="true"/>
|
||||
|
||||
<!--
|
||||
# This namespace will be used when generating URIs for objects created in the
|
||||
# editor. In order to serve linked data, the default namespace must be composed
|
||||
# as follows (optional elements in parentheses):
|
||||
#
|
||||
# scheme + server_name (+ port) (+ servlet_context) + "/individual/"
|
||||
#
|
||||
# For example, Cornell's default namespace is:
|
||||
#
|
||||
# http://vivo.cornell.edu/individual/
|
||||
-->
|
||||
<Environment
|
||||
type="java.lang.String"
|
||||
name="vitro/defaultNamespace"
|
||||
value="http://vivo.mydomain.edu/individual/" override="true"/>
|
||||
|
||||
<!-- Disable persist sessions on shut down.-->
|
||||
<Manager pathname="" />
|
||||
|
|
Loading…
Add table
Reference in a new issue