NIHVIVO-1261 Remove the old ConfigurationProperties class and test.
This commit is contained in:
parent
5fa2864fbe
commit
6b3b426667
2 changed files with 0 additions and 397 deletions
|
@ -1,218 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp;
|
||||
|
||||
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;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Loads the configuration properties from a properties file. The path to the
|
||||
* file is specified an an Environment name in the Context, like this:
|
||||
*
|
||||
* <pre>
|
||||
* <Context override="true">
|
||||
* <Environment name="path.configuration"
|
||||
* value="/wherever/the/file/lives/deploy.properties"
|
||||
* type="java.lang.String"
|
||||
* override="false" />
|
||||
* </Context>
|
||||
* </pre>
|
||||
*
|
||||
* This initializer will look for a file at this path. If it does not find one,
|
||||
* it will look for a resource at this path. So, one might reasonable set this
|
||||
* to a value like <code>/usr/local/vitro/stuff/deploy.properties</code> for a
|
||||
* file, or like <code>deploy.properties</code> for a resource in the classpath.
|
||||
*
|
||||
* When the properties file is loaded, the values are trimmed to remove leading
|
||||
* or trailing white space, since such white space is almost always an error.
|
||||
*
|
||||
* @author jeb228
|
||||
*/
|
||||
public class ConfigurationProperties {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(ConfigurationProperties.class);
|
||||
|
||||
/**
|
||||
* If we don't find the path to the config properties from a JNDI mapping,
|
||||
* use this. Not final, so we can jigger it for unit tests.
|
||||
*/
|
||||
private static String DEFAULT_CONFIG_PATH = "deploy.properties";
|
||||
|
||||
/**
|
||||
* The JNDI naming context where Tomcat stores environment attributes.
|
||||
*/
|
||||
static final String JNDI_BASE = "java:comp/env";
|
||||
|
||||
/**
|
||||
* The name of the JNDI environment mapping for the path to the
|
||||
* configuration file (or resource).
|
||||
*/
|
||||
static final String PATH_CONFIGURATION = "path.configuration";
|
||||
|
||||
/**
|
||||
* The map of the configuration properties.
|
||||
*
|
||||
* This should not be accessed directly, but only through the synchronized
|
||||
* method {@link #getTheMap() (and {@link #reset()} for unit tests).
|
||||
*/
|
||||
private static volatile Map<String, String> theMap;
|
||||
|
||||
/**
|
||||
* Get an unmodifiable copy of the map of configuration properties.
|
||||
*/
|
||||
public static Map<String, String> getMap() {
|
||||
return getTheMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified property, or <code>null</code> if the
|
||||
* property has not been assigned a value.
|
||||
*/
|
||||
public static String getProperty(String key) {
|
||||
return getTheMap().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified property, or use the default value if the
|
||||
* property has not been assigned a value.
|
||||
*/
|
||||
public static String getProperty(String key, String defaultValue) {
|
||||
String value = getTheMap().get(key);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the map to be reloaded on the next attempt to access it.
|
||||
*
|
||||
* This and {@link #getTheMap()} should be the only access to
|
||||
* {@link ConfigurationProperties#theMap}.
|
||||
*
|
||||
* NOTE: This should only be used in Unit Tests.
|
||||
*/
|
||||
static synchronized void reset() {
|
||||
theMap = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This and {@link #reset()} should be the only access to {@link #theMap}.
|
||||
*/
|
||||
private static synchronized Map<String, String> getTheMap() {
|
||||
if (theMap == null) {
|
||||
theMap = loadTheMap();
|
||||
}
|
||||
return theMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* The map is null, so find the properties file and load the map.
|
||||
*/
|
||||
private static synchronized Map<String, String> loadTheMap() {
|
||||
String configPath = getConfigurationFilePath();
|
||||
|
||||
InputStream inStream = getConfigurationInputStream(configPath);
|
||||
|
||||
// Load a properties object - it will parse the file easily.
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
props.load(inStream);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Problem while reading the "
|
||||
+ "configuration properties file at '" + configPath + "'",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
inStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to close input stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
// It's awkward to copy from Properties to a Map.
|
||||
Map<String, String> newMap = new HashMap<String, String>();
|
||||
for (Enumeration<?> keys = props.keys(); keys.hasMoreElements();) {
|
||||
String key = (String) keys.nextElement();
|
||||
String value = props.getProperty(key);
|
||||
// While we're copying, remove leading and trailing white space.
|
||||
String trimmed = value.trim();
|
||||
newMap.put(key, trimmed);
|
||||
}
|
||||
|
||||
log.info("Configuration properties are: " + newMap);
|
||||
|
||||
// Save an unmodifiable version of the Map
|
||||
return Collections.unmodifiableMap(newMap);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the path to the Configuration properties file. If we can't find it
|
||||
* by the JNDI mapping, use the default path.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* If we can't find the path.
|
||||
*/
|
||||
private static String getConfigurationFilePath() {
|
||||
try {
|
||||
Context envCtx = (Context) new InitialContext().lookup(JNDI_BASE);
|
||||
if (envCtx == null) {
|
||||
log.warn("JNDI Lookup on \"" + JNDI_BASE
|
||||
+ "\" failed. Is the context file missing?");
|
||||
return DEFAULT_CONFIG_PATH;
|
||||
}
|
||||
|
||||
// Get the name of the configuration properties file.
|
||||
String configPath = (String) envCtx.lookup(PATH_CONFIGURATION);
|
||||
if (configPath == null) {
|
||||
log.warn("Could not find a JNDI Environment naming for '"
|
||||
+ PATH_CONFIGURATION
|
||||
+ "'. Is the context file set up correctly?");
|
||||
return DEFAULT_CONFIG_PATH;
|
||||
}
|
||||
|
||||
log.info("deploy.property as specified by JNDI: " + configPath);
|
||||
return configPath;
|
||||
} catch (NamingException e) {
|
||||
log.warn("JNDI lookup failed. "
|
||||
+ "Using default path for config properties.", e);
|
||||
return DEFAULT_CONFIG_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the Configuration properties file.
|
||||
*
|
||||
* Interpret the path as a resource path (relative to WEB-INF/classes).
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the path fails to locate a file or a resource.
|
||||
*/
|
||||
private static InputStream getConfigurationInputStream(String configPath) {
|
||||
InputStream inStream = ConfigurationProperties.class.getClassLoader()
|
||||
.getResourceAsStream(configPath);
|
||||
|
||||
if (inStream != null) {
|
||||
return inStream;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"Failed to find a configuration properties resource at '"
|
||||
+ configPath + "'");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.javax.naming.InitialContextStub;
|
||||
import stubs.javax.naming.spi.InitialContextFactoryStub;
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeb228
|
||||
*/
|
||||
public class ConfigurationPropertiesTest extends AbstractTestClass {
|
||||
|
||||
/**
|
||||
* The JNDI Mapping for the configuration properties path.
|
||||
*/
|
||||
private static final String CONFIGURATION_PROPERTIES_MAPPING = ConfigurationProperties.JNDI_BASE
|
||||
+ "/" + ConfigurationProperties.PATH_CONFIGURATION;
|
||||
|
||||
private static final String NOT_THE_DESIRED_MAPPING = ConfigurationProperties.JNDI_BASE
|
||||
+ "/notTheDesiredMapping";
|
||||
|
||||
/**
|
||||
* The resource property files that we might configure.
|
||||
*/
|
||||
private static final String CONFIGURED_PROPERTY_FILE = "edu/cornell/mannlib/vitro/webapp/test_config.properties";
|
||||
private static final String INVALID_PROPERTY_FILE = "edu/cornell/mannlib/vitro/webapp/test_config_invalid.properties";
|
||||
private static final String DEFAULT_PROPERTY_FILE = "edu/cornell/mannlib/vitro/webapp/test_config_default.properties";
|
||||
|
||||
/**
|
||||
* The mappings that we might find from the property files.
|
||||
*/
|
||||
private static final String[][] MAP_VALUES_DEFAULT = new String[][] { {
|
||||
"whichfile", "test_config_default" }, {"trimmed", "whitespace_test"} };
|
||||
private static final String[][] MAP_VALUES_CONFIGURED = new String[][] { {
|
||||
"whichfile", "test_config" } };
|
||||
|
||||
/**
|
||||
* A context to hold the JNDI mappings.
|
||||
*/
|
||||
private InitialContext initial;
|
||||
|
||||
/**
|
||||
* The original default value for the configuration properties path.
|
||||
*/
|
||||
private static Object originalPath;
|
||||
|
||||
@BeforeClass
|
||||
public static void alterTheDefaultPath() throws SecurityException,
|
||||
NoSuchFieldException, IllegalArgumentException,
|
||||
IllegalAccessException {
|
||||
Class<ConfigurationProperties> clazz = ConfigurationProperties.class;
|
||||
Field field = clazz.getDeclaredField("DEFAULT_CONFIG_PATH");
|
||||
field.setAccessible(true);
|
||||
originalPath = field.get(null);
|
||||
field.set(null, DEFAULT_PROPERTY_FILE);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void restoreTheDefaultPath() throws SecurityException,
|
||||
NoSuchFieldException, IllegalArgumentException,
|
||||
IllegalAccessException {
|
||||
Class<ConfigurationProperties> clazz = ConfigurationProperties.class;
|
||||
Field field = clazz.getDeclaredField("DEFAULT_CONFIG_PATH");
|
||||
field.setAccessible(true);
|
||||
field.set(null, originalPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* I don't want to see the INFO messages while running the tests.
|
||||
*/
|
||||
@Before
|
||||
public void setLogging() {
|
||||
setLoggerLevel(ConfigurationProperties.class, Level.WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the context stub, and be sure that it is clean for each test.
|
||||
*/
|
||||
@Before
|
||||
public void initializeContextStubs() throws NamingException {
|
||||
System.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY,
|
||||
InitialContextFactoryStub.class.getName());
|
||||
InitialContextStub.reset();
|
||||
initial = new InitialContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties} is a singleton, so we need to clean it
|
||||
* before each test.
|
||||
*/
|
||||
@Before
|
||||
public void resetProperties() {
|
||||
ConfigurationProperties.reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// the tests
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void topLevelContextIsMissing() {
|
||||
setLoggerLevel(ConfigurationProperties.class, Level.ERROR);
|
||||
ConfigurationProperties.getMap();
|
||||
assertExpectedMap(MAP_VALUES_DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noEnvironmentMapping() throws NamingException {
|
||||
setLoggerLevel(ConfigurationProperties.class, Level.ERROR);
|
||||
// We map something in the same JNDI environment,
|
||||
// but not the mapping we will be looking for.
|
||||
initial.bind(NOT_THE_DESIRED_MAPPING, "doesn't matter");
|
||||
ConfigurationProperties.getMap();
|
||||
assertExpectedMap(MAP_VALUES_DEFAULT);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void fileNotFound() throws NamingException {
|
||||
initial.bind(CONFIGURATION_PROPERTIES_MAPPING, "noSuchResource");
|
||||
ConfigurationProperties.getMap();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invalidFileFormat() throws NamingException {
|
||||
initial.bind(CONFIGURATION_PROPERTIES_MAPPING, INVALID_PROPERTY_FILE);
|
||||
ConfigurationProperties.getMap();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readFromConfiguredResource() throws NamingException {
|
||||
initial.bind(CONFIGURATION_PROPERTIES_MAPPING, CONFIGURED_PROPERTY_FILE);
|
||||
assertExpectedMap(MAP_VALUES_CONFIGURED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkOtherMethods() throws NamingException {
|
||||
initial.bind(CONFIGURATION_PROPERTIES_MAPPING, CONFIGURED_PROPERTY_FILE);
|
||||
assertEquals("test_config",
|
||||
ConfigurationProperties.getProperty("whichfile"));
|
||||
assertEquals(null, ConfigurationProperties.getProperty("notThere"));
|
||||
assertEquals("default",
|
||||
ConfigurationProperties.getProperty("notThere", "default"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Does the configuration properties map look like this group of key/value
|
||||
* pairs?
|
||||
*/
|
||||
private void assertExpectedMap(String[][] strings) {
|
||||
Map<String, String> expected = new HashMap<String, String>();
|
||||
for (String[] pair : strings) {
|
||||
expected.put(pair[0], pair[1]);
|
||||
}
|
||||
assertEquals("properties map", expected,
|
||||
ConfigurationProperties.getMap());
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue