From 5bff9f2ac8848328174100e2d764611ba68a6c84 Mon Sep 17 00:00:00 2001 From: Michael Gamazaychikov Date: Wed, 21 May 2014 14:56:20 +0100 Subject: [PATCH 01/17] ASM #114 - Problem with Distance Speed Tool (merge with 13.5.4 changes). Change-Id: Ic4d6f50c28d0aba440a02010b09b2e3b3117fe85 Former-commit-id: f3ee76edfd95e9c25eff89d1ecbff9e466b3ca75 --- .../awipstools/common/stormtrack/StormTrackDisplay.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java index c6ca1beba3..939444f432 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java @@ -722,15 +722,6 @@ public class StormTrackDisplay implements IRenderable { || currentState.newDuration != -1 || update) { if (currentState.timePoints != null && currentState.timePoints.length != frameCount) { - // need to set theAnchorPoint and theAnchorIndex here - // because timePoints get erased before we get to updateAnchorPoint - DataTime frameTime = paintProps.getDataTime(); - for (int j=0;j Date: Fri, 23 May 2014 15:46:33 -0400 Subject: [PATCH 02/17] ASM #596 - Watch wording not properly inserted into some warning products Change-Id: I7dc223d95f06a6a259e969cfbb8e4bde2f4b9192 Former-commit-id: ed8cd169fe0a531d0d83411f7b1afe787088d406 --- .../utility/common_static/base/warngen/VM_global_library.vm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm index 2e1c9bd44e..c9d739e623 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm @@ -11,6 +11,7 @@ ##### Evan Bookbinder 05-05-2013 handleClosesPoints and 3rd bullet changes (OVER & now) ##### Evan Bookbinder 09-20-2013 Fixed rural area otherPoints in pathcast section, added rural phrase ##### Qinglu Lin 03-17-2014 DR 16309. Updated inserttorwatches and insertsvrwatches. +##### Qinglu Lin 05-21-2014 DR 16309. Updated inserttorwatches and insertsvrwatches by changing 'FOR##' to 'FOR ##'. #################################################################################################### #* Mile Marker Test Code @@ -202,7 +203,7 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local #if(${secondtimezone}) /${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/## #end - FOR## + FOR ## #set($numPortions = ${list.size(${watch.getPortions()})}) #set($count = 0) #foreach(${portion} in ${watch.getPortions()}) @@ -236,7 +237,7 @@ ${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${local #if(${secondtimezone}) /${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/## #end - FOR## + FOR ## #set($numPortions = ${list.size(${watch.getPortions()})}) #set($count = 0) #foreach(${portion} in ${watch.getPortions()}) From ba8d7dbbb7dd4735f20a9496ccccd8b8adff8344 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Tue, 27 May 2014 13:30:35 -0400 Subject: [PATCH 03/17] CM-MERGE:OB13.5.5-10 into 14.1.2 Former-commit-id: d57f7989982a59a546116b63a406294573844039 --- .../src/com/raytheon/edex/plugin/shef/database/PostShef.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java index bb621d1707..ead3309e25 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java @@ -475,7 +475,8 @@ public class PostShef { data.setCreationDateObj(d); data.setCreationDate("1970-01-01 00:00:00"); } - + + locId = data.getLocationId(); String key = locId + prodId + data.getObservationTime(); if (idLocations.containsKey(key)) { postLocData = idLocations.get(key); From e852623f48022e7132ae8d8d5b5a557e2745ad72 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Wed, 28 May 2014 08:40:56 -0400 Subject: [PATCH 04/17] CM-MERGE:OB13.5.5-11 into 14.1.2 Former-commit-id: c85d4369600bfc24405386aa71713d7f2d58b201 --- .../raytheon/edex/plugin/shef/database/PostShef.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java index ead3309e25..641bb4e620 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java @@ -2097,9 +2097,9 @@ public class PostShef { String telem = null; String sql = null; Object[] oa = null; - + String key = locId + data.getPeTsE(); try { - if (!ingestSwitchMap.containsKey(locId)) { + if (!ingestSwitchMap.containsKey(key)) { errorMsg.append("Error getting connection to IHFS Database"); sql = "select lid, pe, dur, ts, extremum, ts_rank, ingest, ofs_input, stg2_input from IngestFilter where lid = '" + locId + "'"; @@ -2136,11 +2136,11 @@ public class PostShef { } } - ingestSwitchMap.put(locId, ingestSwitch); + ingestSwitchMap.put(key, ingestSwitch); } - matchFound = ingestSwitchMap.containsKey(locId); - ingestSwitch = ingestSwitchMap.get(locId); + matchFound = ingestSwitchMap.containsKey(key); + ingestSwitch = ingestSwitchMap.get(key); /* * if there is no ingest record for this entry, then check if the From 5cf0579d201372a4df0086045db1d8b52ad41285 Mon Sep 17 00:00:00 2001 From: "Shawn.Hooper" Date: Thu, 29 May 2014 16:55:36 -0400 Subject: [PATCH 05/17] ASM #209 - Fix Svcbu cleanup script Change-Id: I4da44d4c410c03769e556dc6abca62db52880997 Former-commit-id: 626ee991cd7e9dbfe52342abd9e3fd41b973f72a --- .../svcBackup/ServiceBackup/scripts/cleanup_svcbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/cleanup_svcbk b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/cleanup_svcbk index bbd6744cae..f52f3b09d8 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/cleanup_svcbk +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/cleanup_svcbk @@ -49,7 +49,7 @@ fi if [ -d ${LOCALIZATION_PATH}/cave_static/site/${CAPS_FAILED_SITE}/gfe ]; then log_msg "Removing cave site configuration for site ${CAPS_FAILED_SITE}" - rm -fr ${LOCALIZATION_PATH}/cave_static/site/${SITE}/gfe + rm -fr ${LOCALIZATION_PATH}/cave_static/site/${CAPS_FAILED_SITE}/gfe fi if [ -d ${LOCALIZATION_PATH}/cave_static/site/${CAPS_FAILED_SITE}/bundles/maps ]; then From 71ab6b9ed09b81198d59fc81c18e6e52963803f0 Mon Sep 17 00:00:00 2001 From: "Zhidong.Hao" Date: Tue, 3 Jun 2014 11:55:32 -0400 Subject: [PATCH 06/17] ASM #106 - AvnFPS Monitor TAF valid time display different from A1 Change-Id: Iddf3f4ee46b94f28494dc15764b91f38c0176325 Former-commit-id: 74597b2630ffd8d984b193f72126a9a5d0b3a942 --- .../src/com/raytheon/viz/aviation/monitor/CcfpData.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/CcfpData.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/CcfpData.java index 4a682d7e31..a83f5aa083 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/CcfpData.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/CcfpData.java @@ -49,6 +49,7 @@ import com.vividsolutions.jts.geom.GeometryFactory; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 15, 2009 njensen Initial creation + * Jun 3, 2014 16289 zhao Use "end time" instead of "start time" for CCFP report * * * @@ -119,7 +120,7 @@ public class CcfpData { CcfpRecord area = findMostRelevantArea(c, list); List reports = siteReportMap.get(site); if (area != null) { - String report = mkCCFPReport(site, dt, area); + String report = mkCCFPReport(site, area.getDataTime().getValidPeriod().getEnd(), area); reports.add(report); } siteReportMap.put(site, reports); From 50ab77046bbfed251aa4459b681114da3a1216fc Mon Sep 17 00:00:00 2001 From: Michael Gamazaychikov Date: Wed, 4 Jun 2014 18:42:13 +0100 Subject: [PATCH 07/17] ASM #114 - Problem with Distance Speed Tool. Change-Id: I2b3218b2fb407f99cf9c81edf69feb042a6fee75 Former-commit-id: a38308fa5a6efe9a07ecd84bd93662bea32afc94 --- .../awipstools/common/stormtrack/StormTrackDisplay.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java index 939444f432..c6ca1beba3 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java @@ -722,6 +722,15 @@ public class StormTrackDisplay implements IRenderable { || currentState.newDuration != -1 || update) { if (currentState.timePoints != null && currentState.timePoints.length != frameCount) { + // need to set theAnchorPoint and theAnchorIndex here + // because timePoints get erased before we get to updateAnchorPoint + DataTime frameTime = paintProps.getDataTime(); + for (int j=0;j Date: Thu, 5 Jun 2014 09:32:38 -0500 Subject: [PATCH 08/17] Issue #3222 - Fix for SHEF posting times Former-commit-id: 3f1f9cf4fa6207edae642db5cffdc8284091f31a --- .../edex/plugin/shef/database/PostShef.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java index 47d2b6eae0..4313cd1b23 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java @@ -84,6 +84,7 @@ import com.raytheon.uf.common.dataplugin.shef.util.ShefQC; import com.raytheon.uf.common.ohd.AppsDefaults; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.database.dao.CoreDao; import com.raytheon.uf.edex.database.dao.DaoConfig; import com.raytheon.uf.edex.decodertools.time.TimeTools; @@ -119,6 +120,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools; * 02/18/2014 16572 l. Bousaidi only apply adjust factor to non missing values. * 04/29/2014 3088 mpduff Change logging class, clean up/optimization. * Updated with more performance fixes. + * 05/28/2014 3222 mpduff Fix posting time to be processed time so db doesn't show all post times the same * * * @@ -459,6 +461,8 @@ public class PostShef { return; } + postDate.setTime(getToNearestSecond(TimeUtil + .currentTimeMillis())); boolean same_lid_product = false; String dataValue = data.getStringValue(); @@ -476,7 +480,7 @@ public class PostShef { data.setCreationDateObj(d); data.setCreationDate("1970-01-01 00:00:00"); } - + locId = data.getLocationId(); String key = locId + prodId + data.getObservationTime(); if (idLocations.containsKey(key)) { @@ -731,7 +735,7 @@ public class PostShef { * shefrec structure */ if (!dataValue.equals(ShefConstants.SHEF_MISSING)) { - adjustRawValue(locId, data); + adjustRawValue(locId, data); } /* * multiply non-missing values of discharge values and @@ -2537,6 +2541,8 @@ public class PostShef { */ private void postProductLink(String locId, String productId, Date obsTime) { PersistableDataObject link = null; + + postDate.setTime(getToNearestSecond(TimeUtil.currentTimeMillis())); try { /* Get a Data Access Object */ link = new Productlink(new ProductlinkId(locId, productId, obsTime, @@ -2915,6 +2921,7 @@ public class PostShef { ShefData data, String locId, String tableName, String dataValue, String qualifier, long qualityCode) { PersistableDataObject dataObj = null; + postDate.setTime(getToNearestSecond(TimeUtil.currentTimeMillis())); if (ShefConstants.COMMENT_VALUE.equalsIgnoreCase(tableName)) { Commentvalue comment = new Commentvalue(new CommentvalueId()); @@ -3163,6 +3170,19 @@ public class PostShef { return dataObj; } + /** + * Convert the provided millisecond value to the nearest second. + * + * @param time + * time in milliseconds + * + * @return milliseconds rounded to the nearest second. + */ + private long getToNearestSecond(long time) { + // Force time to nearest second. + return time - (time % 1000); + } + public void close() { postTables.close(); } From c5e6daa943ea479728c738a6112a057971d2dc38 Mon Sep 17 00:00:00 2001 From: "Fay.Liang" Date: Thu, 5 Jun 2014 15:47:37 -0400 Subject: [PATCH 09/17] ASM #611 fix to MHS issues in DR_17297 Change-Id: Ie32edc0bac5458e3d356a0b6b3deea0f8d520cb7 Former-commit-id: fc06896ae4d9adf0973522313f5e65df6ac67fa4 --- .../utility/edex_static/base/gfe/isc/IrtAccess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 89fc8f5e28..31f6af9c6b 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 @@ -491,7 +491,7 @@ class IrtAccess(): self.logEvent("Transmit: ", cmd) import siteConfig from subprocess import Popen,PIPE - output,err = Popen(cmd.split(" "), stdout=PIPE,stderr=PIPE).communicate() + output,err = Popen(cmd, shell=True, stdout=PIPE,stderr=PIPE).communicate() if output.find(siteConfig.GFESUITE_MHSID+"-") == -1: alertMsg = "ISC Send failed transmission to : "+",".join(addresses)+" --> "+output+" "+err self.logProblem(alertMsg) From 33b235a0a4ea267ea005d22fe1de83c4b028fcad Mon Sep 17 00:00:00 2001 From: "Xuezhi.Wei" Date: Fri, 6 Jun 2014 17:40:09 +0000 Subject: [PATCH 10/17] ASM #579 - shef-ingest.xml updates for performance tracking Change-Id: If3b24f8385e955d003d79e22605d4536321c73b2 Former-commit-id: f7b5f3bbc71cc251e19f1764ee7756050895b7a3 --- .../com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml index cbeb83d0e8..af9a640edc 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml @@ -132,6 +132,7 @@ + java.lang.Throwable @@ -151,6 +152,7 @@ + java.lang.Throwable From 39173c380c28d8ee385618fed7276e2d179168ae Mon Sep 17 00:00:00 2001 From: Mike Duff Date: Mon, 24 Mar 2014 16:07:46 -0500 Subject: [PATCH 11/17] ASM #605 - Cherry-pick Omaha Issue #2954 from 14.3.1 into 14.2.2 to fix CAVE not starting if scale bundle is missing. Change-Id: I3f7159b7a48e74fc9ad7a4220d6c30b67240aca1 Former-commit-id: 7fe0dae041cb68aba968e22d5895cce22a210ee6 --- .../core/maps/scales/MapScalesManager.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java index 7d077fcd27..440e228879 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java @@ -61,6 +61,7 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml; * Oct 08, 2013 mschenke Initial creation * Oct 22, 2013 2491 bsteffen Change from SerializationUtil to * ProcedureXmlManager + * Mar 24, 2014 2954 mpduff Check for missing map scale files and handle the situation. * * * @@ -99,16 +100,22 @@ public class MapScalesManager { private String bundleXml; - private boolean isCustom; + private final boolean isCustom; private ManagedMapScale(String baseDir, MapScale scale) throws SerializationException { this.isCustom = false; - this.scaleFile = new AutoUpdatingLocalizationFile( - PathManagerFactory.getPathManager() - .getStaticLocalizationFile( - baseDir + IPathManager.SEPARATOR - + scale.getFileName())); + LocalizationFile file = PathManagerFactory.getPathManager() + .getStaticLocalizationFile( + baseDir + IPathManager.SEPARATOR + + scale.getFileName()); + + if (file == null || !file.exists()) { + throw new IllegalStateException( + "scalesInfo.xml references missing file " + + scale.getFileName()); + } + this.scaleFile = new AutoUpdatingLocalizationFile(file); this.scaleFile.addListener(listener); this.partIds = scale.getPartIds(); this.displayName = scale.getDisplayName(); @@ -200,7 +207,7 @@ public class MapScalesManager { // TODO: Need to figure out best way to create custom scales (depends on // maps loaded so it can't be at the projection dialog level) - private Collection customScales = new ArrayList(); + private final Collection customScales = new ArrayList(); /** * Construct a MapScalesManager for the given scales file. File must be From 8874d418723c96d6d64e5ce0114e963f428429c0 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Tue, 10 Jun 2014 12:52:59 -0400 Subject: [PATCH 12/17] CM-MERGE:OB13.5.6-1,-2 into 14.1.3 Former-commit-id: b859032bcec187616adfd414dd1ce5fe27829e9e --- .../viz/awipstools/ToolsDataManager.java | 191 ++++++++---------- .../viz/awipstools/common/StormTrackData.java | 34 +++- .../common/stormtrack/StormTrackDisplay.java | 3 +- .../base/config/gfe/serverConfig.py | 2 + .../base/parameter/alias/gfeParamName.xml | 8 + .../base/grid/parameterInfo/spcGuideNDFD.xml | 15 ++ .../edex/plugin/shef/database/PostShef.java | 60 ++++-- 7 files changed, 186 insertions(+), 127 deletions(-) diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ToolsDataManager.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ToolsDataManager.java index c1db6598d2..7e479f9a87 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ToolsDataManager.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ToolsDataManager.java @@ -27,7 +27,6 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -35,14 +34,14 @@ import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import javax.xml.bind.JAXB; + import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.preference.IPersistentPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; import com.raytheon.uf.common.localization.FileUpdatedMessage; import com.raytheon.uf.common.localization.ILocalizationFileObserver; @@ -51,6 +50,8 @@ import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.LocalizationFileInputStream; +import com.raytheon.uf.common.localization.LocalizationFileOutputStream; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.localization.exception.LocalizationException; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -60,7 +61,6 @@ import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.viz.core.catalog.DirectDbQuery; import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.points.PointsDataManager; import com.raytheon.viz.awipstools.common.RangeRing; @@ -85,14 +85,14 @@ import com.vividsolutions.jts.geom.LineString; * 04-07-10 #4614 randerso Reworked to use localization files * 07-11-12 #875 rferrel Move points to PointsDataManager. * 04-02-14 DR 16351 D. Friedman Fix updates to storm track from preferences. (backport from 14.2.2) + * 06-03-24 3191 njensen Improved saving/loading storm track data * * * * @author bsteffen * @version 1.0 */ -public class ToolsDataManager implements ILocalizationFileObserver, - IPropertyChangeListener { +public class ToolsDataManager implements ILocalizationFileObserver { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(ToolsDataManager.class); @@ -102,13 +102,9 @@ public class ToolsDataManager implements ILocalizationFileObserver, private static final String P_RANGERING_LOCATIONS = "rangeRingLocations"; - private static final String P_STORMTRACK_SPEED = "stormSpeed"; + private static final String TOOLS_DIR = "awipsTools"; - private static final String P_STORMTRACK_ANGLE = "stormAngle"; - - private static final String P_STORMTRACK_POINTS = "stormCoordinates"; - - private static final String P_STORMTRACK_DATE = "stormDate"; + private static final String STORM_TRACK_FILE = "stormTrackData.xml"; private static final int[] DEFAULT_LINE_RADIUS = { 120, 120, 120, 120, 240, 240, 216, 216, 360, 360 }; @@ -139,8 +135,6 @@ public class ToolsDataManager implements ILocalizationFileObserver, private boolean stormTrackDirty = false; - private String site; - private LocalizationFile userToolsDir; private IPathManager pathMgr; @@ -155,19 +149,19 @@ public class ToolsDataManager implements ILocalizationFileObserver, } private ToolsDataManager() { - site = LocalizationManager.getInstance().getCurrentSite(); - pathMgr = PathManagerFactory.getPathManager(); pointsManager = PointsDataManager.getInstance(); LocalizationContext userCtx = pathMgr.getContext( LocalizationType.CAVE_STATIC, LocalizationLevel.USER); - - userToolsDir = pathMgr.getLocalizationFile(userCtx, "awipsTools" - + File.separator + site); + /* + * TODO: Since it's already under the user localization, why does it + * then want to have the site underneath that? If anyone knows, please + * document it and remove this TODO. PointsManager does a similar thing. + */ + userToolsDir = pathMgr.getLocalizationFile(userCtx, TOOLS_DIR + + IPathManager.SEPARATOR + + LocalizationManager.getInstance().getCurrentSite()); userToolsDir.addFileUpdatedObserver(this); - - CorePlugin.getDefault().getPreferenceStore() - .addPropertyChangeListener(this); } public Collection getBaselineNames() { @@ -252,67 +246,73 @@ public class ToolsDataManager implements ILocalizationFileObserver, } private void loadStormData() { - stormData = new StormTrackData(); - HierarchicalPreferenceStore store = (HierarchicalPreferenceStore) CorePlugin - .getDefault().getPreferenceStore(); - store.setDefault(P_STORMTRACK_SPEED, 35.0); - double speed = store.getDouble(P_STORMTRACK_SPEED); - stormData.setMotionSpeed(speed); - - store.setDefault(P_STORMTRACK_ANGLE, 60.0); - double angle = store.getDouble(P_STORMTRACK_ANGLE); - stormData.setMotionDirection(angle); - - long date = store.getLong(P_STORMTRACK_DATE); - if (date > 0) { - stormData.setDate(new Date(date)); - } - String[] points = store.getStringArray(P_STORMTRACK_POINTS); - if (points != null) { - setCoordinates(stormData, points); + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationFile f = pathMgr.getLocalizationFile( + userToolsDir.getContext(), userToolsDir.getName() + + IPathManager.SEPARATOR + STORM_TRACK_FILE); + if (f.exists()) { + LocalizationFileInputStream is = null; + try { + is = f.openInputStream(); + stormData = JAXB.unmarshal(is, StormTrackData.class); + } catch (Exception e) { + statusHandler.error("Error loading storm track data", e); + stormData = defaultStormTrackData(); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + statusHandler.handle(Priority.DEBUG, + "Error closing storm track data input stream", + e); + } + } + } + } else { + stormData = defaultStormTrackData(); } + stormTrackDirty = false; } - private void setCoordinates(StormTrackData data, String[] points) { - Coordinate[] coords = new Coordinate[points.length]; - for (int i = 0; i < points.length; ++i) { - String[] latLon = points[i].split("[ ]"); - try { - coords[i] = new Coordinate(Double.parseDouble(latLon[0]), - Double.parseDouble(latLon[1])); - } catch (NumberFormatException e) { - statusHandler.handle(Priority.PROBLEM, - "Error reading storm track coordinates", e); - coords = new Coordinate[0]; - break; - } - } - data.setCoordinates(coords); + /** + * Creates and returns a default storm track data + * + * @return + */ + private static StormTrackData defaultStormTrackData() { + StormTrackData data = new StormTrackData(); + data.setMotionSpeed(35.0); + data.setMotionDirection(60.0); + data.setDate(SimulatedTime.getSystemTime().getTime()); + return data; } private void storeStormData() { synchronized (stormLock) { // Update the store time stormData.setDate(SimulatedTime.getSystemTime().getTime()); - HierarchicalPreferenceStore store = (HierarchicalPreferenceStore) CorePlugin - .getDefault().getPreferenceStore(); - store.setValue(P_STORMTRACK_SPEED, stormData.getMotionSpeed()); - store.setValue(P_STORMTRACK_ANGLE, stormData.getMotionDirection()); - Coordinate[] coordinates = stormData.getCoordinates(); - if (coordinates != null) { - String[] coords = new String[coordinates.length]; - for (int i = 0; i < coordinates.length; ++i) { - coords[i] = coordinates[i].x + " " + coordinates[i].y; - } - store.setValue(P_STORMTRACK_POINTS, coords); - } - store.setValue(P_STORMTRACK_DATE, stormData.getDate().getTime()); + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationFile f = pathMgr.getLocalizationFile( + userToolsDir.getContext(), userToolsDir.getName() + + IPathManager.SEPARATOR + STORM_TRACK_FILE); + LocalizationFileOutputStream os = null; try { - store.save(); - } catch (IOException e) { + os = f.openOutputStream(); + JAXB.marshal(stormData, os); + os.closeAndSave(); + } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Error saving storm track data", e); + try { + if (os != null) { + os.close(); + } + } catch (IOException e1) { + statusHandler.handle(Priority.DEBUG, + "Error closing storm track data output stream", e1); + } } } } @@ -593,11 +593,18 @@ public class ToolsDataManager implements ILocalizationFileObserver, */ @Override public void fileUpdated(FileUpdatedMessage message) { + /* + * This will receive messages about points updates too, but since the + * PointsManager is listening for those we don't care. + */ String fileName = new File(message.getFileName()).getName(); if (fileName.startsWith(BASELINE_PREFIX)) { baselineFileUpdated(fileName); - } else { - pointsManager.fileUpdated(message); + } else if (fileName.equals(STORM_TRACK_FILE)) { + stormTrackDirty = true; + for (Object listener : stormListeners.getListeners()) { + ((IToolChangedListener) listener).toolChanged(); + } } } @@ -642,44 +649,4 @@ public class ToolsDataManager implements ILocalizationFileObserver, stormListeners.remove(listener); } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse - * .jface.util.PropertyChangeEvent) - */ - @Override - public void propertyChange(PropertyChangeEvent event) { - String key = event.getProperty(); - if ((P_STORMTRACK_ANGLE.equals(key) || P_STORMTRACK_DATE.equals(key) - || P_STORMTRACK_POINTS.equals(key) || P_STORMTRACK_SPEED - .equals(key)) && stormData != null) { - synchronized (stormLock) { - Object value = event.getNewValue(); - if (P_STORMTRACK_ANGLE.equals(key) && value instanceof Double) { - stormData.setMotionDirection((Double) value); - } else if (P_STORMTRACK_DATE.equals(key) - && value instanceof Long) { - stormData.setDate(new Date((Long) value)); - } else if (P_STORMTRACK_POINTS.equals(key) - && value instanceof String[]) { - setCoordinates(stormData, (String[]) value); - } else if (P_STORMTRACK_SPEED.equals(key) - && value instanceof Double) { - stormData.setMotionSpeed((Double) value); - } else { - /* Incompatible value indicates update from preference - * store. We will want to reload. - */ - stormTrackDirty = true; - } - } - - // fire listeners - for (Object listener : stormListeners.getListeners()) { - ((IToolChangedListener) listener).toolChanged(); - } - } - } } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/StormTrackData.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/StormTrackData.java index b8787bf970..bab4bbad71 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/StormTrackData.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/StormTrackData.java @@ -21,10 +21,18 @@ package com.raytheon.viz.awipstools.common; import java.util.Date; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.serialization.adapters.CoordAdapter; import com.vividsolutions.jts.geom.Coordinate; /** - * TODO Add Description + * Data representing a storm track that can be saved to XML * *
  * 
