diff --git a/opennms-base-assembly/src/main/filtered/etc/opennms.properties b/opennms-base-assembly/src/main/filtered/etc/opennms.properties
index 5031f73..be41c26 100644
--- a/opennms-base-assembly/src/main/filtered/etc/opennms.properties
+++ b/opennms-base-assembly/src/main/filtered/etc/opennms.properties
@@ -116,6 +116,13 @@ rrd.binary=${install.rrdtool.bin}
# Collectd Instrumentation class
# org.opennms.collectd.instrumentationClass=org.opennms.netmgt.collectd.DefaultCollectInstrumentation
+# Enable an aggresive validation against the last modification time of the strings.properties files.
+# This is useful only if the OpenNMS WebUI is running on a different server.
+# Check NMS-5806 for more details.
+#
+# Default: false
+#org.opennms.utils.propertiesCache.enableCheckFileModified=false
+
###### REMOTE METHOD INVOCATION ######
# Though this is not strictly an OpenNMS property this is a setting that you
# may need to set if you are using the distributed monitor either via webstart
diff --git a/opennms-dao/src/test/java/org/opennms/netmgt/dao/support/ResourceTypeUtilsTest.java b/opennms-dao/src/test/java/org/opennms/netmgt/dao/support/ResourceTypeUtilsTest.java
index e344357..690c844 100644
--- a/opennms-dao/src/test/java/org/opennms/netmgt/dao/support/ResourceTypeUtilsTest.java
+++ b/opennms-dao/src/test/java/org/opennms/netmgt/dao/support/ResourceTypeUtilsTest.java
@@ -28,14 +28,23 @@
package org.opennms.netmgt.dao.support;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
-import junit.framework.TestCase;
-
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opennms.core.utils.PropertiesCache;
import org.opennms.netmgt.model.OnmsAttribute;
import org.opennms.netmgt.model.OnmsResource;
import org.opennms.netmgt.model.RrdGraphAttribute;
@@ -45,27 +54,26 @@ import org.opennms.test.ThrowableAnticipator;
/**
* @author DJ Gregor
*/
-public class ResourceTypeUtilsTest extends TestCase {
+public class ResourceTypeUtilsTest {
private FileAnticipator m_fileAnticipator;
private File m_snmp;
private File m_node;
private File m_intf;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
+ @Before
+ public void setUp() throws Exception {
m_fileAnticipator = new FileAnticipator();
RrdTestUtils.initializeNullStrategy();
}
- @Override
- protected void tearDown() {
+ @After
+ public void tearDown() throws Exception {
m_fileAnticipator.tearDown();
}
+ @Test
public void testLoadPropertiesNullRrdDirectory() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("rrdDirectory argument must not be null"));
@@ -78,6 +86,7 @@ public class ResourceTypeUtilsTest extends TestCase {
ta.verifyAnticipated();
}
+ @Test
public void testLoadPropertiesNullRelativePath() {
ThrowableAnticipator ta = new ThrowableAnticipator();
ta.anticipate(new IllegalArgumentException("relativePath argument must not be null"));
@@ -90,6 +99,7 @@ public class ResourceTypeUtilsTest extends TestCase {
ta.verifyAnticipated();
}
+ @Test
public void testLoadPropertiesEmpty() throws Exception {
OnmsResource childResource = createResource();
createPropertiesFile(childResource, "", false);
@@ -100,6 +110,7 @@ public class ResourceTypeUtilsTest extends TestCase {
assertEquals("properties size", 0, p.size());
}
+ @Test
public void testLoadPropertiesNonEmpty() throws Exception {
OnmsResource childResource = createResource();
createPropertiesFile(childResource, "foo=bar", false);
@@ -112,6 +123,7 @@ public class ResourceTypeUtilsTest extends TestCase {
assertEquals("property 'foo' value", "bar", p.get("foo"));
}
+ @Test
public void testLoadPropertiesDoesNotExist() throws Exception {
OnmsResource childResource = createResource();
createPropertiesFile(childResource, "", true);
@@ -120,12 +132,41 @@ public class ResourceTypeUtilsTest extends TestCase {
assertNull("no properties file was created, so the properties object should be null", p);
}
+ @Test
public void testGetAttributesAtRelativePathWithBogusDirectory() {
File bogusRrdDirectory = new File("/foo/bogus/blam/cheese/this/really/should/never/exist");
assertFalse("bogus RRD directory " + bogusRrdDirectory + " should not exist", bogusRrdDirectory.exists());
ResourceTypeUtils.getAttributesAtRelativePath(bogusRrdDirectory, "also-should-never-exist");
}
+ /*
+ * This test is associated with issue NMS-5806:
+ * http://issues.opennms.org/browse/NMS-5806
+ */
+ @Test
+ public void testUpdateFileOutsideResourceTypeUtils() throws Exception {
+ System.setProperty(PropertiesCache.CHECK_LAST_MODIFY_STRING, "true");
+
+ // Be sure that the file doesn't exist.
+ File resourceDir = new File("target/");
+ File propertiesFile = new File(resourceDir, "strings.properties");
+ propertiesFile.delete();
+
+ // Creating a new strings.properties file and adding one value to it
+ ResourceTypeUtils.updateStringProperty(resourceDir, "2012", "year");
+ assertEquals("2012", ResourceTypeUtils.getStringProperty(resourceDir, "year"));
+ Thread.sleep(1000l); // Simulate a delay, to be sure that we are going to have a different lastModifyTime
+
+ // Externally updating the strings.proeprties file
+ Properties properties = new Properties();
+ properties.load(new FileInputStream(propertiesFile));
+ properties.setProperty("year", "2013");
+ properties.store(new FileWriter(propertiesFile), "Updated!");
+
+ // Verify that after the external update, we can get the updated value
+ assertEquals("2013", ResourceTypeUtils.getStringProperty(resourceDir, "year"));
+ }
+
private OnmsResource createResource() {
OnmsResource topResource = new OnmsResource("1", "Node One", new MockResourceType(), new HashSet(0));
diff --git a/opennms-util/src/main/java/org/opennms/core/utils/PropertiesCache.java b/opennms-util/src/main/java/org/opennms/core/utils/PropertiesCache.java
index 976e967..68c5883 100644
--- a/opennms-util/src/main/java/org/opennms/core/utils/PropertiesCache.java
+++ b/opennms-util/src/main/java/org/opennms/core/utils/PropertiesCache.java
@@ -48,12 +48,16 @@ import java.util.concurrent.locks.ReentrantLock;
* @version $Id: $
*/
public class PropertiesCache {
-
+
+ public static final String CHECK_LAST_MODIFY_STRING = "org.opennms.utils.propertiesCache.enableCheckFileModified";
+
private static class PropertiesHolder {
private Properties m_properties;
private final File m_file;
private final Lock lock = new ReentrantLock();
-
+ private long m_lastModify = 0;
+ private boolean m_checkLastModify = Boolean.getBoolean(CHECK_LAST_MODIFY_STRING);
+
PropertiesHolder(File file) {
m_file = file;
m_properties = null;
@@ -69,6 +73,9 @@ public class PropertiesCache {
in = new FileInputStream(m_file);
Properties prop = new Properties();
prop.load(in);
+ if (m_checkLastModify) {
+ m_lastModify = m_file.lastModified();
+ }
return prop;
} finally {
if (in != null) {
@@ -95,6 +102,10 @@ public class PropertiesCache {
try {
if (m_properties == null) {
readWithDefault(new Properties());
+ } else {
+ if (m_checkLastModify && m_file.canRead() && m_lastModify != m_file.lastModified()) {
+ m_properties = read();
+ }
}
return m_properties;
} finally {