s. This is the server-side portion of the
+ * ingestAT/MergeVTEC applications.
*
*
*
@@ -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.
*
*
*
@@ -61,10 +65,10 @@ import com.vividsolutions.jts.io.WKTReader;
* @version 1.0
*/
-public class UpdateActiveTableHandler implements
- IRequestHandler {
+public class MergeActiveTableHandler implements
+ IRequestHandler {
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[] activeTableMap = request.getActiveTable();
- ActiveTableMode mode = request.getMode();
+ public ActiveTableSharingResponse handleRequest(
+ MergeActiveTableRequest request) throws Exception {
+ Map[] activeTableMap = request.getIncomingRecords();
+ ActiveTableMode mode = request.getTableName();
statusHandler.handle(Priority.INFO,
"Received UpdateActiveTable request containing "
+ activeTableMap.length + " maps.");
- List records = null;
+ List 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 {
- /**
- * 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 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 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 mapToRecords(
- Map[] activeTableMap, ActiveTableMode mode) {
+ Map[] activeTableMap, ActiveTableMode mode)
+ throws Exception {
List records = new ArrayList(
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;
}
}
}
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/RetrieveRemoteActiveTableHandler.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/RetrieveRemoteActiveTableHandler.java
new file mode 100644
index 0000000000..fb8f256024
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/RetrieveRemoteActiveTableHandler.java
@@ -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 RetrieveRemoteActiveTableRequest
. Runs the requestAT
+ * application using the parameters from the request as arguments to the
+ * PythonScript.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 6, 2013 dgilling Initial creation
+ *
+ *
+ *
+ * @author dgilling
+ * @version 1.0
+ */
+
+public class RetrieveRemoteActiveTableHandler implements
+ IRequestHandler {
+
+ 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 argMap = new HashMap();
+ 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);
+ }
+}
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/SendActiveTableHandler.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/SendActiveTableHandler.java
new file mode 100644
index 0000000000..3caad2606a
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/handler/SendActiveTableHandler.java
@@ -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 SendActiveTableRequest
. Runs the sendAT application
+ * using the parameters from the request as arguments to the PythonScript.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 6, 2013 dgilling Initial creation
+ *
+ *
+ *
+ * @author dgilling
+ * @version 1.0
+ */
+
+public class SendActiveTableHandler implements
+ IRequestHandler {
+
+ 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 argMap = new HashMap();
+ 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);
+ }
+}
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ActiveTableRecord.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ActiveTableRecord.py
index b740a00dac..1b6b86af59 100644
--- a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ActiveTableRecord.py
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ActiveTableRecord.py
@@ -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
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/MergeVTEC.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/MergeVTEC.py
new file mode 100644
index 0000000000..c03acde673
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/MergeVTEC.py
@@ -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
+
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECPartners.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECPartners.py
index 2e99b85ee4..e690405267 100644
--- a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECPartners.py
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECPartners.py
@@ -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
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableSqueeze.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableSqueeze.py
index 4010fd54fa..94e12be3c3 100644
--- a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableSqueeze.py
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableSqueeze.py
@@ -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
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableUtil.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableUtil.py
index 26239c2923..092dba5f71 100644
--- a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableUtil.py
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/VTECTableUtil.py
@@ -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)
+
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ingestAT.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ingestAT.py
new file mode 100644
index 0000000000..b09ea99b81
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ingestAT.py
@@ -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
+
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/requestAT.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/requestAT.py
new file mode 100644
index 0000000000..5e348f549f
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/requestAT.py
@@ -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()))
+
diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/sendAT.py b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/sendAT.py
new file mode 100644
index 0000000000..3411781652
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/sendAT.py
@@ -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()))
\ No newline at end of file
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/MergeVTEC b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/MergeVTEC
new file mode 100644
index 0000000000..32319a41eb
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/MergeVTEC
@@ -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 "$@"
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/requestAT b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/requestAT
new file mode 100644
index 0000000000..479faf516d
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/requestAT
@@ -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 "$@"
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/sendAT b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/sendAT
new file mode 100644
index 0000000000..12aec0f415
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/sendAT
@@ -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 "$@"
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/MergeVTEC.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/MergeVTEC.py
index 11123b11b7..a39f3a7053 100644
--- a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/MergeVTEC.py
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/MergeVTEC.py
@@ -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()
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/ingestAT.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/ingestAT.py
index 40adafd9ea..8abd3b4d21 100644
--- a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/ingestAT.py
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/ingestAT.py
@@ -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())
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/requestAT.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/requestAT.py
new file mode 100644
index 0000000000..31442a69c4
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/requestAT.py
@@ -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()
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/sendAT.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/sendAT.py
new file mode 100644
index 0000000000..64dd3aa565
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/activeTable/sendAT.py
@@ -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()
diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/deploy.xml b/edexOsgi/com.raytheon.uf.tools.gfesuite/deploy.xml
index 505ae6f152..dc101c42f9 100644
--- a/edexOsgi/com.raytheon.uf.tools.gfesuite/deploy.xml
+++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/deploy.xml
@@ -83,7 +83,7 @@
-
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/__init__.py
index 2a51112ae2..d6497323a0 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/__init__.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/__init__.py
@@ -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
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/MergeActiveTableRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/MergeActiveTableRequest.py
new file mode 100644
index 0000000000..9ffde5404b
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/MergeActiveTableRequest.py
@@ -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)
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/RetrieveRemoteActiveTableRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/RetrieveRemoteActiveTableRequest.py
new file mode 100644
index 0000000000..5cc18757d7
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/RetrieveRemoteActiveTableRequest.py
@@ -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
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/SendActiveTableRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/SendActiveTableRequest.py
new file mode 100644
index 0000000000..cb4d4f4241
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/SendActiveTableRequest.py
@@ -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
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableResponse.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/__init__.py
similarity index 64%
rename from pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableResponse.py
rename to pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/__init__.py
index 9aea6cc366..86acf1ad9e 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableResponse.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/request/__init__.py
@@ -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
+
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableRequest.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/ActiveTableSharingResponse.py
similarity index 55%
rename from pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableRequest.py
rename to pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/ActiveTableSharingResponse.py
index 07f606d056..db10d0e969 100644
--- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/UpdateActiveTableRequest.py
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/ActiveTableSharingResponse.py
@@ -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
diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/__init__.py
new file mode 100644
index 0000000000..9a6076619f
--- /dev/null
+++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/activetable/response/__init__.py
@@ -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
+