Merge "Issue #1778 Watch for bandwidth configuration changes" into development

Former-commit-id: 13ce9b683d [formerly 11e7d3b511] [formerly 6a0a04a519 [formerly f33c6cbe9c63721ec62f57b3953abd48729c8674]]
Former-commit-id: 6a0a04a519
Former-commit-id: 4ec51a98d9
This commit is contained in:
Dustin Johnson 2013-03-12 12:15:50 -05:00 committed by Gerrit Code Review
commit f892ae71f7
18 changed files with 327 additions and 25 deletions

View file

@ -3,6 +3,5 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="unit-test"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,83 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util;
import java.io.File;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Implementation of {@link IFileModifiedWatcher} that watches the last modified
* time of the file. This class is not thread-safe. Intentionally
* package-private, only FileUtil should be constructing instances.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 12, 2013 1778 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
class FileLastModifiedTimeWatcher implements IFileModifiedWatcher {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(FileLastModifiedTimeWatcher.class);
private final File file;
private long configFileLastModified;
/**
* Constructor.
*
* @param file
* the file to watch
*/
FileLastModifiedTimeWatcher(File file) {
this.file = file;
this.configFileLastModified = file.lastModified();
}
@Override
public boolean hasBeenModified() {
final long currentConfigFileLastModified = file.lastModified();
final boolean fileModified = (currentConfigFileLastModified != configFileLastModified);
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
statusHandler
.debug(String
.format("last known last modified [%s], current last modified [%s], changed [%s]",
configFileLastModified,
currentConfigFileLastModified, fileModified));
}
if (fileModified) {
configFileLastModified = currentConfigFileLastModified;
}
return fileModified;
}
}

View file

@ -54,12 +54,14 @@ import java.util.zip.GZIPOutputStream;
* to create temporary directories and files.
* 02/15/2013 #1597 randerso Fixed error when copying empty files
* Feb 15, 2013 1638 mschenke Moved EOL field from edex.common Util
* Mar 11, 2013 1645 djohnson Added file modification watcher.
*
* </pre>
*
* @author njensen
*/
public class FileUtil {
/**
* Displayable string of valid filename characters
*/
@ -74,7 +76,7 @@ public class FileUtil {
* Easy reference to system-dependent end of line
*/
public static final String EOL = System.getProperty("line.separator");
/**
* Joins one or more path components into a single path string. Path
* components are separated by the operating system dependent
@ -858,4 +860,15 @@ public class FileUtil {
c.close();
}
}
/**
* Retrieve a file modification watcher.
*
* @param file
* the file to watch for modifications
* @return the watcher
*/
public static IFileModifiedWatcher getFileModifiedWatcher(File file) {
return new FileLastModifiedTimeWatcher(file);
}
}

View file

@ -0,0 +1,46 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util;
/**
* Interface for checking whether a file has been modified.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 12, 2013 1778 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
public interface IFileModifiedWatcher {
/**
* Checks whether the file has been modified.
*
* @return true if the file has been modified
*/
boolean hasBeenModified();
}

View file