@@ -32,20 +40,29 @@ import com.vividsolutions.jts.geom.Coordinate;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Aug 12, 2009            bwoodle     Initial creation
+ * Jun 03, 2014 3191       njensen      Added xml annotations
  * 
  * 
* * @author bwoodle * @version 1.0 */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement public class StormTrackData { + @XmlJavaTypeAdapter(DateAdapter.class) + @XmlElement(name = "stormDate") private Date date; + @XmlElement(name = "stormAngle") private double motionDirection; + @XmlElement(name = "stormSpeed") private double motionSpeed; + @XmlJavaTypeAdapter(CoordAdapter.class) + @XmlElement(name = "stormCoordinates") private Coordinate[] coordinates; public StormTrackData() { @@ -123,4 +140,19 @@ public class StormTrackData { return date != null && !Double.isNaN(motionDirection) && !Double.isNaN(motionSpeed); } + + private static class DateAdapter extends XmlAdapter { + + @Override + public Date unmarshal(Long v) throws Exception { + return new Date(v); + } + + @Override + public Long marshal(Date v) throws Exception { + return v.getTime(); + } + + } + } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java index 733c9a2269..090c8bd443 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java @@ -99,6 +99,7 @@ import com.vividsolutions.jts.geom.LineString; * 06-11-2013 DR 16234 D. Friedman Fix pivot index when frames count is reduced. * 06-24-2013 DR 16317 D. Friedman Handle "motionless" track. * 04-07-2014 DR 17232 D. Friedman Make sure pivot indexes are valid. + * 06-03-14 3191 njensen Fix postData to not retrieve * * * @@ -1394,7 +1395,7 @@ public class StormTrackDisplay implements IRenderable { } private void postData(StormTrackState state) { - StormTrackData data = dataManager.getStormTrackData(); + StormTrackData data = new StormTrackData(); Coordinate[] coords = new Coordinate[state.timePoints.length]; for (int i = 0; i < coords.length; ++i) { coords[i] = new Coordinate(state.timePoints[i].coord); diff --git a/edexOsgi/build.edex/esb/data/utility/edex_static/base/config/gfe/serverConfig.py b/edexOsgi/build.edex/esb/data/utility/edex_static/base/config/gfe/serverConfig.py index f84a6de509..42e62855ed 100644 --- a/edexOsgi/build.edex/esb/data/utility/edex_static/base/config/gfe/serverConfig.py +++ b/edexOsgi/build.edex/esb/data/utility/edex_static/base/config/gfe/serverConfig.py @@ -30,6 +30,7 @@ # to get correct offsets for Alaska # 04/17/14 2934 dgilling Remove alias for TPCSurgeProb D2D database. # 05/09/2014 3148 randerso Add tpHPCndfd to D2DAccumulativeElements for HPCERP +# 05/29/2014 3224 randerso Added "SPC":8 to D2DDBVERSIONS #---------------------------------------------------------------------------- # USEFUL DEFINES @@ -1006,6 +1007,7 @@ D2DDBVERSIONS = { "TPCProb": 30, "CRMTopo": 1, "NED": 1, + "SPC": 8, } #--------------------------------------------------------------------------- diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml index 9432f441ec..2d82ed704d 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml @@ -27,6 +27,7 @@ geh gh gvv + hailprob heli hidx htsgw @@ -45,14 +46,20 @@ pot p pr + prsvr + prsigsv pvv pw rh scp shf sh + sighailprob + sigtrndprob + sigwindprob sli snd + srcono svv swdir swell @@ -78,6 +85,7 @@ weasd wgh wgs + windprob ws wvdir wvhgt diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/spcGuideNDFD.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/spcGuideNDFD.xml index d15c9fed34..e177287f0f 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/spcGuideNDFD.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/spcGuideNDFD.xml @@ -209,4 +209,19 @@ SFC + + srcono + Convective Outlook + 1 + category + srcono + 0.0 + 100.0 + -99999.0 + 0 + SFC + + SFC + + diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java index 641bb4e620..2218d7f45d 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/database/PostShef.java @@ -118,6 +118,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools; * type is not READING like in A1 code. * 04/29/2014 3088 mpduff Change logging class, clean up/optimization. * Updated with more performance fixes. + * 06/02/2014 mpduff Fix for caching of range checks. * * * @@ -291,6 +292,39 @@ public class PostShef { /** Forecast query results */ private Object[] queryForecastResults; + /** Location range data found flag */ + private boolean locRangeFound = false; + + /** Default range data found flag */ + private boolean defRangeFound = false; + + /** Valid date range flag */ + private boolean validDateRange = false; + + /** Gross range minimum value */ + private double grossRangeMin = ShefConstants.SHEF_MISSING_INT; + + /** Gross range maximum value */ + private double grossRangeMax = ShefConstants.SHEF_MISSING_INT; + + /** Reasonable range minimum value */ + private double reasonRangeMin = ShefConstants.SHEF_MISSING_INT; + + /** Reasonable range maximum value */ + private double reasonRangeMax = ShefConstants.SHEF_MISSING_INT; + + /** Alert upper limit value */ + private double alertUpperLimit = ShefConstants.SHEF_MISSING_INT; + + /** Alarm upper limit value */ + private double alarmUpperLimit = ShefConstants.SHEF_MISSING_INT; + + /** Alert lower limit value */ + private double alertLowerLimit = ShefConstants.SHEF_MISSING_INT; + + /** Alarm lower limit value */ + private double alarmLowerLimit = ShefConstants.SHEF_MISSING_INT; + /** * * @param date @@ -475,7 +509,7 @@ public class PostShef { data.setCreationDateObj(d); data.setCreationDate("1970-01-01 00:00:00"); } - + locId = data.getLocationId(); String key = locId + prodId + data.getObservationTime(); if (idLocations.containsKey(key)) { @@ -1069,6 +1103,18 @@ public class PostShef { useTs = null; basisTimeValues = null; previousQueryForecast = null; + locRangeFound = false; + defRangeFound = false; + validDateRange = false; + grossRangeMin = ShefConstants.SHEF_MISSING_INT; + grossRangeMax = ShefConstants.SHEF_MISSING_INT; + reasonRangeMin = ShefConstants.SHEF_MISSING_INT; + reasonRangeMax = ShefConstants.SHEF_MISSING_INT; + alertUpperLimit = ShefConstants.SHEF_MISSING_INT; + alarmUpperLimit = ShefConstants.SHEF_MISSING_INT; + alertLowerLimit = ShefConstants.SHEF_MISSING_INT; + alarmLowerLimit = ShefConstants.SHEF_MISSING_INT; + } /** @@ -2571,14 +2617,6 @@ public class PostShef { long qualityCode = ShefConstants.DEFAULT_QC_VALUE; String monthdaystart = null; String monthdayend = null; - double grossRangeMin = missing; - double grossRangeMax = missing; - double reasonRangeMin = missing; - double reasonRangeMax = missing; - double alertUpperLimit = missing; - double alarmUpperLimit = missing; - double alertLowerLimit = missing; - double alarmLowerLimit = missing; alertAlarm = ShefConstants.NO_ALERTALARM; @@ -2597,10 +2635,6 @@ public class PostShef { return ShefConstants.QC_MANUAL_FAILED; } - boolean locRangeFound = false; - boolean defRangeFound = false; - boolean validDateRange = false; - boolean executeQuery = true; if (!qualityCheckFlag) { // If qualityCheckFlag is false the the query has already been From 1c84c31e30b17ee1ac9c24e1dbe4fab9dc827c76 Mon Sep 17 00:00:00 2001 From: David Friedman Date: Wed, 11 Jun 2014 13:37:16 +0000 Subject: [PATCH 13/17] ASM #604 - Lightning display varies depending how long CAVE has been open Change-Id: Id85b87e21833ef00e80693b8526d976ccb4bb63e Former-commit-id: a3f4fd6537f3847011e199e0f043968d9f595937 --- .../viz/lightning/LightningResource.java | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResource.java b/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResource.java index 9604088b04..9a916822ce 100644 --- a/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResource.java +++ b/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResource.java @@ -93,6 +93,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; * Sep 4, 2012 15335 kshresth Will now display lightning/wind * fields when magnification set to 0 * Feb 27, 2013 DCS 152 jgerth/elau Support for WWLLN and multiple sources + * Jun 6, 2014 DR 17367 D. Friedman Fix cache object usage. * * * @@ -479,6 +480,24 @@ public class LightningResource extends */ @Override public void remove(DataTime dataTime) { + /* + * Workaround for time matching which does not know about records at the + * end of a time period that may contain data for the next period. If we + * are asked to remove the latest data time and there is only one record + * we know about, return without removing the time. + */ + if (dataTimes.indexOf(dataTime) == dataTimes.size() - 1) { + CacheObject co = cacheObjectMap.get(dataTime); + if (co != null) { + LightningFrameMetadata metadata = co.getMetadata(); + synchronized (metadata) { + if (metadata.newRecords.size() + metadata.processed.size() < 2) { + return; + } + } + } + } + dataTimes.remove(dataTime); cacheObjectMap.remove(dataTime); } @@ -522,20 +541,20 @@ public class LightningResource extends List records = entry.getValue(); - CacheObject co = cacheObjectMap - .get(dt); LightningFrameMetadata frame; - if (co == null) { - // New frame - frame = new LightningFrameMetadata(dt, - resourceData.getBinOffset(), this.lightSource); - co = CacheObject.newCacheObject(frame, resourceBuilder); - cacheObjectMap.put(dt, co); - dataTimes.add(dt); - } else { - // Frame exists - frame = co.getMetadata(); + CacheObject co; + synchronized (cacheObjectMap) { + co = cacheObjectMap.get(dt); + if (co == null) { + // New frame + LightningFrameMetadata key = new LightningFrameMetadata(dt, + resourceData.getBinOffset(), this.lightSource); + co = CacheObject.newCacheObject(key, resourceBuilder); + cacheObjectMap.put(dt, co); + dataTimes.add(dt); + } } + frame = co.getMetadata(); synchronized (frame) { // Add as new records From 81832d97e53033093f3fcdfd4ba4ec5d94c2345d Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Fri, 13 Jun 2014 13:21:19 -0400 Subject: [PATCH 14/17] CM-MERGE:OB13.5.6-3 into 14.1.3 Former-commit-id: df99fcb0a4be27d5f2d22935847fb55b8bfbbb58 --- .../viz/gfe/ServiceBackupComponent.java | 8 +- .../viz/gfe/dialogs/sbu/CheckPermissions.java | 22 +- .../viz/gfe/dialogs/sbu/ServiceBackupDlg.java | 26 ++- .../res/spring/gfe-request.xml | 8 + .../res/spring/gfe-spring.xml | 10 +- .../GetServiceBackupPrimarySiteHandler.java | 68 ++++++ .../edex/plugin/gfe/spc/SPCWatchSrv.java | 150 ------------- .../edex/plugin/gfe/tpc/TPCWatchSrv.java | 204 ----------------- .../gfe/watch/AbstractWatchNotifierSrv.java | 173 ++++++++++++++ .../edex/plugin/gfe/watch/SPCWatchSrv.java | 119 ++++++++++ .../edex/plugin/gfe/watch/TPCWatchSrv.java | 153 +++++++++++++ .../gfe/{wcl => watch}/WCLWatchSrv.java | 211 ++++++++---------- .../plugin/gfe/watch/WatchProductUtil.java | 96 ++++++++ .../plugin/gfe/{wcl => watch}/WclInfo.java | 2 +- .../gfe/{wcl => watch}/TestWCLWatchSrv.java | 19 +- .../WarningDecoder.py | 21 +- .../GetServiceBackupPrimarySiteRequest.java | 45 ++++ 17 files changed, 835 insertions(+), 500 deletions(-) create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/svcbu/GetServiceBackupPrimarySiteHandler.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/AbstractWatchNotifierSrv.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/SPCWatchSrv.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/TPCWatchSrv.java rename edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/{wcl => watch}/WCLWatchSrv.java (71%) create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WatchProductUtil.java rename edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/{wcl => watch}/WclInfo.java (98%) rename edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/{wcl => watch}/TestWCLWatchSrv.java (93%) create mode 100644 edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/request/GetServiceBackupPrimarySiteRequest.java diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ServiceBackupComponent.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ServiceBackupComponent.java index efa8e7f9bf..edf5378bd8 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ServiceBackupComponent.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ServiceBackupComponent.java @@ -35,6 +35,7 @@ import com.raytheon.viz.ui.personalities.awips.AbstractCAVEComponent; * Oct 26, 2012 1287 rferrel Change to force blocking of ServiceBackupDlg. * Mar 21, 2013 1447 dgilling Fix dialog construction so this dialog * is created as a top-level shell. + * Jun 11, 2014 DR-17401 lshi * * * @@ -54,8 +55,11 @@ public class ServiceBackupComponent extends AbstractCAVEComponent { @Override protected void startInternal(String componentName) throws Exception { ServiceBackupDlg svcBuDlg = new ServiceBackupDlg(null); - svcBuDlg.setBlockOnOpen(true); - svcBuDlg.open(); + if (!svcBuDlg.isTerminated()) + { + svcBuDlg.setBlockOnOpen(true); + svcBuDlg.open(); + } } /* diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/CheckPermissions.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/CheckPermissions.java index 22a5f99a0a..686866b51c 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/CheckPermissions.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/CheckPermissions.java @@ -19,9 +19,12 @@ **/ package com.raytheon.viz.gfe.dialogs.sbu; +import java.util.Set; + import com.raytheon.uf.common.auth.user.IUser; import com.raytheon.uf.common.dataplugin.gfe.request.CheckPermissionsRequest; import com.raytheon.uf.common.dataplugin.gfe.request.CheckServiceBackupPrimarySiteRequest; +import com.raytheon.uf.common.dataplugin.gfe.request.GetServiceBackupPrimarySiteRequest; import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -46,7 +49,7 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; * Jul 22, 2013 #1762 dgilling Ensure all fields of * CheckServiceBackupPrimarySiteRequest are * filled. - * + * Jun 10, 2013 DR-17401 lshi Added getPrimarySites() * * * @author bphillip @@ -104,4 +107,21 @@ public class CheckPermissions { } return false; } + + public static Set getPrimarySites() { + Set primary = null; + + GetServiceBackupPrimarySiteRequest request = new GetServiceBackupPrimarySiteRequest(); + try { + @SuppressWarnings("unchecked") + ServerResponse> sr = (ServerResponse>) ThriftClient + .sendRequest(request); + primary = sr.getPayload(); + return primary; + } catch (VizException e) { + statusHandler + .error("Error getting primary site(s)!", e); + } + return primary; + } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/ServiceBackupDlg.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/ServiceBackupDlg.java index e5c4cdc731..73ed603a03 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/ServiceBackupDlg.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/sbu/ServiceBackupDlg.java @@ -94,6 +94,7 @@ import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; * from A1 DR 21404, some code cleanup. * May 01, 2013 1762 dgilling Remove national center check. * Jul 22, 2013 1762 dgilling Fix running as primary check. + * Jun 10,2014 DR-17401 lshi * * * @@ -161,8 +162,15 @@ public class ServiceBackupDlg extends CaveJFACEDialog { private boolean authorized; private SVCBU_OP currentOperation = SVCBU_OP.no_backup; + + private boolean isTerminated = false; + - /** + public boolean isTerminated() { + return isTerminated; + } + + /** * @param parentShell */ public ServiceBackupDlg(Shell parentShell) { @@ -170,6 +178,13 @@ public class ServiceBackupDlg extends CaveJFACEDialog { authorized = CheckPermissions.getAuthorization(); this.site = LocalizationManager.getInstance().getCurrentSite(); this.runningAsPrimary = CheckPermissions.runningAsPrimary(this.site); + + if (!CheckPermissions.getPrimarySites().contains(this.site)) { + displayMessage("You cannot run Service Backup as " + this.site + " - EXITING!!!"); + isTerminated = true; + return; + } + if (!ServiceBackupJobManager.getInstance().isRunning()) { ServiceBackupJobManager.getInstance().start(); } @@ -177,7 +192,6 @@ public class ServiceBackupDlg extends CaveJFACEDialog { progress = new ProgressDlg(getShell()); progress.setBlockOnOpen(false); updateJob = new Job("SvcbuUpdateJob") { - @Override protected IStatus run(IProgressMonitor monitor) { VizApp.runAsync(new Runnable() { @@ -225,7 +239,7 @@ public class ServiceBackupDlg extends CaveJFACEDialog { @Override public boolean close() { updateJob.cancel(); - return super.close(); + return super.close(); } /* @@ -492,7 +506,7 @@ public class ServiceBackupDlg extends CaveJFACEDialog { } private void doImportConfig() { - + switch (currentOperation) { case svcbuMode: displayMessage("" + this.failedSite.toUpperCase() @@ -548,7 +562,7 @@ public class ServiceBackupDlg extends CaveJFACEDialog { if (startGFE) { jobManager.addJob(new SvcbuStartGfeJob(failedSite, this.site)); - } + } } } } @@ -776,7 +790,7 @@ public class ServiceBackupDlg extends CaveJFACEDialog { jobManager.addJob(new SvcbuExitJob(this, this.site)); } } - + } private void doClean(boolean showMessage) { diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-request.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-request.xml index e77af0d0cb..52e9231c84 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-request.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-request.xml @@ -334,6 +334,7 @@ value="com.raytheon.uf.common.dataplugin.gfe.request.GetServiceBackupServerRequest" /> + @@ -374,6 +375,13 @@ value="com.raytheon.uf.common.dataplugin.gfe.request.CheckServiceBackupPrimarySiteRequest" /> + + + + + + + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml index a0faa56337..e0ad01a0ae 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml @@ -21,9 +21,9 @@ - - - + + + @@ -36,7 +36,7 @@ - + java.lang.Throwable @@ -47,7 +47,7 @@ - + java.lang.Throwable diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/svcbu/GetServiceBackupPrimarySiteHandler.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/svcbu/GetServiceBackupPrimarySiteHandler.java new file mode 100644 index 0000000000..19f1de93d0 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/svcbu/GetServiceBackupPrimarySiteHandler.java @@ -0,0 +1,68 @@ +/** + * 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.edex.plugin.gfe.server.handler.svcbu; + +import java.util.Set; + +import com.raytheon.edex.plugin.gfe.svcbackup.SvcBackupUtil; +import com.raytheon.uf.common.dataplugin.gfe.request.GetServiceBackupPrimarySiteRequest; +import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; +import com.raytheon.uf.common.serialization.comm.IRequestHandler; + +/** + * Handler for CheckServiceBackupPrimarySiteRequest. Determines + * whether the specified site id has been configured as one of service backup's + * primary sites. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date           Ticket#    Engineer    Description
+ * ------------   ---------- ----------- --------------------------
+ * Jun 10, 2014   DR-17401     lshi        Initial creation
+ * 
+ * 
+ * + * @author lshi + * @version 1.0 + */ + +public class GetServiceBackupPrimarySiteHandler implements + IRequestHandler { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest + * (com.raytheon.uf.common.serialization.comm.IServerRequest) + */ + @Override + public ServerResponse> handleRequest( + GetServiceBackupPrimarySiteRequest request) throws Exception { + ServerResponse> sr = new ServerResponse>(); + Set primarySites = SvcBackupUtil.getPrimarySites(); + sr.setPayload(primarySites); + + return sr; + } +} + 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 deleted file mode 100644 index db76ab5ccb..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/spc/SPCWatchSrv.java +++ /dev/null @@ -1,150 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.edex.plugin.gfe.spc; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -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.core.EdexException; -import com.raytheon.uf.edex.core.props.EnvProperties; -import com.raytheon.uf.edex.core.props.PropertiesFactory; - -/** - * Watches ingested warnings for WOU products from the SPC (Storm Prediction - * Center). If the warning is a WOU, then it looks to see if the site is in the - * ATTN...WFO... line, and if so, sends a user message to GFE to alert users. - * - *
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Oct 3, 2008            njensen     Initial creation
- * Jul 10, 2009  #2590 njensen     Added multiple site support
- * 
- * - * @author njensen - * @version 1.0 - */ - -public class SPCWatchSrv { - - private static final Pattern ATTN_WFO = Pattern - .compile("ATTN\\.\\.\\.WFO\\.\\.\\.([A-Z]{3}\\.\\.\\.)+"); - - protected transient Log logger = LogFactory.getLog(getClass()); - - public void handleSpcWatch(PluginDataObject[] pdos) throws EdexException { - // create the appropriate SPC notification, returns null if not - // needed. - EnvProperties env = PropertiesFactory.getInstance().getEnvProperties(); - String primarySite = env.getEnvValue("SITENAME"); - String spcSite = (String) VTECPartners.getInstance(primarySite) - .getattr("VTEC_SPC_SITE", "KWNS"); - for (PluginDataObject pdo : pdos) { - AbstractWarningRecord warn = (AbstractWarningRecord) pdo; - if (!warn.getPil().equals("WOU")) { - logger.debug("SPC notification: not WOU product"); - return; - } - - // find the first record from KWNS, SV.A, TO.A in this product - // action code must be "NEW" - if (warn.getOfficeid().equals(spcSite) - && warn.getSig().equals("A") - && (warn.getPhen().equals("TO") || warn.getPhen().equals( - "SV")) && warn.getAct().equals("NEW")) { - // decode the ATTN line, which tells us which WFOs are affected - List wfos = getAttnWfos(warn.getRawmessage()); - for (String siteid : GFESiteActivation.getInstance() - .getActiveSites()) { - if (!wfos.contains(siteid)) { - logger.debug("SPC notification: my site not in ATTN list"); - continue; // not my WFO - } - - // create the message - String txt = ""; - if (warn.getPhen().equals("TO")) { - txt = "Tornado Watch"; - } else if (warn.getPhen().equals("SV")) { - txt = "Severe Thunderstorm Watch"; - } - - String testText = ""; - if (warn.getVtecstr().charAt(1) == 'T') { - testText = " This is a TEST watch. Please restart the GFE " - + "in TEST mode before issuing WCN. "; - } - String msg = "Alert: " - + txt - + " " - + warn.getEtn() - + " has arrived. " - + "Check for 'red' locks (owned by others) on your Hazard grid and resolve them. " - + "If hazards are separated into temporary grids, please run MergeHazards. " - + "Next...save Hazards grid. Finally, select PlotSPCWatches from the Hazards menu."; - msg = msg + testText; - - UserMessageNotification notification = new UserMessageNotification( - msg, Priority.CRITICAL, "GFE", siteid); - SendNotifications.send(notification); - } - } else { - logger.debug("SPC notification: " - + "no SV.A, TO.A vtec lines, or not NEW action code"); - } - } - - } - - private static List getAttnWfos(String rawMessage) { - List list = new ArrayList(); - - // decode the ATTN line, which tells us which WFOs are affected - // only used for WCL and WOU products - Matcher m = ATTN_WFO.matcher(rawMessage); - if (m.find()) { - String found = m.group(); - // eliminate ATTN...WFO... - found = found.substring(13); - if (found != null) { - String[] wfos = found.split("\\.\\.\\."); - for (String s : wfos) { - list.add(s); - } - } - } - - return list; - } - -} 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 deleted file mode 100644 index b2d4a282bc..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/tpc/TPCWatchSrv.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.edex.plugin.gfe.tpc; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -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.core.EdexException; -import com.raytheon.uf.edex.core.props.EnvProperties; -import com.raytheon.uf.edex.core.props.PropertiesFactory; - -/** - * Watches ingested warnings for WOU products from the SPC (Storm Prediction - * Center). If the warning is a WOU, then it looks to see if the site is in the - * ATTN...WFO... line, and if so, sends a user message to GFE to alert users. - * - *
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Oct 3, 2008            njensen     Initial creation
- * Jul 10, 2009  #2590 njensen     Added multiple site support
- * 
- * - * @author njensen - * @version 1.0 - */ - -public class TPCWatchSrv { - - private static final Pattern ATTN_WFO = Pattern - .compile("ATTN\\.\\.\\.WFO\\.\\.\\.([A-Z]{3}\\.\\.\\.)+"); - - private static final Map phensigMap; - - private static final Map actMap; - - static { - Map phensigMapTemp = new HashMap(); - phensigMapTemp.put("HU.A", "Hurricane Watch"); - phensigMapTemp.put("HU.S", "Hurricane Local Statement"); - phensigMapTemp.put("HU.W", "Hurricane Warning"); - phensigMap = Collections.unmodifiableMap(phensigMapTemp); - - Map actMapTemp = new HashMap(); - actMapTemp.put("CON", "Continued"); - actMapTemp.put("CAN", "Cancelled"); - actMapTemp.put("NEW", "New"); - actMap = Collections.unmodifiableMap(actMapTemp); - } - - private static final String alertTxt = "Alert: {0} has arrived from TPC. " - + "Check for 'red' locks (owned by others) on your Hazard grid and resolve them. " - + "If hazards are separated into temporary grids, please run Mergehazards. " - + "Next...save Hazards grid. Finally, select PlotTPCEvents from Hazards menu."; - - protected transient Log logger = LogFactory.getLog(getClass()); - - public void handleTpcWatch(PluginDataObject[] pdos) throws EdexException { - - EnvProperties env = PropertiesFactory.getInstance().getEnvProperties(); - String primarySite = env.getEnvValue("SITENAME"); - String tpcSite = (String) VTECPartners.getInstance(primarySite) - .getattr("VTEC_TPC_SITE", "KNHC"); - Set activeSites = GFESiteActivation.getInstance() - .getActiveSites(); - - AbstractWarningRecord ourWarn = null; - String ourSite = null; - // create the appropriate TPC notification, returns null if not - // needed. - Map> phensigStormAct = new HashMap>(); - for (PluginDataObject pdo : pdos) { - AbstractWarningRecord warn = (AbstractWarningRecord) pdo; - if (!warn.getPil().startsWith("TCV")) { - logger.debug("TPC notification: not TCV product"); - return; - } - - // The warning is a TPC, but for us? - List wfos = getAttnWfos(warn.getRawmessage()); - wfos.retainAll(activeSites); - if (wfos.size() == 0) { - logger.debug("TPC notification: my site not in ATTN list"); - continue; - } - - if (ourWarn == null) { - ourWarn = warn; - ourSite = wfos.get(0); - } - - // Collect action codes by phensig and storm # - if (tpcSite.equals(warn.getOfficeid())) { - String phensig = warn.getPhen() + "." + warn.getSig(); - String storm = warn.getEtn(); - String act = warn.getAct(); - Set psActs = phensigStormAct.get(phensig + ":" + storm); - if (psActs == null) { - psActs = new TreeSet(); - phensigStormAct.put(phensig + ":" + storm, psActs); - } - psActs.add(act); - } - - } - - if (phensigStormAct.size() == 0) { - logger.debug("TPC Notification: no HU/TR vtec lines, or not NEW action code"); - return; - } - - // Build the notification message - StringBuilder msg = new StringBuilder(); - msg.append(MessageFormat.format(alertTxt, ourWarn.getPil())); - - for (String phensigStorm : phensigStormAct.keySet()) { - Collection acts = phensigStormAct.get(phensigStorm); - String[] splitKey = phensigStorm.split(":"); - String phensig = splitKey[0]; - String storm = splitKey[1]; - - String t1 = phensigMap.get(phensig); - if (t1 == null) { - t1 = phensig; - } - msg.append(t1 + ": #" + storm + "("); - String sep = ""; - for (String a : acts) { - String a1 = actMap.get(a); - if (a1 == null) { - a1 = a; - } - msg.append(sep).append(a1); - sep = ","; - } - msg.append("). "); - } - - UserMessageNotification notification = new UserMessageNotification( - msg.toString(), Priority.CRITICAL, "GFE", ourSite); - - SendNotifications.send(notification); - - } - - private static List getAttnWfos(String rawMessage) { - List list = new ArrayList(); - - // decode the ATTN line, which tells us which WFOs are affected - // only used for WCL and WOU products - Matcher m = ATTN_WFO.matcher(rawMessage); - if (m.find()) { - String found = m.group(); - // eliminate ATTN...WFO... - found = found.substring(13); - if (found != null) { - String[] wfos = found.split("\\.\\.\\."); - for (String s : wfos) { - list.add(s); - } - } - } - - return list; - } - -} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/AbstractWatchNotifierSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/AbstractWatchNotifierSrv.java new file mode 100644 index 0000000000..3760e764aa --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/AbstractWatchNotifierSrv.java @@ -0,0 +1,173 @@ +/** + * 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.edex.plugin.gfe.watch; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +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.message.ServerResponse; +import com.raytheon.uf.common.dataplugin.gfe.server.notify.GfeNotification; +import com.raytheon.uf.common.dataplugin.gfe.server.notify.UserMessageNotification; +import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; + +/** + * Base class for a bean that accepts a {@code List} of + * {@code AbstractWarningRecord}s and generates a set of notifications for the + * GFE user if the storm affects their WFO. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 10, 2014  #3268     dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public abstract class AbstractWatchNotifierSrv { + + protected final IUFStatusHandler statusHandler = UFStatus + .getHandler(getClass()); + + protected final String watchType; + + protected final String supportedPIL; + + protected AbstractWatchNotifierSrv(String watchType, String supportedPIL) { + this.watchType = watchType; + this.supportedPIL = supportedPIL; + } + + /** + * Processes the warning records and generates a notification for each + * currently activated GFE site if the storm affects the site. + * + * @param pdos + * A list of {@code PluginDataObject}s that are assumed to be + * {@code AbstractWarningRecord}s all decoded from a common + * warning product. + */ + public final void handleWatch(List pdos) { + List warningRecs = filterIncomingRecordsByPIL(pdos); + if (warningRecs.isEmpty()) { + String logMsg = String.format("%s notification: not %s product", + watchType, supportedPIL); + statusHandler.debug(logMsg); + return; + } + + /* + * We are making an assumption that all PDOs came from the same source + * product. This is a safe assumption because WarningDecoder processes + * records one product at a time and the plugin notifier code that sends + * those records to us does not do any additional grouping or batching. + * + * Hence, any of the remaining records' raw message will be the same as + * the rest and we can just use the first record's copy. + */ + String productText = warningRecs.get(0).getRawmessage(); + Collection wfos = WatchProductUtil.findAttnWFOs(productText); + + for (String siteid : GFESiteActivation.getInstance().getActiveSites()) { + if (!wfos.contains(siteid)) { + String logMsg = String.format( + "%s notification: my site %s not in ATTN list", + watchType, siteid); + statusHandler.debug(logMsg); + continue; + } + + VTECPartners partnersConfig = VTECPartners.getInstance(siteid); + + String msg = buildNotification(warningRecs, partnersConfig); + if (msg != null) { + sendNotification(msg, siteid); + } + } + } + + /** + * Given a list of {@code PluginDataObject}s that are actually + * {@code AbstractWarningRecord}s, filters the list for only those records + * which have the right PIL code. + * + * @param pdos + * List of {@code AbstractWarningRecord}s to filter. + * @return The list of supported {@code AbstractWarningRecord}s as defined + * by {@code getSupportedPIL}. + */ + protected List filterIncomingRecordsByPIL( + List pdos) { + List warningRecords = new ArrayList(); + for (PluginDataObject pdo : pdos) { + AbstractWarningRecord warning = (AbstractWarningRecord) pdo; + + if (warning.getPil().startsWith(supportedPIL)) { + warningRecords.add(warning); + } + } + + return warningRecords; + } + + /** + * Takes the specified list of warning records and {@code VTECPartners} + * configuration data and builds a notification message to send. + * + * @param decodedVTEC + * The warning records. + * @param partnersConfig + * The {@code VTECPartners} configuration data. + * @return The notification message to send to the users for the site, or + * {@code null} if no notification applies. + */ + protected abstract String buildNotification( + List decodedVTEC, VTECPartners partnersConfig); + + /** + * Sends the specified notification message as an AletViz alert to all GFE + * users connected as the specified site. + * + * @param message + * The notification message text to send. + * @param siteId + * The site identifier that will receive the message. + * @return A {@code ServerResponse} containing error message if sending the + * notification message failed. + */ + protected ServerResponse sendNotification(String message, String siteId) { + GfeNotification notification = new UserMessageNotification(message, + Priority.CRITICAL, "GFE", siteId); + return SendNotifications.send(notification); + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/SPCWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/SPCWatchSrv.java new file mode 100644 index 0000000000..b23010b10a --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/SPCWatchSrv.java @@ -0,0 +1,119 @@ +/** + * 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.edex.plugin.gfe.watch; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.raytheon.uf.common.activetable.VTECPartners; +import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; + +/** + * Watches ingested warnings for WOU products from the SPC (Storm Prediction + * Center). If the warning is a WOU, then it looks to see if the site is in the + * ATTN...WFO... line, and if so, sends a user message to GFE to alert users. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 03, 2008            njensen      Initial creation
+ * Jul 10, 2009  #2590     njensen      Added multiple site support
+ * Jun 10, 2014  #3268     dgilling     Re-factor based on AbstractWatchNotifierSrv.
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public final class SPCWatchSrv extends AbstractWatchNotifierSrv { + + private static final String SPC_WATCH_TYPE = "SPC"; + + private static final String SPC_SUPPORTED_PIL = "WOU"; + + private static final String SPC_SITE_ATTRIBUTE = "VTEC_SPC_SITE"; + + private static final String DEFAULT_SPC_SITE = "KNHC"; + + private static final String TEST_TEXT_MSG = " This is a TEST watch. Please restart the GFE in TEST mode before issuing WCN. "; + + private static final String ALERT_MSG = "Alert: %s %s has arrived. " + + "Check for 'red' locks (owned by others) on your Hazard grid and resolve them. " + + "If hazards are separated into temporary grids, please run MergeHazards. " + + "Next...save Hazards grid. Finally, select PlotSPCWatches from the Hazards menu."; + + private static final Map phenTextMap; + + static { + Map phenTextMapTemp = new HashMap(2, 1f); + phenTextMapTemp.put("TO", "Tornado Watch"); + phenTextMapTemp.put("SV", "Severe Thunderstorm Watch"); + phenTextMap = Collections.unmodifiableMap(phenTextMapTemp); + } + + public SPCWatchSrv() { + super(SPC_WATCH_TYPE, SPC_SUPPORTED_PIL); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.gfe.warning.AbstractWarningNotifierSrv# + * buildNotification(java.util.List, java.lang.String, + * com.raytheon.uf.common.activetable.VTECPartners) + */ + @Override + protected String buildNotification(List decodedVTEC, + VTECPartners partnersConfig) { + String spcSite = partnersConfig.getattr(SPC_SITE_ATTRIBUTE, + DEFAULT_SPC_SITE).toString(); + + // find the first record from our configured list of issuing sites. + // Also this product must be a NEW SV.A or TO.A + AbstractWarningRecord matchRecord = null; + for (AbstractWarningRecord e : decodedVTEC) { + if (spcSite.equals(e.getOfficeid()) + && e.getSig().equals("A") + && ((e.getPhen().equals("TO")) || (e.getPhen().equals("SV"))) + && e.getAct().equals("NEW")) { + matchRecord = e; + break; + } + } + + if (matchRecord == null) { + statusHandler.debug("SPC notification: " + + "no SV.A, TO.A vtec lines, or not NEW action code"); + return null; + } + + // create the message + String eventType = phenTextMap.get(matchRecord.getPhen()); + StringBuilder msg = new StringBuilder(String.format(ALERT_MSG, + eventType, matchRecord.getEtn())); + if (matchRecord.getVtecstr().charAt(1) == 'T') { + msg.append(TEST_TEXT_MSG); + } + return msg.toString(); + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/TPCWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/TPCWatchSrv.java new file mode 100644 index 0000000000..ac8cc6de15 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/TPCWatchSrv.java @@ -0,0 +1,153 @@ +/** + * 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.edex.plugin.gfe.watch; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import com.raytheon.uf.common.activetable.VTECPartners; +import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; + +/** + * Watches ingested warnings for WOU products from the SPC (Storm Prediction + * Center). If the warning is a WOU, then it looks to see if the site is in the + * ATTN...WFO... line, and if so, sends a user message to GFE to alert users. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 03, 2008            njensen      Initial creation
+ * Jul 10, 2009  #2590     njensen      Added multiple site support
+ * Jun 10, 2014  #3268     dgilling     Re-factor based on AbstractWatchNotifierSrv.
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public final class TPCWatchSrv extends AbstractWatchNotifierSrv { + + private static final String TPC_WATCH_TYPE = "TPC"; + + private static final String TPC_SUPPORTED_PIL = "TCV"; + + private static final String TPC_SITE_ATTRIBUTE = "VTEC_TPC_SITE"; + + private static final String DEFAULT_TPC_SITE = "KNHC"; + + private static final String ALERT_TXT = "Alert: %s has arrived from TPC. " + + "Check for 'red' locks (owned by others) on your Hazard grid and resolve them. " + + "If hazards are separated into temporary grids, please run Mergehazards. " + + "Next...save Hazards grid. Finally, select PlotTPCEvents from Hazards menu."; + + private static final Map phensigMap; + + private static final Map actMap; + + static { + Map phensigMapTemp = new HashMap(5, 1f); + phensigMapTemp.put("HU.A", "Hurricane Watch"); + phensigMapTemp.put("HU.S", "Hurricane Local Statement"); + phensigMapTemp.put("HU.W", "Hurricane Warning"); + phensigMapTemp.put("TR.A", "Tropical Storm Watch"); + phensigMapTemp.put("TR.W", "Tropical Storm Warning"); + phensigMap = Collections.unmodifiableMap(phensigMapTemp); + + Map actMapTemp = new HashMap(3, 1f); + actMapTemp.put("CON", "Continued"); + actMapTemp.put("CAN", "Cancelled"); + actMapTemp.put("NEW", "New"); + actMap = Collections.unmodifiableMap(actMapTemp); + } + + public TPCWatchSrv() { + super(TPC_WATCH_TYPE, TPC_SUPPORTED_PIL); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.gfe.warning.AbstractWarningNotifierSrv# + * buildNotification(java.util.List, + * com.raytheon.uf.common.activetable.VTECPartners) + */ + @Override + protected String buildNotification(List decodedVTEC, + VTECPartners partnersConfig) { + String tpcSite = partnersConfig.getattr(TPC_SITE_ATTRIBUTE, + DEFAULT_TPC_SITE).toString(); + + // get all VTEC records, assemble unique list of phen/sig and storm# + Map> phensigStormAct = new HashMap>(); + for (AbstractWarningRecord e : decodedVTEC) { + if (tpcSite.equals(e.getOfficeid())) { + String phensig = e.getPhensig(); + String storm = e.getEtn(); + String act = e.getAct(); + Set psActs = phensigStormAct.get(phensig + ":" + storm); + if (psActs == null) { + psActs = new TreeSet(); + phensigStormAct.put(phensig + ":" + storm, psActs); + } + psActs.add(act); + } + } + + if (phensigStormAct.isEmpty()) { + statusHandler + .debug("TPC Notification: no HU/TR vtec lines, or not NEW action code"); + return null; + } + + // create the message + StringBuilder msg = new StringBuilder(String.format(ALERT_TXT, + supportedPIL)); + for (String phensigStorm : phensigStormAct.keySet()) { + Collection acts = phensigStormAct.get(phensigStorm); + String[] splitKey = phensigStorm.split(":"); + String phensig = splitKey[0]; + String storm = splitKey[1]; + + String t1 = phensigMap.get(phensig); + if (t1 == null) { + t1 = phensig; + } + msg.append(t1 + ": #" + storm + "("); + String sep = ""; + for (String a : acts) { + String a1 = actMap.get(a); + if (a1 == null) { + a1 = a; + } + msg.append(sep).append(a1); + sep = ","; + } + msg.append("). "); + } + + return msg.toString(); + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WCLWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java similarity index 71% rename from edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WCLWatchSrv.java rename to edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java index 21f1884f0b..5c6ff84efb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WCLWatchSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java @@ -20,51 +20,60 @@ /** * */ -package com.raytheon.edex.plugin.gfe.wcl; +package com.raytheon.edex.plugin.gfe.watch; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; -import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.commons.logging.Log; -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.dataplugin.gfe.server.notify.GfeNotification; import com.raytheon.uf.common.dataplugin.gfe.server.notify.UserMessageNotification; 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.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.SimulatedTime; +import com.raytheon.uf.common.util.FileUtil; import com.raytheon.uf.edex.core.EdexException; /** - * @author wldougher + * If a WCL (watch county list) is ingested, this class will send a notification + * to the GFE users alerting them that their WFO may be in the path of an + * upcoming TO.A or SV.A. * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * ??? ??, 20??            wldougher    Initial creation
+ * Jun 09, 2014  #3268     dgilling     Ensure code works in multi-domain scenarios.
+ * 
+ * 
+ * + * @author wldougher + * @version 1.0 */ public class WCLWatchSrv { private static final String ALERT_FORM = "Alert: " + "%1$s has arrived. " + "Please select ViewWCL and use %1$s. (Hazards menu)"; - private static final Pattern ATTN_PATTERN = Pattern.compile("^" - + Pattern.quote("ATTN...WFO...")); - private static final Pattern EXPIRE_TIME_PATTERN = Pattern .compile("(\\d{2})(\\d{2})(\\d{2})\\-"); @@ -81,36 +90,8 @@ public class WCLWatchSrv { private static final Pattern UGC_PATTERN = Pattern.compile("\\d{3}\\-"); - protected transient Log logger = LogFactory.getLog(getClass()); - - /** - * Get the WFOs from the ATTN line. - * - * @param lines - * The lines in the warning file - * @return the WFOs from the WFO attention line, as a set of Strings. - */ - protected Set attnWFOs(List lines) { - StringBuilder wfoLine = new StringBuilder(); - boolean attnFound = false; - if (lines != null) { - for (String line : lines) { - attnFound = attnFound || ATTN_PATTERN.matcher(line).lookingAt(); - if (attnFound) { - wfoLine.append(line); - } - } - } - Set wfosR = new HashSet(); - if (wfoLine.length() > 13) { - String[] wfos = wfoLine.substring(13).split(Pattern.quote("...")); - for (String wfo : wfos) { - wfosR.add(wfo.trim()); - } - } - - return wfosR; - } + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(WCLWatchSrv.class); /** * Process a WCL watch, partially parsed and passed as a WclInfo object. @@ -130,20 +111,17 @@ public class WCLWatchSrv { * or when there are problems generating the WCL script file. */ public void handleWclWatch(WclInfo wclInfo) throws EdexException { - logger.debug("handleWclWatch started"); - UserMessageNotification notice = null; - String completeProductPil = wclInfo.getCompleteProductPil(); - Set wfos = attnWFOs(wclInfo.getLines()); + statusHandler.debug("handleWclWatch started"); + Collection sitesToNotify = WatchProductUtil + .findAttnWFOs(wclInfo.getLines()); Set siteIDs = getSiteIDs(); - wfos.retainAll(siteIDs); // Keep shared IDs - if (!wfos.isEmpty()) { - // Get the first matching site ID - String siteID = wfos.toArray(new String[1])[0]; + boolean doNotify = true; - String msg = String.format(ALERT_FORM, completeProductPil); - notice = new UserMessageNotification(msg, Priority.CRITICAL, "GFE", - siteID); + sitesToNotify.retainAll(siteIDs); // Keep shared IDs + if (sitesToNotify.isEmpty()) { + statusHandler.debug("WCL notification: sites not in ATTN list"); + doNotify = false; } // Process the WCL regardless of whether we are sending a notice @@ -160,28 +138,51 @@ public class WCLWatchSrv { // Get the watch type String watchType = getWatchType(wclInfo); + // Get the WCL 'letter' + String completeProductPil = wclInfo.getCompleteProductPil(); + // Create a dummy Procedure for export String wclStr = makeWclStr(finalUGCList, expireTime, issueTime, watchType); - logger.debug("WCLData: " + wclStr); + statusHandler.info("WCLData: " + wclStr); // Write dummy procedure to temp file File tmpFile = createTempWclFile(wclStr); // Move the file to the wcl folder // Rename it to / - makePermanent(tmpFile, completeProductPil); + statusHandler.info("Placing WCL Procedure Utility in ifpServer "); + makePermanent(tmpFile, completeProductPil, siteIDs); - if (notice == null || !wclInfo.getNotify()) { - logger.info("Notification of WCL skipped"); + if (doNotify && wclInfo.getNotify()) { + for (String siteID : sitesToNotify) { + String msg = String.format(ALERT_FORM, completeProductPil); + GfeNotification notify = new UserMessageNotification(msg, + Priority.CRITICAL, "GFE", siteID); + SendNotifications.send(notify); + } } else { - SendNotifications.send(notice); + statusHandler.info("Notification of WCL skipped"); } - logger.debug("handleWclWatch() ending"); + statusHandler.debug("handleWclWatch() ending"); return; } + /** + * Convert a temporary parsed WCL file to a permanent one by moving it to + * the WCL directory. This is done through File.renameTo(). Unfortunately, + * that method returns a boolean success flag rather than throwing an error, + * so all we can do is tell the user that the rename failed, not why. + * + * @param wclData + * WCL data to write to file. + * @param completeProductPil + * The simple name of the file. + * + * @throws EdexException + * if WCL file cannot be opened, written, or closed. + */ /** * Convert a temporary parsed WCL file to a permanent one by moving it to * the WCL directory. This is done through File.renameTo(). Unfortunately, @@ -192,64 +193,40 @@ public class WCLWatchSrv { * The temporary file (may be null) * @param completeProductPil * The simple name of the file. + * @param siteIDs + * The set of siteIDs to write out the WCL data for. * @throws EdexException * if tmpFile cannot be renamed. */ - protected void makePermanent(File tmpFile, String completeProductPil) - throws EdexException { - logger.debug("makePermanent(" + tmpFile + "," + completeProductPil - + ") started"); + protected void makePermanent(File tmpFile, String completeProductPil, + Collection siteIDs) throws EdexException { + statusHandler.debug("makePermanent(" + tmpFile + "," + + completeProductPil + ") started"); if (tmpFile != null) { - File wclDir = getWclDir(); - File dest = new File(wclDir, completeProductPil); - // Try to do things with renameTo() because it's quick if it works. - if (!tmpFile.renameTo(dest)) { - // renameTo() can fail for a variety of reasons. - // Try to do a copy-and-delete. - FileChannel temp = null; - FileChannel perm = null; - IOException firstFail = null; + for (String siteID : siteIDs) { try { - temp = new FileInputStream(tmpFile).getChannel(); - perm = new FileOutputStream(dest).getChannel(); - // should file range be locked before copy? - temp.transferTo(0, temp.size(), perm); - temp.close(); - tmpFile.delete(); + File wclDir = getWclDir(siteID); + if (wclDir != null) { + File dest = new File(wclDir, completeProductPil); + FileUtil.copyFile(tmpFile, dest); + statusHandler.info("Wrote WCL " + + tmpFile.getAbsolutePath() + " to " + + dest.getAbsolutePath()); + } else { + statusHandler + .error("Could not determine WCL directory for site " + + siteID); + } } catch (IOException e) { - throw new EdexException("Renaming \"" - + tmpFile.getAbsolutePath() + "\" to \"" - + dest.getAbsolutePath() + "\" failed.", e); - } finally { - if (temp != null && temp.isOpen()) { - try { - temp.close(); - logger.debug(temp.toString() + " closed"); - } catch (IOException e) { - firstFail = e; - } - } - if (perm != null && perm.isOpen()) { - try { - perm.close(); - logger.debug(perm.toString() + " closed"); - } catch (IOException e) { - if (firstFail == null) { - firstFail = e; - } - } - } - } - if (firstFail != null) { - throw new EdexException("Error closing file", firstFail); + statusHandler.error("Could not copy temporary WCL file " + + tmpFile.getAbsolutePath() + + " to site directory for " + siteID, e); } } - // If we got to here, claim success! - logger.info("" + tmpFile.getAbsolutePath() + " renamed to " - + dest.getAbsolutePath()); } - logger.debug("makePermanent(" + tmpFile + "," + completeProductPil - + ") ending"); + + statusHandler.debug("makePermanent(" + tmpFile + "," + + completeProductPil + ") ending"); } /** @@ -445,19 +422,23 @@ public class WCLWatchSrv { * getSiteIDs(), this is in a method rather than inline so that test code * can override it in subclasses. * + * @param siteID + * The siteID to write the WCL file for. + * * @return the directory, as a File. */ - protected File getWclDir() { + protected File getWclDir(String siteID) { IPathManager pathManager = PathManagerFactory.getPathManager(); - LocalizationContext ctx = pathManager.getContext( - LocalizationType.CAVE_STATIC, LocalizationLevel.SITE); - String wclName = "gfe" + File.separator + "wcl"; + LocalizationContext ctx = pathManager.getContextForSite( + LocalizationType.CAVE_STATIC, siteID); + String wclName = FileUtil.join("gfe", "wcl"); File wclDir = pathManager.getFile(ctx, wclName); if (wclDir == null) { - logger.error("Path manager could not locate " + wclName); + statusHandler.error("Path manager could not locate " + wclName); } else if (!wclDir.exists()) { wclDir.mkdir(); - logger.info("Directory " + wclDir.getAbsolutePath() + " created."); + statusHandler.info("Directory " + wclDir.getAbsolutePath() + + " created."); } return wclDir; } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WatchProductUtil.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WatchProductUtil.java new file mode 100644 index 0000000000..53d209f78a --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WatchProductUtil.java @@ -0,0 +1,96 @@ +/** + * 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.edex.plugin.gfe.watch; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.uf.common.util.StringUtil; + +/** + * Common methods for dealing with watch products that are received from + * national centers. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 14, 2014  #3157     dgilling     Initial creation.
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class WatchProductUtil { + + private static final Pattern ATTN_PATTERN = Pattern + .compile("\\QATTN...WFO...\\E((?:[A-Z]{3}\\Q...\\E)+)"); + + private WatchProductUtil() { + throw new AssertionError(); + } + + /** + * Searches the specified watch product text for a "ATTN...WFO..." line and + * returns a collection of WFOs that appeared in that line of the product. + * + * @param lines + * The lines that comprise the watch product. + * @return The list of WFOs that appear in the "ATTN...WFO..." line of the + * product. + */ + public static Collection findAttnWFOs(List lines) { + return findAttnWFOs(StringUtil.join(lines, '\n')); + } + + /** + * Searches the specified watch product text for a "ATTN...WFO..." line and + * returns a collection of WFOs that appeared in that line of the product. + * + * @param rawMessage + * The full text of the watch product in a single String. + * @returnThe list of WFOs that appear in the "ATTN...WFO..." line of the + * product. + */ + public static Collection findAttnWFOs(String rawMessage) { + Collection retVal = Collections.emptySet(); + + // decode the ATTN line, which tells us which WFOs are affected + // only used for WCL and WOU products + Matcher m = WatchProductUtil.ATTN_PATTERN.matcher(rawMessage); + if (m.find()) { + // eliminate ATTN...WFO... + String found = m.group(1); + String[] wfos = found.split(Pattern.quote("...")); + retVal = new HashSet(Arrays.asList(wfos)); + } + + return retVal; + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WclInfo.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WclInfo.java similarity index 98% rename from edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WclInfo.java rename to edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WclInfo.java index 9a0cbf8d6c..59878355cf 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/wcl/WclInfo.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WclInfo.java @@ -20,7 +20,7 @@ /** * */ -package com.raytheon.edex.plugin.gfe.wcl; +package com.raytheon.edex.plugin.gfe.watch; import java.util.Collections; import java.util.Date; diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/wcl/TestWCLWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/watch/TestWCLWatchSrv.java similarity index 93% rename from edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/wcl/TestWCLWatchSrv.java rename to edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/watch/TestWCLWatchSrv.java index 5a41515c6a..d8980e8020 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/wcl/TestWCLWatchSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/test/com/raytheon/edex/plugin/gfe/watch/TestWCLWatchSrv.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.edex.plugin.gfe.wcl; +package com.raytheon.edex.plugin.gfe.watch; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -29,6 +29,8 @@ import java.io.File; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -39,6 +41,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import com.raytheon.edex.plugin.gfe.watch.WCLWatchSrv; +import com.raytheon.edex.plugin.gfe.watch.WatchProductUtil; +import com.raytheon.edex.plugin.gfe.watch.WclInfo; + public class TestWCLWatchSrv { private WclInfo wclInfoA; @@ -75,11 +81,11 @@ public class TestWCLWatchSrv { wfosExpected.add("OAX"); wfosExpected.add("MFL"); wfosExpected.add("ICT"); - Set wfos = wclWatchSrv.attnWFOs(linesA); + Collection wfos = WatchProductUtil.findAttnWFOs(linesA); assertEquals("LinesA", wfosExpected, wfos); wfosExpected.clear(); - wfos = wclWatchSrv.attnWFOs(linesB); + wfos = WatchProductUtil.findAttnWFOs(linesB); assertEquals("LinesB", wfosExpected, wfos); } @@ -95,7 +101,7 @@ public class TestWCLWatchSrv { } @Override - protected File getWclDir() { + protected File getWclDir(String siteID) { String home = System.getenv("HOME"); File fakeDir = new File(home); return fakeDir; @@ -125,7 +131,7 @@ public class TestWCLWatchSrv { // localization. wclWatchSrv = new WCLWatchSrv() { @Override - protected File getWclDir() { + protected File getWclDir(String siteID) { String home = System.getenv("HOME"); return new File(home); } @@ -135,7 +141,8 @@ public class TestWCLWatchSrv { PrintWriter pw = new PrintWriter(temp); pw.println("Testing"); pw.close(); - wclWatchSrv.makePermanent(temp, completePIL); + Collection dummy = Collections.emptySet(); + wclWatchSrv.makePermanent(temp, completePIL, dummy); assertTrue("expetedFile exists", expectedFile.exists()); assertTrue("expectedFile isFile", expectedFile.isFile()); assertFalse("temp exists", temp.exists()); diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py index d51f38ec3a..d88b25a9bf 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py +++ b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py @@ -4,20 +4,20 @@ ## # 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 +# 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 -# +# 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. ## @@ -36,6 +36,7 @@ # Jun 24, 2013 DR 16317 D. Friedman If no storm line, parse storm motion from event text. # Aug 21, 2013 DR16501 m.gamazaychikov Adjusted calculation of Purge time in NoVTECWarningDecoder. # Sep 12, 2013 DR2249 rferrel When incoming file from warngen adjust start time from file's timestamp. +# Jun 10, 2014 3268 dgilling Update location of WclInfo class. # # # @author rferrel @@ -168,7 +169,7 @@ class StdWarningDecoder(): if self._productPil[0:3] == "WCL": endpoint = "WCLWatch" # build a Java object for the warning - from com.raytheon.edex.plugin.gfe.wcl import WclInfo + from com.raytheon.edex.plugin.gfe.watch import WclInfo import JUtil lines = JUtil.pyValToJavaObj(self._lines) warning = WclInfo(long(self._issueTime * 1000), diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/request/GetServiceBackupPrimarySiteRequest.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/request/GetServiceBackupPrimarySiteRequest.java new file mode 100644 index 0000000000..c797bca4aa --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/request/GetServiceBackupPrimarySiteRequest.java @@ -0,0 +1,45 @@ +/** + * 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.dataplugin.gfe.request; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; + +/** + * Request to determine whether specified site id is one of the server's + * configured primary sites for service backup. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * Jun 10, 2014  DR-17401     lshi      Initial creation
+ * 
+ * 
+ * + * @author lshi + * @version 1.0 + */ + +@DynamicSerialize +public class GetServiceBackupPrimarySiteRequest extends AbstractGfeRequest { + +} From 8ecdd9a192529b783e4aa81f2d171fd0156a0077 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Wed, 18 Jun 2014 08:55:49 -0400 Subject: [PATCH 15/17] CM-MERGE:OB13.5.6-4 into 14.1.3 Former-commit-id: 86dc406cd227362abc5274f4cd64813ceb91d00d --- .../common/stormtrack/StormTrackDisplay.java | 6 ++- .../com/raytheon/viz/warngen/gis/GisUtil.java | 19 +++++++-- .../viz/warngen/gis/PortionsUtil.java | 13 +++++- .../src/com/raytheon/viz/warngen/gis/Wx.java | 3 +- .../edex/plugin/gfe/watch/WCLWatchSrv.java | 41 +++++++------------ .../warning/gis/GeospatialFactory.java | 4 ++ .../ServiceBackup/scripts/proc_receive_grids | 32 ++++++++++++++- .../scripts/receive_grids_from_backup_site | 33 ++++++++++++++- 8 files changed, 115 insertions(+), 36 deletions(-) diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java index 090c8bd443..fa72bd8199 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/StormTrackDisplay.java @@ -100,6 +100,8 @@ import com.vividsolutions.jts.geom.LineString; * 06-24-2013 DR 16317 D. Friedman Handle "motionless" track. * 04-07-2014 DR 17232 D. Friedman Make sure pivot indexes are valid. * 06-03-14 3191 njensen Fix postData to not retrieve + * 06-17-2014 DR17409 mgamazaychikov Fix futurePoints calculation in generateNewTrackInfo() + * and generateExistingTrackInfo() * * * @@ -910,7 +912,7 @@ public class StormTrackDisplay implements IRenderable { // time, the arrow of the pathcast is drawn behind the last frame if (state.duration >= 0) { for (int i = 1; i < futurePoints.length - (remainder == 0 ? 0 : 1); ++i) { - timeInMillis += minIntervalInSeconds * 1000; + timeInMillis += interval * 60 * 1000; DataTime time = new DataTime(new Date(timeInMillis)); double distance = speed @@ -1062,7 +1064,7 @@ public class StormTrackDisplay implements IRenderable { // time, the arrow of the pathcast is drawn behind the last frame if (state.duration >= 0) { for (int i = 1; i < futurePoints.length - (remainder == 0 ? 0 : 1); ++i) { - timeInMillis += minIntervalInSeconds * 1000; + timeInMillis += interval * 60 * 1000; DataTime time = new DataTime(new Date(timeInMillis)); double distance = speed diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java index 5fcb24e5b6..d2fe657abe 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java @@ -21,6 +21,7 @@ package com.raytheon.viz.warngen.gis; import java.awt.geom.Point2D; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; @@ -29,6 +30,7 @@ import java.util.List; import org.geotools.referencing.GeodeticCalculator; +import com.raytheon.uf.common.dataplugin.warning.util.CountyUserData; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; @@ -53,6 +55,8 @@ import com.vividsolutions.jts.geom.GeometryFactory; * 0.10 to 0.0625 for EXTREME_DELTA; Added/modified code. * May 1, 2013 1963 jsanchez Refactored calculatePortion to match A1. Do not allow 'Central' to be included if East and West is included. * Jun 3, 2013 2029 jsanchez Updated A1 special case for calculating a central portion. Allowed East Central and West Central. + * Jun 17, 2014 DR 17390 Qinglu Lin Update calculateLocationPortion(). Use centroid in maps county table for geomCentroid + * for county based products. * * * @author chammack @@ -344,13 +348,22 @@ public class GisUtil { * @return */ public static EnumSet calculateLocationPortion( - Geometry locationGeom, Geometry reference, boolean useExtreme) { + Geometry locationGeom, Geometry reference, boolean useExtreme, boolean notUseShapefileCentroid) { for (int i = 0; i < locationGeom.getNumGeometries(); i++) { Geometry geom = locationGeom.getGeometryN(i); if (geom.intersects(reference)) { - Coordinate geomCentroid = geom.getEnvelope().getCentroid() - .getCoordinate(); + Coordinate geomCentroid = null; + if (notUseShapefileCentroid) { + geomCentroid = geom.getEnvelope().getCentroid() + .getCoordinate(); + } else { + geomCentroid = new Coordinate(); + geomCentroid.x = ((BigDecimal)((CountyUserData)geom.getUserData()). + entry.attributes.get("LON")).doubleValue(); + geomCentroid.y = ((BigDecimal)((CountyUserData)geom.getUserData()). + entry.attributes.get("LAT")).doubleValue(); + } Coordinate refCentroid = reference.getCentroid() .getCoordinate(); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java index c7f294da93..8d47bc5d8c 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java @@ -23,6 +23,7 @@ import java.util.EnumSet; import java.util.List; import java.util.Map; +import com.raytheon.uf.common.dataplugin.warning.util.CountyUserData; import com.raytheon.viz.warngen.gis.GisUtil.Direction; import com.raytheon.viz.warngen.gui.WarngenLayer; import com.vividsolutions.jts.geom.Geometry; @@ -39,6 +40,7 @@ import com.vividsolutions.jts.geom.Geometry; * ------------ ---------- ----------- -------------------------- * Aug 5, 2013 2177 jsanchez Initial creation * Sep 22, 2013 2177 jsanchez Updated logic. Used GisUtil for very small portions. + * Jun 17, 2014 DR 17390 Qinglu Lin Update getPortions(). * * * @@ -78,8 +80,15 @@ public class PortionsUtil { // This takes into account the warned areas that are very small // the convex hull of the warned area is used for case the // warnedArea is a geometry collection. - portions = GisUtil.calculateLocationPortion(countyOrZone, - warnedArea.convexHull(), useExtreme); + CountyUserData cud = (CountyUserData) countyOrZone.getUserData(); + String countyName = (String) cud.entry.attributes.get("COUNTYNAME"); + if (countyName == null) { + portions = GisUtil.calculateLocationPortion(countyOrZone, + warnedArea.convexHull(), useExtreme, true); + } else { + portions = GisUtil.calculateLocationPortion(countyOrZone, + warnedArea.convexHull(), useExtreme, false); + } } else { portions = getAreaDesc(entityData.getMeanMask(), entityData.getCoverageMask(), entityData.getOctants(), diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java index 757e726cab..46e4702f9d 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java @@ -115,6 +115,7 @@ import com.vividsolutions.jts.geom.Point; * Jun 24, 2013 DR 16317 D. Friedman Handle "motionless" track. * Jun 25, 2013 16224 Qinglu Lin Resolved the issue with "Date start" for pathcast in CON. * Apr 29, 2014 3033 jsanchez Updated method to retrieve files in localization. + * Jun 17, 2014 DR 17390 Qinglu Lin Updated getClosestPoints(). * * * @author chammack @@ -766,7 +767,7 @@ public class Wx { cp.partOfArea = GisUtil.asStringList(GisUtil .calculateLocationPortion( cp.prepGeom.getGeometry(), reference, - false)); + false, true)); distance = 0; } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java index 5c6ff84efb..ac0d32a3ae 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/watch/WCLWatchSrv.java @@ -63,6 +63,7 @@ import com.raytheon.uf.edex.core.EdexException; * ------------ ---------- ----------- -------------------------- * ??? ??, 20?? wldougher Initial creation * Jun 09, 2014 #3268 dgilling Ensure code works in multi-domain scenarios. + * Jun 13, 2014 #3278 dgilling Ensure temporary files get deleted. * * * @@ -152,7 +153,13 @@ public class WCLWatchSrv { // Move the file to the wcl folder // Rename it to / statusHandler.info("Placing WCL Procedure Utility in ifpServer "); - makePermanent(tmpFile, completeProductPil, siteIDs); + try { + makePermanent(tmpFile, completeProductPil, siteIDs); + } finally { + if (tmpFile != null) { + tmpFile.delete(); + } + } if (doNotify && wclInfo.getNotify()) { for (String siteID : sitesToNotify) { @@ -166,40 +173,22 @@ public class WCLWatchSrv { } statusHandler.debug("handleWclWatch() ending"); - return; } /** - * Convert a temporary parsed WCL file to a permanent one by moving it to - * the WCL directory. This is done through File.renameTo(). Unfortunately, - * that method returns a boolean success flag rather than throwing an error, - * so all we can do is tell the user that the rename failed, not why. - * - * @param wclData - * WCL data to write to file. - * @param completeProductPil - * The simple name of the file. - * - * @throws EdexException - * if WCL file cannot be opened, written, or closed. - */ - /** - * Convert a temporary parsed WCL file to a permanent one by moving it to - * the WCL directory. This is done through File.renameTo(). Unfortunately, - * that method returns a boolean success flag rather than throwing an error, - * so all we can do is tell the user that the rename failed, not why. + * Convert a temporary parsed WCL file to a permanent one by copying its + * contents to the localization path cave_static.SITE/gfe/wcl/ for each of + * the specified sites. * * @param tmpFile - * The temporary file (may be null) + * The temporary file (may be {@code null}) * @param completeProductPil - * The simple name of the file. + * The base name of the files to write. * @param siteIDs * The set of siteIDs to write out the WCL data for. - * @throws EdexException - * if tmpFile cannot be renamed. */ protected void makePermanent(File tmpFile, String completeProductPil, - Collection siteIDs) throws EdexException { + Collection siteIDs) { statusHandler.debug("makePermanent(" + tmpFile + "," + completeProductPil + ") started"); if (tmpFile != null) { @@ -243,7 +232,7 @@ public class WCLWatchSrv { File tmpFile = null; PrintStream wclOut = null; try { - tmpFile = File.createTempFile("wcl", null, null); + tmpFile = File.createTempFile("wcl", null); wclOut = new PrintStream(tmpFile); wclOut.println(wclStr); } catch (IOException e) { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java index 14833b4abc..995fda31b3 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java @@ -60,6 +60,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; * So, do not add the returned value of getFeAreaField() * to areaFields. * Jan 9, 2013 15600 Qinglu Lin Execute "timezones = myTimeZones;" even if timezones != null. + * Jun 17, 2014 DR 17390 Qinglu Lin Updated getMetaDataMap() for lonField and latField. * * * @@ -211,6 +212,9 @@ public class GeospatialFactory { areaFields.add(feAreaField); } + areaFields.add("LON"); + areaFields.add("LAT"); + if (timeZoneField != null) { areaFields.add(timeZoneField); } diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/proc_receive_grids b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/proc_receive_grids index 88eab0511d..f90e00ca69 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/proc_receive_grids +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/proc_receive_grids @@ -1,4 +1,34 @@ #!/bin/bash +## +# 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. +## +############################################################################## +# Process Received Digital Grids +# This is run at the backup site to merge the failed site's grids into the +# Fcst database. +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/16/15 3276 randerso Added -T to iscMosaic call +############################################################################## import_file=${1} log_msg Processing file: $import_file @@ -98,7 +128,7 @@ log_msg "CDSPORT is $CDSPORT" log_msg Beginning iscMosaic log_msg 75 -${GFESUITE_BIN}/iscMosaic -h $SVCBU_HOST -r $CDSPORT -d ${SITE}_GRID__Fcst_00000000_0000 -f ${SVCBU_HOME}/${failed_site}Grd.netcdf.gz -n +${GFESUITE_BIN}/iscMosaic -h $SVCBU_HOST -r $CDSPORT -d ${SITE}_GRID__Fcst_00000000_0000 -f ${SVCBU_HOME}/${failed_site}Grd.netcdf.gz -n -T if [ $? -ne 0 ] then log_msg "ERROR: iscMosaic failed to import grids from ${SITE}_GRID__Fcst_00000000_0000" diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/receive_grids_from_backup_site b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/receive_grids_from_backup_site index c1a933df26..a528118a9d 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/receive_grids_from_backup_site +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/scripts/receive_grids_from_backup_site @@ -1,4 +1,35 @@ #!/bin/bash +## +# 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. +## +############################################################################## +# Receive grids from backup site +# This script is run when importing your digital data back from the backup site. +# The grids are placed in the Restore database. +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/16/15 3276 randerso Added -T to iscMosaic call +############################################################################## + if [ ${#AWIPS_HOME} = 0 ] then path_to_script=`readlink -f $0` @@ -94,7 +125,7 @@ if [ -a ${import_file} ] then #use iscMosaic to load grids into databases log_msg "Running iscMosaic to unpack griddded data..." - ${GFESUITE_BIN}/iscMosaic -h $SVCBU_HOST -r $CDSPORT -d ${SITE}_GRID__Restore_00000000_0000 -f ${import_file} -n -x + ${GFESUITE_BIN}/iscMosaic -h $SVCBU_HOST -r $CDSPORT -d ${SITE}_GRID__Restore_00000000_0000 -f ${import_file} -n -T -x if [ $? -ne 0 ]; then log_msg "ERROR: iscMosaic failed to run correctly. Please re-run iscMosaic manually." From 97ef9fc3436a53620aaa29baf0725f97f3a22eca Mon Sep 17 00:00:00 2001 From: Nate Jensen Date: Mon, 23 Jun 2014 09:54:11 -0500 Subject: [PATCH 16/17] Issue #3307 fix xml serialization of looping field Former-commit-id: c6ce72840a4ee0f44eacff46015b5382d86dd47f --- .../uf/viz/core/datastructure/LoopProperties.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/datastructure/LoopProperties.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/datastructure/LoopProperties.java index f64f57fceb..8f8c525773 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/datastructure/LoopProperties.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/datastructure/LoopProperties.java @@ -38,6 +38,7 @@ import org.eclipse.ui.commands.ICommandService; * ------------- -------- ----------- -------------------------- * Aug 30, 2007 randerso Initial Creation. * Oct 22, 2013 2491 bsteffen Remove ISerializableObject + * Jun 23, 2014 3307 njensen Fix xml serialization of looping field * * * @@ -50,7 +51,7 @@ public class LoopProperties { public enum LoopMode { Forward, Backward, Cycle - }; + } /** frame time increment in ms */ public static final int FRAME_STEP = 100; @@ -144,12 +145,8 @@ public class LoopProperties { this.mode = mode; } - public boolean isLooping() { - return isLooping; - } - @XmlElement - public boolean getLooping() { + public boolean isLooping() { return isLooping; } From 65619399a05c12458f03014ef069bb22a710fbb5 Mon Sep 17 00:00:00 2001 From: Nate Jensen Date: Thu, 19 Jun 2014 09:51:10 -0500 Subject: [PATCH 17/17] Issue #3248 ensure that a locking file output streams obtains the lock before calling the FileOutputStream constructor Change-Id: I210ac789322c975cb93584facb3eec417f5097f2 (cherry picked from commit 65eb76ff66d40ad9f1817d13a277ac153aee10f3 [formerly 599f2598f711ce2ae6ac69ed78a90502a84d2716]) Former-commit-id: f0ad63d2ccf347e92274701f9890e120b9e70140 --- .../localization/LockingFileOutputStream.java | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LockingFileOutputStream.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LockingFileOutputStream.java index 9c9cf6b5f4..38e6595efa 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LockingFileOutputStream.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LockingFileOutputStream.java @@ -35,7 +35,9 @@ import com.raytheon.uf.common.localization.FileLocker.Type; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jun 23, 2011 mschenke Initial creation + * Jun 23, 2011 mschenke Initial creation + * Jun 05, 2014 3248 njensen Fix constructors so lock is obtained + * before super constructor called * * * @@ -46,7 +48,9 @@ import com.raytheon.uf.common.localization.FileLocker.Type; public class LockingFileOutputStream extends FileOutputStream { private File file; - + + private final Object locker; + /** * Create a new LockingFileOuputStream, creates an exclusive lock on the * file @@ -55,9 +59,7 @@ public class LockingFileOutputStream extends FileOutputStream { * @throws FileNotFoundException */ public LockingFileOutputStream(File file) throws FileNotFoundException { - super(file); - this.file = file; - FileLocker.lock(this, file, Type.WRITE); + this(file, false); } /** @@ -70,9 +72,40 @@ public class LockingFileOutputStream extends FileOutputStream { */ public LockingFileOutputStream(File file, boolean isAppending) throws FileNotFoundException { + this(file, isAppending, new Object()); + } + + /** + * Intentionally private constructor that takes a locker object to provide a + * unique lock tied to this stream instance. This constructor enforces that + * the FileLocker lock will be obtained before the super constructor is + * called. Otherwise, if isAppending is false, the super constructor will + * set the file length to zero, wiping out the contents, and we absolutely + * must have the write lock before that. + * + * @param file + * @param isAppending + * @param locker + * @throws FileNotFoundException + */ + private LockingFileOutputStream(File file, boolean isAppending, Object locker) throws FileNotFoundException { + this(file, isAppending, locker, FileLocker.lock(locker, file, Type.WRITE)); + } + + /** + * Intentionally private constructor that should be called after the file + * lock is obtained. + * + * @param file + * @param isAppending + * @param locker + * @param gotLock + * @throws FileNotFoundException + */ + private LockingFileOutputStream(File file, boolean isAppending, Object locker, boolean gotLock) throws FileNotFoundException { super(file, isAppending); this.file = file; - FileLocker.lock(this, file, Type.WRITE); + this.locker = locker; } @Override @@ -106,7 +139,10 @@ public class LockingFileOutputStream extends FileOutputStream { } } + /** + * Unlocks the file lock associated with the stream. + */ public void unlock() { - FileLocker.unlock(this, file); + FileLocker.unlock(locker, file); } }