From 2ca8e5e42a0c656ee7469226db989db7fc9081ce Mon Sep 17 00:00:00 2001 From: David Gillingham Date: Fri, 1 Mar 2013 11:23:41 -0600 Subject: [PATCH] Issue #1447: Implement active table fetching, make bug fixes to active table sharing from testing. Change-Id: I84a3ed28f2cc8bdce0248faef984a4453d734c0d Former-commit-id: 95f8074c970a385cf479f22208070a59ce43e17d [formerly 95f8074c970a385cf479f22208070a59ce43e17d [formerly cede300be734c8a05f90b9c84372866d9bd4f695]] Former-commit-id: 0a79d08dd891f25278207144b9c240339656d8d1 Former-commit-id: 5ad72e2a7f14b368b427f59d2eec5a7e989d35d0 --- .../META-INF/MANIFEST.MF | 3 +- .../plugin/gfe/config/GFESiteActivation.java | 86 +++++-- .../edex/plugin/gfe/isc/GfeScript.java | 2 + .../edex/plugin/gfe/spc/SPCWatchSrv.java | 2 +- .../edex/plugin/gfe/tpc/TPCWatchSrv.java | 2 +- .../edex_static/base/gfe/isc/IrtAccess.py | 10 +- .../edex_static/base/gfe/isc/IrtServer.py | 103 +++++---- .../edex_static/base/gfe/isc/iscDataRec.py | 27 +-- .../META-INF/MANIFEST.MF | 5 +- .../common/activetable/ActiveTableUtil.java | 217 ++++++++++++++++++ .../uf/common}/activetable/VTECPartners.java | 2 +- .../gfe/python/GfePyIncludeUtil.java | 9 +- .../META-INF/MANIFEST.MF | 4 +- .../res/spring/activetable-request.xml | 21 ++ .../uf/edex/activetable/ActiveTable.java | 168 +------------- .../activetable/DumpActiveTableHandler.java | 4 +- .../GetActiveTableDictHandler.java | 3 +- .../activetable/GetVtecAttributeHandler.java | 1 + .../RetrieveRemoteActiveTableHandler.java | 3 +- .../handler/SendActiveTableHandler.java | 3 +- .../vtecsharing/FetchATJobConfig.java | 208 +++++++++++++++++ .../vtecsharing/FetchActiveTableSrv.java | 204 ++++++++++++++++ .../common_static/base/vtec/VTECTableUtil.py | 4 +- .../common_static/base/vtec/requestAT.py | 3 +- .../utility/common_static/base/vtec/sendAT.py | 2 +- .../cli/src/activeTable/MergeVTEC.py | 2 +- 26 files changed, 829 insertions(+), 269 deletions(-) create mode 100644 edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/ActiveTableUtil.java rename edexOsgi/{com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex => com.raytheon.uf.common.activetable/src/com/raytheon/uf/common}/activetable/VTECPartners.java (99%) create mode 100644 edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchATJobConfig.java create mode 100644 edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchActiveTableSrv.java diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.edex.plugin.gfe/META-INF/MANIFEST.MF index 4d3d835159..330a924e0b 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/META-INF/MANIFEST.MF @@ -25,7 +25,8 @@ Require-Bundle: com.raytheon.uf.common.dataplugin.gfe;bundle-version="1.12.1174" com.raytheon.uf.common.site;bundle-version="1.12.1174", ucar.nc2;bundle-version="1.0.0", com.raytheon.uf.common.parameter;bundle-version="1.0.0", - com.raytheon.uf.common.dataplugin.grid;bundle-version="1.0.0" + com.raytheon.uf.common.dataplugin.grid;bundle-version="1.0.0", + com.google.guava;bundle-version="1.0.0" Export-Package: com.raytheon.edex.plugin.gfe, com.raytheon.edex.plugin.gfe.config, com.raytheon.edex.plugin.gfe.db.dao, diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java index 6eba94d5ba..ce9fdb0397 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java @@ -26,7 +26,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import com.google.common.util.concurrent.MoreExecutors; import com.raytheon.edex.plugin.gfe.cache.d2dparms.D2DParmIdCache; import com.raytheon.edex.plugin.gfe.cache.gridlocations.GridLocationCache; import com.raytheon.edex.plugin.gfe.cache.ifpparms.IFPParmIdCache; @@ -65,9 +69,9 @@ import com.raytheon.uf.edex.site.ISiteActivationListener; /** * Activates the GFE server capabilities for a site - * + * *
- *
+ * 
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
@@ -78,9 +82,11 @@ import com.raytheon.uf.edex.site.ISiteActivationListener;
  * Jul 12, 2012  15162    ryu         added check for invalid db at activation
  * Dec 11, 2012  14360    ryu         log a clean message in case of
  *                                    missing configuration (no stack trace).
- *
+ * Feb 28, 2013  #1447    dgilling    Enable active table fetching on site
+ *                                    activation.
+ * 
  * 