@ -51,6 +51,8 @@ import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.ITimer;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.common.util.IFileModifiedWatcher;
import com.raytheon.uf.common.util.LogUtil;
import com.raytheon.uf.common.util.algorithm.AlgorithmUtil;
import com.raytheon.uf.common.util.algorithm.AlgorithmUtil.IBinarySearchResponse;
@ -103,6 +105,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthUtil;
* Feb 14, 2013 1596 djohnson Do not reschedule allocations when a subscription is removed.
* Feb 20, 2013 1543 djohnson Add try/catch blocks during the shutdown process.
* Feb 27, 2013 1644 djohnson Force sub-classes to provide an implementation for how to schedule SBN routed subscriptions.
* Mar 11, 2013 1645 djohnson Watch configuration file for changes.
* </pre>
*
* @author dhladky
@ -133,6 +136,20 @@ abstract class BandwidthManager extends
@VisibleForTesting
final RetrievalManager retrievalManager;
@VisibleForTesting
final Runnable watchForConfigFileChanges = new Runnable() {
private final IFileModifiedWatcher fileModifiedWatcher = FileUtil.getFileModifiedWatcher(EdexBandwidthContextFactory
.getBandwidthMapConfig());
@Override
public void run() {
if (fileModifiedWatcher.hasBeenModified()) {
bandwidthMapConfigurationUpdated();
}
}
};
public BandwidthManager(IBandwidthDbInit dbInit,
IBandwidthDao bandwidthDao, RetrievalManager retrievalManager,
BandwidthDaoUtil bandwidthDaoUtil) {
@ -144,8 +161,10 @@ abstract class BandwidthManager extends
EventBus.register(this);
BandwidthEventBus.register(this);
// Start a MaintenanceTask
// schedule maintenance tasks
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(watchForConfigFileChanges,
1, 1, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(new MaintanenceTask(), 1, 5,
TimeUnit.MINUTES);
}
@ -1445,7 +1464,6 @@ abstract class BandwidthManager extends
@Override
public void run() {
for (RetrievalPlan plan : retrievalManager.getRetrievalPlans()
.values()) {
plan.resize();
@ -1672,4 +1690,20 @@ abstract class BandwidthManager extends
return true;
}
}
/**
* Signals the bandwidth map localization file is updated, perform a
* reinitialize operation.
*/
private void bandwidthMapConfigurationUpdated() {
IBandwidthRequest request = new IBandwidthRequest();
request.setRequestType(RequestType.REINITIALIZE);
try {
handleRequest(request);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
"Error while reinitializing the bandwidth manager.", e);
}
}
}

View file

