VIVO-364 Include build.properties in ConfigurationProperties

The language-setup smoke tests assumed that we had access to build.properties.
This commit is contained in:
j2blake 2013-10-16 17:21:41 -04:00
parent 63d9466674
commit 9f928d930f
3 changed files with 69 additions and 62 deletions

View file

@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.config;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@ -18,7 +17,8 @@ import org.apache.commons.logging.LogFactory;
* The basic implementation of ConfigurationProperties. It loads the
* configuration properties from a properties file and stores them in a map. It
* also permits the caller to supply a map of "preemptive" properties that will
* be included and will override any matching properties from the file.
* be included and will override any matching properties from the file, and a
* map of "build" properties that may be overridden by the file.
*
* Leading and trailing white space are trimmed from the property values.
*
@ -31,9 +31,14 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
private final Map<String, String> propertyMap;
public ConfigurationPropertiesImpl(InputStream stream,
Map<String, String> preemptiveProperties) throws IOException {
Map<String, String> preemptiveProperties,
Map<String, String> buildProperties) throws IOException {
Map<String, String> map = new HashMap<>(buildProperties);
Properties props = loadFromPropertiesFile(stream);
Map<String, String> map = copyPropertiesToMap(props);
for (String key: props.stringPropertyNames()) {
map.put(key, props.getProperty(key));
}
if (preemptiveProperties != null) {
map.putAll(preemptiveProperties);
@ -52,16 +57,6 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
return props;
}
private Map<String, String> copyPropertiesToMap(Properties props) {
Map<String, String> map = new HashMap<String, String>();
for (Enumeration<?> keys = props.keys(); keys.hasMoreElements();) {
String key = (String) keys.nextElement();
String value = props.getProperty(key);
map.put(key, value);
}
return map;
}
private void trimWhiteSpaceFromValues(Map<String, String> map) {
for (String key : map.keySet()) {
map.put(key, map.get(key).trim());

View file

@ -29,20 +29,20 @@ import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
* This must be invoked before any listener that requires configuration
* properties.
*
* The properties file must be called 'runtime.properties' in the Vitro home
* directory. The path to the Vitro home directory can be specifed by an JNDI
* value, or by a System property, or by a property in
* WEB-INF/resources/build.properties, in that order. If the Vitro home
* directory is specified in more than one way, a warning is issued and the
* first value is used.
* The properties are determined from a file called 'build.properties' in the
* resources directory of the webapp, and a file called 'runtime.properties' in
* the Vitro home directory. In case of conflict, runtime.properties wins.
*
* If the Vitro home directory cannot be located, or if it does not contain a
* file called 'runtime.properties', or if the file cannot be loaded, a fatal
* error is registered to abort the startup.
* The path to the Vitro home directory can be specifed by an JNDI value, or by
* a System property, or by a property in build.properties, in that order. If
* the Vitro home directory is specified in more than one way, a warning is
* issued and the first value is used.
*
* The ConfigurationProperties bean is created from the key/value pairs found in
* 'runtime.properties', and is stored in the servlet context. The value that
* was determined for 'vitro.home' is also included in the bean.
* The value that was determined for 'vitro.home' is also included in the
* ConfigurationProperties bean.
*
* If build.properties or runtime.properties cannot be located or loaded, a
* fatal error is registered to abort the startup.
*/
public class ConfigurationPropertiesSetup implements ServletContextListener {
private static final Log log = LogFactory
@ -63,6 +63,9 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
/** Name of the file that contains runtime properties. */
private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties";
/** Path to the file of build properties baked into the webapp. */
private static final String PATH_BUILD_PROPERTIES = "/WEB-INF/resources/build.properties";
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
@ -79,8 +82,9 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
Map<String, String> preempts = createPreemptiveProperties(
VHD_CONFIGURATION_PROPERTY, vitroHomeDir);
ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl(
stream, preempts);
stream, preempts, getBuildProperties(ctx));
ConfigurationProperties.setBean(ctx, bean);
ss.info(this, "Loaded " + bean.getPropertyMap().size()
@ -94,8 +98,6 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
}
}
}
} catch (IllegalStateException e) {
ss.fatal(this, e.getMessage(), e);
} catch (Exception e) {
ss.fatal(this, e.getMessage(), e);
}
@ -196,42 +198,44 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
private void getVhdFromBuildProperties(ServletContext ctx,
Map<String, String> whereWasIt) {
String resourcePath = "/WEB-INF/resources/build.properties";
Map<String, String> buildProps = getBuildProperties(ctx);
String vhdPath = buildProps.get(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("'" + PATH_BUILD_PROPERTIES
+ "' didn't contain a value for '" + VHD_BUILD_PROPERTY
+ "'.");
return;
}
InputStream stream = null;
try {
stream = ctx.getResourceAsStream(resourcePath);
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.",
PATH_BUILD_PROPERTIES, VHD_BUILD_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
}
private Map<String, String> getBuildProperties(ServletContext ctx) {
Map<String, String> map = new HashMap<>();
try (InputStream stream = ctx
.getResourceAsStream(PATH_BUILD_PROPERTIES)) {
if (stream == null) {
log.debug("Didn't find a resource at '" + resourcePath + "'.");
return;
}
log.debug("Didn't find a resource at '" + PATH_BUILD_PROPERTIES
+ "'.");
} else {
Properties props = new Properties();
props.load(stream);
String vhdPath = props.getProperty(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("'" + resourcePath + "' didn't contain a value for '"
+ VHD_BUILD_PROPERTY + "'.");
return;
}
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.", resourcePath,
VHD_BUILD_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
} catch (IOException e) {
log.warn("Failed to load from '" + resourcePath + "'.", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
Properties props = new Properties();
props.load(stream);
for (String key : props.stringPropertyNames()) {
map.put(key, props.getProperty(key));
}
}
} catch (IOException e) {
throw new SetupException("Failed to load from '"
+ PATH_BUILD_PROPERTIES + "'.", e);
}
return map;
}
private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) {
@ -266,4 +270,12 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
ConfigurationProperties.removeBean(sce.getServletContext());
}
/**
* Indicates a problem setting up. Abandon ship.
*/
private static class SetupException extends RuntimeException {
public SetupException(String message, Throwable cause) {
super(message, cause);
}
}
}

View file

@ -298,13 +298,13 @@ public class ConfigurationPropertiesSmokeTests implements
*/
private void checkLanguages(ConfigurationProperties props, StartupStatus ss) {
String buildString = props.getProperty(PROPERTY_LANGUAGE_BUILD);
boolean buildWithLanguages = StringUtils.isNotEmpty(buildString);
boolean buildWithLanguages = StringUtils.isNotBlank(buildString);
String selectString = props.getProperty(PROPERTY_LANGUAGE_SELECTABLE);
boolean selectableLanguages = StringUtils.isNotEmpty(selectString);
boolean selectableLanguages = StringUtils.isNotBlank(selectString);
String forceString = props.getProperty(PROPERTY_LANGUAGE_FORCE);
boolean forceLanguage = StringUtils.isNotEmpty(forceString);
boolean forceLanguage = StringUtils.isNotBlank(forceString);
String filterString = props.getProperty(PROPERTY_LANGUAGE_FILTER,
"true");