- * + * * @author njensen * @version 1.0 */ @@ -105,6 +111,10 @@ public class GFESiteActivation implements ISiteActivationListener { private boolean intialized = false; + private ExecutorService postActivationTaskExecutor = MoreExecutors + .getExitingExecutorService((ThreadPoolExecutor) Executors + .newCachedThreadPool()); + public static synchronized GFESiteActivation getInstance() { if (instance == null) { instance = new GFESiteActivation(); @@ -217,7 +227,7 @@ public class GFESiteActivation implements ISiteActivationListener { /** * Activates a site by reading its server config and generating maps, topo, * and text products for the site - * + * * @param siteID */ @Override @@ -244,8 +254,7 @@ public class GFESiteActivation implements ISiteActivationListener { sendActivationFailedNotification(siteID); // Stack trace is not printed per requirement for DR14360 statusHandler.handle(Priority.PROBLEM, siteID - + " will not be activated: " - + e.getLocalizedMessage()); + + " will not be activated: " + e.getLocalizedMessage()); throw e; } catch (Exception e) { sendActivationFailedNotification(siteID); @@ -263,10 +272,10 @@ public class GFESiteActivation implements ISiteActivationListener { /** * Activate site routine for internal use. - * + * * Doesn't update the site list so it is preserved when loading sites at * start up - * + * * @param siteID * @throws PluginException * @throws GfeException @@ -344,8 +353,9 @@ public class GFESiteActivation implements ISiteActivationListener { site).get(i)); // cluster locked since IFPGridDatabase can modify the grids // based on changes to grid size, etc - if (db.databaseIsValid()) + if (db.databaseIsValid()) { db.updateDbs(); + } } } } finally { @@ -391,7 +401,7 @@ public class GFESiteActivation implements ISiteActivationListener { // just need to be done, doesn't matter that site isn't fully // activated, in fact would be best to only be done once site is // fully activated. - Thread smartInit = new Thread("SmartInitLauncher") { + Runnable smartInit = new Runnable() { @Override public void run() { long startTime = System.currentTimeMillis(); @@ -478,7 +488,53 @@ public class GFESiteActivation implements ISiteActivationListener { } } }; - smartInit.start(); + postActivationTaskExecutor.submit(smartInit); + + if (config.tableFetchTime() > 0) { + Runnable activateFetchAT = new Runnable() { + + @Override + public void run() { + long startTime = System.currentTimeMillis(); + // wait for system startup or at least 3 minutes + while (!EDEXUtil.isRunning() + || System.currentTimeMillis() > startTime + 180000) { + try { + Thread.sleep(15000); + } catch (InterruptedException e) { + + } + } + + Map fetchATConfig = new HashMap(); + fetchATConfig.put("siteId", configRef.getSiteID().get(0)); + fetchATConfig.put("interval", configRef.tableFetchTime()); + fetchATConfig.put("ancf", configRef + .iscRoutingTableAddress().get("ANCF")); + fetchATConfig.put("bncf", configRef + .iscRoutingTableAddress().get("BNCF")); + fetchATConfig.put("serverHost", configRef.getServerHost()); + fetchATConfig.put("port", configRef.getRpcPort()); + fetchATConfig.put("protocolV", + configRef.getProtocolVersion()); + fetchATConfig.put("mhsid", configRef.getMhsid()); + fetchATConfig.put("transmitScript", + configRef.transmitScript()); + + try { + EDEXUtil.getMessageProducer().sendAsyncUri( + "jms-generic:queue:gfeSiteActivated", + fetchATConfig); + } catch (EdexException e) { + statusHandler.handle(Priority.PROBLEM, + "Could not activate active table sharing for site: " + + siteID, e); + } + } + }; + postActivationTaskExecutor.submit(activateFetchAT); + } + statusHandler.handle(Priority.EVENTA, "Adding " + siteID + " to active sites list."); IFPServerConfigManager.addActiveSite(siteID); @@ -488,7 +544,7 @@ public class GFESiteActivation implements ISiteActivationListener { /** * Deactivates a site's GFE services - * + * * @param siteID */ @Override @@ -562,7 +618,7 @@ public class GFESiteActivation implements ISiteActivationListener { /** * Returns the currently active GFE sites the server is running - * + * * @return the active sites */ @Override @@ -572,7 +628,7 @@ public class GFESiteActivation implements ISiteActivationListener { /* * (non-Javadoc) - * + * * @see com.raytheon.uf.edex.site.ISiteActivationListener#validateConfig() */ @Override diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/GfeScript.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/GfeScript.java index e21743fe77..e98435346e 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/GfeScript.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/GfeScript.java @@ -48,6 +48,7 @@ import com.raytheon.uf.common.python.PythonScript; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Oct 23, 2009 #2960 bphillip Initial creation + * Mar 04, 2013 #1447 dgilling Add VTEC scripts to include path. * * * @@ -108,6 +109,7 @@ public class GfeScript extends Thread { if (pythonIncludePath == null) { pythonIncludePath = PyUtil.buildJepIncludePath( GfePyIncludeUtil.getCommonPythonIncludePath(), + GfePyIncludeUtil.getVtecIncludePath(site), GfePyIncludeUtil.getIscScriptsIncludePath(), GfePyIncludeUtil.getGfeConfigIncludePath(site)); } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java index 504973dee0..db76ab5ccb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java @@ -29,11 +29,11 @@ import org.apache.commons.logging.LogFactory; import com.raytheon.edex.plugin.gfe.config.GFESiteActivation; import com.raytheon.edex.plugin.gfe.util.SendNotifications; +import com.raytheon.uf.common.activetable.VTECPartners; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.gfe.server.notify.UserMessageNotification; import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.edex.activetable.VTECPartners; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.edex.core.props.EnvProperties; import com.raytheon.uf.edex.core.props.PropertiesFactory; diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java index e9d75592e9..b2d4a282bc 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java @@ -36,11 +36,11 @@ import org.apache.commons.logging.LogFactory; import com.raytheon.edex.plugin.gfe.config.GFESiteActivation; import com.raytheon.edex.plugin.gfe.util.SendNotifications; +import com.raytheon.uf.common.activetable.VTECPartners; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.gfe.server.notify.UserMessageNotification; import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.edex.activetable.VTECPartners; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.edex.core.props.EnvProperties; import com.raytheon.uf.edex.core.props.PropertiesFactory; diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtAccess.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtAccess.py index 4e8b8caa5a..89fc8f5e28 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtAccess.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtAccess.py @@ -67,20 +67,20 @@ class IrtAccess(): def __checkArgs(self,parmsWanted, gridDims,gridBoundBox, iscWfosWanted): - if type(parmsWanted) != "list": + if type(parmsWanted) is not list: parmsWanted = JUtil.javaStringListToPylist(parmsWanted) - if type(gridDims) != "list": + if type(gridDims) is not list: pylist = [] size = gridDims.size() for i in range(size): pylist.append(gridDims.get(i).intValue()) gridDims = pylist - if type(gridBoundBox) != "tuple": + if type(gridBoundBox) is not tuple: gridBoundBox = ((gridBoundBox.get(0).doubleValue(),gridBoundBox.get(1).doubleValue()),(gridBoundBox.get(2).doubleValue(),gridBoundBox.get(3).doubleValue())) - if type(iscWfosWanted) != "list": + if type(iscWfosWanted) is not list: iscWfosWanted = JUtil.javaStringListToPylist(iscWfosWanted) @@ -184,7 +184,7 @@ class IrtAccess(): # routine to get the list of servers that are active for the given list # of domains. Returns status flag and XML string. def getServers(self, wfos): - if type(wfos) != "list": + if type(wfos) is not list: wfos = JUtil.javaStringListToPylist(wfos) wfoDict = {'wfoids': ",".join(wfos)} status, xml, transIRT = self.__callIRT('getservers', wfoDict) diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtServer.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtServer.py index 3757e514a9..88b0d83d54 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtServer.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/IrtServer.py @@ -65,7 +65,7 @@ def logDebug(*msg): # returns the active table, filtered, pickled. def getVTECActiveTable(siteAndFilterInfo, xmlPacket): import VTECPartners - if VTECPartners.VTEC_RESPOND_TO_TABLE_REQUESTS: + if not VTECPartners.VTEC_RESPOND_TO_TABLE_REQUESTS: return #respond is disabled #decode the data (pickled) @@ -76,9 +76,10 @@ def getVTECActiveTable(siteAndFilterInfo, xmlPacket): from com.raytheon.uf.common.site import SiteMap from com.raytheon.uf.edex.activetable import ActiveTable from com.raytheon.uf.common.activetable import ActiveTableMode + from com.raytheon.uf.common.activetable import ActiveTableUtil site4Id = SiteMap.getInstance().getSite4LetterId(siteConfig.GFESUITE_SITEID) javaTable = ActiveTable.getActiveTable(site4Id, ActiveTableMode.OPERATIONAL) - dictTable = ActiveTable.convertToDict(javaTable, siteConfig.GFESUITE_SITEID) + dictTable = ActiveTableUtil.convertToDict(javaTable, siteConfig.GFESUITE_SITEID) # we must convert this to a python hash using the A1 field naming conventions # for cross-version compatibility @@ -111,69 +112,73 @@ def getVTECActiveTable(siteAndFilterInfo, xmlPacket): #write the xmlpacket to a temporary file, if one was passed if xmlPacket is not None: - with tempfile.NamedTemporaryFile(suffix='.xml', delete=False) as fp: + with tempfile.NamedTemporaryFile(suffix='.xml', dir=outDir, delete=False) as fp: fnameXML = fp.name fp.write(xmlPacket) + from com.raytheon.edex.plugin.gfe.config import IFPServerConfigManager + config = IFPServerConfigManager.getServerConfig(siteConfig.GFESUITE_SITEID) + ServerHost = siteConfig.GFESUITE_SERVER + ServerPort = str(siteConfig.GFESUITE_PORT) + ServerProtocol = str(config.getProtocolVersion()) + ServerMHS = siteConfig.GFESUITE_MHSID + ServerSite = siteConfig.GFESUITE_SITEID + XmtScript = config.transmitScript() + #call sendAT to send the table to the requestor - pid = os.fork() - if pid == 0: - cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "sendAT") - args = [cmd, '-s', reqsite, '-a', mhsSite, '-H', ServerHost, - '-P', ServerPort, '-L', ServerProtocol, '-M', ServerMHS, - '-S', ServerSite, '-x', XmtScript] - if filterSites is not None: - for fs in filterSites: - args.append('-f') - args.append(fs) - if countDict is not None: - args.append('-c') - args.append(`countDict`) - if issueTime is not None: - args.append('-t') - args.append(`issueTime`) - args.append('-v') - args.append(fname) - if xmlPacket is not None: - args.append('-X') - args.append(fnameXML) - try: - os.execvp(cmd, args) - except: - logProblem("Error executing sendAT: ", traceback.format_exc()) - finally: - os._exit(0) + cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "sendAT") + args = [cmd, '-s', reqsite, '-a', mhsSite, '-H', ServerHost, + '-P', ServerPort, '-L', ServerProtocol, '-M', ServerMHS, + '-S', ServerSite, '-x', XmtScript] + if filterSites is not None: + for fs in filterSites: + args.append('-f') + args.append(fs) + if countDict is not None: + args.append('-c') + args.append(`countDict`) + if issueTime is not None: + args.append('-t') + args.append(`issueTime`) + args.append('-v') + args.append(fname) + if xmlPacket is not None: + args.append('-X') + args.append(fnameXML) + try: + output = subprocess.check_output(args, stderr=subprocess.STDOUT) + except: + logProblem("Error executing sendAT: ", traceback.format_exc()) + logEvent("sendAT command output: ", output) #when we receive a requested active table from another site, this function #is called from iscDataRec def putVTECActiveTable(strTable, xmlPacket): #write the xmlpacket to a temporary file, if one was passed + inDir = os.path.join(siteConfig.GFESUITE_PRDDIR, "ATBL") if xmlPacket is not None: - with tempfile.NamedTemporaryFile(suffix='.xml', delete=False) as fp: + with tempfile.NamedTemporaryFile(suffix='.xml', dir=inDir, delete=False) as fp: fnameXML = fp.name fp.write(xmlPacket) - - inDir = os.path.join(siteConfig.GFESUITE_PRDDIR, "ATBL") with tempfile.NamedTemporaryFile(suffix='.ati', dir=inDir, delete=False) as fp: fname = fp.name fp.write(strTable) - pid = os.fork() - if pid == 0: - cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "ingestAT") - args = [] - args.append(cmd) - args.append("-f") - args.append(fname) - if xmlPacket is not None: - args.append('-X') - args.append(fnameXML) - try: - os.execvp(cmd, args) - except: - logProblem("Error executing ingestAT: ", traceback.format_exc()) - finally: - os._exit(0) + cmd = os.path.join(siteConfig.GFESUITE_HOME, "bin", "ingestAT") + args = [] + args.append(cmd) + args.append("-s") + args.append(siteConfig.GFESUITE_SITEID) + args.append("-f") + args.append(fname) + if xmlPacket is not None: + args.append('-X') + args.append(fnameXML) + try: + output = subprocess.check_output(args, stderr=subprocess.STDOUT) + except: + logProblem("Error executing ingestAT: ", traceback.format_exc()) + logEvent("ingesAT command output: ", output) def initIRT(ancfURL, bncfURL, mhsid, serverHost, serverPort, serverProtocol, site, parmsWanted, gridDims, gridProj, gridBoundBox, iscWfosWanted): diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/iscDataRec.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/iscDataRec.py index 7333ed9694..fa093e3ca6 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/iscDataRec.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/iscDataRec.py @@ -42,6 +42,7 @@ exec $GFESUITE_HOME/bin/run/iscDataRec1 -S -O $0 ${1+"$@"} import iscMosaic,iscUtil import os, stat, sys, re, string, traceback, types import time, xml, LogStream, siteConfig, IrtAccess +import IrtServer from xml.etree import ElementTree from xml.etree.ElementTree import Element, SubElement from java.util import ArrayList @@ -55,6 +56,7 @@ from java.util import ArrayList # Date Ticket# Engineer Description # ------------ ---------- ----------- -------------------------- # 07/06/09 1995 bphillip Initial Creation. +# 01/29/13 1447 dgilling Implement VTEC table sharing. # # # @@ -193,24 +195,18 @@ def execIscDataRec(MSGID,SUBJECT,FILES): continue #this destination is for someone else. # transmit the data to the ifpServer - #try: - # c = PyNet.IFPClient((destServer['host'], int(destServer['port'])), - # int(destServer['protocol'])) - fp = open(dataFile, "rb") - time2 = time.clock() + with open(dataFile, "rb") as fp: + fpData = fp.read() + time2 = time.clock() if SUBJECT == 'PUT_ACTIVE_TABLE': - pass - #c.putVTECActiveTable(fp.read(), None) + IrtServer.putVTECActiveTable(fpData, None) elif SUBJECT == 'PUT_ACTIVE_TABLE2': - pass - #c.putVTECActiveTable(fp.read(), xmlFileBuf) + IrtServer.putVTECActiveTable(fpData, xmlFileBuf) elif SUBJECT == 'GET_ACTIVE_TABLE': - pass - #c.getVTECActiveTable(fp.read(), None) + IrtServer.getVTECActiveTable(fpData, None) elif SUBJECT == 'GET_ACTIVE_TABLE2': - pass - #c.getVTECActiveTable(fp.read(), xmlFileBuf) + IrtServer.getVTECActiveTable(fpData, xmlFileBuf) elif SUBJECT in ['ISCGRIDS', 'ISCGRIDS2']: files = ArrayList() files.add(dataFile) @@ -239,15 +235,12 @@ def execIscDataRec(MSGID,SUBJECT,FILES): mosaic.execute() elif SUBJECT == 'ISCREQUEST': - import IrtServer - IrtServer.serviceISCRequest(fp.read()) + IrtServer.serviceISCRequest(fpData) else: nosend = True logProblem("unknown subject: ", SUBJECT) - fp.close() continue time3 = time.clock() - fp.close() delta1 = time2-time1 delta2 = time3-time2 logEvent('Sent to:', diff --git a/edexOsgi/com.raytheon.uf.common.activetable/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.activetable/META-INF/MANIFEST.MF index 82082d6931..df10602406 100644 --- a/edexOsgi/com.raytheon.uf.common.activetable/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.activetable/META-INF/MANIFEST.MF @@ -18,4 +18,7 @@ Export-Package: com.raytheon.uf.common.activetable, com.raytheon.uf.common.activetable.request, com.raytheon.uf.common.activetable.response Require-Bundle: com.raytheon.uf.common.serialization, - com.raytheon.uf.common.message;bundle-version="1.12.1174" + com.raytheon.uf.common.message;bundle-version="1.12.1174", + com.raytheon.uf.common.localization;bundle-version="1.12.1174", + com.raytheon.uf.common.python;bundle-version="1.12.1174", + org.jep;bundle-version="1.0.0" diff --git a/edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/ActiveTableUtil.java b/edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/ActiveTableUtil.java new file mode 100644 index 0000000000..92776aa31f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/ActiveTableUtil.java @@ -0,0 +1,217 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.activetable; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; + +/** + * Utility module for the ActiveTable plugin. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 4, 2013            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class ActiveTableUtil { + + private ActiveTableUtil() { + // don't allow this class to be directly instantiated, only provides + // static utility methods. + throw new AssertionError(); + } + + /** + * Convert the active table to a list of Maps. Doing it directly + * in Java eliminates the need for Python paths, handling JepExceptions, and + * at least one Python/Java conversion of the active table. + * + * @param records + * A list of ActiveTableRecords to convert to + * Maps. + * @return records, converted to a list of Maps. + */ + public static List> convertToDict( + List records, String site) { + + List> dicts = new ArrayList>( + records.size()); + for (ActiveTableRecord atr : records) { + Map template = new HashMap(); + template.put("vtecstr", atr.getVtecstr()); + template.put("etn", Integer.valueOf(atr.getEtn())); + template.put("sig", atr.getSig()); + template.put("phen", atr.getPhen()); + if (atr.getSegText() != null) { + template.put("segText", atr.getSegText()); + } + if (atr.getOverviewText() != null) { + template.put("overviewText", atr.getOverviewText()); + template.put("hdln", atr.getOverviewText()); + } + template.put("phensig", atr.getPhensig()); + template.put("act", atr.getAct()); + template.put("seg", atr.getSeg()); + template.put("startTime", + atr.getStartTime().getTimeInMillis() / 1000); + template.put("endTime", atr.getEndTime().getTimeInMillis() / 1000); + template.put("ufn", atr.isUfn()); + template.put("officeid", atr.getOfficeid()); + template.put("purgeTime", + atr.getPurgeTime().getTimeInMillis() / 1000); + template.put("issueTime", + atr.getIssueTime().getTimeInMillis() / 1000); + template.put("state", "Decoded"); + template.put("xxxid", atr.getXxxid()); + + template.put("pil", + remapPil(site, atr.getPhen(), atr.getSig(), atr.getPil())); + template.put("productClass", atr.getProductClass()); + + template.put("id", atr.getUgcZone()); + + template.put("rawMessage", atr.getRawmessage()); + template.put("countyheader", atr.getCountyheader()); + Calendar floodBegin = atr.getFloodBegin(); + if (floodBegin != null) { + long floodBeginMillis = floodBegin.getTimeInMillis(); + if (floodBeginMillis != 0) { + template.put("floodBegin", floodBeginMillis / 1000); + } + } + template.put("wmoid", atr.getWmoid()); + + // Warngen fields + Calendar floodCrest = atr.getFloodCrest(); + if (floodCrest != null) { + long floodCrestMillis = floodCrest.getTimeInMillis(); + if (floodCrestMillis != 0) { + template.put("floodCrest", floodCrestMillis / 1000); + } + } + Calendar floodEnd = atr.getFloodEnd(); + if (floodEnd != null) { + long floodEndMillis = floodEnd.getTimeInMillis(); + if (floodEndMillis != 0) { + template.put("floodBegin", floodEndMillis / 1000); + } + } + String floodStatus = atr.getFloodRecordStatus(); + if (floodStatus != null && !"".equals(floodStatus.trim())) { + template.put("floodrecordstatus", floodStatus); + } + String floodSeverity = atr.getFloodSeverity(); + if (floodSeverity != null && !"".equals(floodSeverity.trim())) { + template.put("floodseverity", floodSeverity); + } + + Geometry geometry = atr.getGeometry(); + if (geometry != null && !geometry.isEmpty()) { + StringBuilder sb = new StringBuilder(); + String sep = ""; + long lat; + long lon; + for (Coordinate coordinate : geometry.getCoordinates()) { + sb.append(sep); + sep = " "; + lat = Math.round(Math.abs(coordinate.y) * 100.0); + lon = Math.round(Math.abs(coordinate.x) * 100.0); + sb.append(String.format("%d %d", lat, lon)); + } + template.put("geometry", sb.toString()); + } + + String immediateCause = atr.getImmediateCause(); + if (immediateCause != null && !"".equals(immediateCause.trim())) { + template.put("immediateCause", immediateCause); + } + + String loc = atr.getLoc(); + if (loc != null && !"".equals(loc.trim())) { + template.put("loc", loc); + } + + String locationId = atr.getLocationID(); + if (locationId != null && !"".equals(locationId.trim())) { + template.put("locationId", locationId); + } + + Integer motdir = atr.getMotdir(); + if (motdir != null) { + template.put("motdir", motdir); + } + + Integer motspd = atr.getMotspd(); + if (motspd != null) { + template.put("motspd", motspd); + } + + dicts.add(template); + } + return dicts; + } + + /** + * Some events are issued in one PIL and cancelled or extended in another. + * This finds the PIL needed. + * + * @param siteID + * The site from which + * @param phen + * The phenomenon code to look for + * @param sig + * The significance code to look for + * @param dft + * The PIL to use if the phensig is not remapped + * @return The PIL after remapping. + */ + @SuppressWarnings("unchecked") + private static String remapPil(String siteId, String phen, String sig, + String dft) { + String result = dft; + Map MappedPils = (Map) VTECPartners + .getInstance(siteId).getattr("VTEC_MAPPED_PILS"); + List key = new ArrayList(3); + key.add(phen); + key.add(sig); + key.add(dft); + String mPil = MappedPils.get(key); + if (mPil != null) { + result = mPil; + } + return result; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/VTECPartners.java b/edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/VTECPartners.java similarity index 99% rename from edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/VTECPartners.java rename to edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/VTECPartners.java index 4990a2db52..5585d38eb8 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/VTECPartners.java +++ b/edexOsgi/com.raytheon.uf.common.activetable/src/com/raytheon/uf/common/activetable/VTECPartners.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.edex.activetable; +package com.raytheon.uf.common.activetable; import java.io.File; import java.util.ArrayList; diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/python/GfePyIncludeUtil.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/python/GfePyIncludeUtil.java index 3b157e7abe..9692e3e6ba 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/python/GfePyIncludeUtil.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/python/GfePyIncludeUtil.java @@ -19,7 +19,6 @@ **/ package com.raytheon.uf.common.dataplugin.gfe.python; - import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; @@ -285,6 +284,14 @@ public class GfePyIncludeUtil extends PythonIncludePathUtil { return PyUtil.buildJepIncludePath(siteDir, baseDir); } + public static String getVtecIncludePath(String siteId) { + String baseDir = getPath(PATH_MANAGER.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.BASE), VTEC); + String siteDir = getPath(PATH_MANAGER.getContextForSite( + LocalizationType.COMMON_STATIC, siteId), VTEC); + return PyUtil.buildJepIncludePath(siteDir, baseDir); + } + public static String getConfigIncludePath() { return getConfigIncludePath(true); } diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.activetable/META-INF/MANIFEST.MF index 45e80df44b..94da0d42f4 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.activetable/META-INF/MANIFEST.MF @@ -21,6 +21,8 @@ Require-Bundle: com.raytheon.uf.common.localization;bundle-version="1.11.1", com.raytheon.uf.edex.core, com.raytheon.uf.edex.database, com.raytheon.uf.common.message;bundle-version="1.12.1174", - com.raytheon.uf.common.activetable;bundle-version="1.12.1174" + com.raytheon.uf.common.activetable;bundle-version="1.12.1174", + com.raytheon.uf.edex.site;bundle-version="1.0.0", + com.google.guava;bundle-version="1.0.0" Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Export-Package: com.raytheon.uf.edex.activetable diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml index f6a991af5d..18e1b40a8a 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml @@ -70,4 +70,25 @@ + + + + + + + + + + java.lang.Throwable + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/ActiveTable.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/ActiveTable.java index a07cdd55fd..280c4c6df3 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/ActiveTable.java +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/ActiveTable.java @@ -20,13 +20,11 @@ package com.raytheon.uf.edex.activetable; import java.io.File; -import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -39,6 +37,7 @@ import com.raytheon.uf.common.activetable.MergeResult; import com.raytheon.uf.common.activetable.OperationalActiveTableRecord; import com.raytheon.uf.common.activetable.PracticeActiveTableRecord; import com.raytheon.uf.common.activetable.VTECChange; +import com.raytheon.uf.common.activetable.VTECPartners; import com.raytheon.uf.common.activetable.VTECTableChangeNotification; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -61,8 +60,6 @@ import com.raytheon.uf.edex.database.cluster.handler.CurrentTimeClusterLockHandl import com.raytheon.uf.edex.database.dao.CoreDao; import com.raytheon.uf.edex.database.dao.DaoConfig; import com.raytheon.uf.edex.database.query.DatabaseQuery; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; /** * ActiveTable container and logic. The ActiveTable is a legacy GFE concept of @@ -576,169 +573,6 @@ public class ActiveTable { dao.executeNativeSql(sql); } - /** - * Convert the active table to a list of Maps. Doing it directly - * in Java eliminates the need for Python paths, handling JepExceptions, and - * at least one Python/Java conversion of the active table. - * - * @param records - * A list of ActiveTableRecords to convert to - * Maps. - * @return records, converted to a list of Maps. - * - * TODO: move this method to a static utility class - */ - public static List> convertToDict( - List records, String site) { - - List> dicts = new ArrayList>( - records.size()); - for (ActiveTableRecord atr : records) { - Map template = new HashMap(); - template.put("vtecstr", atr.getVtecstr()); - template.put("etn", Integer.valueOf(atr.getEtn())); - template.put("sig", atr.getSig()); - template.put("phen", atr.getPhen()); - if (atr.getSegText() != null) { - template.put("segText", atr.getSegText()); - } - if (atr.getOverviewText() != null) { - template.put("overviewText", atr.getOverviewText()); - template.put("hdln", atr.getOverviewText()); - } - template.put("phensig", atr.getPhensig()); - template.put("act", atr.getAct()); - template.put("seg", atr.getSeg()); - template.put("startTime", - atr.getStartTime().getTimeInMillis() / 1000); - template.put("endTime", atr.getEndTime().getTimeInMillis() / 1000); - template.put("ufn", atr.isUfn()); - template.put("officeid", atr.getOfficeid()); - template.put("purgeTime", - atr.getPurgeTime().getTimeInMillis() / 1000); - template.put("issueTime", - atr.getIssueTime().getTimeInMillis() / 1000); - template.put("state", "Decoded"); - template.put("xxxid", atr.getXxxid()); - - template.put("pil", - remapPil(site, atr.getPhen(), atr.getSig(), atr.getPil())); - template.put("productClass", atr.getProductClass()); - - template.put("id", atr.getUgcZone()); - - template.put("rawMessage", atr.getRawmessage()); - template.put("countyheader", atr.getCountyheader()); - Calendar floodBegin = atr.getFloodBegin(); - if (floodBegin != null) { - long floodBeginMillis = floodBegin.getTimeInMillis(); - if (floodBeginMillis != 0) { - template.put("floodBegin", floodBeginMillis / 1000); - } - } - template.put("wmoid", atr.getWmoid()); - - // Warngen fields - Calendar floodCrest = atr.getFloodCrest(); - if (floodCrest != null) { - long floodCrestMillis = floodCrest.getTimeInMillis(); - if (floodCrestMillis != 0) { - template.put("floodCrest", floodCrestMillis / 1000); - } - } - Calendar floodEnd = atr.getFloodEnd(); - if (floodEnd != null) { - long floodEndMillis = floodEnd.getTimeInMillis(); - if (floodEndMillis != 0) { - template.put("floodBegin", floodEndMillis / 1000); - } - } - String floodStatus = atr.getFloodRecordStatus(); - if (floodStatus != null && !"".equals(floodStatus.trim())) { - template.put("floodrecordstatus", floodStatus); - } - String floodSeverity = atr.getFloodSeverity(); - if (floodSeverity != null && !"".equals(floodSeverity.trim())) { - template.put("floodseverity", floodSeverity); - } - - Geometry geometry = atr.getGeometry(); - if (geometry != null && !geometry.isEmpty()) { - StringBuilder sb = new StringBuilder(); - String sep = ""; - long lat; - long lon; - for (Coordinate coordinate : geometry.getCoordinates()) { - sb.append(sep); - sep = " "; - lat = Math.round(Math.abs(coordinate.y) * 100.0); - lon = Math.round(Math.abs(coordinate.x) * 100.0); - sb.append(String.format("%d %d", lat, lon)); - } - template.put("geometry", sb.toString()); - } - - String immediateCause = atr.getImmediateCause(); - if (immediateCause != null && !"".equals(immediateCause.trim())) { - template.put("immediateCause", immediateCause); - } - - String loc = atr.getLoc(); - if (loc != null && !"".equals(loc.trim())) { - template.put("loc", loc); - } - - String locationId = atr.getLocationID(); - if (locationId != null && !"".equals(locationId.trim())) { - template.put("locationId", locationId); - } - - Integer motdir = atr.getMotdir(); - if (motdir != null) { - template.put("motdir", motdir); - } - - Integer motspd = atr.getMotspd(); - if (motspd != null) { - template.put("motspd", motspd); - } - - dicts.add(template); - } - return dicts; - } - - /** - * Some events are issued in one PIL and cancelled or extended in another. - * This finds the PIL needed. - * - * @param siteID - * The site from which - * @param phen - * The phenomenon code to look for - * @param sig - * The significance code to look for - * @param dft - * The PIL to use if the phensig is not remapped - * @return The PIL after remapping. - */ - @SuppressWarnings("unchecked") - protected static String remapPil(String siteId, String phen, String sig, - String dft) { - String result = dft; - Map MappedPils = (Map) VTECPartners - .getInstance(siteId).getattr("VTEC_MAPPED_PILS"); - List key = new ArrayList(3); - key.add(phen); - key.add(sig); - key.add(dft); - String mPil = MappedPils.get(key); - if (mPil != null) { - result = mPil; - } - return result; - } - public static File dumpProductToTempFile(String productText) { File file = Util.createTempFile(productText.getBytes(), "vtec"); file.deleteOnExit(); diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/DumpActiveTableHandler.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/DumpActiveTableHandler.java index d7af6415a9..394fa04fb9 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/DumpActiveTableHandler.java +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/DumpActiveTableHandler.java @@ -13,8 +13,10 @@ import jep.JepException; import com.raytheon.uf.common.activetable.ActiveTableMode; import com.raytheon.uf.common.activetable.ActiveTableRecord; +import com.raytheon.uf.common.activetable.ActiveTableUtil; import com.raytheon.uf.common.activetable.DumpActiveTableRequest; import com.raytheon.uf.common.activetable.DumpActiveTableResponse; +import com.raytheon.uf.common.activetable.VTECPartners; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.python.PythonScript; @@ -95,7 +97,7 @@ public class DumpActiveTableHandler implements List tableOfRecords = getActiveTableForSites( sites, fromSite, request.getMode()); - table = ActiveTable.convertToDict(tableOfRecords, fromSite); + table = ActiveTableUtil.convertToDict(tableOfRecords, fromSite); } response.setUnfilteredCount(Integer.valueOf(table.size())); diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetActiveTableDictHandler.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetActiveTableDictHandler.java index fcceacc718..c3a6008ae0 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetActiveTableDictHandler.java +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetActiveTableDictHandler.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import com.raytheon.uf.common.activetable.ActiveTableRecord; +import com.raytheon.uf.common.activetable.ActiveTableUtil; import com.raytheon.uf.common.activetable.GetActiveTableDictRequest; import com.raytheon.uf.common.activetable.GetActiveTableDictResponse; import com.raytheon.uf.common.serialization.comm.IRequestHandler; @@ -60,7 +61,7 @@ public class GetActiveTableDictHandler implements GetActiveTableDictResponse response = new GetActiveTableDictResponse(); List records = ActiveTable.getActiveTable(site, request.getMode(), null, null, null, request.getWfos()); - List> table = ActiveTable.convertToDict(records, + List> table = ActiveTableUtil.convertToDict(records, site); response.setActiveTable(table); statusHandler.handle(Priority.INFO, "ActiveTable for " + site diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetVtecAttributeHandler.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetVtecAttributeHandler.java index 12ea40bc50..20f4629e67 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetVtecAttributeHandler.java +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/GetVtecAttributeHandler.java @@ -21,6 +21,7 @@ package com.raytheon.uf.edex.activetable; import com.raytheon.uf.common.activetable.GetVtecAttributeRequest; import com.raytheon.uf.common.activetable.GetVtecAttributeResponse; +import com.raytheon.uf.common.activetable.VTECPartners; import com.raytheon.uf.common.serialization.comm.IRequestHandler; /** 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 index fb8f256024..1c3667ccca 100644 --- 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 @@ -96,7 +96,8 @@ public class RetrieveRemoteActiveTableHandler implements try { Map argMap = new HashMap(); argMap.put("serverHost", request.getServerHost()); - argMap.put("serverPort", request.getServerPort()); + argMap.put("serverPort", + Integer.toString(request.getServerPort())); argMap.put("serverProtocol", request.getServerProtocol()); argMap.put("mhsid", request.getMhsId()); argMap.put("siteID", siteId); 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 index 3caad2606a..04ae7df26f 100644 --- 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 @@ -95,7 +95,8 @@ public class SendActiveTableHandler implements try { Map argMap = new HashMap(); argMap.put("myServerHost", request.getServerHost()); - argMap.put("myServerPort", request.getServerPort()); + argMap.put("myServerPort", + Integer.toString(request.getServerPort())); argMap.put("myServerProtocol", request.getServerProtocol()); argMap.put("myServerMHSID", request.getMhsId()); argMap.put("myServerSite", siteId); diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchATJobConfig.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchATJobConfig.java new file mode 100644 index 0000000000..9bd77f6059 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchATJobConfig.java @@ -0,0 +1,208 @@ +/** + * 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.vtecsharing; + +import java.util.Map; + +/** + * Configuration information for a given site's vtec active table fetching. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 28, 2013            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class FetchATJobConfig { + + private String siteId; + + private long interval; + + private String ancfAddress; + + private String bncfAddress; + + private String serverHost; + + private String port; + + private String protocolV; + + private String mhsId; + + private String transmitScript; + + public FetchATJobConfig(Map configMap) { + siteId = configMap.get("siteId").toString(); + interval = ((Number) configMap.get("interval")).longValue(); + ancfAddress = configMap.get("ancf").toString(); + bncfAddress = configMap.get("bncf").toString(); + serverHost = configMap.get("serverHost").toString(); + port = configMap.get("port").toString(); + protocolV = configMap.get("protocolV").toString(); + mhsId = configMap.get("mhsid").toString(); + transmitScript = configMap.get("transmitScript").toString(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + FetchATJobConfig other = (FetchATJobConfig) obj; + if (ancfAddress == null) { + if (other.ancfAddress != null) { + return false; + } + } else if (!ancfAddress.equals(other.ancfAddress)) { + return false; + } + if (bncfAddress == null) { + if (other.bncfAddress != null) { + return false; + } + } else if (!bncfAddress.equals(other.bncfAddress)) { + return false; + } + if (interval != other.interval) { + return false; + } + if (mhsId == null) { + if (other.mhsId != null) { + return false; + } + } else if (!mhsId.equals(other.mhsId)) { + return false; + } + if (port == null) { + if (other.port != null) { + return false; + } + } else if (!port.equals(other.port)) { + return false; + } + if (protocolV == null) { + if (other.protocolV != null) { + return false; + } + } else if (!protocolV.equals(other.protocolV)) { + return false; + } + if (serverHost == null) { + if (other.serverHost != null) { + return false; + } + } else if (!serverHost.equals(other.serverHost)) { + return false; + } + if (siteId == null) { + if (other.siteId != null) { + return false; + } + } else if (!siteId.equals(other.siteId)) { + return false; + } + if (transmitScript == null) { + if (other.transmitScript != null) { + return false; + } + } else if (!transmitScript.equals(other.transmitScript)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("FetchATJobConfig [siteId="); + builder.append(siteId); + builder.append(", interval="); + builder.append(interval); + builder.append(", ancfAddress="); + builder.append(ancfAddress); + builder.append(", bncfAddress="); + builder.append(bncfAddress); + builder.append(", serverHost="); + builder.append(serverHost); + builder.append(", port="); + builder.append(port); + builder.append(", protocolV="); + builder.append(protocolV); + builder.append(", mhsId="); + builder.append(mhsId); + builder.append(", transmitScript="); + builder.append(transmitScript); + builder.append("]"); + return builder.toString(); + } + + public String getSiteId() { + return siteId; + } + + public long getInterval() { + return interval; + } + + public String getAncfAddress() { + return ancfAddress; + } + + public String getBncfAddress() { + return bncfAddress; + } + + public String getServerHost() { + return serverHost; + } + + public String getPort() { + return port; + } + + public String getProtocolV() { + return protocolV; + } + + public String getMhsId() { + return mhsId; + } + + public String getTransmitScript() { + return transmitScript; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchActiveTableSrv.java b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchActiveTableSrv.java new file mode 100644 index 0000000000..f39b61e522 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/vtecsharing/FetchActiveTableSrv.java @@ -0,0 +1,204 @@ +/** + * 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.vtecsharing; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.google.common.util.concurrent.MoreExecutors; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.edex.site.ISiteActivationListener; + +/** + * Service that fetches neighboring sites' active table entries that are + * relevant to this site using requestAT. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 28, 2013            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class FetchActiveTableSrv implements ISiteActivationListener { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(FetchActiveTableSrv.class); + + private final Map siteConfigMap; + + private final Map> siteJobInstanceMap; + + private final ScheduledExecutorService jobExecutor; + + public FetchActiveTableSrv() { + siteConfigMap = new ConcurrentHashMap(); + siteJobInstanceMap = new ConcurrentHashMap>(); + jobExecutor = MoreExecutors + .getExitingScheduledExecutorService((ScheduledThreadPoolExecutor) Executors + .newScheduledThreadPool(1)); + } + + public void addSite(Map configData) { + FetchATJobConfig config = new FetchATJobConfig(configData); + final String site = config.getSiteId(); + + statusHandler.debug("Activating FetchAT for " + site); + statusHandler.debug("Site: " + site + " config: " + config); + + if ((siteConfigMap.containsKey(site)) + && siteConfigMap.get(site).equals(config)) { + return; + } + + Runnable job = new Runnable() { + + @Override + public void run() { + statusHandler.info("Starting requestAT process for site: " + + site); + + // requestAT -H ourHost -P ourPort -L ourServerProto -M mhsid + // -S ourSite -t irtWebAddr -x transmitScript + FetchATJobConfig jobConfig = siteConfigMap.get(site); + List args = new ArrayList(17); + args.add("requestAT"); + args.add("-H"); + args.add(jobConfig.getServerHost()); + args.add("-P"); + args.add(jobConfig.getPort()); + args.add("-L"); + args.add(jobConfig.getProtocolV()); + args.add("-M"); + args.add(jobConfig.getMhsId()); + args.add("-S"); + args.add(jobConfig.getSiteId()); + args.add("-a"); + args.add(jobConfig.getAncfAddress()); + args.add("-b"); + args.add(jobConfig.getBncfAddress()); + args.add("-x"); + args.add(jobConfig.getTransmitScript()); + + // String msg = Joiner.on(' ').join(args); + // statusHandler.debug("Running command: " + msg); + + try { + ProcessBuilder command = new ProcessBuilder(args); + command.start(); + } catch (IOException e) { + statusHandler.handle(Priority.PROBLEM, + "Error executing requestAT: ", e); + } + } + }; + + try { + siteConfigMap.put(site, config); + ScheduledFuture jobInstance = jobExecutor.scheduleAtFixedRate( + job, 10, config.getInterval(), TimeUnit.SECONDS); + siteJobInstanceMap.put(site, jobInstance); + } catch (RejectedExecutionException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to submit fetchAT job for execution:", e); + siteConfigMap.remove(site); + siteJobInstanceMap.remove(site); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.site.ISiteActivationListener#deactivateSite(java + * .lang.String) + */ + @Override + public void deactivateSite(String siteID) throws Exception { + statusHandler.info("Deactivating FetchAT for " + siteID); + ScheduledFuture siteJob = siteJobInstanceMap.remove(siteID); + siteJob.cancel(false); + siteConfigMap.remove(siteID); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.site.ISiteActivationListener#activateSite(java.lang + * .String) + */ + @Override + public void activateSite(String siteID) throws Exception { + return; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.site.ISiteActivationListener#getActiveSites() + */ + @Override + public Set getActiveSites() { + return Collections.emptySet(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.site.ISiteActivationListener#validateConfig(java + * .lang.String) + */ + @Override + public String validateConfig(String siteID) { + return null; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.site.ISiteActivationListener#registered() + */ + @Override + public void registered() { + return; + } +} 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 092dba5f71..74a1d4ae0f 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 @@ -33,7 +33,7 @@ import LogStream import JUtil from java.util import ArrayList -from com.raytheon.uf.edex.activetable import ActiveTable +from com.raytheon.uf.common.activetable import ActiveTableUtil class VTECTableUtil: @@ -380,7 +380,7 @@ class VTECTableUtil: for rec in table: javaRecList.add(rec.javaRecord()) - javaDictFormat = ActiveTable.convertToDict(javaRecList, siteId) + javaDictFormat = ActiveTableUtil.convertToDict(javaRecList, siteId) return JUtil.javaObjToPyVal(javaDictFormat) 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 index 5e348f549f..50f558f8a1 100644 --- 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 @@ -44,6 +44,7 @@ import siteConfig import VTECPartners from com.raytheon.uf.common.activetable import ActiveTableMode +from com.raytheon.uf.common.time.util import TimeUtil from com.raytheon.uf.edex.activetable import ActiveTable @@ -104,7 +105,7 @@ def execute_request_at(serverHost, serverPort, serverProtocol, mhsid, siteID, an rec.getOfficeid() not in otherSites: continue - recIssueTime = rec.getIssueTime().getTimeInMillis() / 1000 + recIssueTime = float(rec.getIssueTime().getTimeInMillis() / TimeUtil.MILLIS_PER_SECOND) #track latest issueTime = max(recIssueTime, issueTime) 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 index 3411781652..fa0c6ee4c1 100644 --- 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 @@ -176,7 +176,7 @@ def execute_send_at(myServerHost, myServerPort, myServerProtocol, #-------------------------------------------------------------------- # Create the destination XML file #-------------------------------------------------------------------- - iscOut = Element('isc') + iscOut = ET.Element('isc') irt.addSourceXML(iscOut, myServer) destServers = [] 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 a39f3a7053..6497dc540e 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 @@ -51,7 +51,7 @@ from ufpy import UsageArgumentParser logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s", datefmt="%H:%M:%S", - level=logging.DEBUG) + level=logging.INFO) log = logging.getLogger('MergeVTEC')