@ -128,8 +128,22 @@ class EdexBandwidthContextFactory implements BandwidthContextFactory {
/**
* Retrieve the actual bandwidth map configuration file.
*
* @return the file reference to the bandwidth map config file, the file may
* or may not exist
*/
public static File getBandwidthMapConfig() {
LocalizationFile lf = getBandwidthMapLocalizationFile();
File file = lf.getFile();
return file;
}
/**
* Retrieve the actual bandwidth map localization file.
*
* @return the localization file
*/
public static LocalizationFile getBandwidthMapLocalizationFile() {
// TODO: Change to be site specific
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext lc = pm.getContext(LocalizationType.COMMON_STATIC,
@ -137,8 +151,7 @@ class EdexBandwidthContextFactory implements BandwidthContextFactory {
LocalizationFile lf = pm.getLocalizationFile(lc,
"datadelivery/bandwidthmap.xml");
File file = lf.getFile();
return file;
return lf;
}
/**

View file

@ -43,6 +43,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthDaoUtil;
* ------------ ---------- ----------- --------------------------
* Feb 20, 2013 1543 djohnson Initial creation
* Feb 27, 2013 1644 djohnson Schedule SBN subscriptions.
* Mar 11, 2013 1645 djohnson Add missing Spring file.
*
* </pre>
*
@ -57,6 +58,7 @@ public class NcfBandwidthManagerCreator implements IEdexBandwidthManagerCreator
static class NcfBandwidthManager extends BandwidthManager {
private static final String[] NCF_BANDWIDTH_MANAGER_FILES = new String[] {
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery-ncf-edex-impl.xml"),
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery-edex-impl.xml"),
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery.xml"),
JarUtil.getResResourcePath("/spring/thrift-bandwidth.xml"),

View file

@ -44,6 +44,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthDaoUtil;
* ------------ ---------- ----------- --------------------------
* Feb 20, 2013 1543 djohnson Initial creation
* Feb 27, 2013 1644 djohnson Schedule SBN subscriptions by routing to the NCF bandwidth manager.
* Mar 11, 2013 1645 djohnson Add missing Spring file.
*
* </pre>
*
@ -58,6 +59,7 @@ public class WfoBandwidthManagerCreator implements IEdexBandwidthManagerCreator
static class WfoBandwidthManager extends BandwidthManager {
private static final String[] WFO_BANDWIDTH_MANAGER_FILES = new String[] {
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery-wfo-edex-impl.xml"),
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery-edex-impl.xml"),
JarUtil.getResResourcePath("/spring/bandwidth-datadelivery.xml"),
JarUtil.getResResourcePath("/spring/thrift-bandwidth.xml"),

View file

@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
@ -100,6 +101,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalManagerNotifyEvent;
* Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency.
* Feb 14, 2013 1595 djohnson Fix expired subscription updates that weren't scheduling retrievals.
* Feb 14, 2013 1596 djohnson Add test duplicating errors deleting multiple subscriptions for the same provider/dataset.
* Mar 11, 2013 1645 djohnson Test configuration file modifications.
*
* </pre>
*
@ -956,6 +958,25 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest {
subscriptionDaosAfterDelete.size());
}
@Test
public void testModifiedConfigurationFileWillReinitializeBandwidthManager() {
IntegrationTestBandwidthContextFactory
.getIntegrationTestBandwidthMapConfigFile().setLastModified(
Long.MAX_VALUE);
bandwidthManager.watchForConfigFileChanges.run();
assertThat(EdexBandwidthContextFactory.getInstance(),
is(not(sameInstance(bandwidthManager))));
}
@Test
public void testUnmodifiedConfigurationFileWillNotReinitializeBandwidthManager() {
bandwidthManager.watchForConfigFileChanges.run();
assertThat(EdexBandwidthContextFactory.getInstance(),
is(sameInstance(bandwidthManager)));
}
private void testSubscriptionCyclesAreAllocatedOncePerCyclePerPlanDay(
List<Integer> cycles) throws SerializationException {
Subscription subscription = SubscriptionFixture.INSTANCE.get();

View file

@ -0,0 +1,100 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.util;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
/**
* Test {@link FileLastModifiedTimeWatcher}.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 08, 2013 1645 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
public class FileLastModifiedTimeWatcherTest {
private final File testDir = TestUtil
.setupTestClassDir(FileLastModifiedTimeWatcherTest.class);
private final File file = new File(testDir, "test.txt");
private FileLastModifiedTimeWatcher watcher;
@Before
public void setUp() throws IOException {
file.createNewFile();
watcher = new FileLastModifiedTimeWatcher(file);
}
@Test
public void newerLastModifiedWillReturnTrueForModified() throws IOException {
increaseFileLastModifiedTime();
assertThat(watcher.hasBeenModified(), is(true));
}
private boolean increaseFileLastModifiedTime() {
return file.setLastModified(file.lastModified() + 5000L);
}
@Test
public void sameLastModifiedWillReturnFalseForModified() throws IOException {
assertThat(watcher.hasBeenModified(), is(false));
}
@Test
public void newerLastModifiedTwiceWillReturnTrueForModified()
throws IOException {
increaseFileLastModifiedTime();
watcher.hasBeenModified();
increaseFileLastModifiedTime();
assertThat(watcher.hasBeenModified(), is(true));
}
@Test
public void sameLastModifiedAfterNewerWillReturnFalseForModified()
throws IOException {
increaseFileLastModifiedTime();
watcher.hasBeenModified();
assertThat(watcher.hasBeenModified(), is(false));
}
}

View file

@ -19,8 +19,8 @@
**/
package com.raytheon.uf.common.util;
import junit.framework.Assert;
import org.junit.Assert;
import org.junit.Test;
/**

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.util;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
@ -68,22 +67,15 @@ public class PropertiesUtilTest {
@Test
public void testCanReadPropertiesFile() throws IOException {
File fileToRead = File.createTempFile(
PropertiesUtilTest.class.getSimpleName(), null);
final File testDir = TestUtil.setupTestClassDir(CLASS);
final File fileToRead = new File(testDir, "propertiesFile.properties");
InputStream is = null;
try {
is = CLASS.getResourceAsStream(CLASS.getSimpleName()
+ ".properties");
FileUtil.write(is, fileToRead);
assertTrue("The file to read should exist!", fileToRead.isFile());
} finally {
PropertiesUtil.close(is);
}
FileUtil.bytes2File(
TestUtil.readResource(CLASS, CLASS.getSimpleName()
+ ".properties"), fileToRead);
Properties properties = PropertiesUtil.read(fileToRead);
assertFalse("The properties should not be empty after reading a file!",
properties.isEmpty());
}

View file

@ -22,14 +22,11 @@ package com.raytheon.uf.common.util;
import java.awt.Point;
import java.util.ArrayList;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.util.GridUtil;
/**
* TODO Add Description
*