Issue #1447: Initial commit of VTEC table sharing functionality: port A1 changes to

VTECTableSqueeze, port requestAT/sendAT, re-port ingestAT/MergeVTEC, some minor bug fixes to
serverConfig.py, project configs.

Change-Id: Ibecb0aad913845224be1b7dd713e9fefef19d510

Former-commit-id: 1e72fe30d97504f70352a181de35805a197e50f4
This commit is contained in:
David Gillingham 2013-02-26 17:12:13 -06:00
parent c50e1cbe1c
commit 9351f33c1c
45 changed files with 4031 additions and 653 deletions

View file

@ -24,6 +24,10 @@
</fileset>
</copy>
<!-- Create inbox/outbox directories used for ISC/VTEC sharing -->
<mkdir dir="${gfesuite.directory}/products/ISC" />
<mkdir dir="${gfesuite.directory}/products/ATBL" />
<!-- Adjust GFESuite permissions -->
<chmod perm="ugo+rx">
<fileset dir="${gfesuite.directory}/bin">

View file

@ -405,16 +405,16 @@ def parseSat(satdirs):
def otherParse(serverhost, mhsid, port,
initmodules, accumElem,
initskips, d2ddbver, logfilepurge, prddir, home,
extraWEPrec, autoConfigureNotifyTextProd,
extraWEPrec, vtecRequestTime, autoConfigureNotifyTextProd,
iscRoutingTableAddress, requestedISCsites, requestISC, sendiscOnSave,
sendiscOnPublish, requestedISCparms, transmitScript):
if type(serverhost) != str:
raise TypeError, "GFESUITE_HOST not an str: " + `serverhost`
if type(mhsid) != str:
raise TypeError, "GFESUITE_MHSID not an str: " + `mhsid`
# if type(vtecRequestTime) != int:
# raise TypeError, "VTECPartners: VTEC_REMOTE_TABLE_FETCH_TIME " + \
# "not an int: " + `vtecRequestTime`
if type(vtecRequestTime) != int:
raise TypeError, "VTECPartners: VTEC_REMOTE_TABLE_FETCH_TIME " + \
"not an int: " + `vtecRequestTime`
if type(port) != int:
raise TypeError, "GFESUITE_PORT not an int: " + `port`
initmodules = dictCheck(initmodules, list, str, "INITMODULES")
@ -490,7 +490,7 @@ def otherParse(serverhost, mhsid, port,
return serverhost, mhsid, \
port, initmodules, accumElem, \
initskips, d2ddbver, logfilepurge, prddir, home,\
extraWEPrecision, \
extraWEPrecision, vtecRequestTime, \
autoConfigureNotifyTextProd, \
iscRoutingTableAddress, reqISCsites, requestISC, sendiscOnSave, \
sendiscOnPublish, reqISCparms, transmitScript

View file

@ -1885,7 +1885,7 @@ IFPConfigServer.allowTopoBelowZero = 1
def doIt():
# Import the local site configuration file (if it exists)
import doConfig
# import VTECPartners
import VTECPartners
(models, projections, vis, wx, desDef, allSites, domain, siteId, timeZone,officeTypes) = \
doConfig.parse(GFESUITE_SITEID, DATABASES, types, visibilities, SITES,
allProjections)
@ -1910,6 +1910,7 @@ def doIt():
logFilePurgeAfter, \
prdDir, baseDir, \
extraWEPrecision, \
tableFetchTime, \
autoConfigureNotifyTextProd, \
iscRoutingTableAddress, \
requestedISCsites, requestISC, \
@ -1922,7 +1923,8 @@ def doIt():
D2DAccumulativeElements,
INITSKIPS, D2DDBVERSIONS, LOG_FILE_PURGE_AFTER,
GFESUITE_PRDDIR, GFESUITE_HOME,
ExtraWEPrecision, AUTO_CONFIGURE_NOTIFYTEXTPROD, ISC_ROUTING_TABLE_ADDRESS,
ExtraWEPrecision, VTECPartners.VTEC_REMOTE_TABLE_FETCH_TIME,
AUTO_CONFIGURE_NOTIFYTEXTPROD, ISC_ROUTING_TABLE_ADDRESS,
REQUESTED_ISC_SITES, REQUEST_ISC, SEND_ISC_ON_SAVE, SEND_ISC_ON_PUBLISH,
REQUESTED_ISC_PARMS, TRANSMIT_SCRIPT)
IFPConfigServer.serverHost = serverHost
@ -1936,6 +1938,7 @@ def doIt():
IFPConfigServer.prdDir = prdDir
IFPConfigServer.baseDir = baseDir
IFPConfigServer.extraWEPrecision = extraWEPrecision
IFPConfigServer.tableFetchTime = tableFetchTime
IFPConfigServer.autoConfigureNotifyTextProd = autoConfigureNotifyTextProd
IFPConfigServer.iscRoutingTableAddress = iscRoutingTableAddress
IFPConfigServer.requestedISCsites = requestedISCsites

View file

@ -2,6 +2,6 @@
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>

View file

@ -18,7 +18,9 @@
# further licensing information.
##
import LogStream, siteConfig, tempfile, os, sys, JUtil, subprocess
import cPickle
import LogStream, siteConfig, tempfile, os, sys, JUtil, subprocess, traceback
import time, copy, string, iscUtil
from com.raytheon.edex.plugin.gfe.isc import IRTManager
@ -34,6 +36,9 @@ from com.raytheon.edex.plugin.gfe.isc import IRTManager
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/14/09 1995 bphillip Initial Creation.
# 01/25/13 1447 dgilling Implement routines needed by
# iscDataRec for VTEC table
# sharing.
#
#
#
@ -55,7 +60,121 @@ def logVerbose(*msg):
def logDebug(*msg):
logVerbose(iscUtil.tupleToString(*msg))
# called by iscDataRec when another site has requested the active table
# returns the active table, filtered, pickled.
def getVTECActiveTable(siteAndFilterInfo, xmlPacket):
import VTECPartners
if VTECPartners.VTEC_RESPOND_TO_TABLE_REQUESTS:
return #respond is disabled
#decode the data (pickled)
info = cPickle.loads(siteAndFilterInfo)
(mhsSite, reqsite, filterSites, countDict, issueTime) = info
#get the active table, and write it to a temporary file
from com.raytheon.uf.common.site import SiteMap
from com.raytheon.uf.edex.activetable import ActiveTable
from com.raytheon.uf.common.activetable import ActiveTableMode
site4Id = SiteMap.getInstance().getSite4LetterId(siteConfig.GFESUITE_SITEID)
javaTable = ActiveTable.getActiveTable(site4Id, ActiveTableMode.OPERATIONAL)
dictTable = ActiveTable.convertToDict(javaTable, siteConfig.GFESUITE_SITEID)
# we must convert this to a python hash using the A1 field naming conventions
# for cross-version compatibility
table = []
for i in xrange(dictTable.size()):
convRecord = JUtil.javaObjToPyVal(dictTable.get(i))
convRecord['oid'] = convRecord['officeid']
convRecord['vstr'] = convRecord['vtecstr']
convRecord['end'] = convRecord['endTime']
convRecord['start'] = convRecord['startTime']
convRecord['key'] = convRecord['phensig']
# remove new fields so we don't pickle two copies
del convRecord['officeid']
del convRecord['vtecstr']
del convRecord['endTime']
del convRecord['phensig']
del convRecord['startTime']
if convRecord.has_key('segText'):
convRecord['text'] = convRecord['segText']
del convRecord['segText']
table.append(convRecord)
# additionally, we'll need to pickle our output to match the A1 file
# format
pickledTable = cPickle.dumps(table)
outDir = os.path.join(siteConfig.GFESUITE_PRDDIR, "ATBL")
with tempfile.NamedTemporaryFile(suffix='.ato', dir=outDir, delete=False) as fp:
fname = fp.name
fp.write(pickledTable)
#write the xmlpacket to a temporary file, if one was passed
if xmlPacket is not None:
with tempfile.NamedTemporaryFile(suffix='.xml', delete=False) as fp:
fnameXML = fp.name
fp.write(xmlPacket)
#call sendAT to send the table to the requestor
pid = os.fork()
if pid == 0:
cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "sendAT")
args = [cmd, '-s', reqsite, '-a', mhsSite, '-H', ServerHost,
'-P', ServerPort, '-L', ServerProtocol, '-M', ServerMHS,
'-S', ServerSite, '-x', XmtScript]
if filterSites is not None:
for fs in filterSites:
args.append('-f')
args.append(fs)
if countDict is not None:
args.append('-c')
args.append(`countDict`)
if issueTime is not None:
args.append('-t')
args.append(`issueTime`)
args.append('-v')
args.append(fname)
if xmlPacket is not None:
args.append('-X')
args.append(fnameXML)
try:
os.execvp(cmd, args)
except:
logProblem("Error executing sendAT: ", traceback.format_exc())
finally:
os._exit(0)
#when we receive a requested active table from another site, this function
#is called from iscDataRec
def putVTECActiveTable(strTable, xmlPacket):
#write the xmlpacket to a temporary file, if one was passed
if xmlPacket is not None:
with tempfile.NamedTemporaryFile(suffix='.xml', delete=False) as fp:
fnameXML = fp.name
fp.write(xmlPacket)
inDir = os.path.join(siteConfig.GFESUITE_PRDDIR, "ATBL")
with tempfile.NamedTemporaryFile(suffix='.ati', dir=inDir, delete=False) as fp:
fname = fp.name
fp.write(strTable)
pid = os.fork()
if pid == 0:
cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "ingestAT")
args = []
args.append(cmd)
args.append("-f")
args.append(fname)
if xmlPacket is not None:
args.append('-X')
args.append(fnameXML)
try:
os.execvp(cmd, args)
except:
logProblem("Error executing ingestAT: ", traceback.format_exc())
finally:
os._exit(0)
def initIRT(ancfURL, bncfURL, mhsid, serverHost, serverPort, serverProtocol,
site, parmsWanted, gridDims, gridProj, gridBoundBox, iscWfosWanted):
global IRTthread

View file

@ -14,6 +14,8 @@ Import-Package: com.raytheon.uf.common.dataplugin.annotations,
javax.persistence,
org.hibernate.annotations,
org.springframework.beans.factory.annotation
Export-Package: com.raytheon.uf.common.activetable
Export-Package: com.raytheon.uf.common.activetable,
com.raytheon.uf.common.activetable.request,
com.raytheon.uf.common.activetable.response
Require-Bundle: com.raytheon.uf.common.serialization,
com.raytheon.uf.common.message;bundle-version="1.12.1174"

View file

@ -51,6 +51,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 24, 2009 njensen Initial creation
* Feb 26, 2013 1447 dgilling Implement equals().
*
* </pre>
*
@ -217,6 +218,258 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@Override
public abstract Object clone();
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ActiveTableRecord other = (ActiveTableRecord) obj;
if (act == null) {
if (other.act != null) {
return false;
}
} else if (!act.equals(other.act)) {
return false;
}
if (countyheader == null) {
if (other.countyheader != null) {
return false;
}
} else if (!countyheader.equals(other.countyheader)) {
return false;
}
if (endTime == null) {
if (other.endTime != null) {
return false;
}
} else if (!endTime.equals(other.endTime)) {
return false;
}
if (etn == null) {
if (other.etn != null) {
return false;
}
} else if (!etn.equals(other.etn)) {
return false;
}
if (floodBegin == null) {
if (other.floodBegin != null) {
return false;
}
} else if (!floodBegin.equals(other.floodBegin)) {
return false;
}
if (floodCrest == null) {
if (other.floodCrest != null) {
return false;
}
} else if (!floodCrest.equals(other.floodCrest)) {
return false;
}
if (floodEnd == null) {
if (other.floodEnd != null) {
return false;
}
} else if (!floodEnd.equals(other.floodEnd)) {
return false;
}
if (floodRecordStatus == null) {
if (other.floodRecordStatus != null) {
return false;
}
} else if (!floodRecordStatus.equals(other.floodRecordStatus)) {
return false;
}
if (floodSeverity == null) {
if (other.floodSeverity != null) {
return false;
}
} else if (!floodSeverity.equals(other.floodSeverity)) {
return false;
}
if (forecaster == null) {
if (other.forecaster != null) {
return false;
}
} else if (!forecaster.equals(other.forecaster)) {
return false;
}
if (geometry == null) {
if (other.geometry != null) {
return false;
}
} else if (!geometry.equalsExact(other.geometry)) {
return false;
}
if (immediateCause == null) {
if (other.immediateCause != null) {
return false;
}
} else if (!immediateCause.equals(other.immediateCause)) {
return false;
}
if (issueTime == null) {
if (other.issueTime != null) {
return false;
}
} else if (!issueTime.equals(other.issueTime)) {
return false;
}
if (loc == null) {
if (other.loc != null) {
return false;
}
} else if (!loc.equals(other.loc)) {
return false;
}
if (locationID == null) {
if (other.locationID != null) {
return false;
}
} else if (!locationID.equals(other.locationID)) {
return false;
}
if (motdir == null) {
if (other.motdir != null) {
return false;
}
} else if (!motdir.equals(other.motdir)) {
return false;
}
if (motspd == null) {
if (other.motspd != null) {
return false;
}
} else if (!motspd.equals(other.motspd)) {
return false;
}
if (officeid == null) {
if (other.officeid != null) {
return false;
}
} else if (!officeid.equals(other.officeid)) {
return false;
}
if (overviewText == null) {
if (other.overviewText != null) {
return false;
}
} else if (!overviewText.equals(other.overviewText)) {
return false;
}
if (phen == null) {
if (other.phen != null) {
return false;
}
} else if (!phen.equals(other.phen)) {
return false;
}
if (phensig == null) {
if (other.phensig != null) {
return false;
}
} else if (!phensig.equals(other.phensig)) {
return false;
}
if (pil == null) {
if (other.pil != null) {
return false;
}
} else if (!pil.equals(other.pil)) {
return false;
}
if (productClass == null) {
if (other.productClass != null) {
return false;
}
} else if (!productClass.equals(other.productClass)) {
return false;
}
if (purgeTime == null) {
if (other.purgeTime != null) {
return false;
}
} else if (!purgeTime.equals(other.purgeTime)) {
return false;
}
if (rawmessage == null) {
if (other.rawmessage != null) {
return false;
}
} else if (!rawmessage.equals(other.rawmessage)) {
return false;
}
if (region == null) {
if (other.region != null) {
return false;
}
} else if (!region.equals(other.region)) {
return false;
}
if (seg != other.seg) {
return false;
}
if (segText == null) {
if (other.segText != null) {
return false;
}
} else if (!segText.equals(other.segText)) {
return false;
}
if (sig == null) {
if (other.sig != null) {
return false;
}
} else if (!sig.equals(other.sig)) {
return false;
}
if (startTime == null) {
if (other.startTime != null) {
return false;
}
} else if (!startTime.equals(other.startTime)) {
return false;
}
if (ufn != other.ufn) {
return false;
}
if (ugcZone == null) {
if (other.ugcZone != null) {
return false;
}
} else if (!ugcZone.equals(other.ugcZone)) {
return false;
}
if (vtecstr == null) {
if (other.vtecstr != null) {
return false;
}
} else if (!vtecstr.equals(other.vtecstr)) {
return false;
}
if (wmoid == null) {
if (other.wmoid != null) {
return false;
}
} else if (!wmoid.equals(other.wmoid)) {
return false;
}
if (xxxid == null) {
if (other.xxxid != null) {
return false;
}
} else if (!xxxid.equals(other.xxxid)) {
return false;
}
return true;
}
/**
* @return the wmoid
*/

View file

@ -1,118 +0,0 @@
/**
* 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.activetable;
import java.util.Map;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 13, 2010 wldougher Initial creation
*
* </pre>
*
* @author wldougher
* @version 1.0
*/
@DynamicSerialize
public class UpdateActiveTableRequest implements IServerRequest {
@DynamicSerializeElement
private Map<String, Object>[] activeTable;
@DynamicSerializeElement
private String xmlSource;
@DynamicSerializeElement
private ActiveTableMode mode = ActiveTableMode.PRACTICE;
@DynamicSerializeElement
private float timeOffset = 0.0f;
/**
* @return the activeTable
*/
public Map<String, Object>[] getActiveTable() {
return activeTable;
}
/**
* @param activeTable
* the activeTable to set
*/
public void setActiveTable(Map<String, Object>[] activeTable) {
this.activeTable = activeTable;
}
/**
* @param xmlSource
*/
public void setXmlSource(String xmlSource) {
this.xmlSource = xmlSource;
}
/**
* @return
*/
public String getXmlSource() {
return xmlSource;
}
/**
* @param mode
* the mode to set
*/
public void setMode(ActiveTableMode mode) {
this.mode = mode;
}
/**
* @return the mode
*/
public ActiveTableMode getMode() {
return mode;
}
/**
* @param timeOffset
* the timeOffset to set
*/
public void setTimeOffset(float timeOffset) {
this.timeOffset = timeOffset;
}
/**
* @return the timeOffset
*/
public float getTimeOffset() {
return timeOffset;
}
}

