ASM #512 - Need radar data watchdog functionality
Change-Id: I54bb10185d5940d27417d1d40e21310ed5aeb8e3 Former-commit-id:0c89a2b11a
[formerly5019e2d171
] [formerly343046c159
] [formerly343046c159
[formerlyeab2733238
]] [formerly8326f42ed8
[formerly343046c159
[formerlyeab2733238
] [formerly8326f42ed8
[formerly b3f33a3c49607219a234bede34bd983178151f39]]]] Former-commit-id:8326f42ed8
Former-commit-id: 090f351ae654032e96f541a503b51e5fc091152d [formerly 4cfe1fd8c4dca6cc4a10913b48925c9c91e851e2] [formerly1bd20432a3
[formerlyb63c845a2b
]] Former-commit-id:1bd20432a3
Former-commit-id:f1d7154915
This commit is contained in:
parent
55b3295999
commit
ee68a61d90
5 changed files with 432 additions and 2 deletions
|
@ -0,0 +1,30 @@
|
|||
# radarWatchdog.txt
|
||||
#
|
||||
# Controls how long to wait for products specified on the RPS list before
|
||||
# sounding an alarm. There are two sections: One defines VCP durations
|
||||
# and one that lists products to monitor.
|
||||
#
|
||||
# VCP duration format: <VCP number>|<duration in seconds>
|
||||
#
|
||||
# Product format: <product mnemonic>
|
||||
#
|
||||
# <product mnemonic> is a mnemonic found in radarInfo.txt.
|
||||
#
|
||||
#
|
||||
# If a product is listed, but is not actually in the current RPS list,
|
||||
# it will not be monitored.
|
||||
[VCP]
|
||||
11 | 300
|
||||
211 | 300
|
||||
12 | 270
|
||||
212 | 270
|
||||
21 | 360
|
||||
121 | 360
|
||||
221 | 360
|
||||
31 | 600
|
||||
32 | 600
|
||||
80 | 360
|
||||
90 | 360
|
||||
[Products]
|
||||
V
|
||||
Z
|
|
@ -124,6 +124,7 @@ public class RadarServer implements RadarEventListener {
|
|||
addListener(new DedicatedRadarActivator(this));
|
||||
addListener(new RequestScheduler(this));
|
||||
addListener(new RadarServerAvailable(this));
|
||||
addListener(new RadarWatchdogListener(configuration));
|
||||
}
|
||||
|
||||
public void addListener(RadarEventListener l) {
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.raytheon.rcm.event.RadarEventAdapter;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 9, 2011 mnash Initial creation
|
||||
* 2012-07-27 DR 14896 D. Friedman Handle multiple RPGs.
|
||||
* 2014-05-22 DR 16319 dhuffman Change some methods to static.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -86,7 +87,7 @@ public class RadarServerAvailable extends RadarEventAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
private void sendNotification(final String radarId, final String message) {
|
||||
public static void sendNotification(final String radarId, final String message) {
|
||||
getExecutorService().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -95,7 +96,7 @@ public class RadarServerAvailable extends RadarEventAdapter {
|
|||
});
|
||||
}
|
||||
|
||||
private void sendNotification2(String radarId, String message) {
|
||||
private static void sendNotification2(String radarId, String message) {
|
||||
ProcessBuilder builder;
|
||||
Process proc = null;
|
||||
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
/**
|
||||
* 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.rcm.server;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.raytheon.rcm.config.Configuration;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class encapsulates the watchdog activity into a plugin for the
|
||||
* RadarServer.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- ---------- ----------- --------------------------
|
||||
* May 12, 2014 DR 16319 dhuffman Initial creation.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author dhuffman
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RadarWatchdog extends Thread {
|
||||
|
||||
private static Object semifore = new Object();
|
||||
|
||||
protected static class GsmItem {
|
||||
protected String radarID;
|
||||
protected int vcp;
|
||||
protected long time;
|
||||
protected long alarmTime;
|
||||
protected long nextAlarmTime;
|
||||
|
||||
protected GsmItem() {
|
||||
}
|
||||
}
|
||||
|
||||
protected static class RadarItem {
|
||||
protected String radarID;
|
||||
protected String mnemonic;
|
||||
protected long time;
|
||||
protected long messageTime;
|
||||
|
||||
protected RadarItem() {
|
||||
}
|
||||
}
|
||||
|
||||
private long startTime = 0;
|
||||
private long shortestWait = 0;
|
||||
private static final long fudgeTime = 30;
|
||||
|
||||
private static Map<String, GsmItem> mapGSM = new ConcurrentHashMap<String, GsmItem>();
|
||||
private static Map<String, Map<String, RadarItem>> mapMnemonic = new ConcurrentHashMap<String, Map<String, RadarItem>>();
|
||||
private static Map<Integer, Integer> mapDuration = new ConcurrentHashMap<Integer, Integer>();
|
||||
private static List<String> mapMnemonicProducts = new ArrayList<String>();
|
||||
|
||||
protected Configuration configuration;
|
||||
private static String configFileName = "radarWatchdog.txt";
|
||||
|
||||
protected RadarWatchdog(Configuration conf) {
|
||||
setDaemon(true);
|
||||
startTime = System.currentTimeMillis();
|
||||
configuration = conf;
|
||||
|
||||
loadConfigFile(configFileName);
|
||||
|
||||
Iterator<String> mnem = mapMnemonicProducts.iterator();
|
||||
while (mnem.hasNext()) {
|
||||
String mn = mnem.next();
|
||||
Map<String, RadarItem> mapRadar = new ConcurrentHashMap<String, RadarItem>();
|
||||
mapMnemonic.put(mn, mapRadar);
|
||||
}
|
||||
}
|
||||
|
||||
public GsmItem getGSMItem(final String radarID) {
|
||||
return mapGSM.get(radarID);
|
||||
}
|
||||
|
||||
public void putGSMItem(GsmItem gi) {
|
||||
if (gi != null) {
|
||||
mapGSM.put(gi.radarID, gi);
|
||||
}
|
||||
}
|
||||
|
||||
public RadarItem getRadarItem(final String Mnemonic, final String radarID) {
|
||||
Map<String, RadarItem> mapRadar = mapMnemonic.get(Mnemonic);
|
||||
if (mapRadar != null)
|
||||
return mapRadar.get(radarID);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void putRadarItem(RadarItem ri) {
|
||||
if (ri != null) {
|
||||
Map<String, RadarItem> mapRadar = mapMnemonic.get(ri.mnemonic);
|
||||
if (mapRadar != null) {
|
||||
mapRadar.put(ri.radarID, ri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long currentTime = 0;
|
||||
shortestWait = 0;
|
||||
while (true) {
|
||||
|
||||
try {
|
||||
synchronized (semifore) {
|
||||
semifore.wait(shortestWait < 800 ? 800 : shortestWait);
|
||||
currentTime = System.currentTimeMillis();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
patrol(currentTime);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void patrol(long currentTime) {
|
||||
long duration = 0;
|
||||
long adjustedTime = currentTime - fudgeTime;
|
||||
shortestWait = 0;
|
||||
Iterator<GsmItem> git = mapGSM.values().iterator();
|
||||
while (git.hasNext()) {
|
||||
GsmItem gi = git.next();
|
||||
if (mapDuration.get(gi.vcp) != null) {
|
||||
duration = mapDuration.get(gi.vcp) * 1000;
|
||||
|
||||
Iterator<String> mnem = mapMnemonicProducts.iterator();
|
||||
while (mnem.hasNext()) {
|
||||
String mn = mnem.next();
|
||||
Map<String, RadarItem> mapRadar = mapMnemonic.get(mn);
|
||||
if (mapRadar == null)
|
||||
continue;
|
||||
RadarItem ri = mapRadar.get(gi.radarID);
|
||||
|
||||
if (ri == null) {
|
||||
if (duration + startTime < adjustedTime
|
||||
&& gi.alarmTime != startTime) {
|
||||
alert(duration, gi, mn);
|
||||
gi.alarmTime = startTime;
|
||||
gi.nextAlarmTime = startTime + duration;
|
||||
}
|
||||
|
||||
if (shortestWait < 1 || duration < shortestWait)
|
||||
shortestWait = duration;
|
||||
}
|
||||
|
||||
if (ri != null) {
|
||||
|
||||
if (ri.time + duration < adjustedTime) {
|
||||
if (ri.time <= gi.alarmTime
|
||||
&& gi.nextAlarmTime < currentTime) {
|
||||
alert(duration, gi, ri.mnemonic);
|
||||
gi.alarmTime = ri.time;
|
||||
gi.nextAlarmTime = currentTime + duration;
|
||||
}
|
||||
if (gi.nextAlarmTime < currentTime)
|
||||
gi.alarmTime = ri.time;
|
||||
}
|
||||
|
||||
if ((duration + ri.time) - adjustedTime < shortestWait
|
||||
&& 1 <= (duration + ri.time) - adjustedTime)
|
||||
shortestWait = (duration + ri.time) - adjustedTime;
|
||||
if (shortestWait < 1)
|
||||
shortestWait = duration;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void alert(final long duration, final GsmItem gi, final String mn) {
|
||||
String AlertVizMessage = "Watchdog: Radar ";
|
||||
AlertVizMessage += gi.radarID + " has not produced a '" + mn
|
||||
+ "' product in the last " + duration / 1000 + " seconds.";
|
||||
RadarServerAvailable.sendNotification(gi.radarID, AlertVizMessage);
|
||||
}
|
||||
|
||||
public void notifyWatchdog() {
|
||||
synchronized (semifore) {
|
||||
semifore.notify();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean loadConfigFile(final String filename) {
|
||||
try {
|
||||
InputStream inFile = configuration.getDropInData(filename);
|
||||
InputStreamReader reader = new InputStreamReader(inFile);
|
||||
BufferedReader in = new BufferedReader(reader);
|
||||
String line;
|
||||
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.contains("#"))
|
||||
continue;
|
||||
if (line.contains("["))
|
||||
break;
|
||||
}
|
||||
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.contains("#"))
|
||||
continue;
|
||||
if (line.contains("["))
|
||||
break;
|
||||
String s[] = line.split("\\|");
|
||||
mapDuration.put(Integer.parseInt(s[0].trim()),
|
||||
Integer.parseInt(s[1].trim()));
|
||||
}
|
||||
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.contains("#"))
|
||||
continue;
|
||||
if (line.contains("["))
|
||||
break;
|
||||
mapMnemonicProducts.add(line.trim());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.errorf(": watchdog: Error while loading config file %s",
|
||||
filename, e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* 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.rcm.server;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.raytheon.rcm.config.Configuration;
|
||||
import com.raytheon.rcm.event.RadarEvent;
|
||||
import com.raytheon.rcm.event.RadarEventAdapter;
|
||||
import com.raytheon.rcm.message.GSM;
|
||||
import com.raytheon.rcm.message.GraphicProduct;
|
||||
import com.raytheon.rcm.message.Message;
|
||||
import com.raytheon.rcm.message.GraphicProduct.PDB;
|
||||
import com.raytheon.rcm.products.ProductInfo;
|
||||
import com.raytheon.rcm.products.RadarProduct;
|
||||
import com.raytheon.rcm.server.RadarWatchdog;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class listens to messages sent to the RadarServer, that the watchdog has
|
||||
* an interest in.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- ---------- ----------- --------------------------
|
||||
* May 12, 2014 DR 16319 dhuffman Initial creation.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author dhuffman
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RadarWatchdogListener extends RadarEventAdapter {
|
||||
|
||||
protected static RadarWatchdog radarWatchdog;
|
||||
|
||||
private static HashMap<String, String> mnemonicMap = new HashMap<String, String>();
|
||||
{
|
||||
mnemonicMap.put("HZ", "Z");
|
||||
mnemonicMap.put("HV", "V");
|
||||
mnemonicMap.put("HSW", "SW");
|
||||
}
|
||||
|
||||
public RadarWatchdogListener(Configuration configuration) {
|
||||
radarWatchdog = new RadarWatchdog(configuration);
|
||||
radarWatchdog.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRadarEvent(RadarEvent event) {
|
||||
if (event.getType() == RadarEvent.MESSAGE_RECEIVED) {
|
||||
byte[] msg = event.getMessageData();
|
||||
int messageCode = Message.messageCodeOf(msg);
|
||||
if (messageCode == Message.GSM) {
|
||||
GSM gsm = null;
|
||||
try {
|
||||
gsm = GSM.decode(msg);
|
||||
} catch (Exception e) {
|
||||
// This message error will be reported by EventLogger.
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsm != null) {
|
||||
RadarWatchdog.GsmItem gi = new RadarWatchdog.GsmItem();
|
||||
gi.radarID = event.getRadarID();
|
||||
gi.vcp = gsm.vcp;
|
||||
gi.time = gsm.time.getTimeInMillis();
|
||||
|
||||
RadarWatchdog.GsmItem oldgi = radarWatchdog
|
||||
.getGSMItem(gi.radarID);
|
||||
if (oldgi == null
|
||||
|| (oldgi != null && oldgi.time <= gi.time)) {
|
||||
radarWatchdog.putGSMItem(gi);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (16 <= messageCode) {
|
||||
int mcode = 0;
|
||||
PDB pdb = null;
|
||||
RadarWatchdog.RadarItem ri = new RadarWatchdog.RadarItem();
|
||||
mcode = Message.messageCodeOf(msg);
|
||||
ri.messageTime = (Message.decodeHeader(msg).time)
|
||||
.getTimeInMillis();
|
||||
|
||||
RadarProduct rp = ProductInfo.getInstance().getPoductForCode(
|
||||
mcode);
|
||||
if (rp == null)
|
||||
return;
|
||||
|
||||
ri.mnemonic = rp.mnemonic;
|
||||
String newMnemonic = mnemonicMap.get(ri.mnemonic);
|
||||
if (newMnemonic != null)
|
||||
ri.mnemonic = newMnemonic;
|
||||
|
||||
try {
|
||||
pdb = GraphicProduct.pdbOfMessage(msg);
|
||||
} catch (Exception e) {
|
||||
// This message error will be reported by EventLogger.
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdb != null) {
|
||||
ri.radarID = event.getRadarID();
|
||||
ri.time = System.currentTimeMillis();
|
||||
|
||||
RadarWatchdog.RadarItem oldri = radarWatchdog.getRadarItem(
|
||||
ri.mnemonic, ri.radarID);
|
||||
|
||||
if (oldri == null
|
||||
|| (oldri != null && oldri.messageTime <= ri.messageTime)) {
|
||||
radarWatchdog.putRadarItem(ri);
|
||||
radarWatchdog.notifyWatchdog();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue