lrgs.lrgsmain.JavaLrgsStatusProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opendcs Show documentation
Show all versions of opendcs Show documentation
A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.
The newest version!
/*
* $Id$
*/
package lrgs.lrgsmain;
import java.net.InetAddress;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import ilex.util.Logger;
import lrgs.apistatus.AttachedProcess;
import lrgs.apistatus.DownLink;
import lrgs.apistatus.ArchiveStatistics;
import lrgs.apistatus.QualityMeasurement;
import lrgs.archive.QualLogFile;
import lrgs.archive.QualLogEntry;
import lrgs.archive.MergeFilter;
import lrgs.common.LrgsStatusProvider;
import lrgs.ddsserver.JLddsThread;
import lrgs.gui.LrgsApp;
import lrgs.ldds.LddsParams;
import lrgs.statusxml.LrgsStatusSnapshotExt;
import lrgs.dqm.DqmInterface;
/**
Class JavaLrgsStatusProvider implements the LrgsStatusProvide interface
by accessing java-only methods in the archive and downlinks.
*/
public class JavaLrgsStatusProvider
implements LrgsStatusProvider
{
/** Reference back to parent. */
private LrgsMain lrgsMain;
/** The status snapshot that everyone will work from. */
private LrgsStatusSnapshotExt lsse;
/** The last time a message was received. */
private int lastMsgRcv;
/** Used to maintain the quality log. */
QualLogFile qualLogFile;
/** Current minute's quality log entry. */
QualLogEntry minuteQuality;
/** Slot number for the DdsRecv main interface (set from LrgsMain) */
public int ddsRecvMainSlotNum;
/** Slot number for the DdsRecv main interface (set from LrgsMain) */
public int ddsRecvSecMainSlotNum;
/** Slot number for the DrgsRecv main interface (set from LrgsMain) */
public int drgsRecvMainSlotNum;
public int networkDcpMainSlotNum;
/** Slot number for the NoaaportRecv main interface (set from LrgsMain) */
public int noaaportRecvMainSlotNum;
public Date lrgsStartupTime;
/** Last hour we put dd info into. */
private int lastDomsatDroppedHour = -1;
/** The DQM Interface if one is active. */
private DqmInterface dqmInterface;
/** Last Domsat Sequence Number Seen */
public int lastDomsatSequenceNum;
public long qualLogLastModified = 0L;
/**
* Construct the provider and an internal status snapshot structure,
* along with all the subordinate structures.
* @param lrgsMain the parent.
*/
public JavaLrgsStatusProvider(LrgsMain lrgsMain)
{
this.lrgsMain = lrgsMain;
ddsRecvMainSlotNum = -1;
drgsRecvMainSlotNum = -1;
noaaportRecvMainSlotNum = -1;
networkDcpMainSlotNum = -1;
ddsRecvSecMainSlotNum=-1; // added for secondary group
lsse = new LrgsStatusSnapshotExt();
lsse.fullVersion = LrgsApp.AppVersion + " (" + LrgsApp.releasedOn + ")";
LrgsConfig cfg = LrgsConfig.instance();
lsse.setMaxDownlinks(cfg.maxDownlinks);
lsse.setMaxClients(cfg.ddsMaxClients);
lsse.isUsable = false;
lsse.currentNumClients = 0;
lsse.lss.lrgsTime = (int)(System.currentTimeMillis() / 1000L);
lsse.lss.currentHour = (short)((lsse.lss.lrgsTime / 3600) % 24);
lsse.lss.primaryMissingCount = 0;
lsse.lss.totalRecoveredCount = 0;
lsse.lss.totalGoodCount = 0;
lsse.lss.downLinks = new DownLink[lsse.maxDownlinks];
for(int i=0; i cfg.timeoutSeconds
&& !cfg.getNoTimeout())
{
if (lsse.isUsable)
{
lsse.isUsable = false;
Logger.instance().failure(
LrgsMain.module + ":" + LrgsMain.EVT_TIMEOUT
+ " LRGS Timeout: No data in "
+ cfg.timeoutSeconds + " seconds.");
}
lsse.systemStatus = "Timeout";
}
else if (!lsse.isUsable)
{
Logger.instance().info(
LrgsMain.module + ":" + (-LrgsMain.EVT_TIMEOUT)
+ " LRGS Recovery: Receiving Data Again!");
lsse.isUsable = true;
lsse.systemStatus = "Running";
}
syncDownlinks();
lsse.currentNumClients = getAllClients(lsse.lss.attProcs);
int hour = (lsse.lss.lrgsTime / 3600) % 24;
if (hour != lsse.lss.currentHour)
{
// Starting a new hour, zero out the status structs.
lsse.lss.currentHour = (short)hour;
lsse.domsatDropped[hour] = 0;
QualityMeasurement qm = lsse.lss.qualMeas[hour];
qm.containsData = true;
qm.numGood = 0;
qm.numDropped = 0;
qm.numRecovered = 0;
for(int i=0; i= 0)
{
lsse.lss.arcStats.dirNext = idxNum+1;
}
DownLink dl = lsse.lss.downLinks[dl_slot];
dl.lastMsgRecvTime = arcTime;
int goodInc = (failcode == 'G') ? 1 : 0;
int badInc = (failcode == '?') ? 1 : 0;
if (seqNum != -1)
{
lsse.lss.arcStats.lastSeqNum = seqNum;
dl.lastSeqNum = seqNum;
}
// Update this slot's quality measurement for this hour.
int hour = (arcTime / 3600) % 24;
QualityMeasurement qm = lsse.downlinkQMs[dl_slot].dl_qual[hour];
qm.containsData = true;
qm.numGood += goodInc;
qm.numDropped += badInc;
// Update the 'archived' quality measurements for this hour.
QualityMeasurement arcQM = lsse.lss.qualMeas[hour];
arcQM.containsData = true;
if (mergeResult == MergeFilter.SAVE_DCPMSG)
{
arcQM.numGood += goodInc;
arcQM.numDropped += badInc;
minuteQuality.archivedGood += goodInc;
minuteQuality.archivedErr += badInc;
}
else if (mergeResult == MergeFilter.OVERWRITE_PREV_BAD)
{
// It could be a bad overwriting a bad, so use the incs:
arcQM.numGood += goodInc;
arcQM.numDropped += badInc;
arcQM.numDropped--;
minuteQuality.archivedGood++;
minuteQuality.archivedErr--;
}
// Else no changes to archived stats: Either discarded or overwrote-good
/*
DDS and DRGS are composit downlinks that may have several connections.
After tracking the individual slot quality, we also aggregate
statistics in the parent slot.
*/
if (dl.type == LrgsInputInterface.DL_DDSCON && dl.group.equalsIgnoreCase(LrgsInputInterface.PRIMARY))
{
dl = lsse.lss.downLinks[ddsRecvMainSlotNum];
dl.lastMsgRecvTime = arcTime;
QualityMeasurement mainQM =
lsse.downlinkQMs[ddsRecvMainSlotNum].dl_qual[hour];
mainQM.containsData = true;
mainQM.numGood += goodInc;
mainQM.numDropped += badInc;
minuteQuality.ddsGood += goodInc;
minuteQuality.ddsErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_DDSCON && dl.group.equalsIgnoreCase(LrgsInputInterface.SECONDARY))
{
dl = lsse.lss.downLinks[ddsRecvSecMainSlotNum];
dl.lastMsgRecvTime = arcTime;
QualityMeasurement mainQM =
lsse.downlinkQMs[ddsRecvSecMainSlotNum].dl_qual[hour];
mainQM.containsData = true;
mainQM.numGood += goodInc;
mainQM.numDropped += badInc;
minuteQuality.ddsGood += goodInc;
minuteQuality.ddsErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_DRGSCON)
{
dl = lsse.lss.downLinks[drgsRecvMainSlotNum];
dl.lastMsgRecvTime = arcTime;
QualityMeasurement mainQM =
lsse.downlinkQMs[drgsRecvMainSlotNum].dl_qual[hour];
mainQM.containsData = true;
mainQM.numGood += goodInc;
mainQM.numDropped += badInc;
minuteQuality.drgsGood += goodInc;
minuteQuality.drgsErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_NETDCPCONT
|| dl.type == LrgsInputInterface.DL_NETDCPPOLL)
{
dl = lsse.lss.downLinks[networkDcpMainSlotNum];
dl.lastMsgRecvTime = arcTime;
QualityMeasurement mainQM =
lsse.downlinkQMs[networkDcpMainSlotNum].dl_qual[hour];
mainQM.containsData = true;
mainQM.numGood += goodInc;
mainQM.numDropped += badInc;
minuteQuality.drgsGood += goodInc;
minuteQuality.drgsErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_DOMSAT)
{
minuteQuality.domsatGood += goodInc;
minuteQuality.domsatErr += badInc;
lastDomsatSequenceNum = seqNum;
}
else if (dl.type == LrgsInputInterface.DL_NOAAPORTCON)
{
dl = lsse.lss.downLinks[noaaportRecvMainSlotNum];
dl.lastMsgRecvTime = arcTime;
QualityMeasurement npQM =
lsse.downlinkQMs[noaaportRecvMainSlotNum].dl_qual[hour];
npQM.containsData = true;
npQM.numGood += goodInc;
npQM.numDropped += badInc;
minuteQuality.noaaportGood += goodInc;
minuteQuality.noaaportErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_LRIT)
{
minuteQuality.lritGood += goodInc;
minuteQuality.lritErr += badInc;
}
else if (dl.type == LrgsInputInterface.DL_GR3110)
{
minuteQuality.gr3110Count += goodInc;
}
else if (dl.type == LrgsInputInterface.DL_IRIDIUM)
minuteQuality.iridiumCount += goodInc;
else if (dl.type == LrgsInputInterface.DL_EDL)
minuteQuality.edlCount += goodInc;
}
/**
* Called when a domsat dropout is detected.
* @param numDropped the number of messages dropped.
* @param arcTime the current time_t
* @param gapStart the sequence number of the start of the gap.
* @param elapsedSec the elapsed number of seconds in the gap.
*/
public synchronized void domsatDropped(int numDropped, int arcTime,
int gapStart, int elapsedSec)
{
int hour = (arcTime / 3600) % 24;
if (hour != lastDomsatDroppedHour)
{
// Starting new hour? Zero it out first.
lsse.domsatDropped[hour] = 0;
lastDomsatDroppedHour = hour;
}
lsse.domsatDropped[hour] += numDropped;
minuteQuality.domsatDropped += numDropped;
/*
* This is a hook for DAPS, which monitors quality on the DOMSAT
* uplink. Most LRGS systems will not have a dqmInterface.
*/
if (dqmInterface != null)
dqmInterface.domsatDropped(gapStart, numDropped, elapsedSec);
}
public void setSystemStatus(String status)
{
lsse.systemStatus = status;
}
/**
* Called when we get a new client connection.
* @return AttachedProcess with which to track the client's status,
* or null if all client slots are used.
*/
public AttachedProcess getFreeClientSlot()
{
for(int i=0; i< lsse.lss.attProcs.length; i++)
{
AttachedProcess ap = lsse.lss.attProcs[i];
if (ap.pid == -1)
{
return ap;
}
}
return null;
}
/**
* @return ms time for the last time message was received over the
* DDS link.
*/
public long getLastDdsReceiveTime()
{
if (ddsRecvMainSlotNum == -1)
{
Logger.instance().debug1("StatusProvider.getLastDdsReceiveTime no " +
"ddsRecvMainSlotNum, returning now - 1 hour");
return System.currentTimeMillis() - 3600000L;
}
else
{
DownLink dl = lsse.lss.downLinks[ddsRecvMainSlotNum];
Logger.instance().debug1("StatusProvider.getLastDdsReceiveTime "
+ "returning " + new Date(dl.lastMsgRecvTime * 1000L));
return dl.lastMsgRecvTime * 1000L;
}
}
/**
* @return ms time for the last time message was received over the
* DDS Secondary(Backup) link.
*/
public long getLastSecDdsReceiveTime()
{
if (ddsRecvSecMainSlotNum == -1)
{
return System.currentTimeMillis() - 3600000L;
}
else
{
DownLink dl = lsse.lss.downLinks[ddsRecvSecMainSlotNum];
return dl.lastMsgRecvTime * 1000L;
}
}
/**
* @return ms time for the last time message was received over any link.
*/
public long getLastReceiveTime()
{
long latest = 0L;
String latestName = "(unknown)";
for(int slot = 0; slot latest)
{
latest = t;
latestName = lsse.lss.downLinks[slot].name;
}
}
}
Logger.instance().info("At LRGS Startup, last msg was received at "
+ new Date(latest) + " on downlink " + latestName);
return latest;
}
public boolean isUsable()
{
return lsse.isUsable;
}
public void setIsUsable(boolean tf) { lsse.isUsable = tf; }
}