View file

@ -1,46 +0,0 @@
package com.raytheon.uf.common.activetable;
import java.util.List;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@DynamicSerialize
public class UpdateActiveTableResponse implements ISerializableObject {
@DynamicSerializeElement
private List<String> sourceInfo;
@DynamicSerializeElement
private String message;
/**
* @param sourceInfo
*/
public void setSourceInfo(List<String> sourceInfo) {
this.sourceInfo = sourceInfo;
}
/**
* @return
*/
public List<String> getSourceInfo() {
return sourceInfo;
}
/**
* @param message
* the message to set
*/
public void setMessage(String message) {
this.message = message;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,191 @@
/**
* 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.activetable.request;
import java.util.Map;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
/**
* Request to merge in a provided collection of new active table entries to the
* specified active table using the legacy MergeVTEC logic. Used by CLI
* utilities ingestAT/MergeVTEC for active table sharing.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 13, 2010 wldougher Initial creation
* Feb 13, 2013 1447 dgilling Added additional fields to
* better support VTEC table sharing.
*
* </pre>
*
* @author wldougher
* @version 1.0
*/
@DynamicSerialize
public class MergeActiveTableRequest implements IServerRequest {
@DynamicSerializeElement
private Map<String, Object>[] incomingRecords;
@DynamicSerializeElement
private String site;
@DynamicSerializeElement
private ActiveTableMode tableName;
@DynamicSerializeElement
private float timeOffset;
@DynamicSerializeElement
private String xmlSource;
@DynamicSerializeElement
private boolean fromIngestAT;
@DynamicSerializeElement
private boolean makeBackups;
/**
* No argument constructor. Not intended to be used by anyone, except
* DynamicSerialize.
*/
public MergeActiveTableRequest() {
this(null, ActiveTableMode.PRACTICE, null, 0.0f, null, false, true);
}
/**
* Builds a MergeActiveTableRequest.
*
* @param incomingRecords
* Array containing active table entries in the python-style dict
* or Map format.
* @param tableName
* Table the new records will be merged into.
* @param site
* 3-char site id to perform the merge operation as.
* @param timeOffset
* For DRT; the number of seconds away from current time to use
* as the base time for the merge.
* @param xmlSource
* MHS XML data that contains who sent these active table
* records.
* @param fromIngestAT
* Whether to run ingestAT or MergeVTEC to perform the merge.
* @param makeBackups
* Whether to save a backup copy of the active table prior to the
* merge operation.
*/
public MergeActiveTableRequest(Map<String, Object>[] incomingRecords,
ActiveTableMode tableName, String site, float timeOffset,
String xmlSource, boolean fromIngestAT, boolean makeBackups) {
this.incomingRecords = incomingRecords;
this.tableName = tableName;
this.site = site;
this.timeOffset = timeOffset;
this.xmlSource = xmlSource;
this.fromIngestAT = fromIngestAT;
this.makeBackups = makeBackups;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("MergeActiveTableRequest [incomingRecords=");
builder.append(incomingRecords);
builder.append(", tableName=");
builder.append(tableName);
builder.append(", site=");
builder.append(site);
builder.append(", timeOffset=");
builder.append(timeOffset);
builder.append(", xmlSource=");
builder.append(xmlSource);
builder.append(", fromIngestAT=");
builder.append(fromIngestAT);
builder.append(", makeBackups=");
builder.append(makeBackups);
builder.append("]");
return builder.toString();
}
public Map<String, Object>[] getIncomingRecords() {
return incomingRecords;
}
public void setIncomingRecords(Map<String, Object>[] incomingRecords) {
this.incomingRecords = incomingRecords;
}
public ActiveTableMode getTableName() {
return tableName;
}
public void setTableName(ActiveTableMode tableName) {
this.tableName = tableName;
}
public float getTimeOffset() {
return timeOffset;
}
public void setTimeOffset(float timeOffset) {
this.timeOffset = timeOffset;
}
public String getXmlSource() {
return xmlSource;
}
public void setXmlSource(String xmlSource) {
this.xmlSource = xmlSource;
}
public void setFromIngestAT(boolean fromIngestAT) {
this.fromIngestAT = fromIngestAT;
}
public boolean isFromIngestAT() {
return fromIngestAT;
}
public void setMakeBackups(boolean makeBackups) {
this.makeBackups = makeBackups;
}
public boolean isMakeBackups() {
return makeBackups;
}
public void setSite(String site) {
this.site = site;
}
public String getSite() {
return site;
}
}

View file

@ -0,0 +1,199 @@
/**
* 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.activetable.request;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
/**
* Request to run the requestAT utility, which will send messages over the MHS
* to neighboring sites for their active table entries that are relevant to this
* site.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 6, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@DynamicSerialize
public class RetrieveRemoteActiveTableRequest implements IServerRequest {
@DynamicSerializeElement
private String serverHost;
@DynamicSerializeElement
private int serverPort;
@DynamicSerializeElement
private String serverProtocol;
@DynamicSerializeElement
private String mhsId;
@DynamicSerializeElement
private String siteId;
@DynamicSerializeElement
private String ancfAddress;
@DynamicSerializeElement
private String bncfAddress;
@DynamicSerializeElement
private String transmitScript;
/**
* No argument constructor. Not intended to be used by anyone, except
* DynamicSerialize.
*/
public RetrieveRemoteActiveTableRequest() {
// no-op
}
/**
* Build a RetrieveRemoteActiveTableRequest.
*
* @param serverHost
* Host name of system running requestAT.
* @param serverPort
* Port upon which system runs.
* @param serverProtocol
* MHS protocol string for server.
* @param mhsId
* MHS ID of this system.
* @param siteId
* Site ID of this system.
* @param ancfAddress
* Configured ANCF URL.
* @param bncfAddress
* Configured BNCF URL.
* @param transmitScript
* Command to run to transmit requestAT output over MHS.
*/
public RetrieveRemoteActiveTableRequest(String serverHost, int serverPort,
String serverProtocol, String mhsId, String siteId,
String ancfAddress, String bncfAddress, String transmitScript) {
this.serverHost = serverHost;
this.serverPort = serverPort;
this.serverProtocol = serverProtocol;
this.mhsId = mhsId;
this.siteId = siteId;
this.ancfAddress = ancfAddress;
this.bncfAddress = bncfAddress;
this.transmitScript = transmitScript;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("RetrieveRemoteActiveTableRequest [serverHost=");
builder.append(serverHost);
builder.append(", serverPort=");
builder.append(serverPort);
builder.append(", serverProtocol=");
builder.append(serverProtocol);
builder.append(", mhsId=");
builder.append(mhsId);
builder.append(", siteId=");
builder.append(siteId);
builder.append(", ancfAddress=");
builder.append(ancfAddress);
builder.append(", bncfAddress=");
builder.append(bncfAddress);
builder.append(", transmitScript=");
builder.append(transmitScript);
builder.append("]");
return builder.toString();
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public int getServerPort() {
return serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public String getServerProtocol() {
return serverProtocol;
}
public void setServerProtocol(String serverProtocol) {
this.serverProtocol = serverProtocol;
}
public String getMhsId() {
return mhsId;
}
public void setMhsId(String mhsId) {
this.mhsId = mhsId;
}
public String getSiteId() {
return siteId;
}
public void setSiteId(String siteId) {
this.siteId = siteId;
}
public String getAncfAddress() {
return ancfAddress;
}
public void setAncfAddress(String ancfAddress) {
this.ancfAddress = ancfAddress;
}
public String getBncfAddress() {
return bncfAddress;
}
public void setBncfAddress(String bncfAddress) {
this.bncfAddress = bncfAddress;
}
public String getTransmitScript() {
return transmitScript;
}
public void setTransmitScript(String transmitScript) {
this.transmitScript = transmitScript;
}
}

View file

@ -0,0 +1,286 @@
/**
* 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.activetable.request;
import java.util.List;
import java.util.Map;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
/**
* Request to run the utility sendAT, which will send active table entries
* relevant to the specified sites via MHS.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 6, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@DynamicSerialize
public class SendActiveTableRequest implements IServerRequest {
@DynamicSerializeElement
private String serverHost;
@DynamicSerializeElement
private Integer serverPort;
@DynamicSerializeElement
private String serverProtocol;
@DynamicSerializeElement
private String serverSite;
@DynamicSerializeElement
private String mhsId;
@DynamicSerializeElement
private List<String> sites;
@DynamicSerializeElement
private List<String> filterSites;
@DynamicSerializeElement
private List<String> mhsSites;
@DynamicSerializeElement
private Float issueTime;
@DynamicSerializeElement
private Map<String, Integer> countDict;
@DynamicSerializeElement
private String fileName;
@DynamicSerializeElement
private String xmlIncoming;
@DynamicSerializeElement
private String transmitScript;
/**
* No argument constructor. Not intended to be used by anyone, except
* DynamicSerialize.
*/
public SendActiveTableRequest() {
// no-op
}
/**
* Builds a SendActiveTableRequest.
*
* @param serverHost
* Host name of system running sendAT.
* @param serverPort
* Port upon which system runs.
* @param serverProtocol
* MHS protocol string for server.
* @param serverSite
* Site ID of this system.
* @param mhsId
* MHS ID of this system.
* @param sites
* Sites to collect active table entries for.
* @param filterSites
* Sites to filter out of active table entries.
* @param mhsSites
* optional field for legacy systems. MHS IDs of server to send
* results to.
* @param issueTime
* Time request was made. Epoch time in seconds.
* @param countDict
* Counts of records requesting server has for each site in
* <code>sites</code>.
* @param fileName
* File name containing records to send out.
* @param xmlIncoming
* MHS XML data about the request.
* @param transmitScript
* Command to run to send results via MHS.
*/
public SendActiveTableRequest(String serverHost, int serverPort,
String serverProtocol, String serverSite, String mhsId,
List<String> sites, List<String> filterSites,
List<String> mhsSites, float issueTime,
Map<String, Integer> countDict, String fileName,
String xmlIncoming, String transmitScript) {
this.serverHost = serverHost;
this.serverPort = serverPort;
this.serverProtocol = serverProtocol;
this.serverSite = serverSite;
this.mhsId = mhsId;
this.sites = sites;
this.filterSites = filterSites;
this.mhsSites = mhsSites;
this.issueTime = issueTime;
this.countDict = countDict;
this.fileName = fileName;
this.xmlIncoming = xmlIncoming;
this.transmitScript = transmitScript;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SendActiveTableRequest [serverHost=");
builder.append(serverHost);
builder.append(", serverPort=");
builder.append(serverPort);
builder.append(", serverProtocol=");
builder.append(serverProtocol);
builder.append(", serverSite=");
builder.append(serverSite);
builder.append(", mhsId=");
builder.append(mhsId);
builder.append(", sites=");
builder.append(sites);
builder.append(", filterSites=");
builder.append(filterSites);
builder.append(", mhsSites=");
builder.append(mhsSites);
builder.append(", issueTime=");
builder.append(issueTime);
builder.append(", countDict=");
builder.append(countDict);
builder.append(", fileName=");
builder.append(fileName);
builder.append(", xmlIncoming=");
builder.append(xmlIncoming);
builder.append(", transmitScript=");
builder.append(transmitScript);
builder.append("]");
return builder.toString();
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public Integer getServerPort() {
return serverPort;
}
public void setServerPort(Integer serverPort) {
this.serverPort = serverPort;
}
public String getServerProtocol() {
return serverProtocol;
}
public void setServerProtocol(String serverProtocol) {
this.serverProtocol = serverProtocol;
}
public String getServerSite() {
return serverSite;
}
public void setServerSite(String serverSite) {
this.serverSite = serverSite;
}
public String getMhsId() {
return mhsId;
}
public void setMhsId(String mhsId) {
this.mhsId = mhsId;
}
public List<String> getSites() {
return sites;
}
public void setSites(List<String> sites) {
this.sites = sites;
}
public List<String> getFilterSites() {
return filterSites;
}
public void setFilterSites(List<String> filterSites) {
this.filterSites = filterSites;
}
public List<String> getMhsSites() {
return mhsSites;
}
public void setMhsSites(List<String> mhsSites) {
this.mhsSites = mhsSites;
}
public Float getIssueTime() {
return issueTime;
}
public void setIssueTime(Float issueTime) {
this.issueTime = issueTime;
}
public Map<String, Integer> getCountDict() {
return countDict;
}
public void setCountDict(Map<String, Integer> countDict) {
this.countDict = countDict;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getXmlIncoming() {
return xmlIncoming;
}
public void setXmlIncoming(String xmlIncoming) {
this.xmlIncoming = xmlIncoming;
}
public String getTransmitScript() {
return transmitScript;
}
public void setTransmitScript(String transmitScript) {
this.transmitScript = transmitScript;
}
}

View file

@ -0,0 +1,86 @@
/**
* 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.activetable.response;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Response for the following active table sharing request types:
* <ul>
* <li>MergeActiveTableRequest
* <li>RetrieveRemoteActiveTableRequest
* <li>SendActiveTableRequest
* </ul>
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@DynamicSerialize
public class ActiveTableSharingResponse implements ISerializableObject {
@DynamicSerializeElement
private boolean taskSuccess;
@DynamicSerializeElement
private String errorMessage;
/**
* Build an ActiveTableSharingResponse.
*
* @param taskSuccess
* Whether the task tied to the request succeeded.
* @param errorMessage
* Any status/error messages that could be returned relevant to
* the task.
*/
public ActiveTableSharingResponse(boolean taskSuccess, String errorMessage) {
this.taskSuccess = taskSuccess;
this.errorMessage = errorMessage;
}
public boolean isTaskSuccess() {
return taskSuccess;
}
public void setTaskSuccess(boolean taskSuccess) {
this.taskSuccess = taskSuccess;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}

View file

@ -19,16 +19,13 @@
**/
package com.raytheon.uf.common.dataplugin.gfe.python;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonIncludePathUtil;
import com.raytheon.uf.common.util.FileUtil;
/**
@ -40,15 +37,14 @@ import com.raytheon.uf.common.util.FileUtil;
* ------------ ---------- ----------- --------------------------
* Oct 9, 2008 njensen Initial creation
* Sep 18, 2012 #1091 randerso added base directory to getGfeConfigIncludePath
* Feb 27, 2013 #1447 dgilling Re-factor based on PythonPathIncludeUtil.
* </pre>
*
* @author njensen
* @version 1.0
*/
public class GfePyIncludeUtil {
public static final String PYTHON = "python";
public class GfePyIncludeUtil extends PythonIncludePathUtil {
public static final String GFE = "gfe";
@ -99,33 +95,6 @@ public class GfePyIncludeUtil {
public static final String VCMOD_UTILS = FileUtil
.join(VCMODULES, "utility");
private static final IPathManager PATH_MANAGER = PathManagerFactory
.getPathManager();
private static Map<LocalizationContext, Map<String, String>> pathMap = new HashMap<LocalizationContext, Map<String, String>>();
private static String getPath(LocalizationContext ctx, String locPath) {
Map<String, String> ctxMap = pathMap.get(ctx);
if (ctxMap == null) {
ctxMap = new HashMap<String, String>();
pathMap.put(ctx, ctxMap);
}
String fsPath = ctxMap.get(locPath);
if (fsPath == null) {
LocalizationFile file = PATH_MANAGER.getLocalizationFile(ctx,
locPath);
fsPath = file.getFile().getAbsolutePath();
ctxMap.put(locPath, fsPath);
}
return fsPath;
}
// LocalizationFile getters
public static LocalizationFile getCommonPythonLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, PYTHON);
}
public static LocalizationFile getCommonGfeLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, COMMON_GFE);
}
@ -189,11 +158,6 @@ public class GfePyIncludeUtil {
// Include Path getters
public static String getCommonPythonIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE), PYTHON);
}
public static String getCommonGfeIncludePath() {
String pythonDir = getCommonPythonIncludePath();
String gfeDir = getPath(PATH_MANAGER.getContext(

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.python;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
/**
* Utility for getting python directories to include.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class PythonIncludePathUtil {
protected static final IPathManager PATH_MANAGER = PathManagerFactory
.getPathManager();
private static Map<LocalizationContext, Map<String, String>> pathMap = new HashMap<LocalizationContext, Map<String, String>>();
public static final String PYTHON = "python";
protected static String getPath(LocalizationContext ctx, String locPath) {
Map<String, String> ctxMap = pathMap.get(ctx);
if (ctxMap == null) {
ctxMap = new HashMap<String, String>();
pathMap.put(ctx, ctxMap);
}
String fsPath = ctxMap.get(locPath);
if (fsPath == null) {
LocalizationFile file = PATH_MANAGER.getLocalizationFile(ctx,
locPath);
fsPath = file.getFile().getAbsolutePath();
ctxMap.put(locPath, fsPath);
}
return fsPath;
}
public static LocalizationFile getCommonPythonLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, PYTHON);
}
public static String getCommonPythonIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE), PYTHON);
}
}

View file

@ -2,6 +2,6 @@
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>

View file

@ -46,16 +46,28 @@
<constructor-arg value="com.raytheon.uf.common.activetable.PracticeProductOfftimeRequest"/>
<constructor-arg ref="practiceProductOfftimeHandler"/>
</bean>
<bean id="updateActiveTableHandler" class="com.raytheon.uf.edex.activetable.UpdateActiveTableHandler" />
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.activetable.UpdateActiveTableRequest"/>
<constructor-arg ref="updateActiveTableHandler"/>
</bean>
<bean id="getNextEtnHandler" class="com.raytheon.uf.edex.activetable.GetNextEtnHandler" />
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.activetable.GetNextEtnRequest"/>
<constructor-arg ref="getNextEtnHandler"/>
</bean>
<bean id="requestATHandler" class="com.raytheon.uf.edex.activetable.handler.RetrieveRemoteActiveTableHandler"/>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.activetable.request.RetrieveRemoteActiveTableRequest"/>
<constructor-arg ref="requestATHandler"/>
</bean>
<bean id="sendATHandler" class="com.raytheon.uf.edex.activetable.handler.SendActiveTableHandler"/>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.activetable.request.SendActiveTableRequest"/>
<constructor-arg ref="sendATHandler"/>
</bean>
<bean id="ingestATHandler" class="com.raytheon.uf.edex.activetable.handler.MergeActiveTableHandler"/>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.activetable.request.MergeActiveTableRequest"/>
<constructor-arg ref="ingestATHandler"/>
</bean>
</beans>

View file

@ -51,6 +51,7 @@ import com.raytheon.uf.common.site.SiteMap;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.core.EDEXUtil;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
@ -75,7 +76,9 @@ import com.vividsolutions.jts.geom.Geometry;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 17, 2009 njensen Initial creation
* Dec 21, 2009 4055 njensen Queued thread for updates
* Dec 21, 2009 4055 njensen Queued thread for updates
* Feb 26, 2013 1447 dgilling Add routine to use MergeVTEC as basis
* for merge logic.
*
* </pre>
*
@ -290,7 +293,7 @@ public class ActiveTable {
updateTable(siteId, result, mode);
if (result.changeList.size() > 0) {
sendNotification(mode, result.changeList);
sendNotification(mode, result.changeList, "VTECDecoder");
}
}
}
@ -339,12 +342,13 @@ public class ActiveTable {
return result;
}
private void sendNotification(ActiveTableMode mode, List<VTECChange> changes) {
private static void sendNotification(ActiveTableMode mode,
List<VTECChange> changes, String source) {
Date modTime = new Date();
// VTECTableChangeNotifier.send(mode, modTime, "VTECDecoder", changes);
try {
VTECTableChangeNotification notification = new VTECTableChangeNotification(
mode, modTime, "VTECDecoder",
mode, modTime, source,
changes.toArray(new VTECChange[changes.size()]));
// System.out.println("Sending VTECTableChangeNotification:"
// + notification);
@ -427,7 +431,7 @@ public class ActiveTable {
* @param changes
* the updated table followed by the purged records
*/
private void updateTable(String siteId, MergeResult changes,
private static void updateTable(String siteId, MergeResult changes,
ActiveTableMode mode) {
synchronized (ActiveTable.class) {
List<ActiveTableRecord> updated = changes.updatedList;
@ -468,6 +472,99 @@ public class ActiveTable {
return exc;
}
/**
* Merges the specified new active table records into the active table using
* the legacy MergeVTEC logic (which is different than the legacy logic in
* ActiveTable.py used elsewhere).
*
* @param siteId
* Site ID to perform the merge as.
* @param tableName
* Table to merge the records into.
* @param newRecords
* The incoming new records to merge.
* @param timeOffset
* For DRT; number of seconds from current time to use as base
* time for the merge.
* @param makeBackup
* Whether or not to make a backup of the active table prior to
* the merge.
* @param runIngestAT
* Whether this merge will be performed as ingestAT or MergeVTEC
* (has minor logging effects).
* @param xmlSource
* Only required when <code>runIngestAT</code> is true; XML data
* from MHS about source of new records.
* @throws JepException
* If an unhandled exception is encountered in the python code
* executed.
*/
public static void mergeRemoteTable(String siteId,
ActiveTableMode tableName, List<ActiveTableRecord> newRecords,
float timeOffset, boolean makeBackup, boolean runIngestAT,
String xmlSource) throws JepException {
MergeResult result = null;
PythonScript script = null;
try {
String scriptName = runIngestAT ? "ingestAT.py" : "MergeVTEC.py";
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext commonCx = pathMgr.getContext(
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
String scriptPath = pathMgr.getFile(commonCx,
FileUtil.join(ActiveTablePyIncludeUtil.VTEC, scriptName))
.getPath();
String pythonIncludePath = PyUtil.buildJepIncludePath(
ActiveTablePyIncludeUtil.getCommonPythonIncludePath(),
ActiveTablePyIncludeUtil.getVtecIncludePath(siteId),
ActiveTablePyIncludeUtil.getGfeConfigIncludePath(siteId),
ActiveTablePyIncludeUtil.getIscScriptsIncludePath());
try {
script = new PythonScript(scriptPath, pythonIncludePath,
ActiveTable.class.getClassLoader());
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Error initializing ingestAT or MergeVTEC python", e);
throw e;
}
try {
String site4Char = SiteMap.getInstance().getSite4LetterId(
siteId);
List<ActiveTableRecord> activeTable = getActiveTable(site4Char,
tableName);
HashMap<String, Object> args = new HashMap<String, Object>();
args.put("activeTable", activeTable);
args.put("activeTableMode", tableName.toString());
args.put("newRecords", newRecords);
args.put("drt", timeOffset);
args.put("makeBackups", makeBackup);
if (runIngestAT) {
args.put("xmlIncoming", xmlSource);
}
String methodName = runIngestAT ? "runFromJava" : "merge";
result = (MergeResult) script.execute(methodName, args);
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Error merging active table", e);
throw e;
}
} finally {
if (script != null) {
script.dispose();
script = null;
}
}
if (result != null) {
updateTable(siteId, result, tableName);
if (!result.changeList.isEmpty()) {
sendNotification(tableName, result.changeList, "MergeVTEC");
}
}
}
public void dispose() {
python.dispose();
}

View file

@ -0,0 +1,77 @@
/**
* 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.edex.activetable;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonIncludePathUtil;
import com.raytheon.uf.common.util.FileUtil;
/**
* Utility for getting python directories to include.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 27, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class ActiveTablePyIncludeUtil extends PythonIncludePathUtil {
public static final String GFE = "gfe";
public static final String GFE_CONFIG = FileUtil.join("config", GFE);
public static final String ISC = FileUtil.join(GFE, "isc");
public static final String VTEC = "vtec";
public static String getGfeConfigIncludePath(String siteId) {
String baseConfigDir = getPath(PATH_MANAGER.getContext(
LocalizationType.EDEX_STATIC, LocalizationLevel.BASE),
GFE_CONFIG);
String siteConfigDir = getPath(PATH_MANAGER.getContextForSite(
LocalizationType.EDEX_STATIC, siteId), GFE_CONFIG);
return PyUtil.buildJepIncludePath(siteConfigDir, baseConfigDir);
}
public static String getIscScriptsIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.EDEX_STATIC,
LocalizationLevel.BASE), ISC);
}
public static String getVtecIncludePath(String siteId) {
String baseDir = getPath(PATH_MANAGER.getContext(
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE), VTEC);
String siteDir = getPath(PATH_MANAGER.getContextForSite(
LocalizationType.COMMON_STATIC, siteId), VTEC);
return PyUtil.buildJepIncludePath(siteDir, baseDir);
}
}

View file

@ -17,34 +17,36 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.activetable;
package com.raytheon.uf.edex.activetable.handler;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.activetable.ActiveTableRecord;
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
import com.raytheon.uf.common.activetable.UpdateActiveTableRequest;
import com.raytheon.uf.common.activetable.UpdateActiveTableResponse;
import com.raytheon.uf.common.activetable.request.MergeActiveTableRequest;
import com.raytheon.uf.common.activetable.response.ActiveTableSharingResponse;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.edex.activetable.ActiveTable;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
/**
* Handler for UpdateActiveTableRequests. This is the server-side portion of the
* ingestAT application.
* Handler for
* <code>MergeActiveTableRequest<code>s. This is the server-side portion of the
* ingestAT/MergeVTEC applications.
*
* <pre>
*
@ -54,6 +56,8 @@ import com.vividsolutions.jts.io.WKTReader;
* Sep 13, 2010 wldougher Initial creation
* Aug 20, 2012 #1084 dgilling Properly zero pad incoming
* ETN values.
* Feb 26, 2013 #1447 dgilling Rewrite based on MergeActiveTableRequest
* and use MergeVTEC.py to perform merge.
*
* </pre>
*
@ -61,10 +65,10 @@ import com.vividsolutions.jts.io.WKTReader;
* @version 1.0
*/
public class UpdateActiveTableHandler implements
IRequestHandler<UpdateActiveTableRequest> {
public class MergeActiveTableHandler implements
IRequestHandler<MergeActiveTableRequest> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(UpdateActiveTableHandler.class);
.getHandler(MergeActiveTableHandler.class);
/**
* Handle a request to update the active table with a list of records. The
@ -74,100 +78,39 @@ public class UpdateActiveTableHandler implements
* @see com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest(com.raytheon.uf.common.serialization.comm.IServerRequest)
*/
@Override
public Object handleRequest(UpdateActiveTableRequest request)
throws Exception {
StringBuilder sb = new StringBuilder();
Float timeOffset = request.getTimeOffset();
Map<String, Object>[] activeTableMap = request.getActiveTable();
ActiveTableMode mode = request.getMode();
public ActiveTableSharingResponse handleRequest(
MergeActiveTableRequest request) throws Exception {
Map<String, Object>[] activeTableMap = request.getIncomingRecords();
ActiveTableMode mode = request.getTableName();
statusHandler.handle(Priority.INFO,
"Received UpdateActiveTable request containing "
+ activeTableMap.length + " maps.");
List<ActiveTableRecord> records = null;
List<ActiveTableRecord> records;
try {
records = mapToRecords(activeTableMap, mode);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
"The mapToRecords() call failed.", e);
sb.append(e.getLocalizedMessage());
for (StackTraceElement ste : e.getStackTrace()) {
sb.append(ste.toString() + "\n");
}
// already logged this below, just returning failed status
return new ActiveTableSharingResponse(false,
"Error executing converting incoming records: "
+ e.getLocalizedMessage());
}
if (sb.length() == 0) {
// Records may have entries for more than one site ID (officeid).
// However, the merge() method of ActiveTable assumes it will only
// get records for a single site. So some sorting and slicing of the
// list has to be done.
class OidComparator implements Comparator<ActiveTableRecord> {
/**
* Comparator for sorting ActiveTableRecords by office id.
*
* @see java.util.Comparator#compare(java.lang.Object,
* java.lang.Object)
*/
@Override
public int compare(ActiveTableRecord o1, ActiveTableRecord o2) {
return o1.getOfficeid().compareTo(o2.getOfficeid());
}
}
OidComparator comparator = new OidComparator();
Collections.sort(records, comparator);
// Create an active table instance to perform the merge
ActiveTable table = new ActiveTable();
// A sublist of records, all for the same site
List<ActiveTableRecord> siteRecords = null;
// A dummy record for use with binarySearch
ActiveTableRecord key = new PracticeActiveTableRecord();
// The index of the first record with a different site ID
int nextIdx = -1;
while (records.size() > 0) {
// Get a sublist with identical site IDs
key.setOfficeid(records.get(0).getOfficeid() + " ");
nextIdx = Collections.binarySearch(records, key, comparator);
if (nextIdx < 0) {
nextIdx = -(nextIdx + 1);
}
siteRecords = records.subList(0, nextIdx);
// Merge all the records for the site
Exception exc = table.merge(siteRecords, timeOffset);
if (exc != null) {
statusHandler.handle(Priority.PROBLEM,
"table.merge() returned an error.", exc);
sb.append(exc.getLocalizedMessage());
for (StackTraceElement ste : exc.getStackTrace()) {
sb.append(ste.toString() + "\n");
}
break;
}
// Remove the processed records
records = records.subList(nextIdx, records.size());
}
String xmlSource = request.isFromIngestAT() ? request.getXmlSource()
: null;
try {
ActiveTable.mergeRemoteTable(request.getSite(),
request.getTableName(), records, request.getTimeOffset(),
request.isMakeBackups(), request.isFromIngestAT(),
xmlSource);
} catch (JepException e) {
// already logged this in ActiveTable, just returning failed status
return new ActiveTableSharingResponse(false,
"Error performing merge: " + e.getLocalizedMessage());
}
String xmlSource = request.getXmlSource();
List<String> sourceInfo = null;
if (xmlSource != null && !("".equals(xmlSource.trim()))) {
ServerInfoExtractor infoExtractor = new ServerInfoExtractor();
sourceInfo = infoExtractor.extract(xmlSource);
}
// Tell the user we finished processing.
// The merge() method handles its own error reporting, we get no status
UpdateActiveTableResponse response = new UpdateActiveTableResponse();
response.setSourceInfo(sourceInfo);
if (sb.length() > 0) {
response.setMessage(sb.toString());
}
return response;
return new ActiveTableSharingResponse(true, null);
}
/**
@ -178,9 +121,11 @@ public class UpdateActiveTableHandler implements
* @param activeTableMap
* @param mode
* @return
* @throws Exception
*/
protected List<ActiveTableRecord> mapToRecords(
Map<String, Object>[] activeTableMap, ActiveTableMode mode) {
Map<String, Object>[] activeTableMap, ActiveTableMode mode)
throws Exception {
List<ActiveTableRecord> records = new ArrayList<ActiveTableRecord>(
activeTableMap.length);
if (activeTableMap != null) {
@ -214,16 +159,20 @@ public class UpdateActiveTableHandler implements
atr.setAct(template.get("act").toString());
atr.setSeg((Integer) template.get("seg"));
Calendar start = GregorianCalendar.getInstance();
start.setTimeInMillis(((Integer) template.get("startTime")) * 1000L);
start.setTimeInMillis(((Number) template.get("startTime"))
.longValue() * 1000L);
atr.setStartTime(start);
Calendar end = GregorianCalendar.getInstance();
end.setTimeInMillis(((Integer) template.get("endTime")) * 1000L);
end.setTimeInMillis(((Number) template.get("endTime"))
.longValue() * 1000L);
atr.setEndTime(end);
Calendar purge = GregorianCalendar.getInstance();
purge.setTimeInMillis(((Integer) template.get("purgeTime")) * 1000L);
purge.setTimeInMillis(((Number) template.get("purgeTime"))
.longValue() * 1000L);
atr.setPurgeTime(purge);
Calendar issue = GregorianCalendar.getInstance();
issue.setTimeInMillis(((Integer) template.get("issueTime")) * 1000L);
issue.setTimeInMillis(((Number) template.get("issueTime"))
.longValue() * 1000L);
atr.setIssueTime(issue);
atr.setUfn((Boolean) template.get("ufn"));
atr.setOfficeid(template.get("officeid").toString());
@ -273,7 +222,7 @@ public class UpdateActiveTableHandler implements
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
throw e;
}
}
}

View file

@ -0,0 +1,127 @@
/**
* 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.edex.activetable.handler;
import java.util.HashMap;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.activetable.request.RetrieveRemoteActiveTableRequest;
import com.raytheon.uf.common.activetable.response.ActiveTableSharingResponse;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonScript;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.activetable.ActiveTablePyIncludeUtil;
/**
* Handler for <code>RetrieveRemoteActiveTableRequest</code>. Runs the requestAT
* application using the parameters from the request as arguments to the
* PythonScript.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 6, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class RetrieveRemoteActiveTableHandler implements
IRequestHandler<RetrieveRemoteActiveTableRequest> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(RetrieveRemoteActiveTableHandler.class);
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
* (com.raytheon.uf.common.serialization.comm.IServerRequest)
*/
@Override
public ActiveTableSharingResponse handleRequest(
RetrieveRemoteActiveTableRequest request) throws Exception {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext commonBaseCx = pathMgr.getContext(
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
String scriptPath = pathMgr.getFile(commonBaseCx,
FileUtil.join(ActiveTablePyIncludeUtil.VTEC, "requestAT.py"))
.getPath();
final String siteId = request.getSiteId();
String pythonIncludePath = PyUtil.buildJepIncludePath(
ActiveTablePyIncludeUtil.getCommonPythonIncludePath(),
ActiveTablePyIncludeUtil.getVtecIncludePath(siteId),
ActiveTablePyIncludeUtil.getGfeConfigIncludePath(siteId),
ActiveTablePyIncludeUtil.getIscScriptsIncludePath());
PythonScript script = null;
try {
script = new PythonScript(scriptPath, pythonIncludePath,
RetrieveRemoteActiveTableHandler.class.getClassLoader());
try {
Map<String, Object> argMap = new HashMap<String, Object>();
argMap.put("serverHost", request.getServerHost());
argMap.put("serverPort", request.getServerPort());
argMap.put("serverProtocol", request.getServerProtocol());
argMap.put("mhsid", request.getMhsId());
argMap.put("siteID", siteId);
argMap.put("ancf", request.getAncfAddress());
argMap.put("bncf", request.getBncfAddress());
argMap.put("xmtScript", request.getTransmitScript());
script.execute("runFromJava", argMap);
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Error executing requestAT.", e);
return new ActiveTableSharingResponse(false,
"Error executing requestAT: " + e.getLocalizedMessage());
}
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Unable to instantiate requestAT python script object.", e);
return new ActiveTableSharingResponse(false,
"Unable to instantiate requestAT python script object: "
+ e.getLocalizedMessage());
} finally {
if (script != null) {
script.dispose();
}
}
return new ActiveTableSharingResponse(true, null);
}
}

View file

@ -0,0 +1,131 @@
/**
* 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.edex.activetable.handler;
import java.util.HashMap;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.activetable.request.SendActiveTableRequest;
import com.raytheon.uf.common.activetable.response.ActiveTableSharingResponse;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonScript;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.activetable.ActiveTablePyIncludeUtil;
/**
* Handler for <code>SendActiveTableRequest</code>. Runs the sendAT application
* using the parameters from the request as arguments to the PythonScript.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 6, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class SendActiveTableHandler implements
IRequestHandler<SendActiveTableRequest> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(SendActiveTableHandler.class);
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
* (com.raytheon.uf.common.serialization.comm.IServerRequest)
*/
@Override
public ActiveTableSharingResponse handleRequest(
SendActiveTableRequest request) throws Exception {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext commonBaseCx = pathMgr.getContext(
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
String scriptPath = pathMgr.getFile(commonBaseCx,
FileUtil.join(ActiveTablePyIncludeUtil.VTEC, "sendAT.py"))
.getPath();
final String siteId = request.getServerSite();
String pythonIncludePath = PyUtil.buildJepIncludePath(
ActiveTablePyIncludeUtil.getCommonPythonIncludePath(),
ActiveTablePyIncludeUtil.getVtecIncludePath(siteId),
ActiveTablePyIncludeUtil.getGfeConfigIncludePath(siteId),
ActiveTablePyIncludeUtil.getIscScriptsIncludePath());
PythonScript script = null;
try {
script = new PythonScript(scriptPath, pythonIncludePath,
RetrieveRemoteActiveTableHandler.class.getClassLoader());
try {
Map<String, Object> argMap = new HashMap<String, Object>();
argMap.put("myServerHost", request.getServerHost());
argMap.put("myServerPort", request.getServerPort());
argMap.put("myServerProtocol", request.getServerProtocol());
argMap.put("myServerMHSID", request.getMhsId());
argMap.put("myServerSite", siteId);
argMap.put("sites", request.getSites());
argMap.put("filterSites", request.getFilterSites());
argMap.put("mhsSites", request.getMhsSites());
argMap.put("issueTime", request.getIssueTime());
argMap.put("countDict", request.getCountDict());
argMap.put("fname", request.getFileName());
argMap.put("xmlIncoming", request.getXmlIncoming());
argMap.put("xmtScript", request.getTransmitScript());
script.execute("runFromJava", argMap);
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Error executing sendAT.", e);
return new ActiveTableSharingResponse(false,
"Error executing sendAT: " + e.getLocalizedMessage());
}
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Unable to instantiate sendAT python script object.", e);
return new ActiveTableSharingResponse(false,
"Unable to instantiate sendAT python script object: "
+ e.getLocalizedMessage());
} finally {
if (script != null) {
script.dispose();
}
}
return new ActiveTableSharingResponse(true, null);
}
}

View file

@ -27,6 +27,8 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 12/20/09 njensen Initial Creation.
# 02/26/13 1447 dgilling Implement __eq__() and
# __ne__().
#
#
#
@ -35,7 +37,7 @@
import ActiveTableVtec
from java.util import Calendar
class ActiveTableRecord:
class ActiveTableRecord(object):
def __init__(self, javaRecord, state="Decoded"):
self.atr = javaRecord
@ -150,7 +152,12 @@ class ActiveTableRecord:
def __deepcopy__(self, memo):
return ActiveTableRecord(self.atr.clone(), self.state)
def __eq__(self, other):
return self.javaRecord().equals(other.javeRecord())
def __ne__(self, other):
return not self.__eq__(other)
def javaRecord(self):
return self.atr

View file

@ -0,0 +1,430 @@
##
# 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.
##
# MergeVTEC - merges two "active" tables together.
# Originally written by Mark Mathewson FSL
#
# Port of MergeVTEC code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/25/13 1447 dgilling Initial Creation.
#
#
import copy
import cPickle
import gzip
import logging
import os
import sys
import time
import ActiveTableRecord
import siteConfig
import VTECPartners
import VTECTableSqueeze
import VTECTableUtil
from java.util import ArrayList
from com.raytheon.uf.common.activetable import MergeResult
from com.raytheon.uf.common.activetable import VTECChange
from com.raytheon.uf.common.localization import PathManagerFactory
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as LocalizationType
from com.raytheon.uf.common.site import SiteMap
class MergeVTEC(VTECTableUtil.VTECTableUtil):
def __init__(self, activeTable, activeTableMode, newRecords, offsetSecs=0.0,
makeBackups=True, logger=None):
# activeTable - current activeTable records
# activeTableMode - which table is being modified--OPERATIONAL or PRACTICE
# newRecords - records to merge in to activeTable
# inputIsGZIP (0,1) - remote input file is gzipped
# offsetSecs - Number of seconds +/- current time
# makeBackups (False, True) - make backups of previous table
# logger - python logging object to send all logs to
if logger is not None:
self._log = logger
else:
self._log = self.__initLogging()
# create a dummy name to simplify the file access code in VTECTableUtil
pathMgr = PathManagerFactory.getPathManager()
commonSiteCx = pathMgr.getContextForSite(
LocalizationType.COMMON_STATIC, siteConfig.GFESUITE_SITEID)
filePath = pathMgr.getFile(commonSiteCx,"vtec").getPath()
self._activeTableFilename = os.path.join(filePath, activeTableMode + ".tbl")
# to ensure time calls are based on Zulu
os.environ['TZ'] = "GMT0"
self._time = time.time() + offsetSecs #present time
self._makeBackups = makeBackups
VTECTableUtil.VTECTableUtil.__init__(self, self._activeTableFilename)
# get the SPC site id from the configuration file
self._spcSite = getattr(VTECPartners, "VTEC_SPC_SITE", "KWNS")
self._tpcSite = getattr(VTECPartners, "VTEC_TPC_SITE", "KNHC")
# get our site
siteid = siteConfig.GFESUITE_SITEID
self._ourSite = self._get4ID(siteid)
self._siteFilter = self._getFilterSites()
self._log.info("MergeVTEC Starting")
self._log.info("localFN= " + self._activeTableFilename + " sites= "
+ repr(self._siteFilter))
#read table to merge
otherTable = newRecords
self._log.info("Remote Table size: %d", len(otherTable))
#read active table
self._log.info("Active Table size: %d", len(activeTable))
#save a copy for later backup purposes
oldActiveTable = copy.deepcopy(activeTable)
#delete "obsolete" records from our table and the other table
vts = VTECTableSqueeze.VTECTableSqueeze(self._time)
activeTable, tossRecords = vts.squeeze(activeTable)
self._log.info("Active Table squeezed size: %d", len(activeTable))
self._log.info("Other Table size: %d", len(otherTable))
otherTable, tossRecordsOther = vts.squeeze(otherTable)
self._log.info("Other Table squeezed size: %d", len(otherTable))
#merge the tables
updatedTable, toDelete, changes = self._mergeTable(activeTable, otherTable)
self._log.info("Updated Active Table size: %d", len(updatedTable))
updatedTable, tossRecordsMerged = vts.squeeze(updatedTable)
self._log.info("Updated Active Table squeeze size: %d",
len(updatedTable))
del vts
self._updatedTable = []
self._purgedTable = []
self._changes = []
#notify the ifpServer of changes, save a backup copy
if tossRecords or tossRecordsMerged or changes:
self._log.debug("#tossRecords: %d", len(tossRecords))
self._log.debug("#tossRecordsMerged: %d", len(tossRecordsMerged))
self._log.debug("#changes: %d", len(changes))
# save lists for later retrieval
self._updatedTable = updatedTable
self._purgedTable.extend(tossRecords)
self._purgedTable.extend(toDelete)
self._purgedTable.extend([rec for rec in tossRecordsMerged if rec in oldActiveTable])
self._changes = changes
#save backup copy
if self._makeBackups:
oldActiveTable = self._convertTableToPurePython(oldActiveTable, siteid)
self.saveOldActiveTable(oldActiveTable)
pTime = getattr(VTECPartners, "VTEC_BACKUP_TABLE_PURGE_TIME",
168)
self.purgeOldSavedTables(pTime)
self._log.info("MergeVTEC Finished")
# merges the active and other table together and returns the merged
# table along with the list of changes that occurred.
def _mergeTable(self, activeTable, otherTable):
changes = []
purges = []
compare = ['id', 'phen', 'sig', 'officeid', 'etn', 'pil']
compare1 = ['phen', 'sig', 'officeid']
compare2 = ['officeid', 'pil', 'phen', 'sig', 'etn']
missingEntriesPast = []
missingEntriesAct = []
newReplaceEntriesPast = []
oldReplaceEntriesPast = []
newReplaceEntriesAct = []
oldReplaceEntriesAct = []
ignoredNewReplaceAct = []
ignoredOldReplaceAct = []
currentYear = time.gmtime(self._time)[0]
terminations = ('CAN', 'EXP', 'UPG')
# we process each entry in the other (received) table
for othRec in otherTable:
# filter out all other sites we aren't interested in
if self._siteFilter is not None and \
othRec['officeid'] not in self._siteFilter:
continue
# filter out ROU and COR codes
if othRec['act'] in ["ROU","COR"]:
continue
othRecYear = time.gmtime(othRec['issueTime'])[0]
# check our active table for this event. if there is only one record
# and it is a canceled event, then we keep it that way.
matches = []
for rec in activeTable:
if self.hazardCompare(rec, othRec, compare2):
atRecYear = time.gmtime(rec['issueTime'])[0]
if othRecYear == atRecYear:
matches.append(rec)
if len(matches) == 1 and matches[0]['act'] in terminations:
# done with this remote record
continue
# if the remote table has a single canceled record,
# copy the record if needed and remove the rest for the event
canceled = othRec['act'] in terminations
if canceled:
# determine if the remote table has a single record
for othRec2 in otherTable:
if self.hazardCompare(othRec2, othRec, compare2):
recYear = time.gmtime(othRec2['issueTime'])[0]
if recYear == othRecYear and othRec2['id'] != othRec['id']:
canceled = False
break
if canceled:
# find all the record in our active table for this event
matches = []
for i, rec in enumerate(activeTable):
if self.hazardCompare(rec, othRec, compare2):
atRecYear = time.gmtime(rec['issueTime'])[0]
if othRecYear == atRecYear:
matches.append(i)
changed = False
found = False
matches.reverse()
for i in matches:
rec = activeTable[i]
if rec['id'] == othRec['id']:
found = True
# replace record if not the same
if rec != othRec:
newReplaceEntriesAct.append(othRec)
oldReplaceEntriesAct.append(rec)
activeTable[i] = othRec
changed = True
else:
# remove other records for this event
oldReplaceEntriesAct.append(rec)
del activeTable[i]
changed = True
if not found:
# add the remote record
if len(matches) > 0:
newRplaceEntriesAct.append(othRec)
else:
missingEntriesAct.append(othRec)
activeTable.append(othRec)
changed = True
if changed:
chgRec = (othRec['officeid'], othRec['pil'], othRec['phensig'])
if chgRec not in changes:
changes.append(chgRec)
# done with this remote record
continue
# currently active events
if othRec['endTime'] >= self._time:
# find a match in otherTable that is in our active table
# and replace it if newer, but only if it is from the same
# issuance year.
found = 0
for i in xrange(len(activeTable)):
if self.hazardCompare(activeTable[i], othRec, compare):
found = 1
atRecYear = time.gmtime(activeTable[i]['issueTime'])[0]
if othRec['issueTime'] > activeTable[i]['issueTime']:
if othRecYear == atRecYear:
newReplaceEntriesAct.append(othRec)
oldReplaceEntriesAct.append(activeTable[i])
activeTable[i] = othRec #replace the record
chgRec = (activeTable[i]['officeid'],
activeTable[i]['pil'], activeTable[i]['phensig'])
if chgRec not in changes:
changes.append(chgRec)
else:
ignoredNewReplaceAct.append(othRec)
ignoredOldReplaceAct.append(activeTable[i])
break
# if a match wasn't found, then we may need to add the record
# into our active table
if found == 0:
activeTable.append(othRec) #add the record
missingEntriesAct.append(othRec)
chgRec = (othRec['officeid'], othRec['pil'], othRec['phensig'])
if chgRec not in changes:
changes.append(chgRec)
# past events
else:
othRecYear = time.gmtime(othRec['issueTime'])[0]
if currentYear != othRecYear:
continue #only care about this years
# find the highest ETN for the current year per phen/sig
# in active table and compare to the other table. If found
# higher 'remote' record, replace the record.
maxETN = None
maxETNIndex = None
for i in xrange(len(activeTable)):
a = activeTable[i]
if self.hazardCompare(a, othRec, compare1) and \
time.gmtime(a['issueTime'])[0] == currentYear:
if maxETN is None or a['etn'] > maxETN:
maxETN = a['etn'] #save maxETN
maxETNIndex = i #save the index
if maxETN is not None and othRec['etn'] > maxETN:
newReplaceEntriesPast.append(othRec)
oldReplaceEntriesPast.append(activeTable[maxETNIndex])
activeTable[maxETNIndex] = othRec #replace record
chgRec = (othRec['officeid'], othRec['pil'], othRec['phensig'])
if chgRec not in changes:
changes.append(chgRec)
#if phen/sig not found, then add it
if maxETN is None:
activeTable.append(othRec) #add the record
missingEntriesPast.append(othRec)
chgRec = (othRec['officeid'], othRec['pil'], othRec['phensig'])
if chgRec not in changes:
changes.append(chgRec)
# log the changes
if len(missingEntriesAct):
self._log.debug("Active Missing entries added: %s",
self.printActiveTable(missingEntriesAct, 1))
if len(newReplaceEntriesAct):
self._log.debug("Active Replacement entries (new): %s",
self.printActiveTable(newReplaceEntriesAct, 1))
if len(oldReplaceEntriesAct):
self._log.debug("Active Entries Replaced (old): %s",
self.printActiveTable(oldReplaceEntriesAct, 1))
if len(missingEntriesPast):
self._log.debug("Past Missing entries added %s",
self.printActiveTable(missingEntriesPast, 1))
if len(newReplaceEntriesPast):
self._log.debug("Past Replacement entries (new): %s",
self.printActiveTable(newReplaceEntriesPast, 1))
if len(oldReplaceEntriesPast):
self._log.debug("Past Entries Replaced (old): %s",
self.printActiveTable(oldReplaceEntriesPast, 1))
if len(ignoredNewReplaceAct):
self._log.debug("Ignored Different Year Issuance (new): %s",
self.printActiveTable(ignoredNewReplaceAct, 1))
self._log.debug("Ignored Different Year Issuance (old): %s",
self.printActiveTable(ignoredOldReplaceAct, 1))
self._log.debug("Table Changes: %s", changes)
purges.extend(oldReplaceEntriesAct)
purges.extend(oldReplaceEntriesPast)
return activeTable, purges, changes
def getMergeResults(self):
if not self._updatedTable and not self._purgedTable and not self._changes:
return None
updatedList = ArrayList()
for rec in self._updatedTable:
updatedList.add(rec.javaRecord())
purgedList = ArrayList()
for rec in self._purgedTable:
purgedList.add(rec.javaRecord())
changeList = ArrayList()
for c in self._changes:
changeList.add(VTECChange(c[0],c[1],c[2]))
result = MergeResult(updatedList, purgedList, changeList)
return result
def _getFilterSites(self):
#gets the list of filter sites, which is the list specified, plus
#SPC plus our own site. Returns None for no-filtering.
sites = getattr(VTECPartners, "VTEC_MERGE_SITES", [])
if sites is None:
return None
sites.append(self._spcSite)
sites.append(self._tpcSite)
sites.append(self._ourSite)
self._log.debug("Filter Sites: %s", sites)
return sites
#convert 3 letter to 4 letter site ids
def _get4ID(self, id):
return SiteMap.getInstance().getSite4LetterId(id)
def __initLogging(self):
logPath = os.path.join(siteConfig.GFESUITE_LOGDIR,
time.strftime("%Y%m%d", time.gmtime()), 'MergeVTEC.log')
try:
os.makedirs(os.path.dirname(logPath))
except OSError as e:
if e.errno != errno.EEXIST:
sys.stderr.write("Could not create log directory " + os.path.dirname(logPath))
sys.exit(-1)
logging.basicConfig(filename=logPath,
format="%(levelname)s %(asctime)s [%(process)d:%(thread)d] %(filename)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
return logging.getLogger("MergeVTEC")
def merge(activeTable, activeTableMode, newRecords, drt=0.0, makeBackups=True,
logger=None):
pyActive = []
for i in range(activeTable.size()):
pyActive.append(ActiveTableRecord.ActiveTableRecord(activeTable.get(i)))
pyNew = []
for i in range(newRecords.size()):
pyNew.append(ActiveTableRecord.ActiveTableRecord(newRecords.get(i)))
decoder = MergeVTEC(pyActive, activeTableMode, pyNew, drt, makeBackups, logger)
mergeResults = decoder.getMergeResults()
decoder = None
return mergeResults

View file

@ -17,6 +17,7 @@
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#VTEC_Partners.py - configuration file to control filtering and merging
#of VTEC active table.
@ -46,7 +47,7 @@ VTEC_DECODER_SITES = []
# The following list is a set of product categories (e.g., ZFP, WOU) that
# when decoded, the text for each segment is captured. The text is not
# normally needed to be captured except for warning-style products.
VTEC_CAPTURE_TEXT_CATEGORIES = []#['WSW', 'NPW', 'RFW', 'FFA', 'CFW', 'MWS', 'HLS', 'MWW']
VTEC_CAPTURE_TEXT_CATEGORIES = ['WSW', 'NPW', 'RFW', 'FFA', 'CFW', 'MWS', 'HLS', 'MWW']
# Remapping of product pils. This is required for certain VTEC events
# if a hazard is created in one pil and then updated or cancelled in another

View file

@ -213,7 +213,8 @@ class VTECTableSqueeze:
for ps in phensig:
issueYears = d[o][ps].keys()
for iy in issueYears:
etns = d[o][ps][iy].keys()
dd = d[o][ps][iy]
etns = dd.keys()
#get two maxetn for tropicalPhen (one for site created and the other
#for NHC created. The etn will be more than 100 for NHC hazards),
@ -227,50 +228,75 @@ class VTECTableSqueeze:
else:
maxetn2 = maxetn1
ids1 = d[o][ps][iy][maxetn1]
ids1 = dd[maxetn1]
minid1 = min(ids1)
ids2 = ids1
minid2 = minid1
if maxetn2 > 0 and maxetn2 != maxetn1:
ids2 = d[o][ps][iy][maxetn2]
ids2 = dd[maxetn2]
minid2 = min(ids2)
#determine what to keep and what to toss
for etn in d[o][ps][iy].keys():
for id in d[o][ps][iy][etn].keys():
for rec in d[o][ps][iy][etn][id]:
for etn in etns:
all_hourOld = True
all_cancelled = True
all_twoWeeksOld = True
ufn = None
ufn = rec.get('ufn',0)
for id in dd[etn].keys():
for rec in dd[etn][id]:
if ufn is None:
ufn = rec.get('ufn', False)
hourOld = self.__ctime > rec['endTime'] + (1*3600)
twoWeeksOld = self.__ctime > rec['issueTime'] + (14*86400)
cancelled = rec['act'] in ['CAN','UPG','EXP']
# keep records that are:
# 1. are UFN, not cancelled, and not older then two weeks.
# 2. not UFN, and not ended in the last hour
# 3. cancelled, from this year, are minid, and are maxetn
if ufn and not cancelled and not twoWeeksOld: # 1
all_hourOld &= hourOld
all_cancelled &= cancelled
all_twoWeeksOld &= twoWeeksOld
# keep records if the event:
# 1. is UFN, not cancelled, and not older then two weeks.
# 2. not UFN, and not ended in the last hour
# 3. cancelled, from this year, keep only records that are minid, and maxetn
if ufn and not all_cancelled and not all_twoWeeksOld: # 1
for id in dd[etn].keys():
for rec in dd[etn][id]:
saveRec.append(rec)
elif not ufn and not hourOld: # 2
elif not ufn and not all_hourOld: # 2
for id in dd[etn].keys():
for rec in dd[etn][id]:
saveRec.append(rec)
elif iy == self.__thisYear and \
rec['id'] == minid1 and \
rec['etn'] == maxetn1:
if rec['officeid'] in ['KNHC'] and twoWeeksOld:
LogStream.logDebug("******** WILL PURGE *******", rec['vtecstr'])
else:
saveRec.append(rec)
elif iy == self.__thisYear and \
maxetn1 != maxetn2 and \
rec['phen'] in tropicalPhen and \
rec['id'] == minid2 and \
rec['etn'] == maxetn2: # 3
saveRec.append(rec)
# otherwise, remove them
elif iy == self.__thisYear and etn == maxetn1: # 3
for id in dd[etn].keys():
if (id == minid1):
for rec in dd[etn][id]:
saveRec.append(rec)
else:
for rec in dd[etn][id]:
LogStream.logDebug("******** WILL PURGE *******", rec['vtecstr'])
purgeRec.append(rec)
elif (iy == self.__thisYear) and (etn == maxetn2): # 3
for id in dd[etn].keys():
if (id == minid2):
for rec in dd[etn][id]:
saveRec.append(rec)
else:
for rec in dd[etn][id]:
LogStream.logDebug("******** WILL PURGE *******", rec['vtecstr'])
purgeRec.append(rec)
else:
for id in dd[etn].keys():
for rec in dd[etn][id]:
LogStream.logDebug("******** WILL PURGE *******", rec['vtecstr'])
purgeRec.append(rec)
return saveRec, purgeRec
#prints the dictionary organized by oid, phensig, issueYear, etn, id

View file

@ -19,10 +19,22 @@
##
# Utility classes for the VTEC active table
import time, copy, types
import copy
import cPickle
import errno
import glob
import gzip
import os
import stat
import time
import types
import LogStream
import JUtil
from java.util import ArrayList
from com.raytheon.uf.edex.activetable import ActiveTable
class VTECTableUtil:
@ -290,4 +302,85 @@ class VTECTableUtil:
return "K" + id
#------------------------------------------------------------------
# Table lock/unlock read/write utility
#------------------------------------------------------------------
def saveOldActiveTable(self, oldActiveTable):
#saves off the specified table and time stamps it
if self._activeTableFilename is None:
raise Exception, "saveOldActiveTable without filename"
#determine filename
directory = os.path.join(os.path.dirname(self._activeTableFilename), "backup")
try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
LogStream.logProblem("Could not create active table backup directory:",
directory, LogStream.exc())
raise e
gmtime = time.gmtime(time.time())
format = "%Y%m%d_%H%M%S"
baseN = os.path.basename(self._activeTableFilename)
fn = time.strftime(format, gmtime) + "_" + baseN
filename = os.path.join(directory, fn + ".gz")
t = time.time()
try:
os.chmod(filename, 0666)
os.remove(filename)
except:
pass
#output file
#gzip it to save space
with gzip.GzipFile(filename, 'wb', 9) as fd:
buf = cPickle.dumps(oldActiveTable)
fd.write(buf)
os.chmod(filename, 0664)
t1 = time.time()
tstr = "%.3f" % (t1-t)
LogStream.logVerbose("Saved Previous Active Table: ", fn, "t=",
tstr, "sec.")
def purgeOldSavedTables(self, purgeTime):
#purges old saved tables
if self._activeTableFilename is None:
raise Exception, "purgeOldSavedTables without filename"
#calculate purge time
purgeTime = time.time() - (purgeTime * 3600)
#directory and files
directory = os.path.join(os.path.dirname(self._activeTableFilename), "backup")
baseN = os.path.basename(self._activeTableFilename)
idx = baseN.find(".")
if idx != -1:
baseN = baseN[0:idx]
files = glob.glob(directory + "/*" + baseN + "*.gz")
#delete files older than purgeTime
for f in files:
try:
modTime = os.stat(f)[stat.ST_MTIME]
if modTime < purgeTime:
os.remove(f)
LogStream.logDebug("Removing old file: ", f)
except:
LogStream.logProblem("Problem Removing old backup file: ", f,
LogStream.exc())
def _convertTableToPurePython(self, table, siteId):
javaRecList = ArrayList()
for rec in table:
javaRecList.add(rec.javaRecord())
javaDictFormat = ActiveTable.convertToDict(javaRecList, siteId)
return JUtil.javaObjToPyVal(javaDictFormat)

View file

@ -0,0 +1,103 @@
##
# 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.
##
#
# Port of ingestAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 02/13/13 1447 dgilling Initial Creation.
#
#
import errno
import logging
import os
import sys
import time
import xml.etree.ElementTree as ET
import IrtAccess
import MergeVTEC
import siteConfig
log = None
def init_logging():
logPath = os.path.join(siteConfig.GFESUITE_LOGDIR,
time.strftime("%Y%m%d", time.gmtime()), 'ingestAT.log')
try:
os.makedirs(os.path.dirname(logPath))
except OSError as e:
if e.errno != errno.EEXIST:
sys.stderr.write("Could not create log directory " + os.path.dirname(logPath))
sys.exit(-1)
logging.basicConfig(filename=logPath,
format="%(levelname)s %(asctime)s [%(process)d:%(thread)d] %(filename)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
global log
log = logging.getLogger("ingestAT")
def execute_ingest_at(incomingRecords, activeTable, atName, ztime, makeBackups, xmlIncoming):
# log the source of this data
if xmlIncoming is not None:
irt = IrtAccess.IrtAccess("")
xmlTree = ET.ElementTree(ET.XML(xmlIncoming))
sourceE = xmlTree.find('source')
for addressE in sourceE.getchildren():
sourceServer = irt.decodeXMLAddress(addressE)
if sourceServer is None:
continue
log.info("Source Server: " + irt.printServerInfo(sourceServer))
results = None
try:
results = MergeVTEC.merge(activeTable, atName, incomingRecords, ztime, makeBackups,
logging.getLogger('MergeVTEC'))
except:
log.exception("MergeVTEC fail:")
return results
def runFromJava(activeTable, activeTableMode, newRecords, drt, makeBackups,
xmlIncoming):
init_logging()
log.info('************* ingestAT ************************')
startT = time.time()
results = execute_ingest_at(newRecords, activeTable, activeTableMode, drt,
makeBackups, xmlIncoming)
#--------------------------------------------------------------------
# Finish
#--------------------------------------------------------------------
endT = time.time()
log.info("Final: wctime: {0:-6.2f}, cputime: {1:-6.2f}".format(endT - startT, time.clock()))
return results

View file

@ -0,0 +1,268 @@
##
# 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.
##
#
# Port of requestAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 02/06/13 1447 dgilling Initial Creation.
#
#
import cPickle
import errno
import logging
import os
import sys
import tempfile
import time
import xml.etree.ElementTree as ET
import IrtAccess
import siteConfig
import VTECPartners
from com.raytheon.uf.common.activetable import ActiveTableMode
from com.raytheon.uf.edex.activetable import ActiveTable
log = None
def init_logging():
logPath = os.path.join(siteConfig.GFESUITE_LOGDIR,
time.strftime("%Y%m%d", time.gmtime()), 'requestAT.log')
try:
os.makedirs(os.path.dirname(logPath))
except OSError as e:
if e.errno != errno.EEXIST:
sys.stderr.write("Could not create log directory " + os.path.dirname(logPath))
sys.exit(-1)
logging.basicConfig(filename=logPath,
format="%(levelname)s %(asctime)s [%(process)d:%(thread)d] %(filename)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
global log
log = logging.getLogger("requestAT")
def execute_request_at(serverHost, serverPort, serverProtocol, mhsid, siteID, ancf,
bncf, xmtScript):
#--------------------------------------------------------------------
# Create a message - pickled
# (MHSsiteID, mySiteID, listOfVTECMergeSites, countDict, issueTime)
# Note that VTEC_MERGE_SITES does not contain our site or SPC, TPC.
#--------------------------------------------------------------------
# determine my 4 letter siteid
if siteID in ['SJU']:
mysite4 = "TJSJ"
elif siteID in ['AFG','AJK','HFO','GUM']:
mysite4 = "P" + siteID
elif siteID in ['AER','ALU']:
mysite4 = "PAFC"
else:
mysite4 = "K" + siteID
otherSites = [mysite4, VTECPartners.VTEC_SPC_SITE,
VTECPartners.VTEC_TPC_SITE]
# determine the MHS WMO id for this message
wmoid = "TTAA00 " + mysite4
wmoid += " " + time.strftime("%d%H%M", time.gmtime(time.time()))
# connect to ifpServer and retrieve active table
actTab = ActiveTable.getActiveTable(mysite4, ActiveTableMode.OPERATIONAL)
# analyze active table to get counts
countDict = {}
issueTime = 0
for i in xrange(actTab.size()):
rec = actTab.get(i)
# only care about our own sites that we merge
if rec.getOfficeid() not in VTECPartners.VTEC_MERGE_SITES and \
rec.getOfficeid() not in otherSites:
continue
recIssueTime = rec.getIssueTime().getTimeInMillis() / 1000
#track latest
issueTime = max(recIssueTime, issueTime)
cnt = countDict.get(rec.getOfficeid(), 0) #get old count
countDict[rec.getOfficeid()] = cnt + 1
data = (mhsid, siteID, VTECPartners.VTEC_MERGE_SITES, countDict, issueTime)
log.info("Data: " + repr(data))
tempdir = os.path.join(siteConfig.GFESUITE_HOME, "products", "ATBL")
with tempfile.NamedTemporaryFile(suffix='.reqat', dir=tempdir, delete=False) as fp:
fname = fp.name
buf = cPickle.dumps(data)
fp.write(buf)
#--------------------------------------------------------------------
# Assemble XML source/destination document
#--------------------------------------------------------------------
msgSendDest = [] #list of mhs sites to send request
irt = IrtAccess.IrtAccess(ancf, bncf)
iscE = ET.Element('isc')
# this is the requestor of the data
sourceServer = {'mhsid': mhsid, 'host': serverHost, 'port': serverPort,
'protocol': serverProtocol, 'site': siteID}
irt.addSourceXML(iscE, sourceServer)
log.info("Requesting Server: " + irt.printServerInfo(sourceServer))
# who is running the domains requested?
sites = VTECPartners.VTEC_TABLE_REQUEST_SITES
if not sites:
log.error('No sites defined for VTEC_TABLE_REQUEST_SITES')
sys.exit(1)
status, xml = irt.getServers(sites)
if not status:
log.error('Failure to getServers from IRT')
sys.exit(1)
# decode the XML
try:
serverTree = ET.ElementTree(ET.XML(xml))
serversE = serverTree.getroot()
except:
log.exception("Malformed XML on getServers()")
sys.exit(1)
if serversE.tag != "servers":
log.error("Servers packet missing from web server")
sys.exit(1)
# process each requested domain returned to us
chosenServers = []
matchingServers = []
for domainE in serversE:
if domainE.tag != "domain":
continue
servers = [] #list of servers for this domain
# decode each server in the domain
for addressE in domainE.getchildren():
info = irt.decodeXMLAddress(addressE)
if info is None:
continue #not address tag
servers.append(info)
matchingServers.append(info)
# server search list in priority. The px3 entries are used for
# dual domain for AFC.
hp = [('dx4','98000000'),('px3', '98000000'), ('dx4','98000001'),
('px3', '98000001')]
# choose one server from this domain, find first dx4, 98000000
# try to use one with the same mhsidDest as the site, which
# would be the primary operational GFE. Note that the px3 entries
# are for AFC.
found = False
for matchServer, matchPort in hp:
for server in servers:
if server['host'][0:3] == matchServer and \
server['port'] == matchPort and server['mhsid'] == siteID:
chosenServers.append(server)
if server['mhsid'] not in msgSendDest:
msgSendDest.append(server['mhsid'])
found = True
break
# find first dx4, 98000000, but perhaps a different mhsid
# this is probably not the primary operational GFE
if not found:
for matchServer, matchPort in hp:
for server in servers:
if server['host'][0:3] == matchServer and \
server['port'] == matchPort:
chosenServers.append(server)
if server['mhsid'] not in msgSendDest:
msgSendDest.append(server['mhsid'])
found = True
break
# if didn't find standard one, then take the first one, but don't
# take ourselves unless we are the only one.
if not found and servers:
for server in servers:
if server['mhsid'] != mhsid and server['host'] != serverHost \
and server['port'] != serverPort and \
server['mhsid'] != siteID:
chosenServers.append(server)
if server['mhsid'] not in msgSendDest:
msgSendDest.append(server['mhsid'])
found = True
if not found:
chosenServers.append(servers[0])
if servers[0]['mhsid'] not in msgSendDest:
msgSendDest.append(servers[0]['mhsid'])
# Display the set of matching servers
s = "Matching Servers:"
for x in matchingServers:
s += "\n" + irt.printServerInfo(x)
log.info(s)
# Display the chosen set of servers
s = "Chosen Servers:"
for x in chosenServers:
s += "\n" + irt.printServerInfo(x)
log.info(s)
irt.addDestinationXML(iscE, chosenServers)
# create the XML file
with tempfile.NamedTemporaryFile(suffix='.xml', dir=tempdir, delete=False) as fd:
fnameXML = fd.name
fd.write(ET.tostring(iscE))
#--------------------------------------------------------------------
# Now send the message
#--------------------------------------------------------------------
irt.transmitFiles("GET_ACTIVE_TABLE2", msgSendDest, mhsid,
[fname, fnameXML], xmtScript)
def runFromJava(serverHost, serverPort, serverProtocol, mhsid, siteID, ancf,
bncf, xmtScript):
init_logging()
log.info('*********** requestAT ******************')
startT = time.time()
try:
execute_request_at(serverHost, serverPort, serverProtocol, mhsid,
siteID, ancf, bncf, xmtScript)
except:
log.exception('Error requesting active table')
#--------------------------------------------------------------------
# Finish
#--------------------------------------------------------------------
endT = time.time()
log.info("Final: wctime: {0:-6.2f}, cputime: {1:-6.2f}".format(endT - startT, time.clock()))

View file

@ -0,0 +1,300 @@
##
# 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.
##
#
# Port of sendAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 02/08/13 1447 dgilling Initial Creation.
#
#
import cPickle
import errno
import gzip
import logging
import os
import sys
import time
import tempfile
import stat
import xml.etree.ElementTree as ET
import IrtAccess
import JUtil
import siteConfig
import VTECPartners
import VTECTableSqueeze
# Configuration Item for Test Purposes
FORCE_SEND = False #Set to True to always send even if no updates required.
log = None
def init_logging():
logPath = os.path.join(siteConfig.GFESUITE_LOGDIR,
time.strftime("%Y%m%d", time.gmtime()), 'sendAT.log')
try:
os.makedirs(os.path.dirname(logPath))
except OSError as e:
if e.errno != errno.EEXIST:
sys.stderr.write("Could not create log directory " + os.path.dirname(logPath))
sys.exit(-1)
logging.basicConfig(filename=logPath,
format="%(levelname)s %(asctime)s [%(process)d:%(thread)d] %(filename)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
global log
log = logging.getLogger("sendAT")
def execute_send_at(myServerHost, myServerPort, myServerProtocol,
myServerMHSID, myServerSite, sites, filterSites, mhsSites,
issueTime, countDict, fname, xmlIncoming, xmtScript):
log.info('reqSite= ' + repr(sites))
log.info('filterSites= ' + repr(filterSites))
log.info('mhsSite= ' + repr(mhsSites))
log.info('reqCountDict= ' + repr(countDict))
if issueTime is None:
log.info('reqIssueTime= None')
else:
log.info('reqIssueTime= ' + str(issueTime) + ' ' +
time.asctime(time.gmtime(issueTime)))
irt = IrtAccess.IrtAccess("")
myServer = {'mhsid': myServerMHSID, 'host': myServerHost, 'port': myServerPort,
'protocol': myServerProtocol, 'site': myServerSite}
log.info('MyServer: ' + irt.printServerInfo(myServer))
#--------------------------------------------------------------------
# Prepare the file for sending
#--------------------------------------------------------------------
with open(fname, 'rb') as fd:
buf = fd.read()
os.remove(fname)
table = cPickle.loads(buf) #unpickle it
log.info("Local Table Length= " + str(len(table)))
filtTable = []
# filter by sites listing
if filterSites:
for t in table:
if t['oid'] in filterSites or t['oid'][1:4] in sites or \
t['oid'] == VTECPartners.VTEC_SPC_SITE or \
t['oid'] == VTECPartners.VTEC_TPC_SITE:
filtTable.append(t)
else:
filtTable = table #no filtering
log.info("Site Filtered Table Length= " + str(len(filtTable)))
# eliminate obsolete records
ctime = time.time() #now time
vts = VTECTableSqueeze.VTECTableSqueeze(ctime)
filtTable = rename_fields_for_A2(filtTable)
actTable, tossRecords = vts.squeeze(filtTable)
actTable = rename_fields_for_A1(actTable)
log.info("Squeezed Table Length= " + str(len(actTable)))
# check issuance time - any times newer in remote table (this table) than
# the local table (requesting site)?
if issueTime is not None:
newerRec = False
newestRec = 0.0
for t in actTable:
if newestRec < t['issueTime']:
newestRec = t['issueTime']
if issueTime < newestRec:
newerRec = True
log.info("NewestFound= " + str(newestRec) + ' ' +
time.asctime(time.gmtime(newestRec)))
log.info("IssueTime check. Newer record found= " + str(newerRec))
else:
newerRec = True #just assume there are newer records
# check "counts" for number of records. Any more records means that
# we may be missing some records.
if countDict:
missingRec = False
localCountDict = {}
for t in actTable:
if localCountDict.has_key(t['oid']):
localCountDict[t['oid']] = localCountDict[t['oid']] + 1
else:
localCountDict[t['oid']] = 1
for site in localCountDict:
reqCount = countDict.get(site, 0) #number in requesting site
if reqCount != localCountDict[site]: #records different in request site
missingRec = True
break
log.info("MissingRec check. Missing record found= " + str(missingRec))
log.info("lclCountBySite= " + repr(localCountDict))
log.info("reqCountBySite= " + repr(countDict))
else:
missingRec = True #just assume there are
#should we send?
if missingRec or newerRec or FORCE_SEND:
sendIt = True
else:
sendIt = False
if sendIt:
actTablePickled = cPickle.dumps(actTable) #repickle it
rawSize = len(actTablePickled)
#output it as gzipped
fname = fname + ".gz"
with gzip.open(fname, 'wb', 6) as fd:
fd.write(actTablePickled)
gzipSize = os.stat(fname)[stat.ST_SIZE]
log.info('#dataSize: ' + str(rawSize) + ', #gzipSize: ' + str(gzipSize))
#--------------------------------------------------------------------
# Create the destination XML file
#--------------------------------------------------------------------
iscOut = Element('isc')
irt.addSourceXML(iscOut, myServer)
destServers = []
if xmlIncoming is not None:
with open(xmlIncoming,'rb') as fd:
xml = fd.read()
os.remove(xmlIncoming)
reqTree = ET.ElementTree(ET.XML(xml))
sourceE = reqTree.find('source')
for addressE in sourceE.getchildren():
destServer = irt.decodeXMLAddress(addressE)
if destServer is None:
continue
destServers.append(destServer)
break
# no XML received on request, this is probably from an older site.
# create a dummy response XML file. Try all combinations. Only
# the mhsid is important for older sites.
else:
servers = []
for mhss in mhsSites:
for port in xrange(98000000, 98000002):
for site in sites:
for host in ['dx4f','px3']:
destServer = {'mhsid': mhss, 'host': host,
'port': port, 'protocol': "20070723",
'site': site}
destServers.append(destServer)
irt.addDestinationXML(iscOut, destServers) #add the dest server xml
# print out destinations
s = "Destinations:"
for destServer in destServers:
s += "\n" + irt.printServerInfo(destServer)
log.info(s)
# create XML file
tempdir = os.path.join(siteConfig.GFESUITE_HOME, "products", "ATBL")
with tempfile.NamedTemporaryFile(suffix='.xml', dir=tempdir, delete=False) as fd:
fnameXML = fd.name
fd.write(ET.tostring(iscOut))
#--------------------------------------------------------------------
# Send it
#--------------------------------------------------------------------
irt.transmitFiles("PUT_ACTIVE_TABLE2", mhsSites, myServerSite,
[fname, fnameXML], xmtScript)
else:
log.info("Send has been skipped")
def rename_fields_for_A1(table):
newTable = []
for record in table:
record['oid'] = record['officeid']
del record['officeid']
record['vstr'] = record['vtecstr']
del record['vtecstr']
record['end'] = record['endTime']
del record['endTime']
record['start'] = record['startTime']
del record['startTime']
record['key'] = record['phensig']
del record['phensig']
if record.has_key('segText'):
record['text'] = record['segText']
del record['segText']
newTable.append(record)
return newTable
def rename_fields_for_A2(table):
newTable = []
for record in table:
record['officeid'] = record['oid']
del record['oid']
record['vtecstr'] = record['vstr']
del record['vstr']
record['endTime'] = record['end']
del record['end']
record['startTime'] = record['start']
del record['start']
record['phensig'] = record['key']
del record['key']
if record.has_key('text'):
record['segText'] = record['text']
del record['text']
newTable.append(record)
return newTable
def runFromJava(myServerHost, myServerPort, myServerProtocol, myServerMHSID,
myServerSite, sites, filterSites, mhsSites, issueTime,
countDict, fname, xmlIncoming, xmtScript):
init_logging()
log.info('*********** sendAT ****************')
startT = time.time()
try:
sites = JUtil.javaObjToPyVal(sites)
filterSites = JUtil.javaObjToPyVal(filterSites)
mhsSites = JUtil.javaObjToPyVal(mhsSites)
countDict = JUtil.javaObjToPyVal(countDict)
execute_send_at(myServerHost, myServerPort, myServerProtocol,
myServerMHSID, myServerSite, sites, filterSites,
mhsSites, issueTime, countDict, fname, xmlIncoming,
xmtScript)
except:
log.exception('Error in sendAT:')
sys.exit(1)
#--------------------------------------------------------------------
# Finish
#--------------------------------------------------------------------
endT = time.time()
log.info("Final: wctime: {0:-6.2f}, cputime: {1:-6.2f}".format(endT - startT, time.clock()))

View file

@ -0,0 +1,40 @@
#!/bin/sh
##
# 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.
##
# this allows you to run this script from outside of ./bin
path_to_script=`readlink -f $0`
RUN_FROM_DIR=`dirname $path_to_script`
GFESUITE_DIR=`dirname $RUN_FROM_DIR`
# get the base environment
source ${RUN_FROM_DIR}/setup.env
# setup the environment needed to run the the Python
export LD_LIBRARY_PATH=${GFESUITE_DIR}/src/lib:${PYTHON_INSTALL}/lib
export PYTHONPATH=${RUN_FROM_DIR}/src:${RUN_FROM_DIR}/activeTable:$PYTHONPATH
# execute the Python module
_PYTHON="${PYTHON_INSTALL}/bin/python"
_MODULE="${RUN_FROM_DIR}/src/activeTable/MergeVTEC.py"
# quoting of '$@' is used to prevent command line interpretation
$_PYTHON $_MODULE -h ${DEFAULT_HOST} -p ${DEFAULT_PORT} -a OPERATIONAL "$@"

View file

@ -0,0 +1,40 @@
#!/bin/sh
##
# 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.
##
# this allows you to run this script from outside of ./bin
path_to_script=`readlink -f $0`
RUN_FROM_DIR=`dirname $path_to_script`
GFESUITE_DIR=`dirname $RUN_FROM_DIR`
# get the base environment
source ${RUN_FROM_DIR}/setup.env
# setup the environment needed to run the the Python
export LD_LIBRARY_PATH=${GFESUITE_DIR}/src/lib:${PYTHON_INSTALL}/lib
export PYTHONPATH=${RUN_FROM_DIR}/src:${RUN_FROM_DIR}/activeTable:$PYTHONPATH
# execute the Python module
_PYTHON="${PYTHON_INSTALL}/bin/python"
_MODULE="${RUN_FROM_DIR}/src/activeTable/requestAT.py"
# quoting of '$@' is used to prevent command line interpretation
$_PYTHON $_MODULE "$@"

View file

@ -0,0 +1,40 @@
#!/bin/sh
##
# 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.
##
# this allows you to run this script from outside of ./bin
path_to_script=`readlink -f $0`
RUN_FROM_DIR=`dirname $path_to_script`
GFESUITE_DIR=`dirname $RUN_FROM_DIR`
# get the base environment
source ${RUN_FROM_DIR}/setup.env
# setup the environment needed to run the the Python
export LD_LIBRARY_PATH=${GFESUITE_DIR}/src/lib:${PYTHON_INSTALL}/lib
export PYTHONPATH=${RUN_FROM_DIR}/src:${RUN_FROM_DIR}/activeTable:$PYTHONPATH
# execute the Python module
_PYTHON="${PYTHON_INSTALL}/bin/python"
_MODULE="${RUN_FROM_DIR}/src/activeTable/sendAT.py"
# quoting of '$@' is used to prevent command line interpretation
$_PYTHON $_MODULE "$@"

View file

@ -17,207 +17,224 @@
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
import gzip
#
# MergeVTEC - merges two "active" tables together.
# Ported from AWIPS1 code, originally written by Mark Mathewson FSL
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# ??/??/?? wldougher Initial Creation.
# 02/22/13 1447 dgilling Re-ported to better match
# requestAT/sendAT.
#
#
import argparse
import collections
import cPickle
import os
import stat
import time
import gzip
import logging
import getAT
#import JUtil
import dynamicserialize.dstypes.com.raytheon.uf.common.activetable.UpdateActiveTableRequest as UpdateActiveTableRequest
import os
import re
import sys
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import MergeActiveTableRequest
from ufpy import ThriftClient
from ufpy import TimeUtil
from getVtecAttribute import getVtecAttribute
from getFourCharSites import getFourCharSites
from ufpy import UsageArgumentParser
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger("MergeVTEC")
def merge(removeRemote, remoteATName, atName, inputIsGZIP=False, drt=None,
makeBackups=True, xmlIncoming=None, ourSites=None, host='localhost', port=9581):
oldTable = None
siteFilter = _getFilterSites(ourSites, host, port)
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.DEBUG)
log = logging.getLogger('MergeVTEC')
class CaseInsensitiveStringSet(collections.Set):
def __init__(self, iterable):
self.__internalSet = frozenset(iterable)
def __contains__(self, x):
return x.upper() in (item.upper() for item in self.__internalSet)
if drt is None:
drtOffset = 0.0;
else:
drtOffset = TimeUtil.determineDrtOffset(drt)[0]
atName = atName.upper()
if "PRACTICE" != atName:
atName = "OPERATIONAL"
try:
oldTable = getAT.getActiveTable(atName, siteFilter, host=host, port=port)
except:
log.error('Error getting old table for backup :', exc_info=True)
def __len__(self):
return len(self.__internalSet)
log.info("Active Table size: %d", len(oldTable))
if inputIsGZIP:
fd = gzip.open(remoteATName)
else:
fd = open(remoteATName)
def __iter__(self):
return iter(self.__internalSet)
try:
newTable = cPickle.load(fd)
finally:
class StoreDrtTimeAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
drtInfoTuple = TimeUtil.determineDrtOffset(values)
setattr(namespace, self.dest, drtInfoTuple[0])
class MergeVTEC(object):
def __init__(self, serverHost, serverPort, site, removeRemote,
remoteATName, atName, inputIsGZIP, drt=0, makeBackups=True,
xmlIncoming=None, fromIngestAT=False):
# serverHost - host name to send merge request to
# serverPort - port EDEX is running on
# site - site to perform merge operation as
# removeRemote (False, True) to remove remote table file upon completion
# remoteATName - name of remote active table file
# atName (OPERATIONAL, PRACTICE) - name of active table name
# inputIsGZIP (False, True) - remote input file is gzipped
# drt mode - None, or number of seconds +/- current time
# makeBackups (False, True) - make backups of table changes
# xmlIncoming - None, or XML data from MHS, only used in ingestAT mode
# fromIngestAT (False, True) - run in ingestAT mode, only affects logging
self._thriftClient = ThriftClient.ThriftClient(serverHost, serverPort, '/services')
self._site = site
self._deleteAfterProcessing = removeRemote
self._remoteTableFilename = remoteATName
self._activeTableFilename = atName
drt = 0 if drt is None else drt
self._drtInfo = float(drt)
self._makeBackups = makeBackups
self._xmlIncoming = xmlIncoming
self._fromIngestAT = fromIngestAT
log.info("MergeVTEC Starting")
log.info("remoteFN= " + self._remoteTableFilename +
" localFN= " + self._activeTableFilename +
" siteID= " + self._site)
# read table to merge
otherTable = self._readActiveTable(self._remoteTableFilename,
inputIsGZIP)
log.info("Remote Table size: %d", len(otherTable))
self._mergeTable(otherTable)
# delete remote file, if desired
if self._deleteAfterProcessing:
os.remove(self._remoteTableFilename)
log.info("MergeVTEC Finished")
def _mergeTable(self, otherTable):
# Send the new active table to the server.
# The real merge is done server-side.
request = MergeActiveTableRequest(otherTable, self._activeTableFilename,
self._site, self._drtInfo, self._xmlIncoming,
self._fromIngestAT, self._makeBackups)
response = self._thriftClient.sendRequest(request)
if not response.getTaskSuccess():
raise RuntimeError("Error performing merge: " + response.getErrorMessage())
def _readActiveTable(self, filename, inputIsGZIP=False):
# reads the active table and returns the list of records
records = []
# get the file and unpickle it
if not inputIsGZIP:
fd = open(filename, 'rb')
else:
fd = gzip.open(filename, 'rb')
buf = fd.read()
fd.close()
log.info("Other Table size: %d", len(newTable))
if len(newTable) > 0 and newTable[0].has_key('oid'):
convertToNewFormat(newTable)
log.debug("read active table, size: %d", len(buf))
records = cPickle.loads(buf)
log.debug("cPickle.loads, #records: %d", len(records))
# Filter out any extra sites in the new table.
if siteFilter is not None:
newTable = [x for x in newTable if x['officeid'] in siteFilter]
if records and records[0].has_key('oid'):
self._convertToNewFormat(records)
log.info("Other Table filtered size: %d", len(newTable))
# Send the new active table to the server.
# The real merge is done server-side.
request = UpdateActiveTableRequest()
request.setActiveTable(newTable)
request.setMode(atName)
request.setXmlSource(xmlIncoming)
request.setTimeOffset(drtOffset)
response = None
return records
thriftClient = ThriftClient.ThriftClient(host, port, "/services")
try:
response = thriftClient.sendRequest(request)
log.info('Other table merged.')
except:
log.error("Error sending other table to server:", exc_info=True)
if response is None:
log.error("No response was received from the server.")
return
errMsg = response.getMessage()
if errMsg is not None and "" != errMsg:
log.error("Error on server: %s", errMsg)
return
sourceInfo = response.getSourceInfo()
if sourceInfo is not None:
if type(sourceInfo) != list:
log.info("Converting sourceInfo from " + str(type(sourceInfo)))
# sourceInfo = JUtil.javaStringListToPylist(sourceInfo)
for source in sourceInfo:
log.info("Source Server: %s", str(source))
else:
log.info("sourceInfo is None")
if makeBackups and oldTable:
convertToOldFormat(oldTable)
dirname = os.path.dirname(os.path.abspath(remoteATName))
format = "%Y%m%d_%H%M%S"
gmtime = time.gmtime(time.time() + drtOffset)
bname = time.strftime(format, gmtime) + 'activeTable.gz'
bdirName = os.path.join(dirname, "backup")
if not os.path.exists(bdirName):
# create the dir and give everyone R/W access
os.mkdir(bdirName, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH |
stat.S_IWOTH)
fname = os.path.join(bdirName, bname)
saveFile = gzip.open(fname, "wb")
save_start = time.time()
try:
cPickle.dump(oldTable, saveFile)
finally:
saveFile.close()
def _convertToNewFormat(self, table):
'''Convert an AWIPS I table to AWIPS 2 internally'''
maxFutureTime = long(float(2**31-1))
for entry in table:
entry['officeid'] = entry['oid']
entry['vtecstr'] = entry['vstr']
entry['endTime'] = int(entry['end'])
entry['startTime'] = int(entry['start'])
entry['purgeTime'] = int(entry['purgeTime'])
entry['issueTime'] = int(entry['issueTime'])
entry['phensig'] = entry['key']
entry['state'] = 'Decoded'
if entry['endTime'] >= maxFutureTime:
entry['ufn'] = True
else:
entry['ufn'] = False
entry['productClass'] = entry['vtecstr'][1]
if not entry.has_key('rawMessage'):
entry['rawMessage'] = ''
# Give the user and user's group all access, others read access
os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH)
tdiff = time.time() - save_start
log.info('Saved Previous Active Table: %s t=%.3f sec. ', fname, tdiff)
elif makeBackups:
log.info('No old active table to back up.')
if removeRemote:
os.remove(remoteATName)
log.info('Input file ' + remoteATName + ' deleted.')
# Note: this is not always correct
entry['xxxid'] = entry['officeid'][1:]
if entry.has_key('text'):
entry['segText'] = entry['text']
# adapted from WarningDecoder...
lines = entry['segText'].split('\n')
for count in xrange(len(lines)-1):
dtg_search = re.search(r' ([0123][0-9][012][0-9][0-5][0-9])',
lines[count])
if dtg_search:
pil_search = re.search(r'^([A-Z]{3})(\w{3}|\w{2}|\w{1})',
lines[count+1])
if pil_search:
entry['xxxid'] = pil_search.group(2)
break
def _getFilterSites(ourSites, host, port):
if ourSites is None:
ourSite = os.getenv('GFESUITE_SITEID')
if ourSite is None:
raise Exception("Specify at least one site or set GFESUITE_SITEID.")
else:
ourSite = ourSites[0]
sites = getVtecAttribute('VTEC_MERGE_SITES', [], ourSite, host, port)
if sites is not None:
spcSite = getVtecAttribute("VTEC_SPC_SITE", "KWNS", ourSite, host, port)
tpcSite = getVtecAttribute("VTEC_TPC_SITE", "KNHC", ourSite, host, port)
sites.extend([spcSite, tpcSite])
if ourSites is None:
sites.append(ourSite)
else:
sites.extend(ourSites)
sites = getFourCharSites(sites, host, port)
def process_command_line():
parser = UsageArgumentParser.UsageArgumentParser(prog='MergeVTEC', conflict_handler="resolve")
parser.add_argument("-h", action="store", dest="serverHost",
required=True, metavar="serverHost",
help="host name of the EDEX server")
parser.add_argument("-p", action="store", type=int, dest="serverPort",
required=True, metavar="serverPort",
help="port number for the EDEX server")
parser.add_argument("-d", action="store_true",
dest="removeRemote",
help="delete remote active table when done")
parser.add_argument("-a", action="store", dest="atName",
choices=CaseInsensitiveStringSet(['OPERATIONAL', 'PRACTICE']),
required=True, metavar="atName", default="OPERATIONAL",
help="name of the active table (OPERATIONAL or PRACTICE)")
parser.add_argument("-r", action="store", dest="remoteATName",
required=True, metavar="rmtATName",
help="location of the active table (remote)")
parser.add_argument("-z", action=StoreDrtTimeAction, dest="drt",
metavar="drtMode", help="Run in DRT mode")
parser.add_argument("-n", action="store_false", dest="makeBackups",
help="Don't make backups of vtec table")
parser.add_argument("-g", action="store_true",
dest="inputIsGZIP",
help="Remote active table is compressed")
parser.add_argument("-s", action="store", dest="site", metavar="siteID",
required=True,
help="site to merge AT records into")
return vars(parser.parse_args())
log.debug("Filter Sites: %s", str(sites))
return sites
def merge(serverHost, serverPort, site, removeRemote, remoteATName,
atName, inputIsGZIP=False, drt=0, makeBackups=True, xmlIncoming=None,
fromIngestAT=False):
decoder = MergeVTEC(serverHost, serverPort, site, removeRemote,
remoteATName, atName, inputIsGZIP, drt, makeBackups, xmlIncoming,
fromIngestAT)
decoder = None
return
def convertToNewFormat(newTable):
'''Convert an AWIPS I table to AWIPS 2 internally'''
import re
maxFutureTime = long(float(2**31-1))
for dct in newTable:
dct['officeid'] = dct['oid']
dct['vtecstr'] = dct['vstr']
dct['endTime'] = int(dct['end'])
dct['startTime'] = int(dct['start'])
dct['purgeTime'] = int(dct['purgeTime'])
dct['issueTime'] = int(dct['issueTime'])
dct['phensig'] = dct['key']
dct['state'] = 'Decoded'
if dct['endTime'] >= maxFutureTime:
dct['ufn'] = True
else:
dct['ufn'] = False
dct['productClass'] = dct['vtecstr'][1]
if not dct.has_key('rawMessage'):
dct['rawMessage'] = ''
# Note: this is not always correct
dct['xxxid'] = dct['officeid'][1:]
def main():
args = process_command_line()
try:
merge(**args)
sys.exit(0)
except:
log.exception("Caught Exception: ")
sys.exit(1)
if dct.has_key('text'):
dct['segText'] = dct['text']
# adapted from WarningDecoder...
lines = dct['segText'].split('\n')
for count in xrange(len(lines)-1):
dtg_search = re.search(r' ([0123][0-9][012][0-9][0-5][0-9])',
lines[count])
if dtg_search:
pil_search = re.search(r'^([A-Z]{3})(\w{3}|\w{2}|\w{1})',
lines[count+1])
if pil_search:
dct['xxxid'] = pil_search.group(2)
break
def convertToOldFormat(backupTable):
'Convert an AWIPS 2 table to a table usable by AWIPS 1, in-place.'
for dct in backupTable:
dct['oid'] = dct['officeid']
dct['vstr'] = dct['vtecstr']
dct['end'] = dct['endTime']
dct['start'] = dct['startTime']
dct['key'] = dct['phensig']
# remove new fields so we don't pickle two copies
del dct['officeid']
del dct['vtecstr']
del dct['endTime']
del dct['phensig']
del dct['startTime']
if dct.has_key('segText'):
dct['text'] = dct['segText']
del dct['segText']
if __name__ == "__main__":
main()

View file

@ -17,81 +17,113 @@
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
import tempfile, os, stat, getopt, sys
import logging, time, traceback, string, MergeVTEC
logging.basicConfig()
log = logging.getLogger("ingestAT")
log.info('************* ingestAT ************************')
#
# Port of ingestAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# ??/??/?? wldougher Initial Creation.
# 02/13/13 1447 dgilling Re-ported to better match
# requestAT/sendAT.
#
#
startT = time.time()
import argparse
import collections
import logging
import os
import sys
import MergeVTEC
from ufpy import TimeUtil
from ufpy import UsageArgumentParser
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
log = logging.getLogger('ingestAT')
class CaseInsensitiveStringSet(collections.Set):
def __init__(self, iterable):
self.__internalSet = frozenset(iterable)
def __contains__(self, x):
return x.upper() in (item.upper() for item in self.__internalSet)
def __len__(self):
return len(self.__internalSet)
def __iter__(self):
return iter(self.__internalSet)
class StoreDrtTimeAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
drtInfoTuple = TimeUtil.determineDrtOffset(values)
setattr(namespace, self.dest, drtInfoTuple[0])
class ReadDeleteFileAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
with open(values, 'rb') as fd:
fileData = fd.read()
setattr(namespace, self.dest, fileData)
os.remove(values)
#--------------------------------------------------------------------
# decode command line ingestAT -f remoteActiveTable [-z drtMode]
# -a activeTableName [-n] -X xmlInfo
# -s site
# -a activeTableName [-n] -X xmlInfo
# -s site
#--------------------------------------------------------------------
log.info('Cmd: %s', str(sys.argv[1:]))
fname = None
ztime = None
atName = 'OPERATIONAL'
xmlIncoming = None
makeBackups = 1
ourSites = None
host = 'localhost'
port = 9581
def process_command_line():
parser = UsageArgumentParser.UsageArgumentParser(prog='ingestAT', conflict_handler="resolve")
parser.add_argument("-h", action="store", dest="serverHost",
required=True, metavar="serverHost")
parser.add_argument("-p", action="store", type=int, dest="serverPort",
required=True, metavar="serverPort")
parser.add_argument("-f", action="store", dest="fname",
required=True, metavar="remoteActiveTable")
parser.add_argument("-z", action=StoreDrtTimeAction, dest="ztime",
metavar="drtMode")
parser.add_argument("-a", action="store", dest="atName",
choices=CaseInsensitiveStringSet(['OPERATIONAL', 'PRACTICE']),
default='OPERATIONAL')
parser.add_argument("-n", action="store_false", dest="makeBackups")
parser.add_argument("-X", action=ReadDeleteFileAction, dest="xmlIncoming",
metavar="xmlInfo")
parser.add_argument("-s", action="store", dest="site", metavar="siteID",
required=True)
return parser.parse_args()
try:
optlist, args = getopt.getopt(sys.argv[1:], 'f:z:a:nX:s:h:p:')
for opt in optlist:
if opt[0] == "-f":
fname = opt[1]
elif opt[0] == "-z":
ztime = opt[1]
elif opt[0] == "-a":
atName = opt[1]
elif opt[0] == "-n":
makeBackups = 0
elif opt[0] == "-X":
fd = open(opt[1], 'rb') #open the xml source file
xmlIncoming = fd.read()
fd.close()
os.remove(opt[1]) #delete the incoming xml file
elif opt[0] == "-s":
if ourSites is None:
ourSites = []
ourSites.append(opt[1])
elif opt[0] == "-h":
host = opt[1]
elif opt[0] == "-p":
port = int(opt[1])
except:
t, v, tb = sys.exc_info()
tstr = string.join(traceback.format_exception(t, v, tb))
log.error('Error parsing command line args: %s %s', str(sys.argv), tstr)
sys.exit(1)
def main():
options = process_command_line()
log.debug("Command-line options: " + repr(options))
try:
inputIsGZIP = True
removeRemoteFile = False
fromIngestAT = True
MergeVTEC.merge(options.serverHost, options.serverPort, options.site,
removeRemoteFile, options.fname, options.atName, inputIsGZIP,
options.ztime, options.makeBackups, options.xmlIncoming,
fromIngestAT)
except:
log.exception("MergeVTEC fail: ")
try:
os.remove(options.fname)
except OSError:
pass
try:
inputIsGZIP = 1
removeRemoteFile = False
MergeVTEC.merge(removeRemoteFile, fname, atName, inputIsGZIP, drt=ztime,
makeBackups=makeBackups, xmlIncoming=xmlIncoming, ourSites=ourSites,
host=host, port=port)
removeRemoteFile = True
except:
t, v, tb = sys.exc_info()
tstr = string.join(traceback.format_exception(t, v, tb))
log.error("MergeVTEC fail: " + tstr)
try:
if removeRemoteFile:
os.remove(fname)
except OSError:
pass
if __name__ == '__main__':
main()
#--------------------------------------------------------------------
# Finish
#--------------------------------------------------------------------
endT = time.time()
log.info('Final: wctime: %-0.2f, cputime: %-0.2f',(endT - startT), time.clock())

View file

@ -0,0 +1,98 @@
##
# 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.
##
#
# Port of requestAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/28/13 1447 dgilling Initial Creation.
#
#
import logging
import sys
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import RetrieveRemoteActiveTableRequest
from ufpy import ThriftClient
from ufpy import UsageArgumentParser
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
log = logging.getLogger('requestAT')
#--------------------------------------------------------------------
# command line: requestAT -H ourHost -P ourPort -L ourProto -M mhsid -s siteID
# -t irtServiceAddr -x xmtScript
#--------------------------------------------------------------------
def process_command_line():
parser = UsageArgumentParser.UsageArgumentParser(prog='requestAT', conflict_handler="resolve")
parser.add_argument("-H", action="store", dest="serverHost",
required=True, metavar="ourHost")
parser.add_argument("-P", action="store", type=int, dest="serverPort",
required=True, metavar="ourPort")
parser.add_argument("-L", action="store", dest="serverProtocol",
required=True, metavar="ourProto")
parser.add_argument("-M", action="store", dest="mhsid",
required=True, metavar="mhsid")
parser.add_argument("-S", action="store", dest="siteID",
required=True, metavar="siteID")
parser.add_argument("-a", action="store", dest="ancf")
parser.add_argument("-b", action="store", dest="bncf")
parser.add_argument("-x", action="store", dest="xmtScript",
metavar="xmtScript")
return parser.parse_args()
def build_request(args):
req = RetrieveRemoteActiveTableRequest(args.serverHost, args.serverPort,
args.serverProtocol, args.mhsid,
args.siteID, args.ancf, args.bncf,
args.xmtScript)
return req
def main():
options = process_command_line()
log.debug("Command-line options: " + repr(options))
req = build_request(options)
log.debug("Request: " + repr(req))
thriftClient = ThriftClient.ThriftClient(host=options.serverHost)
try:
response = thriftClient.sendRequest(req)
except:
log.exception("Error posting request.")
sys.exit(1)
if not response.getTaskSuccess():
log.error("Error executing requestAT: " + response.getErrorMessage())
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,122 @@
##
# 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.
##
# sendAT - sends active table to remote site
# sendAT -s reqSite -a mhsSite -f filterSite -f filterSite -f filterSite...
# [-c countDict] [-t timeStamp] -v vtecData [-X serverXMLInfo]
# -H serverhost -P serverPort -L serverProtocol -M serverMHS -S serverSite
# -x xmtScript
#
# Port of sendAT code from AWIPS1
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/28/13 1447 dgilling Initial Creation.
#
#
import logging
import sys
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import SendActiveTableRequest
from ufpy import ThriftClient
from ufpy import UsageArgumentParser
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
log = logging.getLogger('sendtAT')
#--------------------------------------------------------------------
# decode command line, -s siteToSend -f filterSite -a mhsSite
# -c countDict (siteid:records) -t issueTime
# -v vtecData [-X serverXMLInfo] -x transmitScript
#--------------------------------------------------------------------
def process_command_line():
parser = UsageArgumentParser.UsageArgumentParser(prog='sendAT', conflict_handler="resolve")
parser.add_argument("-s", action="append", dest="sites",
metavar="siteToSend")
parser.add_argument("-f", action="append", dest="filterSites",
metavar="filterSite")
parser.add_argument("-a", action="append", dest="mhsSites",
metavar="mhsSite")
parser.add_argument("-t", action="store", type=float, dest="issueTime",
metavar="issueTime")
parser.add_argument("-c", action="store", dest="countDict",
metavar="countDict")
parser.add_argument("-v", action="store", dest="fname",
metavar="vtecData")
parser.add_argument("-X", action="store", dest="xmlIncoming",
metavar="serverXMLInfo")
parser.add_argument("-H", action="store", dest="myServerHost",
metavar="ourHost")
parser.add_argument("-P", action="store", type=int, dest="myServerPort",
metavar="ourPort")
parser.add_argument("-L", action="store", dest="myServerProtocol",
metavar="ourProto")
parser.add_argument("-M", action="store", dest="myServerMHSID",
metavar="ourMHSID")
parser.add_argument("-S", action="store", dest="myServerSite",
metavar="ourSiteID")
parser.add_argument("-x", action="store", dest="xmtScript",
metavar="transmitScript")
args = parser.parse_args()
if args.countDict is not None:
exec "countDict = " + args.countDict
setattr(args, "countDict", countDict)
return args
def build_request(args):
req = SendActiveTableRequest(args.myServerHost, args.myServerPort,
args.myServerProtocol, args.myServerSite,
args.myServerMHSID, args.sites,
args.filterSites, args.mhsSites,
args.issueTime, args.countDict, args.fname,
args.xmlIncoming, args.xmtScript)
return req
def main():
options = process_command_line()
log.debug("Command-line options: " + repr(options))
req = build_request(options)
log.debug("Request: " + repr(req))
thriftClient = ThriftClient.ThriftClient(host=options.myServerHost)
try:
response = thriftClient.sendRequest(req)
except:
log.exception("Error posting request.")
sys.exit(1)
if not response.getTaskSuccess():
log.error("Error executing sendAT: " + response.getErrorMessage())
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -83,7 +83,7 @@
<!-- GFESuite/* will now be common between server and client. -->
<copy todir="${gfe.suite.bin}" overwrite="true">
<fileset dir="${basedir}/../com.raytheon.viz.gfe/GFESuite" />
<fileset dir="${basedir}/../../cave/com.raytheon.viz.gfe/GFESuite" />
<filterset refid="installer.filter.set"/>
</copy>
</target>

View file

@ -33,10 +33,11 @@ __all__ = [
'OperationalActiveTableRecord',
'PracticeActiveTableRecord',
'PracticeProductOfftimeRequest',
'UpdateActiveTableRequest',
'UpdateActiveTableResponse',
'SendPracticeProductRequest',
'VTECChange',
'VTECTableChangeNotification'
'VTECTableChangeNotification',
'request',
'response'
]
from ActiveTableMode import ActiveTableMode
@ -52,8 +53,6 @@ from OperationalActiveTableRecord import OperationalActiveTableRecord
from PracticeActiveTableRecord import PracticeActiveTableRecord
from PracticeProductOfftimeRequest import PracticeProductOfftimeRequest
from SendPracticeProductRequest import SendPracticeProductRequest
from UpdateActiveTableRequest import UpdateActiveTableRequest
from UpdateActiveTableResponse import UpdateActiveTableResponse
from VTECChange import VTECChange
from VTECTableChangeNotification import VTECTableChangeNotification

View file

@ -0,0 +1,94 @@
##
# 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.
##
# File auto-generated against equivalent DynamicSerialize Java class
class MergeActiveTableRequest(object):
def __init__(self, incomingRecords=[], tableName='PRACTICE', site=None,
timeOffset=0.0, xmlSource=None, fromIngestAT=False,
makeBackups=True):
self.incomingRecords = incomingRecords
self.site = site
self.tableName = tableName.upper() if tableName.upper() in ['OPERATIONAL', 'PRACTICE'] else 'PRACTICE'
self.timeOffset = float(timeOffset)
self.xmlSource = xmlSource
self.fromIngestAT = bool(fromIngestAT)
self.makeBackups = bool(makeBackups)
def __repr__(self):
retVal = "MergeActiveTableRequest("
retVal += repr(self.incomingRecords) + ", "
retVal += repr(self.tableName) + ", "
retVal += repr(self.site) + ", "
retVal += repr(self.timeOffset) + ", "
retVal += repr(self.xmlSource) + ", "
retVal += repr(self.fromIngestAT) + ", "
retVal += repr(self.makeBackups) + ")"
return retVal
def __str__(self):
return self.__repr__()
def getIncomingRecords(self):
return self.incomingRecords
def setIncomingRecords(self, incomingRecords):
self.incomingRecords = incomingRecords
def getTableName(self):
return self.tableName
def setTableName(self, tableName):
value = tableName.upper()
if value not in ['OPERATIONAL', 'PRACTICE']:
raise ValueError("Invalid value " + tableName + " specified for ActiveTableMode.")
self.tableName = value
def getSite(self):
return self.site
def setSite(self, site):
self.site = site
def getTimeOffset(self):
return self.timeOffset
def setTimeOffset(self, timeOffset):
self.timeOffset = float(timeOffset)
def getXmlSource(self):
return self.xmlSource
def setXmlSource(self, xmlSource):
self.xmlSource = xmlSource
def getFromIngestAT(self):
return self.fromIngestAT
def setFromIngestAT(self, fromIngestAT):
self.fromIngestAT = bool(fromIngestAT)
def getMakeBackups(self):
return self.makeBackups
def setMakeBackups(self, makeBackups):
self.makeBackups = bool(makeBackups)

View file

@ -0,0 +1,99 @@
##
# 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.
##
# File auto-generated against equivalent DynamicSerialize Java class
class RetrieveRemoteActiveTableRequest(object):
def __init__(self, serverHost=None, serverPort=0, serverProtocol=None,
mhsId=None, siteId=None, ancfAddress=None, bncfAddress=None,
transmitScript=None):
self.serverHost = serverHost
self.serverPort = int(serverPort)
self.serverProtocol = serverProtocol
self.mhsId = mhsId
self.siteId = siteId
self.ancfAddress = ancfAddress
self.bncfAddress = bncfAddress
self.transmitScript = transmitScript
def __repr__(self):
retVal = "RetrieveRemoteActiveTableRequest("
retVal += repr(self.serverHost) + ", "
retVal += repr(self.serverPort) + ", "
retVal += repr(self.serverProtocol) + ", "
retVal += repr(self.mhsId) + ", "
retVal += repr(self.siteId) + ", "
retVal += repr(self.ancfAddress) + ", "
retVal += repr(self.bncfAddress) + ", "
retVal += repr(self.transmitScript) + ")"
return retVal
def __str__(self):
return self.__repr__()
def getServerHost(self):
return self.serverHost
def setServerHost(self, serverHost):
self.serverHost = serverHost
def getServerPort(self):
return self.serverPort
def setServerPort(self, serverPort):
self.serverPort = int(serverPort)
def getServerProtocol(self):
return self.serverProtocol
def setServerProtocol(self, serverProtocol):
self.serverProtocol = serverProtocol
def getMhsId(self):
return self.mhsId
def setMhsId(self, mhsId):
self.mhsId = mhsId
def getSiteId(self):
return self.siteId
def setSiteId(self, siteId):
self.siteId = siteId
def getAncfAddress(self):
return self.ancfAddress
def setAncfAddress(self, ancfAddress):
self.ancfAddress = ancfAddress
def getBncfAddress(self):
return self.bncfAddress
def setBncfAddress(self, bncfAddress):
self.bncfAddress = bncfAddress
def getTransmitScript(self):
return self.transmitScript
def setTransmitScript(self, transmitScript):
self.transmitScript = transmitScript

View file

@ -0,0 +1,140 @@
##
# 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.
##
# File auto-generated against equivalent DynamicSerialize Java class
class SendActiveTableRequest(object):
def __init__(self, serverHost=None, serverPort=None, serverProtocol=None,
serverSite=None, mhsId=None, sites=None, filterSites=None,
mhsSites=None, issueTime=None, countDict=None, fileName=None,
xmlIncoming=None, transmitScript=None):
self.serverHost = serverHost
self.serverPort = None if serverPort is None else int(serverPort)
self.serverProtocol = serverProtocol
self.serverSite = serverSite
self.mhsId = mhsId
self.sites = sites if sites is not None else []
self.filterSites = filterSites if filterSites is not None else []
self.mhsSites = mhsSites if mhsSites is not None else []
self.issueTime = None if issueTime is None else float(issueTime)
self.countDict = countDict if countDict is not None else {}
self.fileName = fileName
self.xmlIncoming = xmlIncoming
self.transmitScript = transmitScript
def __repr__(self):
retVal = "SendActiveTableRequest("
retVal += repr(self.serverHost) + ", "
retVal += repr(self.serverPort) + ", "
retVal += repr(self.serverProtocol) + ", "
retVal += repr(self.serverSite) + ", "
retVal += repr(self.mhsId) + ", "
retVal += repr(self.sites) + ", "
retVal += repr(self.filterSites) + ", "
retVal += repr(self.mhsSites) + ", "
retVal += repr(self.issueTime) + ", "
retVal += repr(self.countDict) + ", "
retVal += repr(self.fileName) + ", "
retVal += repr(self.xmlIncoming) + ", "
retVal += repr(self.transmitScript) + ")"
return retVal
def __str__(self):
return self.__repr__()
def getServerHost(self):
return self.serverHost
def setServerHost(self, serverHost):
self.serverHost = serverHost
def getServerPort(self):
return self.serverPort
def setServerPort(self, serverPort):
self.serverPort = serverPort
def getServerProtocol(self):
return self.serverProtocol
def setServerProtocol(self, serverProtocol):
self.serverProtocol = serverProtocol
def getServerSite(self):
return self.serverSite
def setServerSite(self, serverSite):
self.serverSite = serverSite
def getMhsId(self):
return self.mhsId
def setMhsId(self, mhsId):
self.mhsId = mhsId
def getSites(self):
return self.sites
def setSites(self, sites):
self.sites = sites
def getFilterSites(self):
return self.filterSites
def setFilterSites(self, filterSites):
self.filterSites = filterSites
def getMhsSites(self):
return self.mhsSites
def setMhsSites(self, mhsSites):
self.mhsSites = mhsSites
def getIssueTime(self):
return self.issueTime
def setIssueTime(self, issueTime):
self.issueTime = issueTime
def getCountDict(self):
return self.countDict
def setCountDict(self, countDict):
self.countDict = countDict
def getFileName(self):
return self.fileName
def setFileName(self, fileName):
self.fileName = fileName
def getXmlIncoming(self):
return self.xmlIncoming
def setXmlIncoming(self, xmlIncoming):
self.xmlIncoming = xmlIncoming
def getTransmitScript(self):
return self.transmitScript
def setTransmitScript(self, transmitScript):
self.transmitScript = transmitScript

View file

@ -18,19 +18,15 @@
# further licensing information.
##
class UpdateActiveTableResponse(object):
def __init__(self):
self.sourceInfo = None
self.message = None
def getSourceInfo(self):
return self.sourceInfo
def getMessage(self):
return self.message
def setSourceInfo(self, sourceInfo):
self.sourceInfo = sourceInfo
def setMessage(self, message):
self.message = message
# File auto-generated by PythonFileGenerator
__all__ = [
'MergeActiveTableRequest',
'RetrieveRemoteActiveTableRequest',
'SendActiveTableRequest'
]
from MergeActiveTableRequest import MergeActiveTableRequest
from RetrieveRemoteActiveTableRequest import RetrieveRemoteActiveTableRequest
from SendActiveTableRequest import SendActiveTableRequest

View file

@ -20,35 +20,21 @@
# File auto-generated against equivalent DynamicSerialize Java class
class UpdateActiveTableRequest(object):
class ActiveTableSharingResponse(object):
def __init__(self):
self.activeTable = None
self.xmlSource = None
self.mode = None
self.timeOffset = None
self.taskSuccess = None
self.errorMessage = None
def getActiveTable(self):
return self.activeTable
def getTaskSuccess(self):
return self.taskSuccess
def setActiveTable(self, activeTable):
self.activeTable = activeTable
def setTaskSuccess(self, taskSuccess):
self.taskSuccess = bool(taskSuccess)
def getXmlSource(self):
return self.xmlSource
def getErrorMessage(self):
return self.errorMessage
def setXmlSource(self, xmlSource):
self.xmlSource = xmlSource
def getMode(self):
return self.mode
def setMode(self, mode):
self.mode = mode
def getTimeOffset(self):
return self.timeOffset
def setTimeOffset(self, timeOffset):
self.timeOffset = timeOffset
def setErrorMessage(self, errorMessage):
self.errorMessage = errorMessage

View file

@ -0,0 +1,28 @@
##
# 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.
##
# File auto-generated by PythonFileGenerator
__all__ = [
'ActiveTableSharingResponse'
]
from ActiveTableSharingResponse import ActiveTableSharingResponse