From 323eeb31c9ca6ee0d07b91f2ccbd36074d0e58d5 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 3 Feb 2014 14:55:25 -0500 Subject: [PATCH 1/5] VLab Issue #2916 - NSHARP Errors Swapping into main pane Fixed some widget management errors in the Show Text dialog's close method. Ensure Text Dislog's close method is called when swapping Nsharp display. Change-Id: I6e645aa552980b49e552a2830f9f148d95f27f3b Former-commit-id: ba72d87f07a3ea0465a40714a5724e2d0a5e29e8 [formerly 0ff12f2c322d9cbed696f9ee4f2049d9efed7863] Former-commit-id: 3f6c7ef92cad2064f940f36ad819683049f27cc7 --- .../ui/nsharp/view/NsharpPaletteWindow.java | 6 +- .../ui/nsharp/view/NsharpShowTextDialog.java | 145 ++++-------------- 2 files changed, 38 insertions(+), 113 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java index 0693ee07e6..39b2f671ef 100644 --- a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java +++ b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java @@ -15,10 +15,12 @@ * 09/03/2013 1031 Greg Hull try 5 times to initialize the inventory. * 01/08/2014 Chin Chen Only initializing inventory when in NCP * 01/13/2014 Chin Chen TTR829- when interpolation, edit graph is allowed + * 01/22/2014 Chin Chen DR17003 issue: NSHARP sounding display throws errors when swapping into main pane when show text is turned on. + * * * * @author Chin Chen - * @version 1.0 + * @verFsion 1.0 */ package gov.noaa.nws.ncep.ui.nsharp.view; @@ -1550,7 +1552,7 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, @Override public void partClosed(IWorkbenchPart part) { //System.out.println("view closed "); - /*FixMark:SwapPaneShowText + //*FixMark:SwapPaneShowText NsharpShowTextDialog textarea = NsharpShowTextDialog.getAccess(); if(textarea != null){ textarea.close(); diff --git a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpShowTextDialog.java b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpShowTextDialog.java index c93d51b77a..8064eb0087 100644 --- a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpShowTextDialog.java +++ b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpShowTextDialog.java @@ -12,7 +12,8 @@ package gov.noaa.nws.ncep.ui.nsharp.view; * Date Ticket# Engineer Description * ------- ------- -------- ----------- * 03/23/2010 229 Chin Chen Initial coding - * + * 01/22/2014 Chin Chen DR17003: fixed show text cause error exception when in D2D swapping from main pane to side pane + * 01/22/2014 Chin Chen fixed show text cause nsharp hang issue, when text shown and then start looping action * * * @author Chin Chen @@ -54,17 +55,19 @@ public class NsharpShowTextDialog extends Dialog { private Text text=null; private Group textGp; private Font newFont ; - private static boolean iAmClosed; - //private static String textToSave=""; + + public Text getText() { return text; } protected NsharpShowTextDialog(Shell parentShell) throws VizException { super(parentShell); + //System.out.println("ShowText Dialog constructed"); this.setShellStyle(SWT.TITLE | SWT.MODELESS | SWT.CLOSE ); shell = parentShell; // TODO Auto-generated constructor stub + } private void createShowtextDialogContents(Composite parent){ @@ -89,39 +92,6 @@ public class NsharpShowTextDialog extends Dialog { } - /*private String createDefaultSaveFileName() { - StringTokenizer st = new StringTokenizer(text.getText()); - int i =0; - String fileName; - if(st.hasMoreTokens()== true){ - fileName = ""; - //text header are the first 2,3,4 tokens. use them as default file name - while (st.hasMoreTokens()) { - i++; - String tok = st.nextToken(); - //System.out.println("tok "+ i + " ="+ tok); - if(i==1) - continue; - if(i > 4){ - break; - } - - if(i ==4) { - if(tok.length() >= 5) - tok = " " + tok.substring(0, 5); - else - tok = " " + tok; - } - fileName = fileName + tok; - - } - fileName = fileName + ".nsp"; - } - else - fileName= "nsharp.nsp"; - - return fileName; - }*/ @Override public void createButtonsForButtonBar(Composite parent) { // create buttons with "CLOSE" label but with cancel function @@ -135,63 +105,6 @@ public class NsharpShowTextDialog extends Dialog { public void handleEvent(Event event) { // Action to save text report NsharpSaveHandle.saveFile(shell); - /*FileDialog dlg = new FileDialog(shell, SWT.SAVE); - String fileName = null; - - // The user has finished when one of the - // following happens: - // 1) The user dismisses the dialog by pressing Cancel - // 2) The selected file name does not exist - // 3) The user agrees to overwrite existing file - boolean done = false; - boolean saveFile = false; - while (!done) { - // Open the File Dialog - dlg.setText("Save"); - String[] filterExt = {"*.nsp"}; - dlg.setFilterExtensions(filterExt); - dlg.setFileName(createDefaultSaveFileName()); - fileName = dlg.open(); - //System.out.println("file name = "+ fileName); - if (fileName == null) { - // User has cancelled, so quit and return - done = true; - } else { - // User has selected a file; see if it already exists - File file = new File(fileName); - if (file.exists()) { - // The file already exists; asks for confirmation - MessageBox mb = new MessageBox(dlg.getParent(), SWT.ICON_WARNING - | SWT.YES | SWT.NO); - - // We really should read this string from a - // resource bundle - mb.setMessage(fileName + " already exists. Do you want to replace it?"); - - // If they click Yes, we're done and we drop out. If - // they click No, we redisplay the File Dialog - done = mb.open() == SWT.YES; - if(done == true) - saveFile = true; - } else { - // File does not exist, so drop out - done = true; - saveFile = true; - } - } - } - if(saveFile == true) { - try{ - // Create file - FileWriter fstream = new FileWriter(fileName); - BufferedWriter out = new BufferedWriter(fstream); - out.write(textToSave); - //Close the output stream - out.close(); - }catch (Exception e){//Catch exception if any - System.err.println("Error: " + e.getMessage()); - } - }*/ } } ); } @@ -212,7 +125,7 @@ public class NsharpShowTextDialog extends Dialog { // Initialize all of the menus, controls, and layouts createShowtextDialogContents(top); - refreshTextData(); + doRefreshTextData();/*FixMark:looping */ return top; } @@ -226,15 +139,27 @@ public class NsharpShowTextDialog extends Dialog { this.getShell().setLocation(this.getShell().getParent().getLocation().x+700, this.getShell().getParent().getLocation().y+200); - iAmClosed = false; return super.open(); } @Override public boolean close() { - //System.out.println("ShowText close called"); - iAmClosed = true; + /*FixMark:SwapPaneShowText */ + if(text != null){ + if(text.getFont()!= null){ + text.getFont().dispose(); + newFont=null; + } + text.dispose(); + text=null; + } + if(textGp!=null){ + textGp.dispose(); + textGp= null; + } + INSTANCE = null; + /*end FixMark:SwapPaneShowText */ if(newFont!= null){ newFont.dispose(); newFont=null; @@ -260,19 +185,16 @@ public class NsharpShowTextDialog extends Dialog { } public static NsharpShowTextDialog getAccess() { - if(iAmClosed == true) - return null; return INSTANCE; } - public static NsharpShowTextDialog getAccess(boolean force) { - if(force == true) - return INSTANCE; - else - return getAccess(); - } - public void refreshTextData() { + /*FixMark:looping */ + private void doRefreshTextData() { + + if(NsharpEditor.getActiveNsharpEditor() == null){ + return; + } NsharpResourceHandler rsc = NsharpEditor.getActiveNsharpEditor().getRscHandler(); if(rsc!=null && rsc.getSoundingLys()!= null && !text.isDisposed() && text!=null){ String hdr; @@ -306,18 +228,19 @@ public class NsharpShowTextDialog extends Dialog { textGp.layout(); } } - //Need use asyncExec to handle update text request from other thread (worker thread) - public void updateTextFromWorkerThread(){ + public void refreshTextData(){ try{ Display.getDefault().asyncExec(new Runnable(){ public void run(){ - refreshTextData(); + doRefreshTextData(); } }); }catch(SWTException e){ - System.out.println("updateTextFromWorkerThread: can not run asyncExec()"); + System.out.println("refreshTextData: can not run asyncExec()"); } - } + } + /* end FixMark:looping */ + } From 64044e7ce56f1741c155354cbc974dc2ec53b47a Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Fri, 21 Feb 2014 06:50:59 -0500 Subject: [PATCH 2/5] OB_14.1.1-19 baseline Former-commit-id: cfa499797800ae2d3d0481cd43b48d60f27538ba [formerly db2a591456383d8f980d33757e8c161bdcc01d3a] Former-commit-id: 10b723647b876fca63e62690ef71421957124489 --- .../gfe/userPython/procedures/MakeHazard.py | 3 + .../textUtilities/headline/TextFormatter.py | 192 +++++----- cave/build/static/linux/cave/caveUtil.sh | 2 +- .../jobs/NotificationManagerJob.java | 352 +++++++++--------- .../aviation/editor/TafViewerEditorDlg.java | 19 +- .../gfe/dialogs/FormatterLauncherDialog.java | 245 +++++++----- .../formatterlauncher/ProductAreaComp.java | 58 +-- .../textformatter/CombinationsFileUtil.java | 19 +- .../viz/gfe/textformatter/FormatterUtil.java | 27 +- .../gfe/textformatter/TextProductManager.java | 18 +- edexOsgi/build.edex/esb/conf/log4j-ingest.xml | 4 +- .../build.edex/esb/conf/log4j-registry.xml | 2 +- edexOsgi/build.edex/esb/conf/log4j.xml | 2 +- edexOsgi/build.edex/esb/conf/modes.xml | 9 +- edexOsgi/build.edex/esb/conf/spring/edex.xml | 24 +- .../res/spring/airep-ingest.xml | 2 +- .../res/spring/binlightning_ep-ingest.xml | 2 +- .../res/spring/bufrmos-ingest.xml | 2 +- .../res/spring/bufrua-ingest.xml | 2 +- .../res/spring/ccfp-ingest.xml | 2 +- .../res/spring/gfe-common.xml | 2 +- .../res/spring/gfe-request.xml | 31 +- .../res/spring/gfe-spring.xml | 16 +- .../edex/plugin/gfe/isc/IscSendQueue.java | 22 +- .../res/spring/goessounding-ingest.xml | 2 +- .../res/spring.deprecated/grib-decode.xml | 18 +- .../res/spring.future/grib-decode.xml | 18 +- .../res/spring/grib-distribution.xml | 2 +- .../res/spring/ldad-ingest.xml | 2 +- .../res/spring/ldadhydro-ingest.xml | 2 +- .../res/spring/ldadmanual-ingest.xml | 2 +- .../res/spring/ldadprofiler-ingest.xml | 2 +- .../res/spring/modelsounding-ingest.xml | 2 +- .../res/spring/obs-ingest.xml | 2 +- .../res/spring/pirep-ingest.xml | 2 +- .../res/spring/poessounding-ingest.xml | 2 +- .../res/spring/profiler-ingest.xml | 2 +- .../res/spring/radar-ingest.xml | 23 +- .../res/spring/recco-ingest.xml | 2 +- .../res/spring/redbook-ingest.xml | 2 +- .../res/spring/satellite-ingest.xml | 16 +- .../res/spring/sfcobs-ingest.xml | 2 +- .../res/spring/shef-ingest.xml | 22 +- .../alarms/AlertalarmStdTextProductUtil.java | 90 ++--- .../edex/plugin/shef/alarms/Constants.java | 37 +- .../res/spring/taf-ingest.xml | 4 +- .../edex/plugin/taf/common/ChangeGroup.java | 27 +- .../edex/plugin/taf/common/TafRecord.java | 20 +- .../res/spring/text-ingest.xml | 20 +- .../res/spring/textlightning_ep-ingest.xml | 2 +- .../res/spring/warning-ingest.xml | 24 +- .../res/spring/textdb-request.xml | 16 +- .../dataplugin/obs/metar/MetarRecord.java | 35 +- .../persist/PersistableDataObject.java | 7 +- .../META-INF/MANIFEST.MF | 3 +- .../uf/common/jms/JmsPooledConnection.java | 33 +- .../jms/JmsPooledConnectionFactory.java | 256 +++++-------- .../uf/common/jms/JmsPooledConsumer.java | 25 +- .../uf/common/jms/JmsPooledProducer.java | 32 +- .../uf/common/jms/JmsPooledSession.java | 35 +- .../jms/wrapper/JmsConsumerWrapper.java | 33 +- .../jms/wrapper/JmsProducerWrapper.java | 50 ++- .../res/spring/activetable-common.xml | 13 +- .../res/spring/activetable-ingest.xml | 4 +- .../archive/DatabaseArchiveProcessor.java | 170 +++++---- .../uf/edex/archive/DatabaseArchiver.java | 13 +- .../res/spring/cpgsrv-spring.xml | 2 +- .../res/spring/harvester-datadelivery.xml | 19 +- .../res/spring/distribution-spring.xml | 19 +- .../jms/DedicatedThreadJmsComponent.java | 101 +++++ ...efaultMessageListenerContainerFactory.java | 142 +++++++ .../res/spring/grid-staticdata-process.xml | 2 +- .../res/spring/DPADecoder-spring.xml | 4 +- .../res/spring/arealffgGenerator-spring.xml | 2 +- .../res/spring/hpeDHRDecoder-spring.xml | 4 +- .../res/spring/ohd-common-database.xml | 40 ++ .../res/spring/ohd-common.xml | 36 -- .../res/spring/q2FileProcessor-spring.xml | 2 +- .../res/spring/satpre-spring.xml | 2 +- .../res/spring/acars-ingest.xml | 2 +- .../res/spring/bufrascat-ingest.xml | 2 +- .../res/spring/bufrhdw-ingest.xml | 2 +- .../res/spring/bufrmthdw-ingest.xml | 2 +- .../res/spring/bufrncwf-ingest.xml | 2 +- .../res/spring/bufrquikscat-ingest.xml | 2 +- .../res/spring/bufrsigwx-ingest.xml | 2 +- .../res/spring/bufrssmi-ingest.xml | 2 +- .../res/spring/cwa-ingest.xml | 2 +- .../res/spring/ldadmesonet-ingest.xml | 2 +- .../res/spring/loctables-spring.xml | 2 +- .../res/spring/lsr-ingest.xml | 2 +- .../res/spring/crimss-ingest.xml | 2 +- .../res/spring/nucaps-ingest.xml | 2 +- .../res/spring/viirs-ingest.xml | 14 +- .../res/spring/satellite-mcidas-ingest.xml | 20 +- .../res/spring/svrwx-ingest.xml | 2 +- .../res/spring/tcg-ingest.xml | 2 +- .../res/spring/tcs-ingest.xml | 2 +- .../res/spring/vaa-ingest.xml | 2 +- .../dataplugin/airmet/AirmetRecord.java | 78 ++-- .../ncep/common/dataplugin/aww/AwwRecord.java | 179 ++++----- .../convsigmet/ConvSigmetRecord.java | 59 ++- .../ncep/common/dataplugin/ffg/FfgRecord.java | 79 ++-- .../intlsigmet/IntlSigmetRecord.java | 60 ++- .../dataplugin/ncpafm/NcPafmRecord.java | 10 +- .../dataplugin/ncscat/NcscatRecord.java | 42 +-- .../common/dataplugin/nctaf/NcTafRecord.java | 8 +- .../dataplugin/ncuair/NcUairRecord.java | 71 ++-- .../nonconvsigmet/NonConvSigmetRecord.java | 54 ++- .../dataplugin/ntrans/NtransRecord.java | 44 ++- .../ncep/common/dataplugin/tcm/TcmRecord.java | 11 +- .../ncep/common/dataplugin/wcp/WcpRecord.java | 68 ++-- .../res/spring/ncinventory-request.xml | 2 +- .../res/spring/airmet-ingest.xml | 2 +- .../res/spring/atcf-ingest.xml | 2 +- .../res/spring/aww-ingest.xml | 2 +- .../res/spring/convsigmet-ingest.xml | 2 +- .../res/spring/ffg-ingest.xml | 2 +- .../res/spring/geomag-ingest.xml | 4 +- .../res/spring/idft-ingest.xml | 2 +- .../res/spring/intlsigmet-ingest.xml | 2 +- .../res/spring/mcidas-ingest.xml | 2 +- .../res/spring/ncairep-ingest.xml | 2 +- .../res/spring/ncccfp-ingest.xml | 2 +- .../res/spring/ncgrib-distribution.xml | 2 +- .../res/spring/ncgrib-ingest.xml | 18 +- .../res/spring/ncpafm-ingest.xml | 2 +- .../res/spring/ncpirep-ingest.xml | 2 +- .../res/spring/ncscat-ingest.xml | 2 +- .../res/spring/ncscd-ingest.xml | 2 +- .../res/spring/nctaf-ingest.xml | 2 +- .../res/spring/nctext-ingest.xml | 2 +- .../res/spring/ncuair-ingest.xml | 2 +- .../res/spring/nonconvsigmet-ingest.xml | 2 +- .../res/spring/ntrans-ingest.xml | 2 +- .../res/spring/sgwh-ingest.xml | 2 +- .../res/spring/sgwhv-ingest.xml | 2 +- .../res/spring/solarimage-ingest.xml | 14 +- .../res/spring/ssha-ingest.xml | 2 +- .../res/spring/stormtrack-ingest.xml | 2 +- .../res/spring/tcm-ingest.xml | 2 +- .../res/spring/wcp-ingest.xml | 2 +- .../res/spring/regionalsat-ingest.xml | 18 +- .../scripts/profile.d/awips2Ant.csh | 3 +- rpms/build/x86_64/build.sh | 3 +- 145 files changed, 1766 insertions(+), 1687 deletions(-) create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/MonitoredDefaultMessageListenerContainerFactory.java create mode 100644 edexOsgi/com.raytheon.uf.edex.ohd/res/spring/ohd-common-database.xml diff --git a/cave/build/static/common/cave/etc/gfe/userPython/procedures/MakeHazard.py b/cave/build/static/common/cave/etc/gfe/userPython/procedures/MakeHazard.py index 9b41e7087d..33e8e1eb08 100644 --- a/cave/build/static/common/cave/etc/gfe/userPython/procedures/MakeHazard.py +++ b/cave/build/static/common/cave/etc/gfe/userPython/procedures/MakeHazard.py @@ -11,6 +11,7 @@ # Apr 03,2012 436 randerso Converted to Python procedure to allow some # level of site customization # Apr 09,2012 436 randerso Merged RNK's MakeHazards_Elevation procedure +# Feb 12,2014 17058 ryu Extend converter for Collections$EmptyList objects. # # Author: randerso # ---------------------------------------------------------------------------- @@ -307,6 +308,8 @@ def converter(obj): objtype = obj.jclassname if objtype == "java.util.Date": retVal = AbsTime.AbsTime(obj) + elif objtype == "java.util.Collections$EmptyList": + retVal = [] elif objtype == "com.raytheon.uf.common.time.TimeRange": retVal = TimeRange.TimeRange(obj) return retVal diff --git a/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/TextFormatter.py b/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/TextFormatter.py index 80ed152ac4..d79a243c9a 100644 --- a/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/TextFormatter.py +++ b/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/TextFormatter.py @@ -1,19 +1,19 @@ ## # 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. ## @@ -27,16 +27,25 @@ # # Author: hansen # ---------------------------------------------------------------------------- +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 02/12/2014 #2591 randerso Added retry when loading combinations fails import string, getopt, sys, time, os, types, math import ModuleAccessor import Utility, logging, traceback +import AbsTime from java.lang import ThreadDeath from com.raytheon.uf.common.dataplugin.gfe.reference import ReferenceID, ReferenceData GridLoc = None LatLonIds = [] +MAX_TRIES = 2 + # If someone imports TextFormatter and needs this instance # they should either be fixed to use the IFPImporter module # or turn this line on (which is a kludge but should make @@ -44,19 +53,19 @@ LatLonIds = [] #IFPImporter = IFPImporter.IFPImporter class TextFormatter: - def __init__(self, dataManager): + def __init__(self, dataManager): # Variable for unique combinations self.__comboNumber = -1 self.dataMgr = dataManager self.log = logging.getLogger("FormatterRunner.TextFormatter.TextFormatter") pass - + # def __del__(self): # for i in LatLonIds: # self.dataMgr.getRefManager().deleteRefSet(i, False) def getForecast(self, fcstName, argDict): - " Create the forecast " + " Create the forecast " ForecastNarrative = argDict["ForecastNarrative"] ForecastTable = argDict["ForecastTable"] @@ -71,7 +80,7 @@ class TextFormatter: argDict["getForecast"] = self.getForecast argDict["getFcstDef"] = self.getFcstDef argDict["dataMgr"] = self.dataMgr - self.__ut = argDict["utility"] + self.__ut = argDict["utility"] # Get the Forecast Definition and type from the server #print "finding", fcstName @@ -79,11 +88,11 @@ class TextFormatter: #print "found ", found if found == 0: text = "Text Product Definition Not Found: " + fcstName + " " + \ - traceback.format_exc() + traceback.format_exc() self.log.error("Text Product Definition Not Found: Caught Exception: " + fcstName, exc_info=True) raise Exception, text forecastDef = argDict["forecastDef"] - fcstType = self.__ut.set(forecastDef,"type",None) + fcstType = self.__ut.set(forecastDef, "type", None) argDict["fcstType"] = fcstType if fcstType is None: text = "Text Product Type Not Found: " + fcstName + " " + \ @@ -101,16 +110,16 @@ class TextFormatter: # Must have at least one edit area and time range specified if fcstType != "smart" and fcstType != "component": if argDict["editAreas"] == []: - text= "No Edit Areas Specified over which to generate product." - text=text+'\nTry setting "defaultEditAreas" in the product Definition' - text=text+'\nOr, if running from the command line, add a -r flag.' + text = "No Edit Areas Specified over which to generate product." + text = text + '\nTry setting "defaultEditAreas" in the product Definition' + text = text + '\nOr, if running from the command line, add a -r flag.' text = text + '\n' + string.join(traceback.format_exc()) self.log.error("Caught Exception: " + text) raise Exception, text if argDict["rawRanges"] == []: - text= "No Time Ranges Specified over which to generate product." - text=text+'\nTry setting "defaultRanges" in the product Definition' - text=text+'\nOr, if running from the command line, add a -w flag.' + text = "No Time Ranges Specified over which to generate product." + text = text + '\nTry setting "defaultRanges" in the product Definition' + text = text + '\nOr, if running from the command line, add a -w flag.' text = text + '\n' + string.join(traceback.format_exc()) self.log.error("Caught Exception: " + text) raise Exception, text @@ -153,7 +162,7 @@ class TextFormatter: argDict["module"] = module product.setUp("T", argDict) product._argDict = argDict - + try: text = product.generateForecast(argDict) except RuntimeError, e: @@ -166,11 +175,11 @@ class TextFormatter: # requirement for TEST phrasing for TEST products if argDict.get('testMode', 0): - testMsg = "\nTHIS IS A TEST MESSAGE. DO NOT TAKE ACTION" +\ + testMsg = "\nTHIS IS A TEST MESSAGE. DO NOT TAKE ACTION" + \ " BASED ON THIS TEST\nMESSAGE.\n" #split by "$$" segs = text.split('\n$$') - for i in xrange(len(segs)-1): #never the last one + for i in xrange(len(segs) - 1): #never the last one if text.find(testMsg) == -1: #not found, add it in segs[i] = segs[i] + testMsg text = '\n$$'.join(segs) #put text back together again @@ -185,7 +194,7 @@ class TextFormatter: if not forecastDef.get('lowerCase', 0): text = text.upper() else: - text="Text Product Type Invalid "+\ + text = "Text Product Type Invalid " + \ "(must be 'table', 'component' or 'narrative'): ", fcstName, type text = text + '\n' + string.join(traceback.format_exc()) self.log.error("Caught Exception: " + text) @@ -196,18 +205,18 @@ class TextFormatter: def __createNarrativeDef(self, fcstName, timeRange): return { "methodList": [self.assembleChildWords], - "narrativeDef": [(fcstName, timeRange.duration()/3600)], + "narrativeDef": [(fcstName, timeRange.duration() / 3600)], } def __loop(self, argDict, forecast, forecastDef): # Loop through product by edit areas and time ranges - begText = self.__ut.set(forecastDef,"beginningText","") - endText = self.__ut.set(forecastDef,"endingText","") - editAreaLoopBegText = self.__ut.set(forecastDef,"editAreaLoopBegText","") - timeRangeLoopBegText = self.__ut.set(forecastDef,"timeRangeLoopBegText","") - editAreaLoopEndText = self.__ut.set(forecastDef,"editAreaLoopEndText","") - timeRangeLoopEndText = self.__ut.set(forecastDef,"timeRangeLoopEndText","") + begText = self.__ut.set(forecastDef, "beginningText", "") + endText = self.__ut.set(forecastDef, "endingText", "") + editAreaLoopBegText = self.__ut.set(forecastDef, "editAreaLoopBegText", "") + timeRangeLoopBegText = self.__ut.set(forecastDef, "timeRangeLoopBegText", "") + editAreaLoopEndText = self.__ut.set(forecastDef, "editAreaLoopEndText", "") + timeRangeLoopEndText = self.__ut.set(forecastDef, "timeRangeLoopEndText", "") outerLoop = self.__ut.set(forecastDef, "outerLoop", "EditArea") editAreas = argDict["editAreas"] @@ -274,10 +283,10 @@ class TextFormatter: #print "varDict", varDict for item, default in [ - ("language","english"), - ("appendFile",None), - ("lineLength",69), # no command line option - ("timePeriod",3), + ("language", "english"), + ("appendFile", None), + ("lineLength", 69), # no command line option + ("timePeriod", 3), ]: try: # Try the varDict #print "trying varDict", item @@ -362,19 +371,28 @@ class TextFormatter: # (["Zones37","Zones38"], "/37/38"),"/37/38"), # (["Zones57","Zones58","Zones59"],"57/58/59") # ] - - # RWA-05/19/11: added this check here to force Combinations files - # to be reloaded since we removed a similar check from ModuleAccessor - # to preserve the magicCodeChanges. Perhaps we should be doing something - # similar to magicCodeChanges for Combinations files as well. - if sys.modules.has_key(dfEditAreas): - del sys.modules[dfEditAreas] - - accessor = ModuleAccessor.ModuleAccessor() - dfEditAreas = accessor.variable(dfEditAreas, "Combinations") - if dfEditAreas is None: - return "COMBINATION FILE NOT FOUND: " + \ - self.__ut.set(forecastDef, "defaultEditAreas", []) + + comboName = dfEditAreas + for retryCount in xrange(MAX_TRIES): + accessor = ModuleAccessor.ModuleAccessor() + dfEditAreas = accessor.variable(comboName, "Combinations") + if dfEditAreas is None: + if sys.modules.has_key(comboName): + comboMod = sys.modules[comboName] + if comboMod.__file__.endswith(".pyo"): + os.remove(comboMod.__file__) + comboMod = None + del sys.modules[comboName] + + # if not last try, log and try again + if retryCount < MAX_TRIES - 1: + # log but don't pop up + self.log.error("Error loading combinations file: %s, retrying", comboName) + else: + return "COMBINATION FILE NOT FOUND: " + \ + self.__ut.set(forecastDef, "defaultEditAreas", []) + else: + break elif len(dfEditAreas) > 0: refDataList = [] @@ -411,7 +429,7 @@ class TextFormatter: filterMethod = product.filterMethod except: allowedHazards = None - + if allowedHazards is not None and allowedHazards != []: # Set up editAreas as a list of combinations # Cases: @@ -440,7 +458,7 @@ class TextFormatter: "AreaDictionary") editAreas = self._separateByTimeZone(editAreas, areaDictName, argDict['creationTime'], - effectiveTZ = separateByTZ) + effectiveTZ=separateByTZ) accurateCities = product.Definition.get('accurateCities', 0) cityRefData = [] @@ -464,7 +482,7 @@ class TextFormatter: "contain entry for edit area: " self.log.error(msg + `ean`) continue - + for city, llrec in citydict[ean].iteritems(): # Create a referenceData given lat, lon, dim area = (llrec[0], llrec[1], 0) @@ -490,8 +508,8 @@ class TextFormatter: filterMethod, argDict["databaseID"], stationID4, argDict["vtecActiveTable"], argDict["vtecMode"], sampleThreshold, creationTime=argDict["creationTime"], dataMgr=self.dataMgr, - accurateCities=accurateCities, - cityEditAreas=cityRefData) + accurateCities=accurateCities, + cityEditAreas=cityRefData) # Store hazards object for later use argDict["hazards"] = hazards @@ -540,7 +558,7 @@ class TextFormatter: except: trName = "" if tr is not None: - rawRanges.append((tr,trName)) + rawRanges.append((tr, trName)) elif len(dfRanges) == 0: pass else: @@ -548,13 +566,13 @@ class TextFormatter: forecast = TimeRangeUtils.TimeRangeUtils() for rangeName in dfRanges: rawRange = forecast.getTimeRange(rangeName, argDict) - rawRanges.append((rawRange,rangeName)) + rawRanges.append((rawRange, rangeName)) argDict["rawRanges"] = rawRanges #print "rawRanges", rawRanges # Row Label - areaType = self.__ut.set(forecastDef,"areaType","") - rowVariable = self.__ut.set(forecastDef,"rowVariable","EditArea") + areaType = self.__ut.set(forecastDef, "areaType", "") + rowVariable = self.__ut.set(forecastDef, "rowVariable", "EditArea") if rowVariable == "EditArea": rowLabel = areaType elif rowVariable == "WeatherElement": @@ -566,7 +584,7 @@ class TextFormatter: def __pairAreaWithLabel(self, chosenAreas, defaultEditAreas): # Pair the chosen edit areas with associated labels from # default list and return new list - dfEditAreas= [] + dfEditAreas = [] for area in chosenAreas: for name, label in defaultEditAreas: if area == name: @@ -620,8 +638,8 @@ class TextFormatter: def __getLatLonAreaName(self, latLonTuple): lat, lon, dim = latLonTuple name = "Ref" + '%s%s%s' % (lat, lon, dim) - name = name.replace(".","") - name = name.replace("-","") + name = name.replace(".", "") + name = name.replace("-", "") return name def getCombinations(self, combinations, argDict): @@ -635,7 +653,7 @@ class TextFormatter: newArea = self.getEditArea(editArea, argDict) if comboList.index(editArea) == 0: comboNumber = self.getComboNumber() - label = "Combo"+`comboNumber` + label = "Combo" + `comboNumber` refId = ReferenceID(label) #global GridLoc #GridLoc = newArea.getGloc() @@ -680,7 +698,7 @@ class TextFormatter: try: product = argDict["self"] - exec "fcstDef = product."+fcstName+"()" + exec "fcstDef = product." + fcstName + "()" module = argDict["module"] except: # See if fcstName is variable in imported modules e.g. MyTable = {} @@ -699,7 +717,7 @@ class TextFormatter: try: # Look for fcstName = {} # This can be removed eventually - exec "fcstDef = module."+fcstName + exec "fcstDef = module." + fcstName except: try: # Try to instantiate smart text product class @@ -750,7 +768,7 @@ class TextFormatter: def getEditArea(self, editAreaName, argDict): # Returns an AFPS.ReferenceData object given an edit area name - # as defined in the GFE + # as defined in the GFE # Apply suffix if appropriate refID = ReferenceID(editAreaName) #print "Getting edit area" @@ -779,7 +797,7 @@ class TextFormatter: return tmp def _separateByTimeZone(self, editAreaGroups, areaDictName, creationTime, - effectiveTZ = "effectiveTZ"): + effectiveTZ="effectiveTZ"): #takes the list of areas, and based on the time zones breaks #them up to ensure that each grouping using the same time zone. #areaDictName is name of the area dictionary. creationTime is the @@ -817,7 +835,7 @@ class TextFormatter: zoneTZ = localTZ tzid = localTZid #print "falling back to WFOtz: ", zoneTZ - self.log.warning("WARNING: Entry " + area + + self.log.warning("WARNING: Entry " + area + " missing from AreaDictionary. Using default time zone.") zones = tzDir.get(zoneTZ, []) @@ -835,7 +853,7 @@ class TextFormatter: elif effectiveTZ == "actualTZ": dict = tzDir else: - self.log.error("Invalid effectiveTZ for separateByTZ() " + + self.log.error("Invalid effectiveTZ for separateByTZ() " + effectiveTZ) return editAreaGroups keys = dict.keys() @@ -850,39 +868,39 @@ class TextFormatter: ################################################################# def makeSquare(lat, lon, km): " Make a list of square of given km around lat,lon" - latinc = km/222.0 - loninc = math.cos(lat/57.17) * km / 222.0 + latinc = km / 222.0 + loninc = math.cos(lat / 57.17) * km / 222.0 latTop = lat + latinc - latBottom =lat - latinc + latBottom = lat - latinc lonLeft = lon - loninc lonRight = lon + loninc points = [] - points.append(`latTop`+","+ `lonRight`) - points.append(`latTop`+","+ `lonLeft`) - points.append(`latBottom`+","+ `lonLeft`) - points.append(`latBottom`+","+`lonRight`) + points.append(`latTop` + "," + `lonRight`) + points.append(`latTop` + "," + `lonLeft`) + points.append(`latBottom` + "," + `lonLeft`) + points.append(`latBottom` + "," + `lonRight`) return points def makePoint(point): " Make a CartCoord2D from the point in format: x,y" from com.vividsolutions.jts.geom import Coordinate - ind = string.find(point,",") - latStr = point[0:ind-1] - lonStr = point[ind+1:len(point)] + ind = string.find(point, ",") + latStr = point[0:ind - 1] + lonStr = point[ind + 1:len(point)] lat = float(latStr) - lon = float(lonStr) - return Coordinate(lon,lat) + lon = float(lonStr) + return Coordinate(lon, lat) def makeArea(gridLoc, pointList, refname=None): " Make a Reference Area with a unique ReferenceID" from com.vividsolutions.jts.geom import GeometryFactory, LinearRing, Coordinate, Polygon - from com.raytheon.uf.common.dataplugin.gfe.reference import ReferenceData_CoordinateType as CoordinateType + from com.raytheon.uf.common.dataplugin.gfe.reference import ReferenceData_CoordinateType as CoordinateType geomFactory = GeometryFactory() import jep size = len(pointList) - if pointList[0] != pointList[size-1]: # closing the loop + if pointList[0] != pointList[size - 1]: # closing the loop pointList.append(pointList[0]) pointArray = jep.jarray(len(pointList), Coordinate) for i in range(len(pointList)): @@ -893,7 +911,7 @@ def makeArea(gridLoc, pointList, refname=None): polyArray[0] = poly region = geomFactory.createMultiPolygon(polyArray) if refname is None: - refname = "Ref" + getTime() + refname = "Ref" + getTime() refId = ReferenceID(refname) refData = ReferenceData(gridLoc, refId, region, CoordinateType.LATLON) # randerso: I don't think this is necessary @@ -913,8 +931,8 @@ def storeReferenceData(refSetMgr, refData, temp=True): def getTime(): "Return an ascii string for the current time without spaces or :'s" - timeStr = `time.time()` - timeStr = string.replace(timeStr,".","_") + timeStr = `time.time()` + timeStr = string.replace(timeStr, ".", "_") return timeStr def getAbsTime(timeStr): @@ -926,7 +944,7 @@ def getAbsTime(timeStr): hour = string.atoi(timeStr[9:11]) minute = string.atoi(timeStr[11:13]) - return AFPSSup.AbsTimeYMD(year,month,day,hour,minute) + return AbsTime.absTimeYMD(year, month, day, hour, minute) def usage(): print """ diff --git a/cave/build/static/linux/cave/caveUtil.sh b/cave/build/static/linux/cave/caveUtil.sh index 0930433efe..b15bf1c132 100644 --- a/cave/build/static/linux/cave/caveUtil.sh +++ b/cave/build/static/linux/cave/caveUtil.sh @@ -294,7 +294,7 @@ function logExitStatus() hostPath="$basePath/$hostName/" mkdir -p $hostPath if [ -d "$hostPath" ]; then - cp $coreFile $hostPath + mv $coreFile $hostPath fi fi } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/notification/jobs/NotificationManagerJob.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/notification/jobs/NotificationManagerJob.java index 09e372328f..e56ef77af2 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/notification/jobs/NotificationManagerJob.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/notification/jobs/NotificationManagerJob.java @@ -70,7 +70,8 @@ import com.raytheon.uf.viz.core.notification.NotificationMessage; * 05/08/08 1127 randerso Initial Creation * 09/03/08 1448 chammack Refactored notification observer interface * 04/23/13 1939 randerso Add separate connect method to allow application - * to complete initialization before connecting to JMS + * to complete initialization before connecting to JMS. + * 10/15/2013 2389 rjpeter Updated synchronization to remove session leaks. * * * @author randerso @@ -107,9 +108,10 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + result = (prime * result) + ((queryString == null) ? 0 : queryString.hashCode()); - result = prime * result + ((topic == null) ? 0 : topic.hashCode()); + result = (prime * result) + + ((topic == null) ? 0 : topic.hashCode()); return result; } @@ -156,11 +158,11 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { private static NotificationManagerJob instance; /** The observer map of topic to listeners */ - protected Map listeners; + protected final Map listeners; private Connection connection; - private boolean connected = false; + private volatile boolean connected = false; /** * Get the active subscription manager job. If one does not exist, start an @@ -191,18 +193,29 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { protected void connect(boolean notifyError) { boolean successful = true; - try { - ConnectionFactory connectionFactory = JMSConnection.getInstance() - .getFactory(); - disconnect(notifyError); + synchronized (this) { + try { + ConnectionFactory connectionFactory = JMSConnection + .getInstance().getFactory(); + disconnect(notifyError); - // Create a Connection - connection = connectionFactory.createConnection(); - connection.setExceptionListener(this); - // connection.setClientID(VizApp.getWsId().toString()); + // Create a Connection + connection = connectionFactory.createConnection(); + connection.setExceptionListener(this); + // connection.setClientID(VizApp.getWsId().toString()); - connection.start(); - connected = true; + connection.start(); + connected = true; + } catch (JMSException e) { + if (notifyError) { + statusHandler.handle(Priority.SIGNIFICANT, + "NotificationManager failed to connect.", e); + } + successful = false; + } + } + + synchronized (listeners) { for (NotificationListener listener : listeners.values()) { try { listener.setupConnection(this); @@ -216,12 +229,6 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { } } } - } catch (JMSException e) { - if (notifyError) { - statusHandler.handle(Priority.SIGNIFICANT, - "NotificationManager failed to connect.", e); - } - successful = false; } if (!successful) { @@ -229,7 +236,22 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { } } - protected void disconnect(boolean notifyError) { + /** + * Creates a new AUTO_ACKNOWLEDGE session if connected to JMS, otherwise + * returns null. + * + * @return + * @throws JMSException + */ + protected synchronized Session createSession() throws JMSException { + if (connected) { + return connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + } else { + return null; + } + } + + protected synchronized void disconnect(boolean notifyError) { if (connection != null) { try { connection.stop(); @@ -271,9 +293,11 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { new Timer().schedule(task, 5 * 1000); } - // Reset connected bool - for (NotificationListener listener : listeners.values()) { - listener.connected = false; + synchronized (listeners) { + // disconnect listeners + for (NotificationListener listener : listeners.values()) { + listener.disconnect(); + } } if (e != null) { @@ -282,33 +306,38 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { } } - public static synchronized void addQueueObserver(String queue, - INotificationObserver obs) { + public static void addQueueObserver(String queue, INotificationObserver obs) { addQueueObserver(queue, obs, null); } - public static synchronized void addQueueObserver(String queue, + public static void addQueueObserver(String queue, INotificationObserver obs, String queryString) { NotificationManagerJob notifMgr = getInstance(); ListenerKey key = new ListenerKey(queue, queryString); - NotificationListener listener = notifMgr.listeners.get(key); - if (listener == null || listener.consumer == null) { - try { - listener = new NotificationListener(queue, queryString, - Type.QUEUE); - notifMgr.listeners.put(key, listener); - listener.addObserver(obs); - if (notifMgr.connected) { - listener.setupConnection(notifMgr); + + synchronized (notifMgr.listeners) { + NotificationListener listener = notifMgr.listeners.get(key); + if (listener == null) { + try { + listener = new NotificationListener(queue, queryString, + Type.QUEUE); + notifMgr.listeners.put(key, listener); + listener.addObserver(obs); + if (notifMgr.connected) { + listener.setupConnection(notifMgr); + } + } catch (JMSException e) { + Status s = new Status( + IStatus.ERROR, + Activator.PLUGIN_ID, + 0, + "NotificationManager failed to create queue consumer.", + e); + StatusManager.getManager().handle(s); } - } catch (JMSException e) { - Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, - "NotificationManager failed to create queue consumer.", - e); - StatusManager.getManager().handle(s); + } else { + listener.addObserver(obs); } - } else { - listener.addObserver(obs); } } @@ -320,32 +349,35 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { * @param obs * the alert observer callback */ - public static synchronized void addObserver(String topic, - INotificationObserver obs) { + public static void addObserver(String topic, INotificationObserver obs) { addObserver(topic, obs, null); } - public static synchronized void addObserver(String topic, - INotificationObserver obs, String queryString) { + public static void addObserver(String topic, INotificationObserver obs, + String queryString) { NotificationManagerJob notifMgr = getInstance(); ListenerKey key = new ListenerKey(topic, queryString); - NotificationListener listener = notifMgr.listeners.get(key); - if (listener == null) { - try { - listener = new NotificationListener(topic, queryString, - Type.TOPIC); - notifMgr.listeners.put(key, listener); - listener.addObserver(obs); - if (notifMgr.connected) { - listener.setupConnection(notifMgr); + + synchronized (notifMgr.listeners) { + NotificationListener listener = notifMgr.listeners.get(key); + if (listener == null) { + try { + listener = new NotificationListener(topic, queryString, + Type.TOPIC); + notifMgr.listeners.put(key, listener); + listener.addObserver(obs); + if (notifMgr.connected) { + listener.setupConnection(notifMgr); + } + } catch (JMSException e) { + Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, + 0, + "NotificationManager failed to create consumer.", e); + StatusManager.getManager().handle(s); } - } catch (JMSException e) { - Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, - "NotificationManager failed to create consumer.", e); - StatusManager.getManager().handle(s); + } else { + listener.addObserver(obs); } - } else { - listener.addObserver(obs); } } @@ -358,8 +390,7 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { * @param obs * the observer to remove */ - public static synchronized void removeObserver(String topic, - INotificationObserver obs) { + public static void removeObserver(String topic, INotificationObserver obs) { removeObserver(topic, obs, null); } @@ -373,18 +404,20 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { * the observer to remove * @param queryString */ - public static synchronized void removeObserver(String topic, - INotificationObserver obs, String queryString) { + public static void removeObserver(String topic, INotificationObserver obs, + String queryString) { NotificationManagerJob notifMgr = getInstance(); ListenerKey key = new ListenerKey(topic, queryString); - NotificationListener listener = notifMgr.listeners.get(key); - if (listener == null) { - return; - } - listener.removeObserver(obs); - if (listener.size() <= 0) { - listener.disconnect(); - notifMgr.listeners.remove(key); + synchronized (notifMgr.listeners) { + NotificationListener listener = notifMgr.listeners.get(key); + if (listener == null) { + return; + } + listener.removeObserver(obs); + if (listener.size() <= 0) { + listener.disconnect(); + notifMgr.listeners.remove(key); + } } } @@ -397,18 +430,20 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { * @param obs * the observer to remove */ - public static synchronized void removeQueueObserver(String queue, - String queryString, INotificationObserver obs) { + public static void removeQueueObserver(String queue, String queryString, + INotificationObserver obs) { NotificationManagerJob notifMgr = getInstance(); ListenerKey key = new ListenerKey(queue, queryString); - NotificationListener listener = notifMgr.listeners.get(key); - if (listener == null) { - return; - } - listener.removeObserver(obs); - if (listener.size() <= 0) { - listener.disconnect(); - notifMgr.listeners.remove(key); + synchronized (notifMgr.listeners) { + NotificationListener listener = notifMgr.listeners.get(key); + if (listener == null) { + return; + } + listener.removeObserver(obs); + if (listener.size() <= 0) { + listener.disconnect(); + notifMgr.listeners.remove(key); + } } } @@ -428,24 +463,22 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { private static class NotificationListener implements MessageListener { - private Type type; + private final Type type; - private String id; + private final String id; - private String queryString; + private final String queryString; /** The list of interested parties */ - protected List observers; + protected final List observers; /** The map of job threads from observers */ - protected Map jobWrappers; + protected final Map jobWrappers; protected MessageConsumer consumer; protected Session session; - protected boolean connected = false; - public NotificationListener(String id, String queryString, Type type) { this.observers = new ArrayList(); this.jobWrappers = new HashMap(); @@ -466,40 +499,34 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { break; } } - // If we made it here we are good - connected = true; } - public void disconnect() { - if (connected) { - if (consumer != null) { - try { - consumer.close(); - } catch (JMSException e) { - statusHandler.handle(Priority.PROBLEM, - "Error closing consumer connection", e); - } - consumer = null; + public synchronized void disconnect() { + if (consumer != null) { + try { + consumer.close(); + } catch (JMSException e) { + statusHandler.handle(Priority.PROBLEM, + "Error closing consumer connection", e); } + consumer = null; + } - if (session != null) { - try { - session.close(); - } catch (JMSException e) { - statusHandler.handle(Priority.PROBLEM, - "Error closing session", e); - } - session = null; + if (session != null) { + try { + session.close(); + } catch (JMSException e) { + statusHandler.handle(Priority.PROBLEM, + "Error closing session", e); } - connected = false; + session = null; } } - private void setupQueue(NotificationManagerJob manager) + private synchronized void setupQueue(NotificationManagerJob manager) throws JMSException { disconnect(); - session = manager.connection.createSession(false, - Session.AUTO_ACKNOWLEDGE); + session = manager.createSession(); if (session != null) { String queueName = id; Queue t = session.createQueue(queueName); @@ -510,16 +537,14 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { consumer = session.createConsumer(t); } - setConsumer(consumer); consumer.setMessageListener(this); } } - private void setupTopic(NotificationManagerJob manager) + private synchronized void setupTopic(NotificationManagerJob manager) throws JMSException { disconnect(); - session = manager.connection.createSession(false, - Session.AUTO_ACKNOWLEDGE); + session = manager.createSession(); if (session != null) { String topicName = id; Topic t = session.createTopic(topicName); @@ -534,10 +559,6 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { } } - public void setConsumer(MessageConsumer consumer) { - this.consumer = consumer; - } - /* * (non-Javadoc) * @@ -545,48 +566,37 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { */ @Override public void onMessage(Message msg) { - if (observers == null) { - return; - } - - for (INotificationObserver obs : observers) { - sendToObserver(obs, msg); - } - - // Iterator iterator = jobWrappers.values().iterator(); - // while (iterator.hasNext()) { - // JobWrapper wrapper = iterator.next(); - // if (!wrapper.isEmpty() && wrapper.getState() != Job.RUNNING) { - // wrapper.schedule(); - // } - // } - } - - public synchronized void addObserver(INotificationObserver obs) { - observers.add(obs); - } - - public synchronized void removeObserver(INotificationObserver obs) { - observers.remove(obs); - } - - protected void sendToObserver(INotificationObserver observer, - Message msg) { - // Get the corresponding job, creating the - // wrapper if necessary - JobWrapper wrapper = null; - synchronized (this) { - wrapper = jobWrappers.get(observer); - if (wrapper == null) { - wrapper = new JobWrapper(observer); - jobWrappers.put(observer, wrapper); + synchronized (observers) { + for (INotificationObserver obs : observers) { + // Get the corresponding job, creating the + // wrapper if necessary, really on observers lock for sync + // purposes + JobWrapper wrapper = jobWrappers.get(obs); + if (wrapper == null) { + wrapper = new JobWrapper(obs); + jobWrappers.put(obs, wrapper); + } + wrapper.put(msg); } } - wrapper.put(msg); + } + + public void addObserver(INotificationObserver obs) { + synchronized (observers) { + observers.add(obs); + } + } + + public void removeObserver(INotificationObserver obs) { + synchronized (observers) { + observers.remove(obs); + } } public int size() { - return observers.size(); + synchronized (observers) { + return observers.size(); + } } } @@ -669,7 +679,7 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { if (messageCount.incrementAndGet() > IN_MEM_MESSAGE_LIMIT) { messageCount.decrementAndGet(); messages.remove(); - if (System.currentTimeMillis() - lastErrorPrintTime > 600000) { + if ((System.currentTimeMillis() - lastErrorPrintTime) > 600000) { final Status s = new Status( Status.ERROR, Activator.PLUGIN_ID, @@ -683,15 +693,6 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { this.schedule(); } - /** - * Checks if is empty. - * - * @return true, if is empty - */ - public boolean isEmpty() { - return this.messages.isEmpty(); - } - } /* @@ -701,9 +702,12 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable { */ @Override public void dispose() { - for (NotificationListener listener : listeners.values()) { - listener.disconnect(); + synchronized (listeners) { + for (NotificationListener listener : listeners.values()) { + listener.disconnect(); + } + listeners.clear(); } - listeners.clear(); + disconnect(true); } } diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java index 419d1c11df..db32e1ef6a 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java @@ -225,6 +225,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * 11/05/2012 15477 zhao Trim blank lines in text in Editor when check Syntax * 01/09/2013 15528 zhao Modified saveFile() and restoreFile() * 10/24/2013 16478 zhao add syntax check for extra '=' sign + * 02/12/2014 17076 lvenable Mark guidance tabs as not current so they get refreshed * * * @@ -672,6 +673,10 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, populateTafViewer(); // Update the metar and mos guidance in the viewer tab. updateViewerTab(stationName); + + // Mark the tabs as not current so they get updated. + markTabsAsNotCurrent(); + break; case OPEN_RTN: @@ -767,7 +772,19 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, } } - @Override + + /** + * Mark the tabs as not current so they get refreshed. + */ + private void markTabsAsNotCurrent() { + for (TabItem tbi : guidanceViewerFolder.getItems()) { + if (tbi.getControl() instanceof ViewerTab) { + ((ViewerTab) tbi.getControl()).setDisplayCurrent(false); + } + } + } + + @Override public void clearAll() { if (shell == null) { return; diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java index 3b008d4387..81761361f2 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java @@ -28,6 +28,7 @@ import java.util.Set; import java.util.TimeZone; import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuAdapter; @@ -97,6 +98,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * up warnings. * May 15, 2013 1842 dgilling Pass DataManager instance down to sub- * components. + * Feb 12, 2014 2801 randerso Added prompting if formatter is run against non-normal database * * * @@ -106,6 +108,12 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; public class FormatterLauncherDialog extends CaveJFACEDialog implements IProductTab { + + // formatter data sources. Fcst must be first + private static enum FormatterDataSource { + Fcst, ISC, Official, Default, + } + private final transient IUFStatusHandler statusHandler = UFStatus .getHandler(FormatterLauncherDialog.class); @@ -161,24 +169,9 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements private Image failedImg; /** - * Fcst data source menu item. + * data source menu items */ - private MenuItem fcstMI = null; - - /** - * Official data source menu item. - */ - private MenuItem officialMI = null; - - /** - * ISC data source menu item. - */ - private MenuItem iscMI = null; - - /** - * Default data source menu item. - */ - private MenuItem defaultMI = null; + private java.util.List dataSourceMI; /** * Products menu. @@ -212,8 +205,6 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements private DataManager dataMgr; - private String selectedDataSource = null; - private boolean doClose = false; /** @@ -338,59 +329,47 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements // Get the CAVE operating mode CAVEMode mode = dataMgr.getOpMode(); - // Forecast menu item, set text based on operating mode - fcstMI = new MenuItem(dataSourceMenu, SWT.RADIO); - if (mode.equals(CAVEMode.OPERATIONAL)) { - fcstMI.setText("Fcst"); - } else if (mode.equals(CAVEMode.PRACTICE)) { - fcstMI.setText("Fcst_Prac"); - fcstMI.setSelection(true); - } else { - fcstMI.setText("Fcst_Test"); - fcstMI.setSelection(true); - } - fcstMI.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - selectedDataSource = dataMgr.getParmManager() - .getMutableDatabase().toString(); + this.dataSourceMI = new ArrayList(); + // create menu items + for (FormatterDataSource source : FormatterDataSource.values()) { + MenuItem item = new MenuItem(dataSourceMenu, SWT.RADIO); + item.setData(source); + this.dataSourceMI.add(item); + String text = source.toString(); + if (source.equals(FormatterDataSource.Fcst)) { + if (mode.equals(CAVEMode.PRACTICE)) { + text += "_Prac"; + } else if (mode.equals(CAVEMode.TEST)) { + text += "_Test"; + } } - }); + item.setText(text); + item.addSelectionListener(new SelectionAdapter() { - // Only show these menu items when in operational mode - if (mode.equals(CAVEMode.OPERATIONAL)) { - // ISC menu item - iscMI = new MenuItem(dataSourceMenu, SWT.RADIO); - iscMI.setText("ISC"); - iscMI.addSelectionListener(new SelectionAdapter() { @Override - public void widgetSelected(SelectionEvent event) { - getIscDataSource(); + public void widgetSelected(SelectionEvent e) { + MenuItem item = (MenuItem) e.getSource(); + if (item.getSelection()) { + statusHandler.handle( + Priority.EVENTB, + "User selected formatter data source: " + + item.getText()); + } } }); - // Official menu item - officialMI = new MenuItem(dataSourceMenu, SWT.RADIO); - officialMI.setText("Official"); - officialMI.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - selectedDataSource = getOfficialDataSource(); - } - }); + if (!mode.equals(CAVEMode.OPERATIONAL)) { + item.setSelection(true); + statusHandler.handle(Priority.EVENTB, + "Formatter default data source: " + item.getText()); + break; + } - // Default menu item - defaultMI = new MenuItem(dataSourceMenu, SWT.RADIO); - defaultMI.setText("Default"); - defaultMI.setSelection(true); - defaultMI.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - } - }); - } else { - selectedDataSource = dataMgr.getParmManager().getMutableDatabase() - .toString(); + if (source.equals(FormatterDataSource.Default)) { + item.setSelection(true); + statusHandler.handle(Priority.EVENTB, + "Formatter default data source: " + item.getText()); + } } } @@ -731,32 +710,108 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements * The name of the product * @return The data source */ - public String getSelectedDataSource(String productName) { - if (fcstMI.getSelection()) { - selectedDataSource = getFcstDataSource(); - } else if (iscMI.getSelection()) { - selectedDataSource = getIscDataSource(); - } else if (officialMI.getSelection()) { - selectedDataSource = getOfficialDataSource(); - } else { - // Default value - ProductDefinition prodDef = textProductMgr - .getProductDefinition(productName); - String dataSource = (String) prodDef.get("database"); - if (dataSource == null) { - dataSource = "Official"; - } - - if (dataSource.equals("ISC")) { - selectedDataSource = getIscDataSource(); - } else if (dataSource.equals("Official")) { - selectedDataSource = getOfficialDataSource(); - } else { - selectedDataSource = getFcstDataSource(); + public DatabaseID getSelectedDataSource(String productName) { + FormatterDataSource menuDataSource = FormatterDataSource.Default; + for (MenuItem item : dataSourceMI) { + if (item.getSelection()) { + menuDataSource = (FormatterDataSource) item.getData(); + break; } } - return selectedDataSource; + // Default value + ProductDefinition prodDef = textProductMgr + .getProductDefinition(productName); + String dbString = (String) prodDef.get("database"); + FormatterDataSource productDataSource; + if (dbString == null) { + productDataSource = FormatterDataSource.Default; + } else { + try { + productDataSource = FormatterDataSource.valueOf(dbString); + } catch (IllegalArgumentException e) { + StringBuilder msg = new StringBuilder(); + msg.append("The "); + msg.append(productName); + msg.append(" product definition contains an invalid database selection: \""); + msg.append(dbString); + msg.append("\". Valid values are: ["); + for (FormatterDataSource src : FormatterDataSource.values()) { + if (!src.equals(FormatterDataSource.Default)) { + msg.append(src).append(", "); + } + } + msg.delete(msg.length() - 2, msg.length()); + msg.append("]"); + statusHandler.error(msg.toString()); + return null; + } + } + + FormatterDataSource dataSource; + if (menuDataSource.equals(FormatterDataSource.Default)) { + if (productDataSource.equals(FormatterDataSource.Default)) { + dataSource = FormatterDataSource.Official; + } else { + dataSource = productDataSource; + } + } else { + dataSource = menuDataSource; + } + + if (!productDataSource.equals(FormatterDataSource.Default)) { + if (!dataSource.equals(productDataSource)) { + // A check should be made that a hazard formatter is actually + // being run on the database specified in the Local or + // Definition file (Definition["database"] entry). If the + // database being run is different, provide a warning to the + // forecaster that requires acknowledgment before running. + MessageDialog dlg = new MessageDialog(getShell(), + "Confirm Data Source", null, + "The product definition indicates the " + productName + + " formatter should be run against the " + + productDataSource + + " database, but you have selected the " + + dataSource + + " database.\n\nDo you wish to continue?", + MessageDialog.WARNING, new String[] { "Yes", "No" }, 1); + int retVal = dlg.open(); + if (retVal != 0) { + dataSource = null; + } + } + } else { + if (dataSource.equals(FormatterDataSource.ISC)) { + // If the database is not explicitly defined (default), provide + // a a warning to the forecaster that requires acknowledgment + // before running if the database being used is ISC + MessageDialog dlg = new MessageDialog( + getShell(), + "Confirm Data Source", + null, + "You are about to run the " + + productName + + " formatter against the ISC database.\n\nDo you wish to continue?", + MessageDialog.WARNING, new String[] { "Yes", "No" }, 1); + int retVal = dlg.open(); + if (retVal != 0) { + dataSource = null; + } + } + } + + DatabaseID selectedDbId; + if (dataSource == null) { + selectedDbId = null; + } else if (dataSource.equals(FormatterDataSource.ISC)) { + selectedDbId = getIscDataSource(); + } else if (dataSource.equals(FormatterDataSource.Official)) { + selectedDbId = getOfficialDataSource(); + } else { + selectedDbId = getFcstDataSource(); + } + + return selectedDbId; } /** @@ -1009,8 +1064,8 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements * * @return The FcstDataSource */ - private String getFcstDataSource() { - return dataMgr.getParmManager().getMutableDatabase().toString(); + private DatabaseID getFcstDataSource() { + return dataMgr.getParmManager().getMutableDatabase(); } /** @@ -1021,13 +1076,13 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements * * @return The ISC Data Source */ - private String getIscDataSource() { + private DatabaseID getIscDataSource() { java.util.List dbs = dataMgr.getParmManager() .getIscDatabases(); if (dbs.size() > 0) { // Always return the last one in the list - return dbs.get(dbs.size() - 1).toString(); + return dbs.get(dbs.size() - 1); } return null; @@ -1038,12 +1093,12 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements * * @return The Official Data source */ - private String getOfficialDataSource() { - String source = null; + private DatabaseID getOfficialDataSource() { + DatabaseID source = null; try { ServerResponse> sr = dataMgr.getClient() .getOfficialDBName(); - source = sr.getPayload().get(0).toString(); + source = sr.getPayload().get(0); } catch (GFEServerException e) { statusHandler.handle(Priority.PROBLEM, "Unable to determine official db", e); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java index ac377cd260..2f16d0d691 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java @@ -34,6 +34,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.TabFolder; +import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.core.DataManager; import com.raytheon.viz.gfe.dialogs.FormatterLauncherDialog; @@ -64,6 +65,8 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager; * 05 SEP 2013 2329 randerso Added call to ZoneCombinerComp.applyZoneCombo when * when run formatter button is clicked. * 05 FEB 2014 2591 randerso Added dataManager to ZoneCombinerComp constructor + * Passed dataMgr instance to FormatterUtil.runFormatterScript + * 12 FEB 2014 2801 randerso Added prompting if formatter is run against non-normal database * * * @@ -365,36 +368,37 @@ public class ProductAreaComp extends Composite implements productEditorBtnSelected(); if (okToLoseText()) { - productEditorComp.clearProductText(); - abortFormatterBtn.setEnabled(true); - // closeTabBtn.setEnabled(false); - runFormatterBtn.setEnabled(false); - String vtecMode = ""; - if (formattingCbo.isVisible()) { - vtecMode = formattingCbo.getText(); - } else { - int hazIndex = productName.indexOf("Hazard_"); - if (hazIndex > -1) { - String category = productName.substring( - hazIndex + 7, hazIndex + 10); - vtecMode = textProductMgr - .getVtecMessageType(category); - if (vtecMode == null) { - vtecMode = ""; + DatabaseID dbId = ((FormatterLauncherDialog) productTabCB) + .getSelectedDataSource(productName); + + if (dbId != null) { + productEditorComp.clearProductText(); + abortFormatterBtn.setEnabled(true); + // closeTabBtn.setEnabled(false); + runFormatterBtn.setEnabled(false); + String vtecMode = ""; + if (formattingCbo.isVisible()) { + vtecMode = formattingCbo.getText(); + } else { + int hazIndex = productName.indexOf("Hazard_"); + if (hazIndex > -1) { + String category = productName.substring( + hazIndex + 7, hazIndex + 10); + vtecMode = textProductMgr + .getVtecMessageType(category); + if (vtecMode == null) { + vtecMode = ""; + } } } - } - // Check the data source menus, if one is selected then - // use - // it, else use the default - String dbId = null; - zoneCombiner.applyZoneCombo(); - dbId = ((FormatterLauncherDialog) productTabCB) - .getSelectedDataSource(productName); - FormatterUtil.runFormatterScript(textProductMgr, - productName, dbId, vtecMode, - ProductAreaComp.this); + // Get the source database + zoneCombiner.applyZoneCombo(); + FormatterUtil.runFormatterScript(dataMgr, + textProductMgr, productName, + dbId.toString(), vtecMode, + ProductAreaComp.this); + } } } }); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java index e0a9f44252..34b0b9ecbb 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java @@ -22,6 +22,7 @@ package com.raytheon.viz.gfe.textformatter; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -219,12 +220,18 @@ public class CombinationsFileUtil { // retrieve combinations file if it's changed LocalizationFile lf = pm.getStaticLocalizationFile(FileUtil.join( COMBO_DIR_PATH, comboName + ".py")); - File pyFile; - try { - pyFile = lf.getFile(true); - } catch (LocalizationException e) { - throw new GfeException("Error retrieving combinations file: " - + comboName, e); + File pyFile = null; + if (lf != null) { + try { + pyFile = lf.getFile(true); + } catch (LocalizationException e) { + throw new GfeException("Error retrieving combinations file: " + + comboName, e); + } + } + + if (pyFile == null || !pyFile.exists()) { + return Collections.emptyList(); } LocalizationContext baseContext = pm.getContext( diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java index 1d0915d84f..9cb65090f9 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java @@ -24,7 +24,6 @@ import java.util.TimeZone; 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.time.TimeRange; import com.raytheon.viz.core.mode.CAVEMode; @@ -42,6 +41,8 @@ import com.raytheon.viz.gfe.tasks.TaskManager; * Sep 8, 2008 njensen Initial creation * Jan 15, 2010 3395 ryu Fix "issued by" functionality * Sep 05, 2013 2329 randerso Removed save of combinations file + * Feb 12, 2014 2591 randerso Passed dataMgr instance to FormatterUtil.runFormatterScript + * Removed call to TextProductManager.reloadModule * * * @@ -59,6 +60,9 @@ public class FormatterUtil { /** * Runs a text formatter script for a given product * + * @param dataMgr + * the DataManager instance to use + * * @param productMgr * the formatter instance to use * @param productName @@ -70,22 +74,12 @@ public class FormatterUtil { * @param finish * listener to fire when formatter finishes generating product */ - public static void runFormatterScript(TextProductManager productMgr, - String productName, String dbId, String vtecMode, - TextProductFinishListener finish) { - try { - String filename = productMgr.getCombinationsFileName(productName); - boolean mapRequired = productMgr.mapRequired(productName); - if (filename != null && mapRequired) { - productMgr.reloadModule(filename); - } - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, - "Cannot generate combinations file", e); - } + public static void runFormatterScript(DataManager dataMgr, + TextProductManager productMgr, String productName, String dbId, + String vtecMode, TextProductFinishListener finish) { int testMode = 0; - if (DataManager.getCurrentInstance().getOpMode().equals(CAVEMode.TEST)) { + if (dataMgr.getOpMode().equals(CAVEMode.TEST)) { testMode = 1; } @@ -106,8 +100,7 @@ public class FormatterUtil { } String name = productMgr.getModuleName(productName); - String varDict = productMgr.getVarDict(productName, - DataManager.getCurrentInstance(), dbId); + String varDict = productMgr.getVarDict(productName, dataMgr, dbId); if (varDict != null) { // run the formatter with the normal active table diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/TextProductManager.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/TextProductManager.java index 339d416024..b18878c0a6 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/TextProductManager.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/TextProductManager.java @@ -55,9 +55,10 @@ import com.raytheon.viz.gfe.core.DataManager; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * May 1, 2009 njensen Initial creation - * Jan 15, 2010 3395 ryu Fix "issued by" functionality - * Apr 24, 2013 1936 dgilling Remove unused imports. + * May 1, 2009 njensen Initial creation + * Jan 15, 2010 3395 ryu Fix "issued by" functionality + * Apr 24, 2013 1936 dgilling Remove unused imports. + * Feb 12, 2014 2591 randerso Removed reloadModule method * * * @@ -269,17 +270,6 @@ public class TextProductManager { return mapName; } - protected void reloadModule(String moduleName) { - Map args = new HashMap(1); - args.put("moduleName", moduleName); - try { - script.execute("reloadModule", args); - } catch (JepException e) { - statusHandler.handle(Priority.PROBLEM, - "Exception reloading module " + moduleName, e); - } - } - public void setIssuedBy(String issuedBy) { if (LocalizationManager.getInstance().getCurrentSite().equals(issuedBy)) { this.issuedBy = ""; diff --git a/edexOsgi/build.edex/esb/conf/log4j-ingest.xml b/edexOsgi/build.edex/esb/conf/log4j-ingest.xml index 8640e52fe9..e3ed1f4bdb 100644 --- a/edexOsgi/build.edex/esb/conf/log4j-ingest.xml +++ b/edexOsgi/build.edex/esb/conf/log4j-ingest.xml @@ -2,7 +2,7 @@ - + @@ -169,7 +169,7 @@ - + diff --git a/edexOsgi/build.edex/esb/conf/log4j-registry.xml b/edexOsgi/build.edex/esb/conf/log4j-registry.xml index e8715acd76..bb89704cf8 100644 --- a/edexOsgi/build.edex/esb/conf/log4j-registry.xml +++ b/edexOsgi/build.edex/esb/conf/log4j-registry.xml @@ -64,7 +64,7 @@ - + diff --git a/edexOsgi/build.edex/esb/conf/log4j.xml b/edexOsgi/build.edex/esb/conf/log4j.xml index 553ebc2b0b..a8edd563ce 100644 --- a/edexOsgi/build.edex/esb/conf/log4j.xml +++ b/edexOsgi/build.edex/esb/conf/log4j.xml @@ -2,7 +2,7 @@ - + diff --git a/edexOsgi/build.edex/esb/conf/modes.xml b/edexOsgi/build.edex/esb/conf/modes.xml index 35b803374d..04e4ad1713 100644 --- a/edexOsgi/build.edex/esb/conf/modes.xml +++ b/edexOsgi/build.edex/esb/conf/modes.xml @@ -120,10 +120,11 @@ shef-ingest.xml persist-ingest.xml obs-common.xml - obs-ingest.xml - metartohmdb-plugin.xml - pointdata-common.xml + obs-ingest.xml + metartohmdb-plugin.xml + pointdata-common.xml shef-common.xml + ohd-common-database.xml ohd-common.xml alarmWhfs-spring.xml arealffgGenerator-spring.xml @@ -148,6 +149,7 @@ fssobs-common.xml + ohd-common-database.xml ohd-common.xml database-common.xml ohd-request.xml @@ -232,6 +234,7 @@ shef-common.xml satellite-common.xml satellite-dataplugin-common.xml + ohd-common-database.xml ohd-common.xml management-common.xml auth-common.xml diff --git a/edexOsgi/build.edex/esb/conf/spring/edex.xml b/edexOsgi/build.edex/esb/conf/spring/edex.xml index 3d741415d7..0bf8d7cdc6 100644 --- a/edexOsgi/build.edex/esb/conf/spring/edex.xml +++ b/edexOsgi/build.edex/esb/conf/spring/edex.xml @@ -14,33 +14,30 @@ - + - - - - - + + - - + + - + - + @@ -66,13 +63,13 @@ - + - + - + diff --git a/edexOsgi/com.raytheon.edex.plugin.airep/res/spring/airep-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.airep/res/spring/airep-ingest.xml index a757baaf8e..010872c7d2 100644 --- a/edexOsgi/com.raytheon.edex.plugin.airep/res/spring/airep-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.airep/res/spring/airep-ingest.xml @@ -12,7 +12,7 @@ - + - + - + - + - + - + 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 b296dc27ba..e77af0d0cb 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 @@ -460,17 +460,11 @@ - - - - - - - - + class="com.raytheon.uf.edex.esb.camel.spring.JmsThreadPoolTaskExecutor"> + + + - - - - - - - - - @@ -584,7 +567,7 @@ - + @@ -623,7 +606,7 @@ - + @@ -643,7 +626,7 @@ errorHandlerRef="errorHandler" autoStartup="false"> - + 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 0f267bc501..a0faa56337 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 @@ -4,16 +4,10 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - - - - - + + @@ -93,7 +87,7 @@ - + @@ -104,7 +98,7 @@ - + @@ -117,7 +111,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendQueue.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendQueue.java index a28fd672d0..8930f626f1 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendQueue.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendQueue.java @@ -59,9 +59,10 @@ import com.raytheon.uf.edex.database.dao.DaoConfig; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Oct 20, 2011 dgilling Initial creation - * May 08, 2012 #600 dgilling Re-work logic for handling PENDING - * records. + * Oct 20, 2011 dgilling Initial creation + * May 08, 2012 600 dgilling Re-work logic for handling PENDING + * records. + * Feb 07, 2014 2357 rjpeter iscSendNotification uri. * * * @@ -74,9 +75,9 @@ public class IscSendQueue { // how we'll organize the temporary queue private class JobSetQueueKey { - private ParmID pid; + private final ParmID pid; - private IscSendState state; + private final IscSendState state; public JobSetQueueKey(ParmID pid, IscSendState state) { this.pid = pid; @@ -92,8 +93,9 @@ public class IscSendQueue { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((pid == null) ? 0 : pid.hashCode()); - result = prime * result + ((state == null) ? 0 : state.hashCode()); + result = (prime * result) + ((pid == null) ? 0 : pid.hashCode()); + result = (prime * result) + + ((state == null) ? 0 : state.hashCode()); return result; } @@ -148,7 +150,7 @@ public class IscSendQueue { private int timeoutMillis = 60000; - private Map> jobSet = new HashMap>(); + private final Map> jobSet = new HashMap>(); private static final IscSendQueue instance = new IscSendQueue(); @@ -168,7 +170,7 @@ public class IscSendQueue { try { byte[] messages = SerializationUtil.transformToThrift(sendJobs); EDEXUtil.getMessageProducer().sendAsyncUri( - "jms-iscsend:queue:iscSendNotification", messages); + "jms-durable:queue:iscSendNotification", messages); } catch (SerializationException e) { handler.error("Unable to serialize IscSendRecords.", e); } catch (EdexException e) { @@ -238,7 +240,7 @@ public class IscSendQueue { // Now combine time ranges if we can int i = 0; - while (i <= pending.size() - 2) { + while (i <= (pending.size() - 2)) { TimeRange time = pending.get(i).getTimeRange(); TimeRange time1 = pending.get(i + 1).getTimeRange(); diff --git a/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml index 25158070e6..5f7aa56c3c 100644 --- a/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml @@ -12,7 +12,7 @@ - + - - - - - - - - - - @@ -58,7 +46,7 @@ autoStartup="false"> - + @@ -67,7 +55,7 @@ grid - + @@ -108,7 +96,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/res/spring.future/grib-decode.xml b/edexOsgi/com.raytheon.edex.plugin.grib/res/spring.future/grib-decode.xml index 3c36fb0ed9..6e39cd4665 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/res/spring.future/grib-decode.xml +++ b/edexOsgi/com.raytheon.edex.plugin.grib/res/spring.future/grib-decode.xml @@ -5,18 +5,6 @@ - - - - - - - - - - @@ -54,7 +42,7 @@ autoStartup="false"> - + @@ -63,7 +51,7 @@ grid - + @@ -99,7 +87,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/res/spring/grib-distribution.xml b/edexOsgi/com.raytheon.edex.plugin.grib/res/spring/grib-distribution.xml index be6ad0a4f3..bea7cd0041 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/res/spring/grib-distribution.xml +++ b/edexOsgi/com.raytheon.edex.plugin.grib/res/spring/grib-distribution.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.ldad/res/spring/ldad-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.ldad/res/spring/ldad-ingest.xml index 6c33246a98..84ae50fe1e 100644 --- a/edexOsgi/com.raytheon.edex.plugin.ldad/res/spring/ldad-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.ldad/res/spring/ldad-ingest.xml @@ -8,7 +8,7 @@ - + - + diff --git a/edexOsgi/com.raytheon.edex.plugin.ldadmanual/res/spring/ldadmanual-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.ldadmanual/res/spring/ldadmanual-ingest.xml index 08bb3d9182..7d21714988 100644 --- a/edexOsgi/com.raytheon.edex.plugin.ldadmanual/res/spring/ldadmanual-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.ldadmanual/res/spring/ldadmanual-ingest.xml @@ -12,7 +12,7 @@ - + - + - + - + - + - + - + - - - - - - - - - - + - + - + radar - + --> - + radar-sbn @@ -61,7 +50,7 @@ - + radar-local diff --git a/edexOsgi/com.raytheon.edex.plugin.recco/res/spring/recco-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.recco/res/spring/recco-ingest.xml index 2ef0c4dbe6..7ab29724e2 100644 --- a/edexOsgi/com.raytheon.edex.plugin.recco/res/spring/recco-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.recco/res/spring/recco-ingest.xml @@ -12,7 +12,7 @@ - + - + - + satellite diff --git a/edexOsgi/com.raytheon.edex.plugin.sfcobs/res/spring/sfcobs-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.sfcobs/res/spring/sfcobs-ingest.xml index f27a884f78..2c54b38d55 100644 --- a/edexOsgi/com.raytheon.edex.plugin.sfcobs/res/spring/sfcobs-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.sfcobs/res/spring/sfcobs-ingest.xml @@ -13,7 +13,7 @@ - + - - - - - - - - - - @@ -47,13 +35,13 @@ factory-method="register"> + value="jms-durable:queue:Ingest.Shef"/> - + + uri="jms-durable:queue:Ingest.Shef"/> shef @@ -103,7 +91,7 @@ + uri="jms-durable:queue:Ingest.ShefStaged"/> shef @@ -155,7 +143,7 @@ + uri="jms-durable:queue:Ingest.ShefManual"/> shef diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/AlertalarmStdTextProductUtil.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/AlertalarmStdTextProductUtil.java index f30156189e..1a6c51132a 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/AlertalarmStdTextProductUtil.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/AlertalarmStdTextProductUtil.java @@ -33,8 +33,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; -import com.raytheon.edex.textdb.dbapi.impl.TextDB; -import com.raytheon.uf.common.dataplugin.text.request.WriteProductRequest; import com.raytheon.uf.common.ohd.AppsDefaults; import com.raytheon.uf.edex.core.EDEXUtil; @@ -45,12 +43,11 @@ import com.raytheon.uf.edex.core.EDEXUtil; *
  * 
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * June 15, 2011    9377     jnjanga     Initial creation
- *  July 12, 2013   15711     wkwock      Fix verbose, observe mode, etc
- * 
- * 
+ * Date          Ticket#    Engineer    Description
+ * ------------- ---------- ----------- --------------------------
+ * Jun 15, 2011  9377       jnjanga     Initial creation.
+ * Jul 12, 2013  15711      wkwock      Fix verbose, observe mode, etc.
+ * Feb 10, 2014  2781       rjpeter     Removed dead method.
  * 
* * @author jnjanga @@ -88,7 +85,7 @@ public class AlertalarmStdTextProductUtil { setCurrentReportfile(); reportAlarm(); - + System.exit(reportWriter.getAlarmCount()); } @@ -104,7 +101,7 @@ public class AlertalarmStdTextProductUtil { options.addOption(CmdlineOptionId.FILE_SUFFIX); options.addOption(CmdlineOptionId.FLAGS); options.addOption(CmdlineOptionId.PE); - options.addOption(CmdlineOptionId.VERBOSE,false); + options.addOption(CmdlineOptionId.VERBOSE, false); return options; } @@ -147,13 +144,14 @@ public class AlertalarmStdTextProductUtil { String optName = optId.toString(); System.out.println("optName = " + optName); if (optName.equalsIgnoreCase("v")) { - if (line.hasOption(optName)) { - System.out.println(" optValue = true"); - } else { - System.out.println(" optValue = false"); - } + if (line.hasOption(optName)) { + System.out.println(" optValue = true"); + } else { + System.out.println(" optValue = false"); + } } else { - System.out.println(" optValue = " + line.getOptionValue(optName)); + System.out.println(" optValue = " + + line.getOptionValue(optName)); } if (line.hasOption(optName)) { @@ -177,9 +175,10 @@ public class AlertalarmStdTextProductUtil { ignoreMin.add(ReportMode.NEAREST); ignoreMin.add(ReportMode.LATEST_MAXFCST); if (rptOptions.isMinutesGiven() - && ignoreMin.contains(rptOptions.getMode())) + && ignoreMin.contains(rptOptions.getMode())) { System.out .println("Usage : -m value ignored for this -r"); + } reportOptions = rptOptions; @@ -191,9 +190,11 @@ public class AlertalarmStdTextProductUtil { private static boolean hasDuplicateOptions(CommandLine line) { Option[] userOptions = line.getOptions(); Set unique = new HashSet(); - for (Option option : userOptions) - if (!unique.add(option.getOpt())) + for (Option option : userOptions) { + if (!unique.add(option.getOpt())) { return true; + } + } return false; } @@ -221,9 +222,9 @@ public class AlertalarmStdTextProductUtil { reportWriter.writeHeader(); reportWriter.writeBody(aaRecord); if (reportOptions.getVerbose()) { - reportWriter.writeVerboseTrailer(); + reportWriter.writeVerboseTrailer(); } else { - reportWriter.writeReportTrailer(); + reportWriter.writeReportTrailer(); } // save it to the text database if indeed @@ -232,7 +233,7 @@ public class AlertalarmStdTextProductUtil { if (alarmCount > 0) { log.info(alarmCount + " alarms reported, report written to " + reportWriter.getFilename()); - //saveReportTotextDb(); + // saveReportTotextDb(); } else { log.info("No alarms reported, info sent to " + reportWriter.getFilename()); @@ -241,37 +242,6 @@ public class AlertalarmStdTextProductUtil { } - /* - * saves the report contents to the text database. - */ - private static void saveReportTotextDb() { - - setApplicationSpringContext(Constants.FXA_CONFIG); - - WriteProductRequest request = new WriteProductRequest(); - request.setProductId(reportOptions.getProductId()); - request.setOperationalMode(true); - request.setNotifyAlarmAlert(true); - String rptData = reportWriter.getReportData(); - request.setReportData(rptData); - - log.info("Sending " + reportWriter.getFilename() + " to textdb as id " - + request.getProductId()); - - TextDB textdb = new TextDB(); - long result = textdb.writeProduct(request.getProductId(), - request.getReportData(), request.getOperationalMode(), null); - - if (result != Long.MIN_VALUE) { - log.info("Product " + request.getProductId() - + " successfully sent to textdb"); - } else { - log.error("Error sending product " + request.getProductId() - + " to textdb. status=" + result); - } - - } - /* * verify whether necessary application tokens have been defined. */ @@ -308,18 +278,20 @@ public class AlertalarmStdTextProductUtil { String pid = reportOptions.getProductId(); String suffix = reportOptions.getFileSuffix(); - if (suffix.length() > 0) - currReport = new File(reportDir + File.separator + pid + "." + suffix); - else + if (suffix.length() > 0) { + currReport = new File(reportDir + File.separator + pid + "." + + suffix); + } else { currReport = new File(reportDir + File.separator + pid); + } try { currReport.createNewFile(); } catch (Exception e) { - log.fatal("Could not create report file " + log.fatal("Could not create report file " + String.valueOf(currReport)); - log.info("Exiting."); - System.exit(0); + log.info("Exiting."); + System.exit(0); } } diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/Constants.java b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/Constants.java index c09f29263a..c8b0a35dbc 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/Constants.java +++ b/edexOsgi/com.raytheon.edex.plugin.shef/src/com/raytheon/edex/plugin/shef/alarms/Constants.java @@ -23,30 +23,41 @@ import java.text.SimpleDateFormat; import com.raytheon.uf.common.dataplugin.shef.util.ShefConstants; - +/** + * Constants for alert alarm. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 10, 2014 2781       rjpeter     Initial history, update IHFS_CONFIG path.
+ * 
+ * + * @author jnjanga + * @version 1.0 + */ class Constants { - + public static final SimpleDateFormat REPORT_TIME_PATTERN = new SimpleDateFormat( - "HH:mm:ss z, yyyy.MM.dd "); + "HH:mm:ss z, yyyy.MM.dd "); public static final int MISSING_VALUE_INT = ShefConstants.SHEF_MISSING_INT; - + public static final double MISSING_VALUE_DOUBLE = -9999999.87654321; public static final String NEWLINE = System.getProperty("line.separator"); - + public final static String EOL = NEWLINE; public static final String SPACE = " "; - + public static final String REPORT_ALARM_LOG = "report_alarm.log"; - + public static final String WHFS_PRODUCT_DIR = "whfs_product_dir"; - + public static final String WHFS_UTIL_LOG_DIR = "whfs_util_log_dir"; - - public static final String IHFS_CONFIG = "/res/spring/ohd-common.xml"; - - public static final String FXA_CONFIG = "/res/spring/alertalarm.xml"; - + + public static final String IHFS_CONFIG = "/res/spring/ohd-common-database.xml"; } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml index fcd1df9358..651083abdb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml @@ -9,13 +9,13 @@ - + - + * @@ -108,7 +109,6 @@ public class ChangeGroup extends PersistableDataObject implements @Id @GeneratedValue - @DynamicSerializeElement private int id; /** A String containing the change group */ @@ -912,6 +912,11 @@ public class ChangeGroup extends PersistableDataObject implements public void setTurbulence_layers(Set turbulence_layers) { this.turbulence_layers = turbulence_layers; + if ((turbulence_layers != null) && (turbulence_layers.size() > 0)) { + for (TurbulenceLayer turbulence_layer : turbulence_layers) { + turbulence_layer.setParentID(this); + } + } } public Set getIcing_layers() { @@ -920,6 +925,11 @@ public class ChangeGroup extends PersistableDataObject implements public void setIcing_layers(Set icing_layers) { this.icing_layers = icing_layers; + if ((icing_layers != null) && (icing_layers.size() > 0)) { + for (IcingLayer icing_layer : icing_layers) { + icing_layer.setParentID(this); + } + } } public Set getTemp_forecasts() { @@ -928,6 +938,11 @@ public class ChangeGroup extends PersistableDataObject implements public void setTemp_forecasts(Set temp_forecasts) { this.temp_forecasts = temp_forecasts; + if ((temp_forecasts != null) && (temp_forecasts.size() > 0)) { + for (TemperatureForecast temForecast : temp_forecasts) { + temForecast.setParentID(this); + } + } } public Set getWeather() { @@ -936,6 +951,11 @@ public class ChangeGroup extends PersistableDataObject implements public void setWeather(Set weather) { this.weather = weather; + if ((weather != null) && (weather.size() > 0)) { + for (TafWeatherCondition twc : weather) { + twc.setParentID(this); + } + } } public Set getSky_cover() { @@ -944,6 +964,11 @@ public class ChangeGroup extends PersistableDataObject implements public void setSky_cover(Set sky_cover) { this.sky_cover = sky_cover; + if ((sky_cover != null) && (sky_cover.size() > 0)) { + for (TafSkyCover tsc : sky_cover) { + tsc.setParentID(this); + } + } } private void checkGroupDataEnd(StringBuilder group) { diff --git a/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/common/TafRecord.java b/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/common/TafRecord.java index 4690840804..c658fc377a 100644 --- a/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/common/TafRecord.java +++ b/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/common/TafRecord.java @@ -69,6 +69,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * May 07, 2013 1869 bsteffen Remove dataURI column from * PluginDataObject. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 10, 2014 2777 rferrel Assign parent id when setting ChangeGroup. + * Feb 11, 2014 2784 rferrel Remove override of setIdentifier. * * * @@ -292,6 +294,11 @@ public class TafRecord extends PluginDataObject implements ISpatialEnabled { */ public void setChangeGroups(Set changeGroups) { this.changeGroups = changeGroups; + if ((changeGroups != null) && (changeGroups.size() > 0)) { + for (ChangeGroup changeGroup : changeGroups) { + changeGroup.setParentID(this); + } + } } /** @@ -339,19 +346,6 @@ public class TafRecord extends PluginDataObject implements ISpatialEnabled { this.remarks = remarks; } - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - if ((this.changeGroups != null) && (this.changeGroups.size() > 0)) { - for (ChangeGroup group : this.changeGroups) { - group.setParentID(this); - } - } - - } - /** * Get the IDecoderGettable reference for this record. * diff --git a/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml index f2c2cdc1bc..95a4a7083a 100644 --- a/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml @@ -11,13 +11,13 @@ - + - + @@ -27,18 +27,6 @@ - - - - - - - - - - @@ -118,7 +106,7 @@
- + text @@ -145,7 +133,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml index feb8c3a7a6..5f5ada5907 100644 --- a/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml @@ -9,7 +9,7 @@ - + - + - + - - - - - - - - - - - + warning @@ -67,11 +55,11 @@ - - + + - +
diff --git a/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-request.xml b/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-request.xml index 5ebc2d0a0f..12bb2fc4aa 100644 --- a/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-request.xml +++ b/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-request.xml @@ -41,12 +41,18 @@
- - - + + + - + + + + + + @@ -64,7 +70,7 @@ - +
diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.obs/src/com/raytheon/uf/common/dataplugin/obs/metar/MetarRecord.java b/edexOsgi/com.raytheon.uf.common.dataplugin.obs/src/com/raytheon/uf/common/dataplugin/obs/metar/MetarRecord.java index 173fad6ece..15caba37ac 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.obs/src/com/raytheon/uf/common/dataplugin/obs/metar/MetarRecord.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.obs/src/com/raytheon/uf/common/dataplugin/obs/metar/MetarRecord.java @@ -97,6 +97,7 @@ import com.raytheon.uf.common.time.util.TimeUtil; * May 07, 2013 1869 bsteffen Remove dataURI column from * PluginDataObject. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 11, 2014 2784 rferrel Remove override of setIdentifier. * * * @author bphillip @@ -984,6 +985,11 @@ public class MetarRecord extends PersistablePluginDataObject implements */ public void setSkyCoverage(Set skyCoverage) { this.skyCoverage = skyCoverage; + if ((skyCoverage != null) && (skyCoverage.size() > 0)) { + for (SkyCover cover : skyCoverage) { + cover.setParentMetar(this); + } + } } public void addSkyCoverage(SkyCover cover) { @@ -1019,6 +1025,11 @@ public class MetarRecord extends PersistablePluginDataObject implements */ public void setWeatherCondition(List weatherCondition) { this.weatherCondition = weatherCondition; + if ((weatherCondition != null) && (weatherCondition.size() > 0)) { + for (WeatherCondition cond : weatherCondition) { + cond.setParentMetar(this); + } + } } public void addWeatherCondition(WeatherCondition condition) { @@ -1116,30 +1127,6 @@ public class MetarRecord extends PersistablePluginDataObject implements this.snowWater = snowWater; } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - // set the parentID to the dataURI for all values - if ((this.getWeatherCondition() != null) - && (this.getWeatherCondition().size() > 0)) { - for (WeatherCondition cond : this.getWeatherCondition()) { - cond.setParentMetar(this); - } - } - - // set the parentID to the dataURI for all values - if ((this.getSkyCoverage() != null) - && (this.getSkyCoverage().size() > 0)) { - for (SkyCover cover : this.getSkyCoverage()) { - cover.setParentMetar(this); - } - } - } - public String getReportType() { return reportType; } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/persist/PersistableDataObject.java b/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/persist/PersistableDataObject.java index eb55100ec0..eb5657f98e 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/persist/PersistableDataObject.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/persist/PersistableDataObject.java @@ -28,7 +28,6 @@ import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * This is the root class for any object being persisted in the database using @@ -50,6 +49,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * 7/24/07 353 bphillip Initial Check in * 20080408 1039 jkorman Added traceId for tracing data. * Oct 10, 2012 1261 djohnson Add generic for identifier. + * Feb 11, 2014 2784 rferrel Identifier no longer a DynamicSerializeElement. * * * @@ -59,8 +59,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public abstract class PersistableDataObject implements - IPersistableDataObject, - Serializable, ISerializableObject { + IPersistableDataObject, Serializable, + ISerializableObject { private static final long serialVersionUID = -6747395152869923909L; @@ -69,7 +69,6 @@ public abstract class PersistableDataObject implements * key for the associated database table. */ @XmlElement - @DynamicSerializeElement protected IDENTIFIER_TYPE identifier; private String traceId = ""; diff --git a/edexOsgi/com.raytheon.uf.common.jms/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.jms/META-INF/MANIFEST.MF index b55485d361..5677c0d2f5 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.jms/META-INF/MANIFEST.MF @@ -5,6 +5,7 @@ Bundle-SymbolicName: com.raytheon.uf.common.jms Bundle-Version: 1.12.1174.qualifier Bundle-Vendor: Raytheon Require-Bundle: javax.jms, - com.raytheon.uf.common.status + com.raytheon.uf.common.status, + org.apache.qpid Export-Package: com.raytheon.uf.common.jms Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnection.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnection.java index 27076515d6..4a806981a7 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnection.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnection.java @@ -39,7 +39,8 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * connection can be released to the pool. Any exception will close pooled * session instead of returning to the pool. The sessions are tracked in both * active and available states. An available session can be reused by the next - * client. + * client. The connection is pinned to Thread that creates the connection and + * cannot be used/reused by any other thread. * * Synchronization Principle To prevent deadlocks: Chained sync blocks can only * happen in a downward direction. A manager has a synchronized lock can make a @@ -52,9 +53,11 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 15, 2011 rjpeter Initial creation - * Mar 08, 2012 194 njensen Improved safety of close() - * Feb 21, 2013 1642 rjpeter Fix deadlock scenario + * Apr 15, 2011 rjpeter Initial creation. + * Mar 08, 2012 194 njensen Improved safety of close(). + * Feb 21, 2013 1642 rjpeter Fix deadlock scenario. + * Feb 07, 2014 2357 rjpeter Track by Thread, close session is it has no + * producers/consumers. * * * @author rjpeter @@ -86,7 +89,7 @@ public class JmsPooledConnection implements ExceptionListener { private volatile AvailableJmsPooledObject availableSession = null; - private volatile String key = null; + private final Thread thread; private final String clientId; @@ -94,8 +97,10 @@ public class JmsPooledConnection implements ExceptionListener { private volatile boolean exceptionOccurred = false; - public JmsPooledConnection(JmsPooledConnectionFactory connFactory) { + public JmsPooledConnection(JmsPooledConnectionFactory connFactory, + Thread thread) { this.connFactory = connFactory; + this.thread = thread; this.clientId = null; getConnection(); } @@ -123,7 +128,8 @@ public class JmsPooledConnection implements ExceptionListener { if (availableSession != null) { JmsPooledSession availSess = availableSession.getPooledObject(); synchronized (availSess.getStateLock()) { - if (availSess.isValid()) { + if (availSess.isValid() + && availSess.hasProducersOrConsumers()) { availSess.setState(State.InUse); session = availSess; } else { @@ -185,6 +191,7 @@ public class JmsPooledConnection implements ExceptionListener { } if (canClose) { + statusHandler.info("Closing connection: " + this.toString()); // njensen: I moved removing the connection from the pool to be // the first thing in this block instead of last thing so // there's no chance it could be closed and then retrieved from @@ -283,6 +290,8 @@ public class JmsPooledConnection implements ExceptionListener { // safe since conn is volatile synchronized (stateLock) { if (conn == null) { + statusHandler.info("Creating connection: " + + this.toString()); long exceptionLastHandled = 0; boolean connected = false; while (!connected) { @@ -298,7 +307,7 @@ public class JmsPooledConnection implements ExceptionListener { connectionStartTime = System.currentTimeMillis(); connected = true; } catch (Exception e) { - if (exceptionLastHandled + ERROR_BROADCAST_INTERVAL < System + if ((exceptionLastHandled + ERROR_BROADCAST_INTERVAL) < System .currentTimeMillis()) { exceptionLastHandled = System .currentTimeMillis(); @@ -502,12 +511,8 @@ public class JmsPooledConnection implements ExceptionListener { } } - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; + public Thread getThread() { + return thread; } /** diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnectionFactory.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnectionFactory.java index b5c5d03be7..757869d6a6 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnectionFactory.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConnectionFactory.java @@ -1,23 +1,3 @@ -package com.raytheon.uf.common.jms; - -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; - -import com.raytheon.uf.common.jms.wrapper.JmsConnectionWrapper; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; - /** * This software was developed and / or modified by Raytheon Company, * pursuant to Contract DG133W-05-CQ-1067 with the US Government. @@ -37,9 +17,37 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ +package com.raytheon.uf.common.jms; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; + +import com.raytheon.uf.common.jms.wrapper.JmsConnectionWrapper; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; /** - * TODO Add Description + * Connection Factory that keep underlying JMS resources used by a thread open + * for re-use by that same thread. This is to get around Spring's opening and + * closing the full jms stack for each message. We cannot use Spring caching + * mechanism since it requires one connection object to be used for all jms + * sessions. In that scenario one error causes every jms resource to disconnect + * and has been known to dead lock in the qpid code. + * + * The close action puts the resource into a pool for reuse. The jms resource + * may only be reused by the same thread. This is in part since each thread + * always connects to the same set of jms resources. Also on the QPID broker + * transient data is only removed when the session itself is closed. So reusing + * a resource on a different thread can cause transient topic resources with no + * consumers. * *
  * 
@@ -48,7 +56,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Apr 15, 2011            rjpeter     Initial creation
- * 
+ * Oct 04, 2013 2357       rjpeter     Removed pooling, keeps resources open for the
+ *                                     thread that created them for a configured amount of time.
+ * Feb 07, 2014 2357       rjpeter     Track by Thread object, periodly check that tracked Threads are still alive.
  * 
* * @author rjpeter @@ -63,26 +73,18 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { private String provider = "QPID"; - // connections in use, key is "threadId-threadName" - private final Map inUseConnections = new HashMap(); + // connections in use + private final Map inUseConnections = new HashMap(); - // connections that were recently returned, key is "threadId-threadName" - private final Map> pendingConnections = new HashMap>(); - - // connections that have been released from pendingConnections and are - // awaiting being closed. - private final Deque> availableConnections = new LinkedList>(); + // connections that were recently returned + private final Map> pendingConnections = new HashMap>(); private final ConcurrentLinkedQueue deadConnections = new ConcurrentLinkedQueue(); private int reconnectInterval = 30000; - private int connectionHoldTime = 120000; - private int resourceRetention = 180000; - private int maxSpareConnections = 10; - public JmsPooledConnectionFactory(ConnectionFactory factory) { this.connFactory = factory; } @@ -94,24 +96,23 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { */ @Override public Connection createConnection() throws JMSException { - String threadKey = "" + Thread.currentThread().getId() + "-" - + Thread.currentThread().getName(); + Thread thread = Thread.currentThread(); JmsPooledConnection conn = null; synchronized (inUseConnections) { - conn = inUseConnections.get(threadKey); + conn = inUseConnections.get(thread); if (conn != null) { JmsConnectionWrapper ref = conn.createReference(); if (ref != null) { statusHandler - .info(threadKey + .info(thread.getName() + " already has a connection in use, returning previous connection thread, references=" + conn.getReferenceCount()); return ref; } else { deadConnections.add(conn); - inUseConnections.remove(threadKey); + inUseConnections.remove(thread); conn = null; } } @@ -121,13 +122,14 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { // check connections by Thread synchronized (pendingConnections) { - wrapper = pendingConnections.remove(threadKey); + wrapper = pendingConnections.remove(thread); } // was retrieved connection valid if (wrapper != null) { conn = wrapper.getPooledObject(); - JmsConnectionWrapper ref = getConnectionWrapper(threadKey, conn); + + JmsConnectionWrapper ref = getConnectionWrapper(conn); if (ref != null) { return ref; @@ -137,51 +139,22 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { } } - // check available connections - boolean keepChecking = true; - - while (keepChecking) { - synchronized (availableConnections) { - wrapper = availableConnections.poll(); - } - - if (wrapper != null) { - conn = wrapper.getPooledObject(); - } else { - keepChecking = false; - } - - if (conn != null) { - // was retrieved connection valid - JmsConnectionWrapper ref = getConnectionWrapper(threadKey, conn); - - if (ref != null) { - return ref; - } else { - deadConnections.add(conn); - conn = null; - } - } - } - // create new connection? if (conn == null) { - conn = new JmsPooledConnection(this); + conn = new JmsPooledConnection(this, thread); } - return getConnectionWrapper(threadKey, conn); + return getConnectionWrapper(conn); } - private JmsConnectionWrapper getConnectionWrapper(String threadKey, - JmsPooledConnection conn) { + private JmsConnectionWrapper getConnectionWrapper(JmsPooledConnection conn) { synchronized (conn.getStateLock()) { if (conn.isValid()) { conn.setState(State.InUse); JmsConnectionWrapper ref = conn.createReference(); if (ref != null) { - conn.setKey(threadKey); synchronized (inUseConnections) { - inUseConnections.put(threadKey, conn); + inUseConnections.put(conn.getThread(), conn); } return ref; } @@ -233,13 +206,13 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { } public void removeConnectionFromPool(JmsPooledConnection conn) { - String threadKey = conn.getKey(); + Thread thread = conn.getThread(); boolean success = false; // remove it from inUseConnections if it was in use, theoretically could // go by connection state, but may miss something due to threading synchronized (inUseConnections) { - JmsPooledConnection inUse = inUseConnections.remove(threadKey); + JmsPooledConnection inUse = inUseConnections.remove(thread); // make sure the one we removed is indeed this connection, 99% // of time this is correct @@ -254,7 +227,7 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { // really only here for bullet proofing code against bad // use of pool if (inUse != null) { - inUseConnections.put(threadKey, inUse); + inUseConnections.put(thread, inUse); } } } @@ -262,29 +235,24 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { // remove it from pendingConnections AvailableJmsPooledObject pooledObj = null; synchronized (pendingConnections) { - pooledObj = pendingConnections.remove(threadKey); + pooledObj = pendingConnections.remove(thread); if (pooledObj != null) { if (pooledObj.getPooledObject() == conn) { // found conn, done return; } else { - pendingConnections.put(threadKey, pooledObj); + pendingConnections.put(thread, pooledObj); } } } - - // remove it from availableConnections - synchronized (availableConnections) { - availableConnections.remove(conn); - } } public boolean returnConnectionToPool(JmsPooledConnection conn) { boolean success = false; - String threadKey = conn.getKey(); + Thread thread = conn.getThread(); synchronized (inUseConnections) { - JmsPooledConnection inUse = inUseConnections.remove(threadKey); + JmsPooledConnection inUse = inUseConnections.remove(thread); // make sure the one we removed is indeed this connection, 99% // of time this is correct @@ -296,7 +264,7 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { // really only here for bullet proofing code against bad // use of pool if (inUse != null) { - inUseConnections.put(threadKey, inUse); + inUseConnections.put(thread, inUse); statusHandler .handle(Priority.INFO, "Another connection already in use for this thread, not returning this connection to pool"); @@ -310,20 +278,17 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { AvailableJmsPooledObject prev = null; synchronized (pendingConnections) { prev = pendingConnections - .put(threadKey, + .put(thread, new AvailableJmsPooledObject( conn)); } - if (prev != null) { + if ((prev != null) && (prev.getPooledObject() != conn)) { // there was a previous connection registered to - // this thread, move it to available + // this thread, close it statusHandler .handle(Priority.WARN, - "Another connection already pooled for this thread, moving previous connection to available"); - prev.reset(); - synchronized (availableConnections) { - availableConnections.add(prev); - } + "Another connection already pooled for this thread, closing previous connection"); + deadConnections.add(prev.getPooledObject()); } } else { success = false; @@ -333,11 +298,11 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { } public void checkPooledResources() { - long curTime = System.currentTimeMillis(); - List> connectionsToProcess = new LinkedList>(); int connectionsClosed = 0; - // grab connections to move from pending to available + long curTime = System.currentTimeMillis(); + + // check for connections to close synchronized (pendingConnections) { Iterator> iter = pendingConnections .values().iterator(); @@ -346,44 +311,22 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { .next(); if (wrapper.expired(curTime, resourceRetention)) { iter.remove(); - connectionsToProcess.add(wrapper); - } - } - } - - synchronized (availableConnections) { - for (AvailableJmsPooledObject wrapper : connectionsToProcess) { - wrapper.reset(); - - // putting to available pool - JmsPooledConnection conn = wrapper.getPooledObject(); - conn.setKey(null); - availableConnections.add(wrapper); - } - } - - connectionsToProcess.clear(); - - synchronized (availableConnections) { - Iterator> iter = availableConnections - .iterator(); - while (iter.hasNext()) { - AvailableJmsPooledObject wrapper = iter - .next(); - // available sessions added based on time, so oldest is front of - // queue - if (wrapper.expired(curTime, connectionHoldTime) - || (availableConnections.size() > maxSpareConnections)) { - // not immediately closing connection so that we minimize - // time in sync block deadConnections.add(wrapper.getPooledObject()); - iter.remove(); - } else { - // connections ordered in reverse order - break; } } + } + // check for dead threads + synchronized (inUseConnections) { + Iterator> iter = inUseConnections + .entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + if (!entry.getKey().isAlive()) { + iter.remove(); + deadConnections.add(entry.getValue()); + } + } } while (!deadConnections.isEmpty()) { @@ -394,29 +337,29 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { } } - List connectionsToCheck = null; + ArrayList connectionsToCheck = null; synchronized (inUseConnections) { connectionsToCheck = new ArrayList( inUseConnections.values()); } + int resourcesClosed = 0; for (JmsPooledConnection conn : connectionsToCheck) { resourcesClosed += conn.closeOldPooledResources(resourceRetention); } + connectionsToCheck.clear(); // close pooled resources on pending connections synchronized (pendingConnections) { - connectionsToProcess = new ArrayList>( - pendingConnections.values()); + connectionsToCheck.ensureCapacity(pendingConnections.size()); + for (AvailableJmsPooledObject wrapper : pendingConnections + .values()) { + connectionsToCheck.add(wrapper.getPooledObject()); + } } - synchronized (availableConnections) { - connectionsToProcess.addAll(availableConnections); - } - - for (AvailableJmsPooledObject wrapper : connectionsToProcess) { - resourcesClosed += wrapper.getPooledObject() - .closeOldPooledResources(resourceRetention); + for (JmsPooledConnection conn : connectionsToCheck) { + resourcesClosed += conn.closeOldPooledResources(resourceRetention); } if ((connectionsClosed > 0) || (resourcesClosed > 0)) { @@ -429,33 +372,4 @@ public class JmsPooledConnectionFactory implements ConnectionFactory { } } - /** - * @return the connectionHoldTime - */ - public int getConnectionHoldTime() { - return connectionHoldTime; - } - - /** - * @param connectionHoldTime - * the connectionHoldTime to set - */ - public void setConnectionHoldTime(int connectionHoldTime) { - this.connectionHoldTime = connectionHoldTime; - } - - /** - * @return the maxSpareConnections - */ - public int getMaxSpareConnections() { - return maxSpareConnections; - } - - /** - * @param maxSpareConnections - * the maxSpareConnections to set - */ - public void setMaxSpareConnections(int maxSpareConnections) { - this.maxSpareConnections = maxSpareConnections; - } } diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConsumer.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConsumer.java index f8e3e053fa..0a671ffbd9 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConsumer.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledConsumer.java @@ -26,6 +26,8 @@ import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageConsumer; +import org.apache.qpid.client.BasicMessageConsumer; + import com.raytheon.uf.common.jms.wrapper.JmsConsumerWrapper; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -47,9 +49,10 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 18, 2011 rjpeter Initial creation - * Mar 08, 2012 194 njensen Improved logging - * Feb 26, 2013 1642 rjpeter Removed lazy initialization + * Apr 18, 2011 rjpeter Initial creation. + * Mar 08, 2012 194 njensen Improved logging. + * Feb 26, 2013 1642 rjpeter Removed lazy initialization. + * Feb 07, 2014 2357 rjpeter Updated logging. * * * @author rjpeter @@ -87,6 +90,14 @@ public class JmsPooledConsumer { this.destKey = destKey; consumer = sess.getSession().createConsumer(destination, messageSelector); + + if (consumer instanceof BasicMessageConsumer) { + statusHandler.info("Creating AMQ consumer " + + ((BasicMessageConsumer) consumer).getDestination() + .getQueueName()); // njensen + } else { + statusHandler.info("Creating consumer " + destKey); // njensen + } } public String getDestKey() { @@ -164,7 +175,13 @@ public class JmsPooledConsumer { if (close) { try { - statusHandler.info("Closing consumer " + destKey); // njensen + if (consumer instanceof BasicMessageConsumer) { + statusHandler.info("Closing AMQ consumer " + + ((BasicMessageConsumer) consumer) + .getDestination().getQueueName()); // njensen + } else { + statusHandler.info("Closing consumer " + destKey); // njensen + } consumer.close(); } catch (Throwable e) { statusHandler.handle(Priority.WARN, "Failed to close consumer " diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledProducer.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledProducer.java index e693b74750..445e7fff4a 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledProducer.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledProducer.java @@ -25,6 +25,9 @@ import java.util.List; import javax.jms.JMSException; import javax.jms.MessageProducer; +import org.apache.qpid.client.AMQDestination; +import org.apache.qpid.client.BasicMessageProducer; + import com.raytheon.uf.common.jms.wrapper.JmsProducerWrapper; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -46,9 +49,10 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 18, 2011 rjpeter Initial creation - * Mar 08, 2012 194 njensen Improved logging - * Feb 26, 2013 1642 rjpeter Removed lazy initialization + * Apr 18, 2011 rjpeter Initial creation. + * Mar 08, 2012 194 njensen Improved logging. + * Feb 26, 2013 1642 rjpeter Removed lazy initialization. + * Feb 07, 2014 2357 rjpeter Updated logging. * * * @author rjpeter @@ -84,6 +88,19 @@ public class JmsPooledProducer { this.sess = sess; this.destKey = destKey; this.producer = producer; + if (producer instanceof BasicMessageProducer) { + try { + statusHandler.info("Creating AMQ producer " + + ((AMQDestination) ((BasicMessageProducer) producer) + .getDestination()).getQueueName()); + } catch (Exception e) { + statusHandler + .error("Could not get producer destination for key " + + destKey, e); + } + } else { + statusHandler.info("Creating producer " + destKey); // njensen + } } public String getDestKey() { @@ -161,7 +178,14 @@ public class JmsPooledProducer { if (close) { try { - statusHandler.info("Closing producer " + destKey); // njensen + if (producer instanceof BasicMessageProducer) { + statusHandler + .info("Closing AMQ producer " + + ((AMQDestination) ((BasicMessageProducer) producer) + .getDestination()).getQueueName()); // njensen + } else { + statusHandler.info("Closing producer " + destKey); // njensen + } producer.close(); } catch (Throwable e) { statusHandler.handle(Priority.WARN, "Failed to close producer", diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledSession.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledSession.java index d3ad93562e..9c1ce83c72 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledSession.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/JmsPooledSession.java @@ -44,7 +44,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * can be released to the pool. Any exception will close pooled session instead * of returning to the pool. The consumers/producers are tracked in both active * and available states. An available consumer/producer can be reused by the - * next client. + * next client. Once a consumer has been closed the entire session is closed at + * next opportunity since QPID tracks consumers at the session level. Not doing + * this can leave a topic with no consumers on the qpid broker. * * Synchronization Principle To prevent deadlocks: Chained sync blocks can only * happen in a downward direction. A manager has a synchronized lock can make a @@ -60,6 +62,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * Apr 15, 2011 rjpeter Initial creation * Mar 08, 2012 194 njensen Improved logging * Feb 21, 2013 1642 rjpeter Fix deadlock scenario + * Jan 26, 2014 2357 rjpeter Close a session when it has no producers or consumers. + * Feb 07, 2014 2357 rjpeter Close session at next return to pool after a + * consumer has closed. * * * @author rjpeter @@ -77,7 +82,7 @@ public class JmsPooledSession { // The thread this session was most recently used by for tracking a pending // session that is being reserved for a given thread. - private String threadKey; + private final Thread thread; private volatile boolean exceptionOccurred = false; @@ -85,6 +90,10 @@ public class JmsPooledSession { private volatile State state = State.InUse; + // flag to stat that session should be closed instead of returned to pool on + // next iteration + private volatile boolean shouldClose = false; + // keeps track of number of creates vs. closes to know when it can be // returned to the pool private final List references = new ArrayList( @@ -101,6 +110,8 @@ public class JmsPooledSession { public JmsPooledSession(JmsPooledConnection conn, Session sess) { this.conn = conn; this.sess = sess; + this.thread = conn.getThread(); + statusHandler.info("Opening session: " + this.toString()); } public long getCreateTime() { @@ -120,12 +131,8 @@ public class JmsPooledSession { return conn; } - public String getThreadKey() { - return threadKey; - } - - public void setThreadKey(String threadKey) { - this.threadKey = threadKey; + public Thread getThread() { + return thread; } public boolean isValid() { @@ -436,6 +443,9 @@ public class JmsPooledSession { String destKey = consumer.getDestKey(); boolean removed = false; + // a consumer was closed, close the session at next opportunity + shouldClose = true; + synchronized (inUseConsumers) { JmsPooledConsumer inUse = inUseConsumers.remove(destKey); removed = inUse == consumer; @@ -462,6 +472,7 @@ public class JmsPooledSession { } if (canClose) { + statusHandler.info("Closing session: " + this.toString()); closePooledConsumersProducers(); // need to close down all wrappers @@ -627,7 +638,7 @@ public class JmsPooledSession { } } - boolean valid = isValid(); + boolean valid = isValid() && !shouldClose && hasProducersOrConsumers(); if (valid && returnToPool) { valid = conn.returnSessionToPool(this); } @@ -654,4 +665,10 @@ public class JmsPooledSession { public Object getStateLock() { return stateLock; } + + public boolean hasProducersOrConsumers() { + return !inUseConsumers.isEmpty() || !inUseProducers.isEmpty() + || !availableConsumers.isEmpty() + || !availableProducers.isEmpty(); + } } diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsConsumerWrapper.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsConsumerWrapper.java index ec978fe7b8..4dd79cc2fa 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsConsumerWrapper.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsConsumerWrapper.java @@ -37,8 +37,9 @@ import com.raytheon.uf.common.jms.JmsPooledConsumer; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 18, 2011 rjpeter Initial creation + * Apr 18, 2011 rjpeter Initial creation. * Feb 26, 2013 1642 rjpeter Added volatile references for better concurrency handling. + * Feb 07, 2014 2357 rjpeter Set linked exception in exception handling. * * * @author rjpeter @@ -124,8 +125,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in getMessageListener"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -144,8 +148,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in getMessageSelector"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -164,8 +171,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in receive"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -184,8 +194,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in receive(timeout)"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -204,8 +217,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in receiveNoWait"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -226,8 +242,11 @@ public class JmsConsumerWrapper implements MessageConsumer { } catch (Throwable e) { exceptionOccurred = true; JMSException exc = new JMSException( - "Exception occurred on pooled consumer"); + "Exception occurred on pooled consumer in setMessageLister"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } diff --git a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsProducerWrapper.java b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsProducerWrapper.java index 5ab53cb6a8..581dd63898 100644 --- a/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsProducerWrapper.java +++ b/edexOsgi/com.raytheon.uf.common.jms/src/com/raytheon/uf/common/jms/wrapper/JmsProducerWrapper.java @@ -37,9 +37,10 @@ import com.raytheon.uf.common.jms.JmsPooledProducer; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Dec fi8, 2011 rjpeter Initial creation + * Dec 08, 2011 rjpeter Initial creation. * Feb 26, 2013 1642 rjpeter Added volatile references for better concurrency handling. - * Jun 07, 2013 DR 16316 rjpeter Fix memory leak + * Jun 07, 2013 DR 16316 rjpeter Fix memory leak. + * Feb 07, 2014 2357 rjpeter Set linked exception in exception handling. * * * @author rjpeter @@ -122,6 +123,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -142,6 +146,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -162,6 +169,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -182,6 +192,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -202,6 +215,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -222,6 +238,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -242,6 +261,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -264,6 +286,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -285,6 +310,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -309,6 +337,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -329,6 +360,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -349,6 +383,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -369,6 +406,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -389,6 +429,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } @@ -409,6 +452,9 @@ public class JmsProducerWrapper implements MessageProducer { JMSException exc = new JMSException( "Exception occurred on pooled producer"); exc.initCause(e); + if (e instanceof Exception) { + exc.setLinkedException((Exception) e); + } throw exc; } } diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-common.xml b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-common.xml index 403e49cd4b..9e9dde3cac 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-common.xml +++ b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-common.xml @@ -15,17 +15,6 @@
- - - - - - - - - @@ -46,7 +35,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml index 0d6e84d11e..434c097ac8 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml @@ -25,8 +25,8 @@ - - + + java.lang.Throwable diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java index 8c81d43e9c..646061083c 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java @@ -77,6 +77,7 @@ import com.raytheon.uf.edex.database.processor.IDatabaseProcessor; * Dec 10, 2013 2555 rjpeter Initial creation. * Jan 23, 2014 2555 rjpeter Updated to be a row at a time using ScrollableResults. * Feb 04, 2014 2770 rferrel The dumpPdos now dumps all PluginDataObjects. + * Feb 12, 2014 2784 rjpeter Update logging for dup elim scenarios. * * * @author rjpeter @@ -194,6 +195,7 @@ public class DatabaseArchiveProcessor> if (entriesInMemory > 0) { try { savePdoMap(pdosByFile); + pdosByFile.clear(); int prev = recordsSaved; recordsSaved += entriesInMemory; statusHandler.info(pluginName + ": Processed rows " + prev @@ -436,74 +438,93 @@ public class DatabaseArchiveProcessor> } List> pdosFromDisk = readDataFromDisk(dataFile); - if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { - statusHandler.debug(pluginName + ": Checking " - + pdosFromDisk.size() + " old records from file: " - + dataFile.getAbsolutePath()); - } - Iterator> pdoIter = pdosFromDisk - .iterator(); - boolean needsUpdate = false; - int dupsRemoved = 0; - int index = 0; - while (pdoIter.hasNext() && (index < dupElimUntil)) { - PersistableDataObject pdo = pdoIter.next(); - - if (identifierSet.contains(pdo.getIdentifier())) { - pdoIter.remove(); - needsUpdate = true; - dupsRemoved++; - } - - index++; - } - - if (statusHandler.isPriorityEnabled(Priority.DEBUG) - && (dupsRemoved > 0)) { - statusHandler.debug(pluginName + ": Removed " + dupsRemoved - + " old records from file: " - + dataFile.getAbsolutePath()); - } - - if (!fileIter.hasNext() && (pdosFromDisk.size() < fetchSize)) { - // last file, add more data to it - needsUpdate = true; - - if (prevFileStatus == null) { - prevFileStatus = new FileStatus(); - prevFileStatus.dupElimUntilIndex = pdosFromDisk.size(); - prevFileStatus.fileFull = pdos.size() >= fetchSize; - filesCreatedThisSession.put(dataFile.getAbsolutePath(), - prevFileStatus); - } - - int numToAdd = fetchSize - pdosFromDisk.size(); - numToAdd = Math.min(numToAdd, pdos.size()); - + if (pdosFromDisk.size() > 0) { if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { - statusHandler.debug(pluginName + ": Adding " + numToAdd - + " records to file: " + statusHandler.debug(pluginName + ": Checking " + + pdosFromDisk.size() + + " old records from file: " + dataFile.getAbsolutePath()); } - pdosFromDisk.addAll(pdos.subList(0, numToAdd)); - if (numToAdd < pdos.size()) { - pdos = pdos.subList(numToAdd, pdos.size()); - } else { - pdos = Collections.emptyList(); - } - } + Iterator> pdoIter = pdosFromDisk + .iterator(); + int dupsRemoved = 0; + int index = 0; + boolean needsUpdate = false; - if (needsUpdate) { - if (!pdosFromDisk.isEmpty()) { - writeDataToDisk(dataFile, pdosFromDisk); - if (prevFileStatus != null) { - prevFileStatus.fileFull = pdosFromDisk.size() >= fetchSize; + while (pdoIter.hasNext() && (index < dupElimUntil)) { + PersistableDataObject pdo = pdoIter.next(); + + if (identifierSet.contains(pdo.getIdentifier())) { + pdoIter.remove(); + needsUpdate = true; + dupsRemoved++; + } + + index++; + } + + if (dupsRemoved > 0) { + statusHandler.info(pluginName + ": Removed " + + dupsRemoved + " old records from file: " + + dataFile.getAbsolutePath()); + } + + if (!fileIter.hasNext() + && (pdosFromDisk.size() < fetchSize)) { + // last file, add more data to it + needsUpdate = true; + + if (prevFileStatus == null) { + prevFileStatus = new FileStatus(); + prevFileStatus.dupElimUntilIndex = pdosFromDisk + .size(); + prevFileStatus.fileFull = pdos.size() >= fetchSize; + filesCreatedThisSession.put( + dataFile.getAbsolutePath(), prevFileStatus); + } + + int numToAdd = fetchSize - pdosFromDisk.size(); + numToAdd = Math.min(numToAdd, pdos.size()); + + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + statusHandler.debug(pluginName + ": Adding " + + numToAdd + " records to file: " + + dataFile.getAbsolutePath()); + } + + pdosFromDisk.addAll(pdos.subList(0, numToAdd)); + if (numToAdd < pdos.size()) { + pdos = pdos.subList(numToAdd, pdos.size()); + } else { + pdos = Collections.emptyList(); + } + } + + if (needsUpdate) { + if (!pdosFromDisk.isEmpty()) { + writeDataToDisk(dataFile, pdosFromDisk); + if (prevFileStatus != null) { + prevFileStatus.fileFull = pdosFromDisk.size() >= fetchSize; + } + } else { + + dirsToCheckNumbering.add(dataFile.getParentFile()); + if (dataFile.exists() && !dataFile.delete()) { + statusHandler + .error(pluginName + + ": Failed to delete file [" + + dataFile.getAbsolutePath() + + "], all entries have been updated in later files."); + if (!dataFile.renameTo(new File(dataFile + .getAbsoluteFile() + ".bad"))) { + statusHandler.error(pluginName + ": file [" + + dataFile.getAbsoluteFile() + + "] cannot be renamed to .bad"); + } + } + fileIter.remove(); } - } else { - dirsToCheckNumbering.add(dataFile.getParentFile()); - dataFile.delete(); - fileIter.remove(); } } } @@ -543,7 +564,13 @@ public class DatabaseArchiveProcessor> } finally { if (!successful) { // couldn't read in file, move it to bad - file.renameTo(new File(file.getAbsoluteFile() + ".bad")); + if (file.exists() + && !file.renameTo(new File(file.getAbsoluteFile() + + ".bad"))) { + statusHandler.error(pluginName + ": file [" + + file.getAbsoluteFile() + + "] cannot be renamed to .bad"); + } } if (is != null) { try { @@ -668,8 +695,9 @@ public class DatabaseArchiveProcessor> writer = new BufferedWriter(new FileWriter(dumpFile)); if (statusHandler.isPriorityEnabled(Priority.INFO)) { - statusHandler.info(String.format("%s: Dumping records to: %s", - pluginName, dumpFile.getAbsolutePath())); + statusHandler.info(String.format("%s: Dumping " + pdos.size() + + " records to: %s", pluginName, + dumpFile.getAbsolutePath())); } while (pdoIter.hasNext()) { @@ -753,6 +781,8 @@ public class DatabaseArchiveProcessor> } while (size > 0); DecimalFormat format = new DecimalFormat(formatString.toString()); + statusHandler.info("Checking file numbering consistency for " + + dir.getAbsolutePath()); for (Map.Entry entry : fileMap.entrySet()) { int fileNum = entry.getKey(); @@ -771,7 +801,15 @@ public class DatabaseArchiveProcessor> } File newFile = new File(oldFile.getParent(), newFileName); - oldFile.renameTo(newFile); + if (!oldFile.renameTo(newFile)) { + statusHandler + .error("Failed rename file " + + oldFile.getAbsolutePath() + + " to " + + newFile.getAbsolutePath() + + ". Stopping file number consistency checking."); + return; + } } nextFileCount++; diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java index f9a4e8af2c..70cae04fdf 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java @@ -58,6 +58,7 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory; * Nov 05, 2013 2499 rjpeter Repackaged, removed config files, always compresses hdf5. * Nov 11, 2013 2478 rjpeter Updated data store copy to always copy hdf5. * Dec 13, 2013 2555 rjpeter Refactored logic into DatabaseArchiveProcessor. + * Feb 12, 2014 2784 rjpeter Fixed clusterLock to not update the time by default. * * * @author rjpeter @@ -145,14 +146,16 @@ public class DatabaseArchiver implements IPluginArchiver { // cluster lock, grabbing time of last successful archive CurrentTimeClusterLockHandler lockHandler = new CurrentTimeClusterLockHandler( - CLUSTER_LOCK_TIMEOUT, dateFormat.format(runTime.getTime()), - false); + CLUSTER_LOCK_TIMEOUT, false); ClusterTask ct = ClusterLockUtils.lock(TASK_NAME, pluginName, lockHandler, false); if (!LockState.SUCCESSFUL.equals(ct.getLockState())) { return true; } + // keep extra info the same until processing updates the time. + lockHandler.setExtraInfo(ct.getExtraInfo()); + Calendar startTime = null; long timimgStartMillis = System.currentTimeMillis(); int recordCount = 0; @@ -226,12 +229,6 @@ public class DatabaseArchiver implements IPluginArchiver { .info(pluginName + ": Found no records to archive"); } } catch (Throwable e) { - // previous run time needs to be reset - if (startTime != null) { - lockHandler - .setExtraInfo(dateFormat.format(startTime.getTime())); - } - statusHandler.error(pluginName + ": Error occurred archiving data", e); } finally { diff --git a/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml b/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml index 69c5a9e7f6..f7dbf3e5ca 100644 --- a/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml @@ -26,7 +26,7 @@ autoStartup="false"> - + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml index d231a27f79..cd4b4a859d 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml @@ -3,21 +3,6 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - - - - - - - - - - - @@ -29,11 +14,11 @@ errorHandlerRef="errorHandler"> - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml b/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml index 018a905229..38cd142db1 100644 --- a/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml @@ -8,19 +8,6 @@ - - - - - - - - - - - - + @@ -40,7 +27,7 @@ - + @@ -51,7 +38,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java new file mode 100644 index 0000000000..978efdac8f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java @@ -0,0 +1,101 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.esb.camel.jms; + +import java.util.Map; + +import org.apache.camel.Endpoint; +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsEndpoint; + +import com.raytheon.uf.edex.esb.camel.spring.JmsThreadPoolTaskExecutor; + +/** + * Custom JMS component that makes dedicated thread pools for each JmsEndpoint + * based on the concurrent consumers needed. Each pool is named based on the JMS + * endpoint. Each endpoint also overrides the message listener container factory + * to monitor the created containers to see if they need to be restarted in a + * disconnect scenario. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 07, 2014 2357       rjpeter     Initial creation.
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class DedicatedThreadJmsComponent extends JmsComponent { + + public DedicatedThreadJmsComponent( + org.apache.camel.component.jms.JmsConfiguration jmsconfig) { + super(jmsconfig); + } + + /* + * (non-Javadoc) + * + * @see + * org.apache.camel.component.jms.JmsComponent#createEndpoint(java.lang. + * String, java.lang.String, java.util.Map) + */ + @Override + protected Endpoint createEndpoint(String uri, String remaining, + Map parameters) throws Exception { + String threadName = (String) parameters.remove("threadName"); + Endpoint e = super.createEndpoint(uri, remaining, parameters); + if (e instanceof JmsEndpoint) { + JmsEndpoint jmsE = (JmsEndpoint) e; + if ((threadName != null) && (threadName.length() > 0) + && !threadName.endsWith("-")) { + threadName += "-"; + } else { + threadName = jmsE.getDestinationName() + "-"; + } + /* + * This is used for a SimpleMessageListenerContainer use case. + * + * JmsSimpleMessageListenerTaskExecutor executor = new + * JmsSimpleMessageListenerTaskExecutor( + * jmsE.getConcurrentConsumers(), threadName); + */ + // DefaultMessageListenerContainer use case + JmsThreadPoolTaskExecutor executor = new JmsThreadPoolTaskExecutor(); + executor.setThreadNamePrefix(threadName); + executor.setCorePoolSize(jmsE.getConcurrentConsumers()); + executor.setMaxPoolSize(Math.max(jmsE.getConcurrentConsumers(), + jmsE.getMaxConcurrentConsumers())); + executor.setQueueCapacity(0); + executor.afterPropertiesSet(); + + jmsE.setTaskExecutor(executor); + jmsE.setMessageListenerContainerFactory(MonitoredDefaultMessageListenerContainerFactory + .getInstance()); + + return jmsE; + } + throw new Exception( + "JmsComponent did not create a JmsEnpoint. Check Camel Jms Override"); + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/MonitoredDefaultMessageListenerContainerFactory.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/MonitoredDefaultMessageListenerContainerFactory.java new file mode 100644 index 0000000000..074c2a0377 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/MonitoredDefaultMessageListenerContainerFactory.java @@ -0,0 +1,142 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.esb.camel.jms; + +import java.util.Collection; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.camel.component.jms.DefaultJmsMessageListenerContainer; +import org.apache.camel.component.jms.JmsEndpoint; +import org.apache.camel.component.jms.MessageListenerContainerFactory; +import org.springframework.jms.listener.AbstractMessageListenerContainer; +import org.springframework.jms.listener.DefaultMessageListenerContainer; + +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.core.EDEXUtil; + +/** + * Creates DefaultMessageListenerContainer instances that are then monitored + * once a minute for paused tasks. If a paused task is found the container is + * restarted. This is necessary in broker restart scenarios. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 8, 2014  2357      rjpeter     Initial creation.
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class MonitoredDefaultMessageListenerContainerFactory implements + MessageListenerContainerFactory { + private static final AtomicInteger threadCount = new AtomicInteger(1); + + private final Collection containers = new ConcurrentLinkedQueue(); + + private final IUFStatusHandler statusHandler = UFStatus + .getHandler(MonitoredDefaultMessageListenerContainerFactory.class); + + private static final MonitoredDefaultMessageListenerContainerFactory instance = new MonitoredDefaultMessageListenerContainerFactory(); + + public static MonitoredDefaultMessageListenerContainerFactory getInstance() { + return instance; + } + + private MonitoredDefaultMessageListenerContainerFactory() { + Thread containerChecker = new Thread("MessageListenerContainerMonitor-" + + threadCount.getAndIncrement()) { + /* + * (non-Javadoc) + * + * @see java.lang.Thread#run() + */ + @Override + public void run() { + while (!EDEXUtil.isRunning()) { + try { + Thread.sleep(TimeUtil.MILLIS_PER_MINUTE); + } catch (InterruptedException e) { + // ignore + } + } + + while (true) { + try { + for (DefaultMessageListenerContainer container : containers) { + if (container.getPausedTaskCount() > 0) { + StringBuilder msg = new StringBuilder(160); + msg.append("Container[") + .append(container.getDestinationName()) + .append("] has paused tasks. Container is "); + if (!container.isRunning()) { + msg.append("not "); + } + msg.append("running. Container is "); + if (container.isActive()) { + msg.append("not "); + } + msg.append("active. Restarting container."); + statusHandler.warn(msg.toString()); + container.start(); + } + } + + try { + Thread.sleep(TimeUtil.MILLIS_PER_MINUTE); + } catch (InterruptedException e) { + // ignore + } + } catch (Throwable e) { + statusHandler + .error("Error occurred in checking message listener containers", + e); + } + } + } + }; + containerChecker.start(); + } + + /* + * (non-Javadoc) + * + * @see org.apache.camel.component.jms.MessageListenerContainerFactory# + * createMessageListenerContainer + * (org.apache.camel.component.jms.JmsEndpoint) + */ + @Override + public AbstractMessageListenerContainer createMessageListenerContainer( + JmsEndpoint endpoint) { + // track the container for monitoring in the case of a provider + // reconnect + DefaultJmsMessageListenerContainer container = new DefaultJmsMessageListenerContainer( + endpoint); + containers.add(container); + return container; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.grid.staticdata/res/spring/grid-staticdata-process.xml b/edexOsgi/com.raytheon.uf.edex.grid.staticdata/res/spring/grid-staticdata-process.xml index 8db9b3d210..5bdf3a1eab 100644 --- a/edexOsgi/com.raytheon.uf.edex.grid.staticdata/res/spring/grid-staticdata-process.xml +++ b/edexOsgi/com.raytheon.uf.edex.grid.staticdata/res/spring/grid-staticdata-process.xml @@ -12,7 +12,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/DPADecoder-spring.xml b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/DPADecoder-spring.xml index e5e7eff311..e926100e28 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/DPADecoder-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/DPADecoder-spring.xml @@ -9,13 +9,13 @@ - + - + - + - + - + + + + + + + com.raytheon.edex.plugin.shef + + + + + + + file:///${edex.home}/conf/db/hibernateConfig/ihfs/hibernate.cfg.xml + + + + + + + + + + + + + file:///${edex.home}/conf/db/hibernateConfig/damCatalog/hibernate.cfg.xml + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/ohd-common.xml b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/ohd-common.xml index a87ebe243a..c9553e670e 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/ohd-common.xml +++ b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/ohd-common.xml @@ -1,42 +1,6 @@ - - - - - - com.raytheon.edex.plugin.shef - - - - - - - file:///${edex.home}/conf/db/hibernateConfig/ihfs/hibernate.cfg.xml - - - - - - - - - - - - - file:///${edex.home}/conf/db/hibernateConfig/damCatalog/hibernate.cfg.xml - - - - - - diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/q2FileProcessor-spring.xml b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/q2FileProcessor-spring.xml index 4c90c7a7f8..b7840916b5 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/q2FileProcessor-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/q2FileProcessor-spring.xml @@ -8,7 +8,7 @@ - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml index 3970913f1b..e89bd76d0a 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml @@ -10,7 +10,7 @@ - + - + - + - + - + - + - + - + - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.loctables/res/spring/loctables-spring.xml b/edexOsgi/com.raytheon.uf.edex.plugin.loctables/res/spring/loctables-spring.xml index 761d2fdf82..18bd451570 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.loctables/res/spring/loctables-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.loctables/res/spring/loctables-spring.xml @@ -24,7 +24,7 @@ - + - + - + - + - - - - - - - - - - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml index 43c3f88bdf..988a5a7b45 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml @@ -3,26 +3,14 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - - - - - - - - - - - + + + @@ -35,7 +23,7 @@ - + satellite-mcidas diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml index 09021bf61e..58689cd836 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml @@ -10,7 +10,7 @@ - + - + - + - + - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - package gov.noaa.nws.ncep.common.dataplugin.airmet; import java.util.Calendar; @@ -53,6 +24,37 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * AirmetRecord + * + * This java class performs the mapping to the database table for AIRMET + * + *
+ * HISTORY
+ * 
+ * Date         Author      Description
+ * ------------ ----------  ----------- --------------------------
+ * 05/2009      L. Lin      Initial creation    
+ * 
+ * This code has been developed by the SIB for use in the AWIPS2 system.
+ * 
+ * Date         Ticket#         Engineer    Description
+ * ------------ ----------      ----------- --------------------------
+ * 05/2009      39              L. Lin      Initial coding
+ * 07/2009      39              L. Lin      Migration to TO11
+ * 09/2011                      Chin Chen   changed to improve purge performance and
+ *                                          removed xml serialization as well
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013       1857 bgonzale         Added SequenceGenerator annotation.
+ * May 07, 2013 1869            bsteffen    Remove dataURI column from
+ *                                          PluginDataObject.
+ * Feb 11, 2014 2784            rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "airmetseq") @Table(name = "airmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -319,24 +321,6 @@ public class AirmetRecord extends PluginDataObject { */ public void addAirmetReport(AirmetReport curReport) { airmetReport.add(curReport); - // curReport.setParentID(this); - } - - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - /* - * if(this.getAirmetReport() != null && this.getAirmetReport().size() > - * 0) { for (Iterator iter = - * this.getAirmetReport().iterator(); iter.hasNext();) { AirmetReport cs - * = iter.next(); cs.setParentID(this); } } - */ - } @Override diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java index 61e7aecdb9..9c14f7cdbb 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java @@ -1,38 +1,3 @@ -/** - * AwwRecord - * - * This java class performs the mapping to the database tables for AWW. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 12/2008 38 L. Lin Initial coding - * 04/2009 38 L. Lin Convert to TO10. - * 07/2009 38 L. Lin Migration to TO11 - * 05/2010 38 L. Lin Migration to TO11DR11 - * 01/11/2011 N/A M. Gao Add mndTime as the 5th element to construct - * dataUri value that is used as a unique constraint - * when the aww record is inserted into relational DB - * The reason mndTime is used is because the combination - * of original 4 elements is not unique in some scenarios. - * 01/26/2011 N/A M. Gao Add designatorBBB as the 6th (No.4) element to construct - * dataUri value that is used as a unique constraint - * when the aww record is inserted into relational DB - * The reason mndTime is used is because the combination - * of original 5 elements is not unique in some scenarios. - * 09/2011 Chin Chen changed to improve purge performance and - * removed xml serialization as well - * Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime - * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. - * May 07, 2013 1869 bsteffen Remove dataURI column from - * PluginDataObject. - * July 29, 2013 1028 ghull add AwwReportType enum - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ package gov.noaa.nws.ncep.common.dataplugin.aww; import java.util.Calendar; @@ -59,6 +24,43 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * AwwRecord + * + * This java class performs the mapping to the database tables for AWW. + * + * SOFTWARE HISTORY + * + *
+ * Date         Ticket#         Engineer    Description
+ * ------------ ----------      ----------- --------------------------
+ * 12/2008      38              L. Lin      Initial coding
+ * 04/2009      38              L. Lin      Convert to TO10.
+ * 07/2009      38              L. Lin      Migration to TO11
+ * 05/2010      38              L. Lin      Migration to TO11DR11
+ * 01/11/2011   N/A             M. Gao      Add mndTime as the 5th element to construct 
+ *                                          dataUri value that is used as a unique constraint 
+ *                                          when the aww record is inserted into relational DB
+ *                                          The reason mndTime is used is because the combination 
+ *                                          of original 4 elements is not unique in some scenarios.                                       
+ * 01/26/2011   N/A             M. Gao      Add designatorBBB as the 6th (No.4) element to construct 
+ *                                          dataUri value that is used as a unique constraint 
+ *                                          when the aww record is inserted into relational DB
+ *                                          The reason mndTime is used is because the combination 
+ *                                          of original 5 elements is not unique in some scenarios.                                       
+ * 09/2011                      Chin Chen   changed to improve purge performance and
+ *                                          removed xml serialization as well
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013 1857            bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869            bsteffen    Remove dataURI column from
+ *                                          PluginDataObject.
+ * July 29, 2013 1028           ghull       add AwwReportType enum
+ * Feb 11, 2014 2784            rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "awwseq") @Table(name = "aww", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -86,68 +88,42 @@ public class AwwRecord extends PluginDataObject { * REPORT 27. HIGH WIND WARNING 28. FREEZE WARNING 29. ADVERTENCIA DE * INUNDACIONES 30. HYDROLOGIC STATEMENT 31. URGENT WEATHER MESSAGE */ - public static enum AwwReportType { - SEVERE_THUNDERSTORM_WARNING, - SEVERE_THUNDERSTORM_WATCH, - TORNADO_WARNING, - TORNADO_WATCH, - SEVERE_THUNDERSTORM_OUTLINE_UPDATE, - TORNADO_WATCH_OUTLINE_UPDATE, - FLASH_FLOOD_WARNING, - FLASH_FLOOD_WATCH, - FLOOD_WARNING, - FLOOD_WATCH, - FLOOD_STATEMENT, - // WINTER STORM. something is getting decoded as WINTER STORM - WINTER_STORM_WARNING, - WINTER_STORM_WATCH, - WATCH_COUNTY_NOTIFICATION, - SEVERE_WEATHER_STATEMENT, - WIND_ADVISORY, // ?WIND CHILL ADVISORY? - // WIND CHILL ADVISORYs getting decoded as "ADVISORY" - FOG_ADVISORY, - HEAT_ADVISORY, - FROST_ADVISORY, - SMOKE_ADVISORY, - WEATHER_ADVISORY, - WINTER_WEATHER_ADVISORY, - SIGNIGICANT_WEATHER_ADVISORY, - SPECIAL_WEATHER_STATEMENT, - RED_FLAG_WARNING, - TORNADO_REPORT, - HIGH_WIND_WARNING, - FREEZE_WARNING, - ADVERTENCIA_DE_INUNDACIONES, - HYDROLOGIC_STATEMENT, - URGENT_WEATHER_MESSAGE, - UNKNOWN_AWW_REPORT_TYPE, - // DON"T know what this is but WTCH is looking for it (isSevereWeatherStatusNotification)? - STATUS_REPORT; + public static enum AwwReportType { + SEVERE_THUNDERSTORM_WARNING, SEVERE_THUNDERSTORM_WATCH, TORNADO_WARNING, TORNADO_WATCH, SEVERE_THUNDERSTORM_OUTLINE_UPDATE, TORNADO_WATCH_OUTLINE_UPDATE, FLASH_FLOOD_WARNING, FLASH_FLOOD_WATCH, FLOOD_WARNING, FLOOD_WATCH, FLOOD_STATEMENT, + // WINTER STORM. something is getting decoded as WINTER STORM + WINTER_STORM_WARNING, WINTER_STORM_WATCH, WATCH_COUNTY_NOTIFICATION, SEVERE_WEATHER_STATEMENT, WIND_ADVISORY, // ?WIND + // CHILL + // ADVISORY? + // WIND CHILL ADVISORYs getting decoded as "ADVISORY" + FOG_ADVISORY, HEAT_ADVISORY, FROST_ADVISORY, SMOKE_ADVISORY, WEATHER_ADVISORY, WINTER_WEATHER_ADVISORY, SIGNIGICANT_WEATHER_ADVISORY, SPECIAL_WEATHER_STATEMENT, RED_FLAG_WARNING, TORNADO_REPORT, HIGH_WIND_WARNING, FREEZE_WARNING, ADVERTENCIA_DE_INUNDACIONES, HYDROLOGIC_STATEMENT, URGENT_WEATHER_MESSAGE, UNKNOWN_AWW_REPORT_TYPE, + // DON"T know what this is but WTCH is looking for it + // (isSevereWeatherStatusNotification)? + STATUS_REPORT; - public static AwwReportType getReportType( String rtStr ) { - rtStr = rtStr.trim().replace(" ", "_" ); - for( AwwReportType rt : values() ) { - if( rt.toString().equals( rtStr ) ) { - return rt; - } - } - // WTCH is looking for - if( rtStr.equals("THUNDERSTORM_REPORT" ) ) { - return SEVERE_THUNDERSTORM_WATCH; - } - if( rtStr.endsWith( "STATUS REPORT" ) ) { -// ??? return AwwReportType.SEVERE_WEATHER_STATUS_NOTIFICATION - } - // WSTM is looking for - if( rtStr.equals( "WINTER_STORM" ) ) { - // ??? - } - if( rtStr.equals( "ADVISORY" ) ) { - // ???? WIND CHILL ADVISORY is getting decoded as "ADVISORY"??? - } - return UNKNOWN_AWW_REPORT_TYPE; - } - } + public static AwwReportType getReportType(String rtStr) { + rtStr = rtStr.trim().replace(" ", "_"); + for (AwwReportType rt : values()) { + if (rt.toString().equals(rtStr)) { + return rt; + } + } + // WTCH is looking for + if (rtStr.equals("THUNDERSTORM_REPORT")) { + return SEVERE_THUNDERSTORM_WATCH; + } + if (rtStr.endsWith("STATUS REPORT")) { + // ??? return AwwReportType.SEVERE_WEATHER_STATUS_NOTIFICATION + } + // WSTM is looking for + if (rtStr.equals("WINTER_STORM")) { + // ??? + } + if (rtStr.equals("ADVISORY")) { + // ???? WIND CHILL ADVISORY is getting decoded as "ADVISORY"??? + } + return UNKNOWN_AWW_REPORT_TYPE; + } + } @Column(length = 40) @DataURI(position = 1) @@ -304,17 +280,6 @@ public class AwwRecord extends PluginDataObject { // pugc.setParentID(this); } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - } - /** * @return the designator */ diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java index 6799bf4f97..40d4dc9eb0 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java @@ -1,26 +1,3 @@ -/** - * ConvsigmetRecord - * - * This java class performs the mapping to the database table for CONVSIGMET - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 07/2009 87/114 L. Lin Migration to TO11 - * 09/2011 Chin Chen changed to improve purge performance and - * removed xml serialization as well - * Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime - * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. - * May 07, 2013 1869 bsteffen Remove dataURI column from - * PluginDataObject. - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - package gov.noaa.nws.ncep.common.dataplugin.convsigmet; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @@ -49,6 +26,31 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * ConvsigmetRecord + * + * This java class performs the mapping to the database table for CONVSIGMET + * + * SOFTWARE HISTORY + * + *
+ * Date         Ticket#         Engineer    Description
+ * ------------ ----------      ----------- --------------------------
+ * 03/2009      87/114          L. Lin      Initial coding
+ * 07/2009      87/114          L. Lin      Migration to TO11
+ * 09/2011                      Chin Chen   changed to improve purge performance and
+ *                                          removed xml serialization as well
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013 1857            bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869            bsteffen    Remove dataURI column from
+ *                                          PluginDataObject.
+ * Feb 11, 2014 2784            rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "convsigmetseq") @Table(name = "convsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -291,17 +293,6 @@ public class ConvSigmetRecord extends PluginDataObject { } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java index bf9c24bf61..6975cd6147 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java @@ -1,34 +1,3 @@ -/** - * - * FfgRecord - * - * This java class performs the mapping to the database tables for FFG. - * - *
- * SOFTWARE HISTORY
- *
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 08/2008      14         T. Lee      Initial coding
- * 12/2008      14         T. Lee      Initialized variable
- * 03/2009      14         T. Lee      Migration to TO10
- * 07/2009      14         T. Lee      Migration to TO11
- * 09/2011                 Chin Chen   changed to improve purge performance
- *                                     and  removed xml serialization as
- *                                     well
- * Apr 04, 2013 1846       bkowal      Added an index on refTime and
- *                                     forecastTime
- * Apr 12, 2013 1857       bgonzale    Added SequenceGenerator annotation.
- * May 07, 2013 1869       bsteffen    Remove dataURI column from
- *                                     PluginDataObject.
- * Aug 30, 2013 2298       rjpeter     Make getPluginName abstract
- *
- * 
- * - * @author T.Lee - * @version 1.0 - */ - package gov.noaa.nws.ncep.common.dataplugin.ffg; import java.util.Calendar; @@ -55,6 +24,38 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * + * FfgRecord + * + * This java class performs the mapping to the database tables for FFG. + * + *
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 08/2008      14         T. Lee      Initial coding
+ * 12/2008      14         T. Lee      Initialized variable
+ * 03/2009      14         T. Lee      Migration to TO10
+ * 07/2009      14         T. Lee      Migration to TO11
+ * 09/2011                 Chin Chen   changed to improve purge performance
+ *                                     and  removed xml serialization as
+ *                                     well
+ * Apr 04, 2013 1846       bkowal      Added an index on refTime and
+ *                                     forecastTime
+ * Apr 12, 2013 1857       bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869       bsteffen    Remove dataURI column from
+ *                                     PluginDataObject.
+ * Aug 30, 2013 2298       rjpeter     Make getPluginName abstract
+ * Feb 11, 2014 2784       rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * @author T.Lee + * @version 1.0 + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "ffgseq") @Table(name = "ffg", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -288,22 +289,6 @@ public class FfgRecord extends PluginDataObject { // precip.setParentID (this); } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - /* - * if (this.getFfgP() != null && this.getFfgP().size() > 0) { for - * (Iterator iter = this.getFfgP().iterator(); - * iter.hasNext();) { FfgPrecip fp = iter.next(); - * //fp.setParentID(this); } } - */ - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java index 60b09f4e49..e2fe0b3494 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java @@ -1,28 +1,3 @@ -/** - * IntlsigmetRecord - * - * This java class performs the mapping to the database table for ITNLSIGMET - * - * HISTORY - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 113 L. Lin Initial coding - * 07/2009 113 L. Lin Migration to TO11 - * 05/2010 113 L. Lin Migration to TO11DR11 - * 09/2011 Chin Chen changed to improve purge performance and - * removed xml serialization as well - * Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime - * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. - * May 07, 2013 1869 bsteffen Remove dataURI column from - * PluginDataObject. - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @@ -51,6 +26,32 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * IntlsigmetRecord + * + * This java class performs the mapping to the database table for ITNLSIGMET + * + * SOFTWARE HISTORY + * + *
+ * This code has been developed by the SIB for use in the AWIPS2 system.
+ * Date         Ticket#         Engineer    Description
+ * ------------ ----------      ----------- --------------------------
+ * 06/2009      113             L. Lin      Initial coding
+ * 07/2009      113             L. Lin      Migration to TO11
+ * 05/2010      113             L. Lin      Migration to TO11DR11
+ * 09/2011                      Chin Chen   changed to improve purge performance and
+ *                                          removed xml serialization as well
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013 1857            bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869            bsteffen    Remove dataURI column from         
+ *                                          PluginDataObject.
+ * Feb 11, 2014 2784            rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "intlsigmetseq") @Table(name = "intlsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -575,15 +576,6 @@ public class IntlSigmetRecord extends PluginDataObject { } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncpafm/src/gov/noaa/nws/ncep/common/dataplugin/ncpafm/NcPafmRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncpafm/src/gov/noaa/nws/ncep/common/dataplugin/ncpafm/NcPafmRecord.java index 1063ca2c1b..b97b222e99 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncpafm/src/gov/noaa/nws/ncep/common/dataplugin/ncpafm/NcPafmRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncpafm/src/gov/noaa/nws/ncep/common/dataplugin/ncpafm/NcPafmRecord.java @@ -64,6 +64,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * May 07, 2013 1869 bsteffen Remove dataURI column from * PluginDataObject. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 11, 2014 2784 rferrel Remove override of setIdentifier. * * * @author F. J. Yen, SIB @@ -385,15 +386,6 @@ public class NcPafmRecord extends PersistablePluginDataObject implements return null; } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatRecord.java index 031199a14b..c26133fc4c 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatRecord.java @@ -1,20 +1,3 @@ -/** - * NcscatRecord - * - * This java class performs the mapping to the database table for ASCAT,Quikscat - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 11/2009 Uma Josyula Initial creation - * Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime - * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. - * May 07, 2013 bsteffen Remove dataURI column from PluginDataObject. - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - package gov.noaa.nws.ncep.common.dataplugin.ncscat; import java.util.Calendar; @@ -43,6 +26,26 @@ import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * NcscatRecord + * + * This java class performs the mapping to the database table for ASCAT,Quikscat + * + *
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket Author      Description
+ * ------------ ------ ----------  ----------- --------------------------
+ * 11/2009      Uma Josyula Initial creation    
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013  1857       bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 bsteffen    Remove dataURI column from PluginDataObject.
+ * Feb 11, 2014 2784   rferrel     Remove override of setIdentifier.
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "ncscatseq") @Table(name = "ncscat", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -145,11 +148,6 @@ public class NcscatRecord extends PersistablePluginDataObject { return serialVersionUID; } - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - } - public int getRecordLength() { return recordLength; } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nctaf/src/gov/noaa/nws/ncep/common/dataplugin/nctaf/NcTafRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nctaf/src/gov/noaa/nws/ncep/common/dataplugin/nctaf/NcTafRecord.java index b26e3018a8..092e462b64 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nctaf/src/gov/noaa/nws/ncep/common/dataplugin/nctaf/NcTafRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nctaf/src/gov/noaa/nws/ncep/common/dataplugin/nctaf/NcTafRecord.java @@ -78,6 +78,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools; * May 07, 2013 1869 bsteffen Remove dataURI column from * PluginDataObject. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 11, 2014 2784 rferrel Remove override of setIdentifier. * * * @@ -614,13 +615,6 @@ public class NcTafRecord extends PluginDataObject implements ISpatialEnabled, this.issue_timeString = issue_timeString; } - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - } - /** * Get the IDecoderGettable reference for this record. * diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/NcUairRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/NcUairRecord.java index 6a023c45eb..0f25fa466b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/NcUairRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/NcUairRecord.java @@ -1,31 +1,3 @@ -/** - * NcUairRecord - * - *
- * The java class defines the parameters in the postgres table and
- * the for HDF5 dataset for the upper air data.
- * 
- * Date         Ticket#         Engineer    Description
- * ------------ ----------      ----------- --------------------------
- * 03/2010      210				L. Lin     	Initial creation
- * 4/2011						T. Lee		Persist to HDF5
- * 09/2011      457             S. Gurung   Renamed H5 to Nc and h5 to nc
- * 09/2011                   	Chin Chen   support batch decoding methods for better performance and
- * 											remove xml serialization as well
- * 10/2011                      S. Gurung   Replace slat/slon/selv with location of type SurfaceObsLocation
- * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
- * 04/2013      1293            bkowal      Removed references to hdffileid. 
- * Apr 12, 2013 1857            bgonzale    Added SequenceGenerator annotation.
- * May 07, 2013 1869            bsteffen    Remove dataURI column from
- *                                          PluginDataObject.
- * 
- * 
- * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - package gov.noaa.nws.ncep.common.dataplugin.ncuair; import java.util.Calendar; @@ -60,6 +32,38 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.vividsolutions.jts.geom.Geometry; +/** + * NcUairRecord + * + *
+ * The java class defines the parameters in the postgres table and
+ * the for HDF5 dataset for the upper air data.
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#         Engineer    Description
+ * ------------ ----------      ----------- --------------------------
+ * 03/2010      210             L. Lin      Initial creation
+ * 4/2011                       T. Lee      Persist to HDF5
+ * 09/2011      457             S. Gurung   Renamed H5 to Nc and h5 to nc
+ * 09/2011                      Chin Chen   support batch decoding methods for better performance and
+ *                                          remove xml serialization as well
+ * 10/2011                      S. Gurung   Replace slat/slon/selv with location of type SurfaceObsLocation
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * 04/2013      1293            bkowal      Removed references to hdffileid. 
+ * Apr 12, 2013 1857            bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869            bsteffen    Remove dataURI column from
+ *                                          PluginDataObject.
+ * Feb 11, 2014 2784            rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + * @author L. Lin + * @version 1.0 + */ @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "ncuairseq") @Table(name = "ncuair", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -478,17 +482,6 @@ public class NcUairRecord extends PersistablePluginDataObject implements // li.setParentID(this); } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - } - @Override public SurfaceObsLocation getSpatialObject() { return location; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java index ffd2bd171c..1f8d810b63 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java @@ -1,22 +1,3 @@ -/** - * NonConvsigmetRecord - * - * This java class performs the mapping to the database table for NONCONVSIGMET - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 Uma Josyula Initial creation - * 09/2011 Chin Chen changed to improve purge performance and - * removed xml serialization as well - * Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime - * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. - * May 07, 2013 bsteffen Remove dataURI column from PluginDataObject. - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @@ -45,6 +26,30 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * NonConvsigmetRecord + * + * This java class performs the mapping to the database table for NONCONVSIGMET + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket Author      Description
+ * ------------ ------ ------  ----------- --------------------------
+ * 06/2009      Uma Josyula Initial creation    
+ * 09/2011      Chin Chen   changed to improve purge performance and
+ *                          removed xml serialization as well
+ * Apr 4, 2013        1846 bkowal      Added an index on refTime and forecastTime
+ * Apr 12, 2013       1857 bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 bsteffen    Remove dataURI column from PluginDataObject.
+ * Feb 11, 2014 2784   rferrel    Remove override of setIdentifier.
+ * 
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "nonconvsigmetseq") @Table(name = "nonconvsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -519,17 +524,6 @@ public class NonConvSigmetRecord extends PluginDataObject { } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ntrans/src/gov/noaa/nws/ncep/common/dataplugin/ntrans/NtransRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ntrans/src/gov/noaa/nws/ncep/common/dataplugin/ntrans/NtransRecord.java index 179a35f666..0bb0b26d44 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ntrans/src/gov/noaa/nws/ncep/common/dataplugin/ntrans/NtransRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ntrans/src/gov/noaa/nws/ncep/common/dataplugin/ntrans/NtransRecord.java @@ -1,21 +1,3 @@ -/** - * NtransRecord - * - * This java class performs the mapping to the database table for NTRANS Metafiles - * - *
- * HISTORY
- *
- * Date     	Author		Description
- * ------------	----------	-----------	--------------------------
- * 02/2013		B. Hebbard	Initial creation	
- * Apr 4, 2013  1846 bkowal Added an index on refTime and forecastTime	
- * Apr 12, 2013       1857 bgonzale    Added SequenceGenerator annotation.
- * May 07, 2013 bsteffen    Remove dataURI column from PluginDataObject.
- * 
- * This code has been developed by the SIB for use in the AWIPS2 system.
- */
-
 package gov.noaa.nws.ncep.common.dataplugin.ntrans;
 
 import javax.persistence.Access;
@@ -43,6 +25,27 @@ import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
 import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
 import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
 
+/**
+ * NtransRecord
+ * 
+ * This java class performs the mapping to the database table for NTRANS
+ * Metafiles
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket# Author      Description
+ * ------------ ------- ----------  ----------- --------------------------
+ * 02/2013      B. Hebbard  Initial creation    
+ * Apr 4, 2013  1846 bkowal Added an index on refTime and forecastTime  
+ * Apr 12, 2013       1857 bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 bsteffen    Remove dataURI column from PluginDataObject.
+ * Feb 11, 2014 2784    rferrel     Remove override of setIdentifier.
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "ntransseq") @Table(name = "ntrans", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -235,11 +238,6 @@ public class NtransRecord extends PersistablePluginDataObject { return serialVersionUID; } - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java index 27f67b511b..7d90969610 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java @@ -47,6 +47,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation. * May 07, 2013 1869 bsteffen Remove dataURI column from PluginDataObject. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 11, 2014 2784 rferrel Remove override of setIdentifier. *
* * @author T.Lee @@ -494,16 +495,6 @@ public class TcmRecord extends PluginDataObject { } - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - - } - @Override public IDecoderGettable getDecoderGettable() { // TODO Auto-generated method stub diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java index a04b47479f..3a1fa1b52f 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java @@ -1,34 +1,3 @@ -/** - * WcpRecord is the Data Access component for WCP Watch Corner Point data. - * This contains getters and setters for the main parent table wcp. - * This code has been developed by the SIB for use in the AWIPS2 system. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 12Dec2008    37         F. J. Yen   Initial Coding.
- * 17Apr2009    37         F. J. Yen   Refactored for TO10
- * 24Aug2009    37         F. J. Yen   Refactored for TO11
- * 17May2010    37         F. J. Yen   Refactored to dataplugin for migration to
- *                                     to11dr11
- * 09/2011                 Chin Chen   changed to improve purge performance and
- *                                     removed xml serialization as well
- * Apr 04, 2013 1846       bkowal      Added an index on refTime and
- *                                     forecastTime
- * Apr 12, 2013 1857       bgonzale    Added SequenceGenerator annotation.
- * May 07, 2013 1869       bsteffen    Remove dataURI column from
- *                                     PluginDataObject.
- * Aug 30, 2013 2298       rjpeter     Make getPluginName abstract
- * 
- * 
- * - * @author F. J. Yen, SIB - * @version 1.0 - */ - package gov.noaa.nws.ncep.common.dataplugin.wcp; import java.util.Calendar; @@ -55,6 +24,37 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +/** + * WcpRecord is the Data Access component for WCP Watch Corner Point data. This + * contains getters and setters for the main parent table wcp. This code has + * been developed by the SIB for use in the AWIPS2 system. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 12Dec2008    37         F. J. Yen   Initial Coding.
+ * 17Apr2009    37         F. J. Yen   Refactored for TO10
+ * 24Aug2009    37         F. J. Yen   Refactored for TO11
+ * 17May2010    37         F. J. Yen   Refactored to dataplugin for migration to
+ *                                     to11dr11
+ * 09/2011                 Chin Chen   changed to improve purge performance and
+ *                                     removed xml serialization as well
+ * Apr 04, 2013 1846       bkowal      Added an index on refTime and
+ *                                     forecastTime
+ * Apr 12, 2013 1857       bgonzale    Added SequenceGenerator annotation.
+ * May 07, 2013 1869       bsteffen    Remove dataURI column from
+ *                                     PluginDataObject.
+ * Aug 30, 2013 2298       rjpeter     Make getPluginName abstract
+ * Feb 11, 2014 2784       rferrel     Remove override of setIdentifier.
+ * 
+ * 
+ * + * @author F. J. Yen, SIB + * @version 1.0 + */ @Entity @SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "wcpseq") @Table(name = "wcp", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) @@ -172,12 +172,6 @@ public class WcpRecord extends PluginDataObject { } - @Override - public void setIdentifier(Object dataURI) { - this.identifier = dataURI; - - } - @Override @Column @Access(AccessType.PROPERTY) diff --git a/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml b/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml index 2fe290a42b..5ed9a3a3d2 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml @@ -36,7 +36,7 @@ autoStartup="false"> - + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml index 867cee8113..fbdc17c4e2 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml @@ -12,7 +12,7 @@ - + - + - + @@ -65,12 +53,12 @@ ncgrib - + - + ncgrib diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml index dba9ae8fc6..902d9bf772 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml @@ -15,7 +15,7 @@ - + - + - + - + - + - + - + - + - + - + - + - - @@ -27,7 +15,7 @@ - + - + - + - + - + - - - - - - - - - - - - @@ -25,10 +11,10 @@ - + - + diff --git a/rpms/awips2.core/Installer.ant/scripts/profile.d/awips2Ant.csh b/rpms/awips2.core/Installer.ant/scripts/profile.d/awips2Ant.csh index b0d5da3f7d..3ee35cb6ae 100644 --- a/rpms/awips2.core/Installer.ant/scripts/profile.d/awips2Ant.csh +++ b/rpms/awips2.core/Installer.ant/scripts/profile.d/awips2Ant.csh @@ -1,8 +1,7 @@ #!/bin/csh # Determine where ant has been installed. -set ANT_INSTALL=`rpm -q --queryformat '%{INSTALLPREFIX}' awips2-ant` -setenv ANT_HOME "${ANT_INSTALL}" +setenv ANT_INSTALL "/awips2/ant" if $?PATH then setenv PATH ${ANT_INSTALL}/bin:$PATH diff --git a/rpms/build/x86_64/build.sh b/rpms/build/x86_64/build.sh index e15fbc57ca..0f45a7b5cd 100644 --- a/rpms/build/x86_64/build.sh +++ b/rpms/build/x86_64/build.sh @@ -456,8 +456,9 @@ if [ "${1}" = "-custom" ]; then #buildRPM "awips2-alertviz" #buildRPM "awips2-python" #buildRPM "awips2-alertviz" + buildRPM "awips2-ant" #buildRPM "awips2-eclipse" - buildRPM "awips2-python" + #buildRPM "awips2-python" exit 0 fi From 16117255f39233daba9577fe24c37b3a91f56030 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Wed, 26 Feb 2014 17:39:15 -0500 Subject: [PATCH 3/5] OB_14.1.1-20 baseline Former-commit-id: 324696c43681f4c0c7216c3d7a5e5559fa5a5c3f [formerly bdb1c79ea2557e4e830a4d1c8782a3a1dc3776de] Former-commit-id: 2bad40cfeeaa6038da50428a029b0edec6759572 --- cave/build/cave/customTargets.xml | 33 +++++++- cave/build/cave/memorySettings.xml | 58 +++++++++++++- .../cave/etc/aviation/thresholds/KUES.hdf5 | Bin 0 -> 169287 bytes cave/build/static/linux/cave/caveUtil.sh | 9 ++- .../META-INF/MANIFEST.MF | 3 +- .../cave/refresh/DataRefreshTask.java | 19 ++++- .../refresh/ThinClientDataUpdateTree.java | 73 ++++++++++++++++++ .../viz/aviation/editor/EditorTafTabComp.java | 11 ++- .../aviation/editor/TafViewerEditorDlg.java | 38 ++++++++- .../raytheon/viz/grid/inv/RadarUpdater.java | 9 ++- .../raytheon/viz/grid/util/RadarAdapter.java | 21 +++++ .../res/spring/event-ingest.xml | 21 ----- .../raytheon/uf/edex/plugin/qc/QCScanner.java | 17 ++-- rpms/build/x86_64/build.sh | 2 +- 14 files changed, 276 insertions(+), 38 deletions(-) create mode 100644 cave/build/static/common/cave/etc/aviation/thresholds/KUES.hdf5 mode change 100755 => 100644 cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java delete mode 100644 edexOsgi/com.raytheon.uf.edex.event/res/spring/event-ingest.xml diff --git a/cave/build/cave/customTargets.xml b/cave/build/cave/customTargets.xml index 8fd76c7cdc..e99c1784d2 100644 --- a/cave/build/cave/customTargets.xml +++ b/cave/build/cave/customTargets.xml @@ -270,7 +270,7 @@ + value="4.0"/> + + + + + + + + + + + + + + + + + diff --git a/cave/build/cave/memorySettings.xml b/cave/build/cave/memorySettings.xml index 65a6c0c1e1..7f82b6136d 100644 --- a/cave/build/cave/memorySettings.xml +++ b/cave/build/cave/memorySettings.xml @@ -2,7 +2,7 @@ - 3.0 + 4.0 + + + wfo + + + 3072M + + + + DEFAULT + + + + + + rfc + + + 2048M + + + + DEFAULT + + + + + + ncep + + + 2048M + + + + DEFAULT + + + + + + cwsu + + + 3072M + + + + DEFAULT + + + + diff --git a/cave/build/static/common/cave/etc/aviation/thresholds/KUES.hdf5 b/cave/build/static/common/cave/etc/aviation/thresholds/KUES.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..b15ccbef01de813747d146971f18c38c069e2174 GIT binary patch literal 169287 zcmeFa1z1#H+y6^T3@P0)lnyCUg5=OCIdlyn-JqmOBi$*8fRvPUheHZ7A|N0Q0@5NS zaPTL-=Y7s!-t(O6dd~6uy=HsO+-u!y?R)R_@t!r`z4jgrlarRg#iqnY`mteRBB3D> zAff(K`T2H!xydG?{Nwml|JCK$WoP6|N5Eyl&v;vn_@X`wXv^R!A!AMBxNWZxLvcGnlMf+Kz zzjPGh{Va%I*13s)7ECVdbre4f0he`gx}Sx%%R0jR??nI^>H0r8MSpqP1Q(yrADiIk zpN`pI3HP&l(U<9G4qp1vkud+MBcr1H%#olm*}F$kL}0N*Q9Ob0Z43@b&QJ^Oe85K2@Q=4&-IHJ#>MOBSt226N=PbQe1I;t zpIrVa{SMyl;13ZE%{wxnK*ws8v{s0eXHd@j41$G1PggL&xB@*wBCn#cTqkjGCQhjyt7k&twM3Co{{|6ksJ zU4L2syt4gY+J89&FAH8czdXOU;+O7F!0+4tck%wax&?jW&*qhG(odql({a21!Myr+ zc`VKUSssN-SMyl@13bFF{8=8Dvsd#t{{uW;eEYLJtnIJnvHlPSC|l%a83(T~8Md{UrLkdHD1{ zm{4iLHIKzVzynPDXL;1+U(I9x5Aa~7{j)qU4X@_$`9H|x*F0?f^KeM? zKNd#+ht27-&5PuJ=ycKKb=e$B`akyzxNJ@#`=9&$|Go9!op;dL{%l^!wf-deyLtHN zKbTklE{`RiKg)wH>S`W4e}G5#oj=PXH0x>}U;hA)7vMk3qmJon9y9+z9zW+{Or+4C zheIm-b;IYf{(m(wzZ_J*3ct50mu>>;-?#trKD#W?)BN)M-WFcExoLmj{>xi_SqP>7 z<@vp>yL6{8{J#B{x9ze}$oR|id;9OsJ3*>{Hm^S4{CWPrn}=urgL(Du@_<7AERPiT zt9fkv0UluUKg;7V=xQF@|3MxKoIyF30$QYOt1KT95UL^=Our!K4l*y))#na z5PISFBoST&0R#aA0R#aAfxnl)ReAyS3cY{?MCgUTHyaQmLl8g^KoCF>KoIynfvfaF z#})S@P;Vgg!tY5Uya)ma0tf;K0tfP2)*$4 zW&>hm2m%NK2m%NK2m-$+aFt#_y5jeg*lGy9@OzR7FMKoIynf&Zs^p}`8F7k*C?;YAQY5I_(>5I_+4 zdkI{n7nH7e-tmP!LNENi*?<@sf&hX5f&hX5g23+yT%{L`uFwlRt_Z#Gdy)t*f&hX5 zf&hX5g23NP;3~cF;fm)MR39Mp!rz+>h>;-(AP67`AP67`{GPy7dST)Uy%6x_U*p`m ztg8I08&N|LKoCF>KoCF>KoIzg2oN9<{4*Narzrnea@3!L10ae2Q$W7>hnp}j{%Fc; zDuFLN*Dqew7q4Hd42oJ{4SF>fM>A718#@~}Z+cB@7pSYXqn(B8Kl=la*#5D<;z%h; zXlPt`e#H54%i~uZ*?X#5Y8UnYv;U8yVj^jS?`g=Zs{GR*?Z5Ts;k7-+|AJi+ldF8&D_n@%ns_x zsRT8(#FnwKbA!6LVmt9-n;RROxnERm9E^>z9nJ1T&E2q_Zegpq-E-o@X0vd*jjh4z zYVB@mX$NJ+cH+mD=fQT>U^RENcd~~pou-~a%MJhmizb?iBYA%Fgq;$co1e

@Gfp3Fx<2P{H(N}s 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 literal 0 HcmV?d00001 diff --git a/cave/build/static/linux/cave/caveUtil.sh b/cave/build/static/linux/cave/caveUtil.sh index b15bf1c132..df1dcb049f 100644 --- a/cave/build/static/linux/cave/caveUtil.sh +++ b/cave/build/static/linux/cave/caveUtil.sh @@ -29,6 +29,7 @@ # Jan 30, 2014 #2593 bclement extracted generic part of getPidsOfMyRunningCaves into forEachRunningCave # added methods for reading max memory from .ini files # fixes for INI files with spaces +# Feb 20, 2014 #2780 bclement added site type ini file check # # @@ -68,7 +69,13 @@ function lookupINI() if [ ${RC} -eq 0 ]; then export CAVE_INI_ARG="--launcher.ini /awips2/cave/${ASSOCIATED_INI}" else - export CAVE_INI_ARG="--launcher.ini /awips2/cave/cave.ini" + siteTypeIni="/awips2/cave/${SITE_TYPE}.ini" + if [[ -e ${siteTypeIni} ]] + then + export CAVE_INI_ARG="--launcher.ini ${siteTypeIni}" + else + export CAVE_INI_ARG="--launcher.ini /awips2/cave/cave.ini" + fi fi return 0 fi diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.thinclient.cave/META-INF/MANIFEST.MF index be854e77a5..7510bc3505 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.thinclient.cave/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: com.raytheon.uf.viz.core, com.raytheon.viz.core;bundle-version="1.12.1174", com.raytheon.viz.ui;bundle-version="1.12.1174", com.raytheon.viz.alerts;bundle-version="1.12.1174", - com.raytheon.uf.viz.thinclient;bundle-version="1.0.0" + com.raytheon.uf.viz.thinclient;bundle-version="1.0.0", + com.raytheon.viz.grid;bundle-version="1.12.1174" Import-Package: com.raytheon.uf.common.comm, com.raytheon.uf.common.datastorage, com.raytheon.uf.viz.core.maps.rsc, diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/DataRefreshTask.java b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/DataRefreshTask.java index a07089df10..ebffd8b5f0 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/DataRefreshTask.java +++ b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/DataRefreshTask.java @@ -19,12 +19,17 @@ **/ package com.raytheon.uf.viz.thinclient.cave.refresh; +import java.util.ArrayList; +import java.util.Collection; + import org.eclipse.jface.preference.IPreferenceStore; +import com.raytheon.uf.viz.core.alerts.AlertMessage; import com.raytheon.uf.viz.thinclient.Activator; import com.raytheon.uf.viz.thinclient.preferences.ThinClientPreferenceConstants; import com.raytheon.uf.viz.thinclient.refresh.TimedRefresher.RefreshTimerTask; import com.raytheon.viz.alerts.jobs.AutoUpdater; +import com.raytheon.viz.alerts.observers.ProductAlertObserver; /** * Timer task responsible for refreshing IEditorParts that implement @@ -38,6 +43,7 @@ import com.raytheon.viz.alerts.jobs.AutoUpdater; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Nov 10, 2011 mschenke Initial creation + * Feb 21, 2014 DR 16744 D. Friedman Update all alert observers * *

* @@ -56,8 +62,17 @@ public class DataRefreshTask implements RefreshTimerTask { public void run() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); if (store.getBoolean(ThinClientPreferenceConstants.P_DISABLE_JMS)) { - new AutoUpdater().alertArrived(ThinClientDataUpdateTree - .getInstance().updateAllData()); + Collection alerts = ThinClientDataUpdateTree + .getInstance().updateAllData(); + + // Make sure it gets to GridUpdater + ArrayList s = new ArrayList(alerts.size()); + for (AlertMessage am : alerts) { + s.add(am.dataURI); + } + ProductAlertObserver.processDataURIAlerts(s); + + new AutoUpdater().alertArrived(alerts); } } diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/ThinClientDataUpdateTree.java b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/ThinClientDataUpdateTree.java index 333d5db5d8..59544005c7 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/ThinClientDataUpdateTree.java +++ b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/refresh/ThinClientDataUpdateTree.java @@ -30,8 +30,10 @@ import java.util.Set; import java.util.TimeZone; import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -46,6 +48,8 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; import com.raytheon.uf.viz.core.rsc.AbstractResourceData; import com.raytheon.uf.viz.core.rsc.updater.DataUpdateTree; +import com.raytheon.viz.grid.inv.RadarUpdater; +import com.raytheon.viz.grid.util.RadarAdapter; /** * TODO Add Description @@ -57,6 +61,7 @@ import com.raytheon.uf.viz.core.rsc.updater.DataUpdateTree; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Dec 13, 2011 bsteffen Initial creation + * Feb 21, 2014 DR 16744 D. Friedman Add radar/grid updates * * * @@ -125,9 +130,77 @@ public class ThinClientDataUpdateTree extends DataUpdateTree { e); } } + getRadarUpdates(time, messages); + getGridUpdates(time, messages); return messages; } + /** + * Get radar update messages. This is needed to update the + * radar-as-gridded-data inventory. + */ + private void getRadarUpdates(String time, Set messages) { + Set radarMessages = new HashSet(); + Map metadata = RadarAdapter.getInstance().getUpdateConstraints(); + metadata = new HashMap(metadata); + metadata.put("insertTime", new RequestConstraint(time, + ConstraintType.GREATER_THAN)); + LayerProperty property = new LayerProperty(); + try { + property.setEntryQueryParameters(metadata, false); + List records = DataCubeContainer.getData(property, + 60000); // 60-second timeout + if (records != null && !records.isEmpty()) { + for (Object record : records) { + if (record instanceof PluginDataObject) { + PluginDataObject pdo = (PluginDataObject) record; + AlertMessage am = new AlertMessage(); + am.dataURI = pdo.getDataURI(); + am.decodedAlert = RecordFactory.getInstance() + .loadMapFromUri(am.dataURI); + radarMessages.add(am); + } + } + } + messages.addAll(radarMessages); + for (String dataURI: RadarUpdater.getInstance().convertRadarAlertsToGridDatauris(radarMessages)) { + AlertMessage am = new AlertMessage(); + am.dataURI = dataURI; + am.decodedAlert = RecordFactory.getInstance() + .loadMapFromUri(am.dataURI); + messages.add(am); + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + + /** Get gridded data update messages. */ + private void getGridUpdates(String time, Set messages) { + Map newQuery = new HashMap(); + DbQueryRequest dbRequest = new DbQueryRequest(); + newQuery.put("pluginName", new RequestConstraint("grid")); + newQuery.put("insertTime", new RequestConstraint(time, + ConstraintType.GREATER_THAN)); + dbRequest.setConstraints(newQuery); + dbRequest.addRequestField("dataURI"); + DbQueryResponse response = null; + try { + response = (DbQueryResponse) ThriftClient.sendRequest(dbRequest); + for (String dataURI: response.getFieldObjects("dataURI", String.class)) { + AlertMessage am = new AlertMessage(); + am.dataURI = dataURI; + am.decodedAlert = RecordFactory.getInstance() + .loadMapFromUri(am.dataURI); + messages.add(am); + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + /** * Get the estimated difference between the clock on the server and the * local clock. The offset returned from this method will always be slightly diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java old mode 100755 new mode 100644 index b33b68b36d..7382bed6d4 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java @@ -73,7 +73,8 @@ import com.raytheon.viz.aviation.resource.ResourceConfigMgr.ResourceTag; * text height and width. * 12/9/2010 7380 rferrel Adjust text size to be more like AWIPS I. * 1/17/2011 7782 rferrel Added qcSkipCheck to mimic A1. - * 3/18/2011 7888 rferrel Added getLargeTF method. + * 3/18/2011 7888 rferrel Added getLargeTF method. + * 02/19/2014 16980 zhao added getter and setter for the Alt flag * * * @@ -1368,4 +1369,12 @@ public class EditorTafTabComp extends Composite { rtdRdo.setEnabled(editable); corRdo.setEnabled(editable); } + + public boolean getAlt() { + return alt; + } + + public void setAlt(boolean b) { + alt = b; + } } diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java index db32e1ef6a..b1e55b751d 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java @@ -80,8 +80,10 @@ import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; @@ -226,6 +228,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * 01/09/2013 15528 zhao Modified saveFile() and restoreFile() * 10/24/2013 16478 zhao add syntax check for extra '=' sign * 02/12/2014 17076 lvenable Mark guidance tabs as not current so they get refreshed + * 02/19/2014 16980 zhao add code to ensure the Alt flag is false after the Alt kay is released * * * @@ -1088,6 +1091,11 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Create the File menu item with a File "dropdown" menu Menu fileMenu = new Menu(menuBar); fileMenuItem.setMenu(fileMenu); + fileMenu.addListener(SWT.Show, new Listener() { + public void handleEvent(Event event) { + setAltFlagForEditorTafTabComp(); + } + }); // ------------------------------------------------- // Create all the items in the File dropdown menu @@ -1194,6 +1202,11 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Create the Options menu item with a Options "dropdown" menu Menu optionsMenu = new Menu(menuBar); optionsMenuItem.setMenu(optionsMenu); + optionsMenu.addListener(SWT.Show, new Listener() { + public void handleEvent(Event event) { + setAltFlagForEditorTafTabComp(); + } + }); // ---------------------------------------------------- // Create all the items in the Options dropdown menu @@ -1268,7 +1281,12 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Create the File menu item with a File "dropdown" menu Menu editMenu = new Menu(menuBar); editMenuItem.setMenu(editMenu); - + editMenu.addListener(SWT.Show, new Listener() { + public void handleEvent(Event event) { + setAltFlagForEditorTafTabComp(); + } + }); + // ------------------------------------------------- // Create all the items in the Edit dropdown menu // ------------------------------------------------- @@ -1342,6 +1360,19 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, } }); } + + /** + * When respectively using alt+'f', alt+'e', alt+'o' and alt+'h' + * to open/display menus 'File', 'Edit', 'Options' and 'Help', + * the alt flag of the editorTafTabComp object is set to true; + * it needs to be re-set to false + * (DR16980) + */ + private void setAltFlagForEditorTafTabComp() { + if ( editorTafTabComp.getAlt() ) { + editorTafTabComp.setAlt(false); + } + } /** * Create the Help menu. @@ -1359,6 +1390,11 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Create the File menu item with a File "dropdown" menu Menu helpMenu = new Menu(menuBar); helpMenuItem.setMenu(helpMenu); + helpMenu.addListener(SWT.Show, new Listener() { + public void handleEvent(Event event) { + setAltFlagForEditorTafTabComp(); + } + }); // ------------------------------------------------- // Create all the items in the Help dropdown menu diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java index f74e5ce966..90e9186064 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java @@ -40,6 +40,7 @@ import com.raytheon.viz.grid.util.RadarProductCodeMapping; * ------------ ---------- ----------- -------------------------- * Sep 20, 2012 bsteffen Initial creation * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 21, 2014 DR 16744 D. Friedman Support thin client updates * * * @@ -150,10 +151,14 @@ public class RadarUpdater implements IAlertObserver { @Override public void alertArrived(Collection alertMessages) { + ProductAlertObserver.processDataURIAlerts(convertRadarAlertsToGridDatauris(alertMessages)); + } + + public Set convertRadarAlertsToGridDatauris(Collection alertMessages) { RadarStation configuredRadar = RadarAdapter.getInstance() .getConfiguredRadar(); if (configuredRadar == null) { - return; + return new HashSet(); } Set datauris = new HashSet(); for (AlertMessage alertMessage : alertMessages) { @@ -209,7 +214,7 @@ public class RadarUpdater implements IAlertObserver { "Unable to generate updates for derived product", e); } } - ProductAlertObserver.processDataURIAlerts(datauris); + return datauris; } private CacheKey getCacheKey(RadarRequestableLevelNode rNode) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/RadarAdapter.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/RadarAdapter.java index 73b1053f59..8154c29cec 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/RadarAdapter.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/RadarAdapter.java @@ -20,6 +20,7 @@ package com.raytheon.viz.grid.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -80,6 +81,7 @@ import com.raytheon.viz.radar.util.StationUtils; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 23, 2010 #4473 rjpeter Initial creation + * Feb 21, 2014 DR 16744 D. Friedman Add getUpdateConstraints * * * @@ -394,4 +396,23 @@ public class RadarAdapter { return rval; } + + public Map getUpdateConstraints() { + RadarProductCodeMapping rpcMap = RadarProductCodeMapping.getInstance(); + HashSet productCodes = new HashSet(); + for (String abbrev : rpcMap.getParameterAbbrevs()) { + productCodes.addAll(rpcMap.getProductCodesForAbbrev(abbrev)); + } + Map rcMap = new HashMap(); + rcMap.put(RadarAdapter.PLUGIN_NAME_QUERY, new RequestConstraint( + RADAR_SOURCE)); + rcMap.put(ICAO_QUERY, new RequestConstraint(getConfiguredRadar() + .getRdaId().toLowerCase())); + rcMap.put( + PRODUCT_CODE_QUERY, + new RequestConstraint(Arrays.toString(new ArrayList( + productCodes).toArray()), + RequestConstraint.ConstraintType.IN)); + return rcMap; + } } diff --git a/edexOsgi/com.raytheon.uf.edex.event/res/spring/event-ingest.xml b/edexOsgi/com.raytheon.uf.edex.event/res/spring/event-ingest.xml deleted file mode 100644 index 9a2ecd4632..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.event/res/spring/event-ingest.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.qc/src/com/raytheon/uf/edex/plugin/qc/QCScanner.java b/edexOsgi/com.raytheon.uf.edex.plugin.qc/src/com/raytheon/uf/edex/plugin/qc/QCScanner.java index 5c77463dda..f84d8bd4e9 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.qc/src/com/raytheon/uf/edex/plugin/qc/QCScanner.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.qc/src/com/raytheon/uf/edex/plugin/qc/QCScanner.java @@ -59,6 +59,7 @@ import com.raytheon.uf.edex.plugin.qc.dao.QCDao; * pupynere * May 16, 2013 1869 bsteffen Remove DataURI column from qc. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract + * Feb 20, 2014 DR 17098 D. Friedman Filter out invalid lat/lon values. * * * @@ -207,13 +208,15 @@ public class QCScanner { while (ri < records.length) { QCRecord r = new QCRecord(); double obsTime = dObsTime.getDouble(ri); + double lat = dLat.getDouble(ri); + double lon = dLon.getDouble(ri); if ((obsTime != vObsTimeFillValue) - && ((vObsTimeMissingValue == null) || (vObsTimeMissingValue != obsTime))) { + && ((vObsTimeMissingValue == null) || (vObsTimeMissingValue != obsTime)) + && Math.abs(lon) <= 180 && Math.abs(lat) <= 90) { r.setDataTime(new DataTime(new Date( (long) (obsTime * 1000)))); SurfaceObsLocation loc = new SurfaceObsLocation(); - loc.assignLocation(dLat.getDouble(ri), - dLon.getDouble(ri)); + loc.assignLocation(lat, lon); loc.setElevation(dElev.getInt(ri)); StringBuilder stationId = new StringBuilder( ID_LENGTH); @@ -230,10 +233,12 @@ public class QCScanner { ++index; ++ri; } - if (oi < records.length) { - records = Arrays.copyOf(records, oi); + if (oi > 0) { + if (oi < records.length) { + records = Arrays.copyOf(records, oi); + } + target.acceptRecords(records); } - target.acceptRecords(records); } } finally { nc.close(); diff --git a/rpms/build/x86_64/build.sh b/rpms/build/x86_64/build.sh index 0f45a7b5cd..e3043a6207 100644 --- a/rpms/build/x86_64/build.sh +++ b/rpms/build/x86_64/build.sh @@ -411,7 +411,7 @@ if [ "${1}" = "-viz" ]; then buildRPM "awips2" buildRPM "awips2-common-base" #buildRPM "awips2-python-numpy" - buildRPM "awips2-ant" + #buildRPM "awips2-ant" #buildRPM "awips2-python-dynamicserialize" #buildRPM "awips2-python" #buildRPM "awips2-adapt-native" From 7cad374af58f4a2b974b53742112cf9c4074a876 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Tue, 4 Mar 2014 11:47:42 -0500 Subject: [PATCH 4/5] OB_14.1.1-21 baseline Former-commit-id: 1d92e5bab6f2f86483cf869e91874dbb5896a928 [formerly d220320ed3c6e9a0fe9fe26d83dd71eec6eafa0b] Former-commit-id: 29681c7ca46274a331f6311fb453de7b86432fb5 --- .../gfe/userPython/procedures/MergeHazards.py | 703 +++++++++--------- .../gfe/userPython/utilities/SmartScript.py | 14 + edexOsgi/build.edex/esb/conf/modes.xml | 4 +- .../res/spring/obs-ingest-decode.xml | 42 ++ .../res/spring/obs-ingest-metarshef.xml | 41 + .../res/spring/obs-ingest.xml | 37 +- 6 files changed, 458 insertions(+), 383 deletions(-) create mode 100644 edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-decode.xml create mode 100644 edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml diff --git a/cave/build/static/common/cave/etc/gfe/userPython/procedures/MergeHazards.py b/cave/build/static/common/cave/etc/gfe/userPython/procedures/MergeHazards.py index 337454975f..6981218183 100644 --- a/cave/build/static/common/cave/etc/gfe/userPython/procedures/MergeHazards.py +++ b/cave/build/static/common/cave/etc/gfe/userPython/procedures/MergeHazards.py @@ -1,61 +1,70 @@ ## # 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. ## -# ---------------------------------------------------------------------------- -# This software is in the public domain, furnished "as is", without technical -# support, and with no warranty, express or implied, as to its usefulness for -# any purpose. -# -# MergeHazards -# -# Author: lefebvre -# -# This procedure reads all of the temporary hazard grids and selectively -# loads them in the the "Hazards" grid. -# ---------------------------------------------------------------------------- - -# The MenuItems list defines the GFE menu item(s) under which the -# Procedure is to appear. -# Possible items are: Populate, Edit, Consistency, Verify, Hazards -MenuItems = ["Hazards"] - -#import Tkinter -import SmartScript -import string -import HazardUtils -import VTECTable -import LogStream -import numpy -from MessageBox import MessageBox - -from HazardUtils import MODEL -from HazardUtils import ELEMENT -from HazardUtils import LEVEL - -######################### CONFIGURATION SECTION ###################### -# -# This dictionary defines which hazards cannot be combined with other -# Hazards. The structure lists each hazard in the VTECTable followed -# by a list of VTEC codes that may not be combined with it at the same -# grid point. For example "DS.W" : ["DU.Y"] means that DS.W may not -# be combined with a DU.Y hazard at the same grid point. - +# ---------------------------------------------------------------------------- +# This software is in the public domain, furnished "as is", without technical +# support, and with no warranty, express or implied, as to its usefulness for +# any purpose. +# +# MergeHazards +# +# Author: lefebvre +# +# This procedure reads all of the temporary hazard grids and selectively +# loads them in the the "Hazards" grid. +# ---------------------------------------------------------------------------- +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# Dec 23, 2013 16893 ryu Check in njensen's change to removeTempHazards() +# to call SmartScript.unloadWEs(). +# +######################################################################## + +# The MenuItems list defines the GFE menu item(s) under which the +# Procedure is to appear. +# Possible items are: Populate, Edit, Consistency, Verify, Hazards +MenuItems = ["Hazards"] + +#import Tkinter +import SmartScript +import string +import HazardUtils +import VTECTable +import LogStream +import numpy +from MessageBox import MessageBox + +from HazardUtils import MODEL +from HazardUtils import ELEMENT +from HazardUtils import LEVEL + +######################### CONFIGURATION SECTION ###################### +# +# This dictionary defines which hazards cannot be combined with other +# Hazards. The structure lists each hazard in the VTECTable followed +# by a list of VTEC codes that may not be combined with it at the same +# grid point. For example "DS.W" : ["DU.Y"] means that DS.W may not +# be combined with a DU.Y hazard at the same grid point. + HazardsConflictDict = { "AF.W" : ["AF.Y"], "AF.Y" : ["AF.W"], @@ -187,301 +196,303 @@ HazardsConflictDict = { "ZR.Y" : ["BZ.A", "LE.A", "WS.A", "BZ.W", "IS.W", "WS.W", "LE.W", "WW.Y", "LE.Y"], } - -########################## END OF CONFIGURATION SECTION ######################## - -class Procedure(SmartScript.SmartScript): - def __init__(self, dbss): - SmartScript.SmartScript.__init__(self, dbss) - self._dbss = dbss - - ## - # Get the list of loaded temporary hazard parms - # @return: Temporary hazard parm names, i.e., ["hazAFY"] - # @rtype: List of Strings - def getHazardParmNames(self): - parms = self.loadedParms() - hazParms = [] - for weName, level, dbID in parms: - if string.find(weName, "haz") == 0: - # TODO: Why is this back/forth xform needed? - key = self._hazUtils._tempWENameToKey(weName) - index = string.find(key, ":") - if index != -1: - mkey = key[0:index] - segNum = key[index+1:] - else: - mkey = key - segNum = "" - - # append the hazard and a description - parmName = "haz" + key - parmName = string.replace(parmName, ".", "") - parmName = string.replace(parmName, ":", "") - hazParms.append(parmName) - - return hazParms - - ## - # Unload (delete) all the temporary hazards - def removeTempHazards(self): - parms = self.loadedParms() - - for weName, level, dbID in parms: - if string.find(weName, "haz") == 0: - self.unloadWE(MODEL, weName, level) - - return - - ## - # The action performed when the user opts to cancel a merge. - # This was a callback under Tcl/tk; now displayDialog invokes - # it directly. - def cancelCommand(self): - LogStream.logEvent("MergeHazards: cancel") - return - - ## - # The action performed when the user opts to continue a merge. - # This was a callback under Tcl/tk; now displayDialog invokes - # it directly. - def continueCommand(self): - LogStream.logEvent("MergeHazards: continue") - parm = self.getParm(MODEL, ELEMENT, LEVEL) - parm.setMutable(True) - self.mergeHazardGrids() - return - - ## - # Displays a dialog box and queries the user to continue to merge or - # abort the merge - def displayDialog(self, message): - messageBox = MessageBox(style=MessageBox.ICON_WARNING) - messageBox.setText("MakeHazard") - messageBox.setMessage(message) - messageBox.setButtonLabels(["Continue Merge", "Cancel Merge"]) - messageBox.setDefaultIndex(1) - if (messageBox.open() == 0): - self.continueCommand() - else: - self.cancelCommand() - - return - - ## - # Returns the set of hazParms grids that overlap with the specified - # timeRange. - # @param hazParms: Hazard parm names to check - # @type hazParms: Sequence of string - # @param timeRange: The time range to check for overlap with - # @type timeRange: Python TimeRange - # @return: Byte grids and keys of the overlapping parms - # @rtype: 2-tuple: list of byte arrays, list of list of strings - def getOverlappingHazGrids(self, hazParms, timeRange): - byteGridList = [] - keyList = [] - for hazParm in hazParms: - trList = self._hazUtils._getWEInventory(hazParm) - for tr in trList: - if tr.overlaps(timeRange): - byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, - tr, mode="First") - if isinstance(hazKey, str): - hazKey = eval(hazKey) - byteGridList.append(byteGrid) - keyList.append(hazKey) - - return byteGridList, keyList - - ## - # Returns the first non-None key it finds in the keyList - # @param keyList: Keys to search - # @type keyList: Sequence of string - # @return: First key that is not "" - # @rtype: string - def getHazardKey(self, keyList): - for k in keyList: - if k != "": - return k - - ## - # Checks the specified hazard grids to see if they are conflicting - # Each grid is a tuple (byteGrid, key). Uses the configurable - # HazardConflictDict to determine whether two hazards can be combined - # at the same grid point. Returns an empty list if no conflict or - # the list of hazards if they do. - # - # This method should really only be used internally; it assumes that - # there is at most one key other than "", and that it contains - # a single subkey. - # - # @param hazGrid1: The first hazard grid - # @type hazGrid1: 2-tuple: numpy array of int8, list of String - # @param hazGrid2: The second hazard grid - # @type hazGrid2: 2-tuple: numpy array of int8, list of String - # @return: conflicting hazard names or empty list - # @rtype: list - def conflictingHazards(self, hazGrid1, hazGrid2): - byteGrid1, hazKey1 = hazGrid1 - byteGrid2, hazKey2 = hazGrid2 - - key1 = self.getHazardKey(hazKey1) - key2 = self.getHazardKey(hazKey2) - phenSig1 = key1[0:4] # remove the etn - phenSig2 = key2[0:4] - - keyConflict = False - if phenSig1 == phenSig2 and key1 != key2: - keyConflict = True - elif HazardsConflictDict.has_key(phenSig1): - if phenSig2 in HazardsConflictDict[phenSig1]: - keyConflict = True - - if keyConflict: - # calculate the overlap, adding the grids together will tell us if - # there is any overlap. Any grid points > 1 are overlapped - totalGrid = byteGrid1 + byteGrid2 - overlapMask = numpy.greater(totalGrid, 1) - if numpy.any(overlapMask): - return [key1, key2] - - return [] - - ## - # See if there are any temporary hazards for the same position and time - # that conflict with one another. - # - # @param hazParms: Temporary hazard parm names to check. - # @type hazParms: sequence of string - # @return: The first conflict, or None if there are no conflicts - # @rtype: 2-tuple(TimeRange, list of string) or NoneType - def checkForHazardConflicts(self, hazParms): - timeList = [] - for hazParm in hazParms: - trList = self._hazUtils._getWEInventory(hazParm) - for tr in trList: - if tr.startTime().unixTime() not in timeList: - timeList.append(tr.startTime().unixTime()) - if tr.endTime().unixTime() not in timeList: - timeList.append(tr.endTime().unixTime()) - - timeList.sort() # sort the list - - for t in xrange(len(timeList) - 1): - start = timeList[t] - end = timeList[t+1] - timeRange = self._hazUtils._makeTimeRange(start, end) - byteGridList = [] - keyList = [] - byteGridList, keyList = self.getOverlappingHazGrids(hazParms, timeRange) - # compare each grid to all other grids at this timeRange - for firstIndex in xrange(len(byteGridList) - 1): - for secondIndex in xrange(firstIndex + 1, len(byteGridList)): - grid1 = (byteGridList[firstIndex], keyList[firstIndex]) - grid2 = (byteGridList[secondIndex], keyList[secondIndex]) - conflictList = self.conflictingHazards(grid1, grid2) - if conflictList != []: - return (timeRange, conflictList) - - # if we made it to here, all is well - return None - - ## - # Perform checks to see if it's OK to merge hazards. If there are no conflicting - # locks or incompatible hazards, do the merge. If there are conflicting locks, - # generate a status bar message and quit. If there incompatible - # hazards, show a warning and let the user decide whether to continue. - def checkForMerge(self): - # get the hazards selected by the forecaster - hazParms = self.getHazardParmNames() - - # check for empty list of hazards - if hazParms == []: - self.statusBarMsg("No temporary grids to merge.", "S") - return - - # FIXME: Lock race condition - # check for conflicting locks - if self._hazUtils._conflictingLocks(hazParms): - self.statusBarMsg("There are conflicting locks. " + - "Please resolve these before merging any hazards", "S") - return - - conflicts = self.checkForHazardConflicts(hazParms) - if conflicts is None: - # if no conflicts, merge the grids - # We made the hazards parm immutable when we separated hazard grids. - # It has to be made mutable to do the merge. - parm = self.getParm(MODEL, ELEMENT, LEVEL) - parm.setMutable(True) - self.mergeHazardGrids() - else: - haz1 = string.replace(conflicts[1][0], ".", "") - haz2 = string.replace(conflicts[1][1], ".", "") - timeRange = str(conflicts[0]) - msg = "Hazard conflict detected!\n\n" - msg += "Time: " + timeRange + " \n\n" - msg += "with Hazard grids haz" + haz1 + " and haz" + haz2 + ".\n" - - LogStream.logEvent("Merge conflict: "+ msg) - self.displayDialog(msg) - - return - - ## - # Performs the actual merge of the temp hazards grids into the "Hazards" grid. - def mergeHazardGrids(self): - # get the hazards selected by the forecaster - hazParms = self.getHazardParmNames() - - self._hazUtils._removeAllHazardsGrids() - - for hazParm in hazParms: - trList = self._hazUtils._getWEInventory(hazParm) - - for tr in trList: - byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, tr, - mode="First") - if isinstance(hazKey, str): - hazKey = eval(hazKey) - - uniqueKeys = self._hazUtils._getUniqueKeys(byteGrid, hazKey) - for uKey in uniqueKeys: - if uKey == "": - continue - subKeys = self._hazUtils._getSubKeys(uKey) - for subKey in subKeys: - # make the mask - find all areas that contain the subKey - mask = numpy.zeros(byteGrid.shape) - for haz in hazKey: - if string.find(haz, subKey) >= 0: - hazIndex = self.getIndex(haz, hazKey) - mask = numpy.logical_or(numpy.equal(byteGrid, hazIndex), mask) - - # make the grid - self._hazUtils._addHazard(ELEMENT, tr, subKey, mask) - LogStream.logEvent("merge: " + \ - str(self._hazUtils._printTime(tr.startTime().unixTime())) + " " + \ - str(self._hazUtils._printTime(tr.endTime().unixTime())) + " " + \ - subKey + "\n") - - self.removeTempHazards() - - return - - ## - # The main entry point of the procedure. - def execute(self): - self.setToolType("numeric") - - self._hazUtils = HazardUtils.HazardUtils(self._dbss, None) - - # see if the Hazards WE is loaded in the GFE, if not abort the tool - if not self._hazUtils._hazardsLoaded(): - self.statusBarMsg("Hazards Weather Element must be loaded in " +\ - "the GFE before running MergeHazards", "S") - self.cancel() - - self.checkForMerge() - return - + +########################## END OF CONFIGURATION SECTION ######################## + +class Procedure(SmartScript.SmartScript): + def __init__(self, dbss): + SmartScript.SmartScript.__init__(self, dbss) + self._dbss = dbss + + ## + # Get the list of loaded temporary hazard parms + # @return: Temporary hazard parm names, i.e., ["hazAFY"] + # @rtype: List of Strings + def getHazardParmNames(self): + parms = self.loadedParms() + hazParms = [] + for weName, level, dbID in parms: + if string.find(weName, "haz") == 0: + # TODO: Why is this back/forth xform needed? + key = self._hazUtils._tempWENameToKey(weName) + index = string.find(key, ":") + if index != -1: + mkey = key[0:index] + segNum = key[index+1:] + else: + mkey = key + segNum = "" + + # append the hazard and a description + parmName = "haz" + key + parmName = string.replace(parmName, ".", "") + parmName = string.replace(parmName, ":", "") + hazParms.append(parmName) + + return hazParms + + ## + # Unload (delete) all the temporary hazards + def removeTempHazards(self): + parms = self.loadedParms() + + toRemovePairs = [] + for weName, level, dbID in parms: + if string.find(weName, "haz") == 0: + toRemovePairs.append((weName, level)) + self.unloadWEs(MODEL, toRemovePairs) + + return + + ## + # The action performed when the user opts to cancel a merge. + # This was a callback under Tcl/tk; now displayDialog invokes + # it directly. + def cancelCommand(self): + LogStream.logEvent("MergeHazards: cancel") + return + + ## + # The action performed when the user opts to continue a merge. + # This was a callback under Tcl/tk; now displayDialog invokes + # it directly. + def continueCommand(self): + LogStream.logEvent("MergeHazards: continue") + parm = self.getParm(MODEL, ELEMENT, LEVEL) + parm.setMutable(True) + self.mergeHazardGrids() + return + + ## + # Displays a dialog box and queries the user to continue to merge or + # abort the merge + def displayDialog(self, message): + messageBox = MessageBox(style=MessageBox.ICON_WARNING) + messageBox.setText("MakeHazard") + messageBox.setMessage(message) + messageBox.setButtonLabels(["Continue Merge", "Cancel Merge"]) + messageBox.setDefaultIndex(1) + if (messageBox.open() == 0): + self.continueCommand() + else: + self.cancelCommand() + + return + + ## + # Returns the set of hazParms grids that overlap with the specified + # timeRange. + # @param hazParms: Hazard parm names to check + # @type hazParms: Sequence of string + # @param timeRange: The time range to check for overlap with + # @type timeRange: Python TimeRange + # @return: Byte grids and keys of the overlapping parms + # @rtype: 2-tuple: list of byte arrays, list of list of strings + def getOverlappingHazGrids(self, hazParms, timeRange): + byteGridList = [] + keyList = [] + for hazParm in hazParms: + trList = self._hazUtils._getWEInventory(hazParm) + for tr in trList: + if tr.overlaps(timeRange): + byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, + tr, mode="First") + if isinstance(hazKey, str): + hazKey = eval(hazKey) + byteGridList.append(byteGrid) + keyList.append(hazKey) + + return byteGridList, keyList + + ## + # Returns the first non-None key it finds in the keyList + # @param keyList: Keys to search + # @type keyList: Sequence of string + # @return: First key that is not "" + # @rtype: string + def getHazardKey(self, keyList): + for k in keyList: + if k != "": + return k + + ## + # Checks the specified hazard grids to see if they are conflicting + # Each grid is a tuple (byteGrid, key). Uses the configurable + # HazardConflictDict to determine whether two hazards can be combined + # at the same grid point. Returns an empty list if no conflict or + # the list of hazards if they do. + # + # This method should really only be used internally; it assumes that + # there is at most one key other than "", and that it contains + # a single subkey. + # + # @param hazGrid1: The first hazard grid + # @type hazGrid1: 2-tuple: numpy array of int8, list of String + # @param hazGrid2: The second hazard grid + # @type hazGrid2: 2-tuple: numpy array of int8, list of String + # @return: conflicting hazard names or empty list + # @rtype: list + def conflictingHazards(self, hazGrid1, hazGrid2): + byteGrid1, hazKey1 = hazGrid1 + byteGrid2, hazKey2 = hazGrid2 + + key1 = self.getHazardKey(hazKey1) + key2 = self.getHazardKey(hazKey2) + phenSig1 = key1[0:4] # remove the etn + phenSig2 = key2[0:4] + + keyConflict = False + if phenSig1 == phenSig2 and key1 != key2: + keyConflict = True + elif HazardsConflictDict.has_key(phenSig1): + if phenSig2 in HazardsConflictDict[phenSig1]: + keyConflict = True + + if keyConflict: + # calculate the overlap, adding the grids together will tell us if + # there is any overlap. Any grid points > 1 are overlapped + totalGrid = byteGrid1 + byteGrid2 + overlapMask = numpy.greater(totalGrid, 1) + if numpy.any(overlapMask): + return [key1, key2] + + return [] + + ## + # See if there are any temporary hazards for the same position and time + # that conflict with one another. + # + # @param hazParms: Temporary hazard parm names to check. + # @type hazParms: sequence of string + # @return: The first conflict, or None if there are no conflicts + # @rtype: 2-tuple(TimeRange, list of string) or NoneType + def checkForHazardConflicts(self, hazParms): + timeList = [] + for hazParm in hazParms: + trList = self._hazUtils._getWEInventory(hazParm) + for tr in trList: + if tr.startTime().unixTime() not in timeList: + timeList.append(tr.startTime().unixTime()) + if tr.endTime().unixTime() not in timeList: + timeList.append(tr.endTime().unixTime()) + + timeList.sort() # sort the list + + for t in xrange(len(timeList) - 1): + start = timeList[t] + end = timeList[t+1] + timeRange = self._hazUtils._makeTimeRange(start, end) + byteGridList = [] + keyList = [] + byteGridList, keyList = self.getOverlappingHazGrids(hazParms, timeRange) + # compare each grid to all other grids at this timeRange + for firstIndex in xrange(len(byteGridList) - 1): + for secondIndex in xrange(firstIndex + 1, len(byteGridList)): + grid1 = (byteGridList[firstIndex], keyList[firstIndex]) + grid2 = (byteGridList[secondIndex], keyList[secondIndex]) + conflictList = self.conflictingHazards(grid1, grid2) + if conflictList != []: + return (timeRange, conflictList) + + # if we made it to here, all is well + return None + + ## + # Perform checks to see if it's OK to merge hazards. If there are no conflicting + # locks or incompatible hazards, do the merge. If there are conflicting locks, + # generate a status bar message and quit. If there incompatible + # hazards, show a warning and let the user decide whether to continue. + def checkForMerge(self): + # get the hazards selected by the forecaster + hazParms = self.getHazardParmNames() + + # check for empty list of hazards + if hazParms == []: + self.statusBarMsg("No temporary grids to merge.", "S") + return + + # FIXME: Lock race condition + # check for conflicting locks + if self._hazUtils._conflictingLocks(hazParms): + self.statusBarMsg("There are conflicting locks. " + + "Please resolve these before merging any hazards", "S") + return + + conflicts = self.checkForHazardConflicts(hazParms) + if conflicts is None: + # if no conflicts, merge the grids + # We made the hazards parm immutable when we separated hazard grids. + # It has to be made mutable to do the merge. + parm = self.getParm(MODEL, ELEMENT, LEVEL) + parm.setMutable(True) + self.mergeHazardGrids() + else: + haz1 = string.replace(conflicts[1][0], ".", "") + haz2 = string.replace(conflicts[1][1], ".", "") + timeRange = str(conflicts[0]) + msg = "Hazard conflict detected!\n\n" + msg += "Time: " + timeRange + " \n\n" + msg += "with Hazard grids haz" + haz1 + " and haz" + haz2 + ".\n" + + LogStream.logEvent("Merge conflict: "+ msg) + self.displayDialog(msg) + + return + + ## + # Performs the actual merge of the temp hazards grids into the "Hazards" grid. + def mergeHazardGrids(self): + # get the hazards selected by the forecaster + hazParms = self.getHazardParmNames() + + self._hazUtils._removeAllHazardsGrids() + + for hazParm in hazParms: + trList = self._hazUtils._getWEInventory(hazParm) + + for tr in trList: + byteGrid, hazKey = self.getGrids(MODEL, hazParm, LEVEL, tr, + mode="First") + if isinstance(hazKey, str): + hazKey = eval(hazKey) + + uniqueKeys = self._hazUtils._getUniqueKeys(byteGrid, hazKey) + for uKey in uniqueKeys: + if uKey == "": + continue + subKeys = self._hazUtils._getSubKeys(uKey) + for subKey in subKeys: + # make the mask - find all areas that contain the subKey + mask = numpy.zeros(byteGrid.shape) + for haz in hazKey: + if string.find(haz, subKey) >= 0: + hazIndex = self.getIndex(haz, hazKey) + mask = numpy.logical_or(numpy.equal(byteGrid, hazIndex), mask) + + # make the grid + self._hazUtils._addHazard(ELEMENT, tr, subKey, mask) + LogStream.logEvent("merge: " + \ + str(self._hazUtils._printTime(tr.startTime().unixTime())) + " " + \ + str(self._hazUtils._printTime(tr.endTime().unixTime())) + " " + \ + subKey + "\n") + + self.removeTempHazards() + + return + + ## + # The main entry point of the procedure. + def execute(self): + self.setToolType("numeric") + + self._hazUtils = HazardUtils.HazardUtils(self._dbss, None) + + # see if the Hazards WE is loaded in the GFE, if not abort the tool + if not self._hazUtils._hazardsLoaded(): + self.statusBarMsg("Hazards Weather Element must be loaded in " +\ + "the GFE before running MergeHazards", "S") + self.cancel() + + self.checkForMerge() + return + diff --git a/cave/build/static/common/cave/etc/gfe/userPython/utilities/SmartScript.py b/cave/build/static/common/cave/etc/gfe/userPython/utilities/SmartScript.py index 15e984f5ac..648e66139c 100644 --- a/cave/build/static/common/cave/etc/gfe/userPython/utilities/SmartScript.py +++ b/cave/build/static/common/cave/etc/gfe/userPython/utilities/SmartScript.py @@ -47,6 +47,7 @@ # Jun 21, 2013 14983 ryu Fixed encodeEditArea() to evaluate query # when necessary # Oct 07, 2013 2424 randerso remove use of pytz +# Dec 23, 2013 16893 ryu Added unloadWEs() method (created by njensen) # ######################################################################## import types, string, time, sys @@ -1788,6 +1789,19 @@ class SmartScript(BaseTool.BaseTool): parmJA[0] = parm self.__parmMgr.deleteParm(parmJA) + def unloadWEs(self, model, elementLevelPairs, mostRecent=0): + jparms = [] + for element, level in elementLevelPairs: + exprName = self.getExprName(model, element, level, mostRecent) + parm = self.__parmMgr.getParmInExpr(exprName, 1) + if parm: + jparms.append(parm) + if jparms: + parmJA = jep.jarray(len(jparms), jparms[0]) + for i in xrange(len(jparms)): + parmJA[i] = jparms[i] + self.__parmMgr.deleteParm(parmJA) + def saveElements(self, elementList): # Save the given Fcst elements to the server # Example: diff --git a/edexOsgi/build.edex/esb/conf/modes.xml b/edexOsgi/build.edex/esb/conf/modes.xml index 04e4ad1713..b054a28b61 100644 --- a/edexOsgi/build.edex/esb/conf/modes.xml +++ b/edexOsgi/build.edex/esb/conf/modes.xml @@ -86,6 +86,7 @@ .*datadelivery.* .*bandwidth.* excludeDpaAndOgc + obs-ingest-metarshef.xml aww-ingest.xml ncairep-ingest.xml @@ -120,7 +121,8 @@ shef-ingest.xml persist-ingest.xml obs-common.xml - obs-ingest.xml + obs-ingest.xml + obs-ingest-metarshef.xml metartohmdb-plugin.xml pointdata-common.xml shef-common.xml diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-decode.xml b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-decode.xml new file mode 100644 index 0000000000..f225ad374e --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-decode.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + obs + + + + + + + + + + + + + + + java.lang.Throwable + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml new file mode 100644 index 0000000000..3fa8f85c54 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + obs + + + + + + + + + + + + + java.lang.Throwable + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml index f86f783477..876404ccac 100644 --- a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - + @@ -14,40 +14,5 @@ - - - - - - - - - - - obs - - - - - - - - - - - - - - - java.lang.Throwable - - - - - \ No newline at end of file From a4c136fd603e9f1e7e90ea30e84b5245c3315600 Mon Sep 17 00:00:00 2001 From: "Brian.Dyke" Date: Fri, 7 Mar 2014 08:49:00 -0500 Subject: [PATCH 5/5] 14.1.1-22 baseline Former-commit-id: 21f17d4f9b8f12bae7a6cbe39cb483742eb8df90 [formerly ae37ad5bac445251d1456f37588819fccfede061] Former-commit-id: 08d8f1a0ee00daf478d9ccdf95aa12f1e33b2cb0 --- .../static/win32.x86/alertviz/alertviz.bat | 69 +++++++++ cave/build/static/win32.x86/cave/cave.bat | 72 +++++++++ msi/VizLauncher/VizLauncher.sln | 20 --- msi/VizLauncher/VizLauncher.suo | Bin 42496 -> 0 bytes msi/VizLauncher/VizLauncher/Form1.Designer.cs | 79 ---------- msi/VizLauncher/VizLauncher/Form1.cs | 20 --- msi/VizLauncher/VizLauncher/Form1.resx | 120 --------------- msi/VizLauncher/VizLauncher/Program.cs | 31 ---- .../VizLauncher/Properties/AssemblyInfo.cs | 36 ----- .../Properties/Resources.Designer.cs | 71 --------- .../VizLauncher/Properties/Resources.resx | 117 --------------- .../Properties/Settings.Designer.cs | 30 ---- .../VizLauncher/Properties/Settings.settings | 7 - .../VizLauncher/VizLauncher.csproj | 94 ------------ .../VizLauncher/VizLauncher.csproj.user | 3 - .../com/raytheon/viz/launcher/VizLauncher.cs | 68 --------- .../environment/EnvironmentProperties.cs | 34 ----- .../launcher/environment/VizEnvironment.cs | 137 ------------------ .../process/AbstractProcessLauncher.cs | 137 ------------------ .../viz/launcher/process/IProcessLauncher.cs | 16 -- .../process/impl/AlertvizProcessLauncher.cs | 62 -------- .../process/impl/CaveProcessLauncher.cs | 45 ------ .../A2Staging/VisualStudio/VizLauncher.exe | Bin 16384 -> 0 bytes 23 files changed, 141 insertions(+), 1127 deletions(-) create mode 100644 cave/build/static/win32.x86/alertviz/alertviz.bat create mode 100644 cave/build/static/win32.x86/cave/cave.bat delete mode 100644 msi/VizLauncher/VizLauncher.sln delete mode 100644 msi/VizLauncher/VizLauncher.suo delete mode 100644 msi/VizLauncher/VizLauncher/Form1.Designer.cs delete mode 100644 msi/VizLauncher/VizLauncher/Form1.cs delete mode 100644 msi/VizLauncher/VizLauncher/Form1.resx delete mode 100644 msi/VizLauncher/VizLauncher/Program.cs delete mode 100644 msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs delete mode 100644 msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs delete mode 100644 msi/VizLauncher/VizLauncher/Properties/Resources.resx delete mode 100644 msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs delete mode 100644 msi/VizLauncher/VizLauncher/Properties/Settings.settings delete mode 100644 msi/VizLauncher/VizLauncher/VizLauncher.csproj delete mode 100644 msi/VizLauncher/VizLauncher/VizLauncher.csproj.user delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/VizLauncher.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/EnvironmentProperties.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/VizEnvironment.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/AbstractProcessLauncher.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/IProcessLauncher.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/AlertvizProcessLauncher.cs delete mode 100644 msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/CaveProcessLauncher.cs delete mode 100644 msi/build/A2Staging/VisualStudio/VizLauncher.exe diff --git a/cave/build/static/win32.x86/alertviz/alertviz.bat b/cave/build/static/win32.x86/alertviz/alertviz.bat new file mode 100644 index 0000000000..5e4b50ee83 --- /dev/null +++ b/cave/build/static/win32.x86/alertviz/alertviz.bat @@ -0,0 +1,69 @@ +@echo OFF + +REM Determine if we are running on a 32-bit or 64-bit OS. +IF NOT EXIST C:\Windows\SysWOW64\reg.exe ( + SET REG_EXE=C:\Windows\System32\reg.exe +) ELSE ( + SET REG_EXE=C:\Windows\SysWOW64\reg.exe +) + +REM Determine where we are located. +SET CONTAINING_DIRECTORY=%~dp0 + +REM Prepare the environment. + +REM Registry Query Variables. +SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java" +SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python" +REM Determine where AWIPS II Java (the jre) is located. +%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1 +IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT) +FOR /F "tokens=2* delims= " %%A IN ( +'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO ( +SET JavaJreDirectory=%%B) +REM Determine where AWIPS II Python is located. +%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1 +IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT) +FOR /F "tokens=2* delims= " %%A IN ( +'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO ( +SET PythonInstallDirectory=%%B) + +REM Add Java and Python to the path. +SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% +SET Path=%JavaJreDirectory%\bin;%Path% +REM Define 'PythonPath'. +SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% +SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% +SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% +SET PythonPath=%PythonInstallDirectory%;%PythonPath% + +REM Eliminate variables that will no longer be used. +SET PythonInstallDirectory= +SET JavaJreDirectory= +SET REG_EXE= +SET A2_JAVA_REG= +SET A2_PYTHON_REG= + +REM Determine where we will be logging to. +SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH% +SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs +SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% +IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") + +echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'. +REM Start AlertViz (and implement the alertviz restart capability). +:AlertVizLoopStart +SET RND=%random% +SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp +REM Python is used to retrieve the current date and time because the order +REM of the Windows date/time fields is not necessarily guaranteed and the +REM Windows date/time fields can only be extracted using substring operations +REM instead of -formatter- strings like Linux allows. +python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% +SET /p LOG_DATETIME= < %RND_DATETIME_FILE% +DEL %RND_DATETIME_FILE% +"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1 +IF %ERRORLEVEL% == 0 (EXIT) +echo Restarting AlertViz. +GOTO AlertVizLoopStart + diff --git a/cave/build/static/win32.x86/cave/cave.bat b/cave/build/static/win32.x86/cave/cave.bat new file mode 100644 index 0000000000..0b347287dd --- /dev/null +++ b/cave/build/static/win32.x86/cave/cave.bat @@ -0,0 +1,72 @@ +@echo OFF + +REM Determine if we are running on a 32-bit or 64-bit OS. +IF NOT EXIST C:\Windows\SysWOW64\reg.exe ( + SET REG_EXE=C:\Windows\System32\reg.exe +) ELSE ( + SET REG_EXE=C:\Windows\SysWOW64\reg.exe +) + +REM Determine where we are located. +SET CONTAINING_DIRECTORY=%~dp0 + +REM Prepare the environment. + +REM Registry Query Variables. +SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java" +SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python" +REM Determine where AWIPS II Java (the jre) is located. +%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1 +IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT) +FOR /F "tokens=2* delims= " %%A IN ( +'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO ( +SET JavaJreDirectory=%%B) +REM Determine where AWIPS II Python is located. +%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1 +IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT) +FOR /F "tokens=2* delims= " %%A IN ( +'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO ( +SET PythonInstallDirectory=%%B) + +REM Add Java and Python to the path. +SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% +SET Path=%JavaJreDirectory%\bin;%Path% +REM Add the CAVE lib directory to the path. +SET Path=%CONTAINING_DIRECTORY%lib;%Path% +REM Define 'PythonPath'. +SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath% +SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% +SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% +SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% +SET PythonPath=%PythonInstallDirectory%;%PythonPath% + +REM Eliminate variables that will no longer be used. +SET PythonInstallDirectory= +SET JavaJreDirectory= +SET REG_EXE= +SET A2_JAVA_REG= +SET A2_PYTHON_REG= + +REM Determine where we will be logging to. +SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH% +SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs +SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% +IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") + +SET RND=%random% +SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp +REM Python is used to retrieve the current date and time because the order +REM of the Windows date/time fields is not necessarily guaranteed and the +REM Windows date/time fields can only be extracted using substring operations +REM instead of -formatter- strings like Linux allows. +python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% +SET /p LOG_DATETIME= < %RND_DATETIME_FILE% +DEL %RND_DATETIME_FILE% + +echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME! +cd %HOMEPATH% +REM Start CAVE. +"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1 +IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE) + +EXIT diff --git a/msi/VizLauncher/VizLauncher.sln b/msi/VizLauncher/VizLauncher.sln deleted file mode 100644 index b9a96d5c02..0000000000 --- a/msi/VizLauncher/VizLauncher.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C# Express 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VizLauncher", "VizLauncher\VizLauncher.csproj", "{45B15612-0725-479C-8E1B-9B63F2FB45A3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {45B15612-0725-479C-8E1B-9B63F2FB45A3}.Debug|x86.ActiveCfg = Debug|x86 - {45B15612-0725-479C-8E1B-9B63F2FB45A3}.Debug|x86.Build.0 = Debug|x86 - {45B15612-0725-479C-8E1B-9B63F2FB45A3}.Release|x86.ActiveCfg = Release|x86 - {45B15612-0725-479C-8E1B-9B63F2FB45A3}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/msi/VizLauncher/VizLauncher.suo b/msi/VizLauncher/VizLauncher.suo deleted file mode 100644 index 9b44de8eee19ecf4a53f374cd85079c898ee0610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42496 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 - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.lblFailureDetail = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // label1 - // - this.label1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(12, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(337, 50); - this.label1.TabIndex = 0; - this.label1.Text = "Failed to Start AWIPS II Viz!"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // lblFailureDetail - // - this.lblFailureDetail.BackColor = System.Drawing.Color.White; - this.lblFailureDetail.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblFailureDetail.Location = new System.Drawing.Point(14, 59); - this.lblFailureDetail.Name = "lblFailureDetail"; - this.lblFailureDetail.Size = new System.Drawing.Size(335, 119); - this.lblFailureDetail.TabIndex = 1; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(361, 187); - this.Controls.Add(this.lblFailureDetail); - this.Controls.Add(this.label1); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "Form1"; - this.ShowInTaskbar = false; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Viz Launcher"; - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label lblFailureDetail; - } -} - diff --git a/msi/VizLauncher/VizLauncher/Form1.cs b/msi/VizLauncher/VizLauncher/Form1.cs deleted file mode 100644 index 4c206c62fe..0000000000 --- a/msi/VizLauncher/VizLauncher/Form1.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace VizLauncher -{ - public partial class Form1 : Form - { - public Form1(String errorText) - { - InitializeComponent(); - this.lblFailureDetail.Text = errorText; - } - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/Form1.resx b/msi/VizLauncher/VizLauncher/Form1.resx deleted file mode 100644 index 29dcb1b3a3..0000000000 --- a/msi/VizLauncher/VizLauncher/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/Program.cs b/msi/VizLauncher/VizLauncher/Program.cs deleted file mode 100644 index dd5d415317..0000000000 --- a/msi/VizLauncher/VizLauncher/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; -using VizLauncher.com.raytheon.viz.launcher; - -namespace VizLauncher -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - VizLauncher.com.raytheon.viz.launcher.VizLauncher vizLauncher = - new VizLauncher.com.raytheon.viz.launcher.VizLauncher(); - bool success = vizLauncher.run(Application.StartupPath); - if (success == false) - { - // Display the "Failure" dialog. - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1(vizLauncher.getErrorDetail())); - } - - Application.Exit(); - } - } -} diff --git a/msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs b/msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs deleted file mode 100644 index 5d149225c7..0000000000 --- a/msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("VizLauncher")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("VizLauncher")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7f929b46-b56e-47eb-b6e6-ff79e54f6572")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs b/msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs deleted file mode 100644 index fb7e7281d0..0000000000 --- a/msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace VizLauncher.Properties -{ - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VizLauncher.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { - return resourceCulture; - } - set - { - resourceCulture = value; - } - } - } -} diff --git a/msi/VizLauncher/VizLauncher/Properties/Resources.resx b/msi/VizLauncher/VizLauncher/Properties/Resources.resx deleted file mode 100644 index ffecec851a..0000000000 --- a/msi/VizLauncher/VizLauncher/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs b/msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs deleted file mode 100644 index b5a088c6b6..0000000000 --- a/msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace VizLauncher.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { - return defaultInstance; - } - } - } -} diff --git a/msi/VizLauncher/VizLauncher/Properties/Settings.settings b/msi/VizLauncher/VizLauncher/Properties/Settings.settings deleted file mode 100644 index abf36c5d3d..0000000000 --- a/msi/VizLauncher/VizLauncher/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/msi/VizLauncher/VizLauncher/VizLauncher.csproj b/msi/VizLauncher/VizLauncher/VizLauncher.csproj deleted file mode 100644 index ccd040c7b0..0000000000 --- a/msi/VizLauncher/VizLauncher/VizLauncher.csproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {45B15612-0725-479C-8E1B-9B63F2FB45A3} - WinExe - Properties - VizLauncher - VizLauncher - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - Form - - - Form1.cs - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/VizLauncher.csproj.user b/msi/VizLauncher/VizLauncher/VizLauncher.csproj.user deleted file mode 100644 index 695b5c78b9..0000000000 --- a/msi/VizLauncher/VizLauncher/VizLauncher.csproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/VizLauncher.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/VizLauncher.cs deleted file mode 100644 index f00af7eaf9..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/VizLauncher.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using VizLauncher.com.raytheon.viz.launcher.environment; -using VizLauncher.com.raytheon.viz.launcher.process; -using VizLauncher.com.raytheon.viz.launcher.process.impl; - -namespace VizLauncher.com.raytheon.viz.launcher -{ - public class VizLauncher - { - private String errorDetail; - - public bool run(String location) - { - VizEnvironment vizEnvironment = new VizEnvironment(location); - if (vizEnvironment.isReady() == false) - { - this.errorDetail = vizEnvironment.getExceptionText(); - return false; - } - - /* Alternatively, we would be able to construct both process launchers using Spring and inject them. */ - - // Construct the AlertViz Process Launcher. - IProcessLauncher alertvizProcessLauncher = new AlertvizProcessLauncher(vizEnvironment); - if (alertvizProcessLauncher.isReady() == false) - { - this.errorDetail = alertvizProcessLauncher.getExceptionText(); - return false; - } - Thread alertvizThread = new Thread(alertvizProcessLauncher.launchProcess); - - // Construct the CAVE Process Launcher. - IProcessLauncher caveProcessLauncher = new CaveProcessLauncher(vizEnvironment); - if (caveProcessLauncher.isReady() == false) - { - this.errorDetail = caveProcessLauncher.getExceptionText(); - return false; - } - Thread caveThread = new Thread(caveProcessLauncher.launchProcess); - - // Start AlertViz. - alertvizThread.Start(); - - // Delay - Give Alertviz Time To Start. - Thread.Sleep(1000); - - // Start CAVE. - caveThread.Start(); - - // Wait for CAVE. - caveThread.Join(); - - // Wait for AlertViz. - alertvizThread.Join(); - - return true; - } - - public String getErrorDetail() - { - return this.errorDetail; - } - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/EnvironmentProperties.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/EnvironmentProperties.cs deleted file mode 100644 index 6db871db40..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/EnvironmentProperties.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; - -namespace VizLauncher.com.raytheon.viz.launcher.environment -{ - public abstract class EnvironmentProperties - { - /* Environment Properties */ - public static readonly String USER_HOME_ENV_PROPERTY = "%HOMEDRIVE%%HOMEPATH%"; - public static readonly String COMPUTER_NAME_ENV_PROPERTY = "%COMPUTERNAME%"; - - /* Registry Constants */ - public static readonly String A2_JAVA_REG = @"Software\Raytheon\Runtime Environment\AWIPS II Java"; - public static readonly String A2_PYTHON_REG = @"Software\Raytheon\Runtime Environment\AWIPS II Python"; - - public static readonly String JAVA_JRE_VALUE_NAME = "JavaJreDirectory"; - public static readonly String PYTHON_INSTALL_NAME = "PythonInstallDirectory"; - - /* Environment Additions */ - public static readonly String ENVIRONMENT_VARIABLE_PATH = "Path"; - public static readonly String ENVIRONMENT_VARIABLE_PYTHON_PATH = "PythonPath"; - - public static readonly String PATH_PYTHON_DLLS = Path.DirectorySeparatorChar + "DLLs"; - public static readonly String PATH_JAVA_BIN = Path.DirectorySeparatorChar + "bin"; - - public static readonly String PYTHON_PATH_PYTHON_LIBTK = - Path.DirectorySeparatorChar + "Lib" + Path.DirectorySeparatorChar + "lib-tk"; - public static readonly String PYTHON_PATH_PYTHON_DLLS = Path.DirectorySeparatorChar + "DLLs"; - public static readonly String PYTHON_PATH_PYTHON_LIB = Path.DirectorySeparatorChar + "Lib"; - } -} diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/VizEnvironment.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/VizEnvironment.cs deleted file mode 100644 index 5172e046ee..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/environment/VizEnvironment.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using Microsoft.Win32; - -namespace VizLauncher.com.raytheon.viz.launcher.environment -{ - public class VizEnvironment - { - private static readonly String CONSOLE_LOGS_DIRECTORY = - Path.DirectorySeparatorChar + "caveData" + Path.DirectorySeparatorChar + - "logs" + Path.DirectorySeparatorChar + "consoleLogs"; - private String location; - private String logDirectory = null; - private String path = null; - private String pythonPath = null; - - // did an error occur while initializing this object? - private bool ready; - // details about the error that has occurred. - private String exceptionText; - - public VizEnvironment(String location) - { - this.location = location; - this.init(); - } - - private void init() - { - /* For now we will assume that the environment properties will be available */ - // determine the location of the user's "home" directory. - String homeDirectory = - this.resolveEnvironmentProperty(EnvironmentProperties.USER_HOME_ENV_PROPERTY); - - // determine the computer name. - String computerName = - this.resolveEnvironmentProperty(EnvironmentProperties.COMPUTER_NAME_ENV_PROPERTY); - - // construct the path to the log directory. - this.logDirectory = homeDirectory + CONSOLE_LOGS_DIRECTORY + - Path.DirectorySeparatorChar + computerName; - - // retrieve the jdk directory from the registry. - String jdkDirectory = - this.retrieveRegistryProperty(EnvironmentProperties.A2_JAVA_REG, - EnvironmentProperties.JAVA_JRE_VALUE_NAME); - if (jdkDirectory == null) - { - this.notReady("Unable to retrieve the Java JDK Path from the registry!"); - return; - } - - // retrieve the python location from the registry. - String pythonLocation = - this.retrieveRegistryProperty(EnvironmentProperties.A2_PYTHON_REG, - EnvironmentProperties.PYTHON_INSTALL_NAME); - if (pythonLocation == null) - { - this.notReady("Unable to retrieve the Python Install Location from the registry!"); - return; - } - - // Construct the PATH. - this.path = pythonLocation + Path.PathSeparator; - this.path += pythonLocation + EnvironmentProperties.PATH_PYTHON_DLLS + Path.PathSeparator; - this.path += jdkDirectory + EnvironmentProperties.PATH_JAVA_BIN; - - // Construct the PYTHON_PATH. - this.pythonPath = pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_LIBTK + Path.PathSeparator; - this.pythonPath += pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_DLLS + Path.PathSeparator; - this.pythonPath += pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_LIB + Path.PathSeparator; - this.pythonPath += pythonLocation; - - this.ready = true; - } - - private String resolveEnvironmentProperty(String property) - { - return Environment.ExpandEnvironmentVariables(property); - } - - private String retrieveRegistryProperty(String registryKeyName, String valueName) - { - RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(registryKeyName); - if (registryKey == null) - { - return null; - } - Object registryValue = registryKey.GetValue(valueName, null); - if (registryValue == null) - { - return null; - } - - return registryValue.ToString(); - } - - private void notReady(String reason) - { - this.ready = false; - this.exceptionText = reason; - } - - public String getLocation() - { - return this.location; - } - - public String getLogDirectory() - { - return this.logDirectory; - } - - public String getPath() - { - return this.path; - } - - public String getPythonPath() - { - return this.pythonPath; - } - - public bool isReady() - { - return this.ready; - } - - public String getExceptionText() - { - return this.exceptionText; - } - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/AbstractProcessLauncher.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/AbstractProcessLauncher.cs deleted file mode 100644 index f07dff604f..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/AbstractProcessLauncher.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Diagnostics; -using VizLauncher.com.raytheon.viz.launcher.environment; - -namespace VizLauncher.com.raytheon.viz.launcher.process -{ - public abstract class AbstractProcessLauncher : IProcessLauncher - { - private static readonly String LOG_DATE_FORMAT = "yyyyMMdd_HHmmss"; - protected static readonly String LOG_SUFFIX = ".log"; - protected Process process = null; - private StreamWriter logFileWriter; - protected VizEnvironment vizEnvironment; - - private bool ready = false; - private String exceptionText = null; - - public AbstractProcessLauncher(VizEnvironment vizEnvironment) - { - this.vizEnvironment = vizEnvironment; - // Prepare the log file. - if (Directory.Exists(vizEnvironment.getLogDirectory()) == false) - { - Directory.CreateDirectory(vizEnvironment.getLogDirectory()); - } - String logName = vizEnvironment.getLogDirectory() + - Path.DirectorySeparatorChar + this.constructLogName(this.determineLogDate()); - - // Prepare the process. - this.process = new Process(); - this.process.StartInfo = this.constructProcessStartInfo(vizEnvironment); - this.process.OutputDataReceived += new DataReceivedEventHandler(processOutputHandler); - this.validate(); - if (this.ready == false) - { - return; - } - - /* - * Access the log file for write access; other processes will have read-only access to - * the log file until it is closed. - **/ - this.logFileWriter = - new StreamWriter(File.Open(logName, FileMode.Append, - FileAccess.Write, FileShare.Read)); - } - - private String determineLogDate() - { - return DateTime.Now.ToString(LOG_DATE_FORMAT); - } - - private ProcessStartInfo constructProcessStartInfo(VizEnvironment vizEnvironment) - { - ProcessStartInfo processStartInfo = - new ProcessStartInfo(this.constructProcessName(vizEnvironment.getLocation())); - // include the default system PATH in the application PATH - String systemPath = System.Environment.GetEnvironmentVariable("PATH"); - processStartInfo.EnvironmentVariables[EnvironmentProperties.ENVIRONMENT_VARIABLE_PATH] = - vizEnvironment.getPath() + this.getApplicationSpecificPath() + systemPath; - processStartInfo.EnvironmentVariables[EnvironmentProperties.ENVIRONMENT_VARIABLE_PYTHON_PATH] = - vizEnvironment.getPythonPath(); - processStartInfo.UseShellExecute = false; - processStartInfo.Arguments = this.getCommandLineArguments(); - processStartInfo.RedirectStandardOutput = true; - - return processStartInfo; - } - - protected void validate() - { - String application = this.process.StartInfo.FileName; - /* ensure that the specified application exists. */ - if (File.Exists(application) == false) - { - this.ready = false; - this.exceptionText = "Unable to find the specified Viz application: " + application; - return; - } - - this.ready = true; - } - - public virtual void launchProcess() - { - this.runProcess(); - this.closeLog(); - } - - protected void runProcess() - { - this.process.Start(); - this.process.BeginOutputReadLine(); - this.process.WaitForExit(); - this.process.CancelOutputRead(); - } - - protected void closeLog() - { - this.logFileWriter.Close(); - } - - private void processOutputHandler(Object sendingProcess, DataReceivedEventArgs outline) - { - if (String.IsNullOrEmpty(outline.Data)) - { - return; - } - this.logFileWriter.WriteLine(outline.Data); - } - - public bool isReady() - { - return this.ready; - } - - public String getExceptionText() - { - return this.exceptionText; - } - - protected virtual String getApplicationSpecificPath() - { - return String.Empty; - } - - protected abstract String constructProcessName(String location); - - protected abstract String constructLogName(String logDate); - - protected abstract String getCommandLineArguments(); - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/IProcessLauncher.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/IProcessLauncher.cs deleted file mode 100644 index 0540d4b4ab..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/IProcessLauncher.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; - -namespace VizLauncher.com.raytheon.viz.launcher.process -{ - public interface IProcessLauncher - { - void launchProcess(); - - bool isReady(); - String getExceptionText(); - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/AlertvizProcessLauncher.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/AlertvizProcessLauncher.cs deleted file mode 100644 index 2b281391c9..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/AlertvizProcessLauncher.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using System.IO; -using VizLauncher.com.raytheon.viz.launcher.process; -using VizLauncher.com.raytheon.viz.launcher.environment; - -namespace VizLauncher.com.raytheon.viz.launcher.process.impl -{ - public class AlertvizProcessLauncher : AbstractProcessLauncher - { - private static readonly String LOG_PREFIX = "alertviz_"; - private static readonly String COMMAND_LINE_ARGUMENTS = "-component thinalertviz"; - private static readonly String ALERTVIZ_PROCESS_NAME = "alertviz"; - private static readonly String ALERTVIZ_EXECUTABLE = - Path.DirectorySeparatorChar + "AlertViz" + - Path.DirectorySeparatorChar + "alertviz.exe"; - - public AlertvizProcessLauncher(VizEnvironment vizEnvironment) : base(vizEnvironment) - { - } - - public override void launchProcess() - { - // need to verify that another AlertViz process is not already running. - if (this.isAlertVizAlreadyRunning()) - { - // do not start a new AlertViz process. - return; - } - - this.runProcess(); - while (this.process.ExitCode != 0) - { - this.runProcess(); - } - this.closeLog(); - } - - private Boolean isAlertVizAlreadyRunning() - { - return (Process.GetProcessesByName(ALERTVIZ_PROCESS_NAME).Length > 0); - } - - protected override String constructProcessName(String location) - { - return location + ALERTVIZ_EXECUTABLE; - } - - protected override String constructLogName(String logDate) - { - return LOG_PREFIX + logDate + AbstractProcessLauncher.LOG_SUFFIX; - } - - protected override String getCommandLineArguments() - { - return COMMAND_LINE_ARGUMENTS; - } - } -} \ No newline at end of file diff --git a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/CaveProcessLauncher.cs b/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/CaveProcessLauncher.cs deleted file mode 100644 index 83321fea2d..0000000000 --- a/msi/VizLauncher/VizLauncher/com/raytheon/viz/launcher/process/impl/CaveProcessLauncher.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using VizLauncher.com.raytheon.viz.launcher.process; -using VizLauncher.com.raytheon.viz.launcher.environment; - -namespace VizLauncher.com.raytheon.viz.launcher.process.impl -{ - public class CaveProcessLauncher : AbstractProcessLauncher - { - private static readonly String LOG_PREFIX = "cave_"; - private static readonly String COMMAND_LINE_ARGUMENTS = "-component thinclient"; - private static readonly String CAVE_DIRECTORY = Path.DirectorySeparatorChar + "CAVE"; - private static readonly String CAVE_EXECUTABLE = - CAVE_DIRECTORY + Path.DirectorySeparatorChar + "cave.exe"; - - public CaveProcessLauncher(VizEnvironment vizEnvironment) - : base(vizEnvironment) - { - } - - protected override String getApplicationSpecificPath() - { - return Path.PathSeparator + this.vizEnvironment.getLocation() + - CAVE_DIRECTORY + Path.DirectorySeparatorChar + "lib" + Path.PathSeparator; - } - - protected override String constructProcessName(String location) - { - return location + CAVE_EXECUTABLE; - } - - protected override String constructLogName(String logDate) - { - return LOG_PREFIX + logDate + AbstractProcessLauncher.LOG_SUFFIX; - } - - protected override String getCommandLineArguments() - { - return COMMAND_LINE_ARGUMENTS; - } - } -} \ No newline at end of file diff --git a/msi/build/A2Staging/VisualStudio/VizLauncher.exe b/msi/build/A2Staging/VisualStudio/VizLauncher.exe deleted file mode 100644 index 099e80ea286c05b009e3f9c8084597b5b80682ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHu4R9RSac0l#V)h5Xk_(U^A%W%q6y+sItoScdA}ua}1+^spgk6A=O$S`;4!|`R zJFA%mNQg%WjBK5hA4iI8pDjxjiDlo(NjW7uKUVBmmK{be$&t&6E&FoOU8E#VZ23oJ z$N5oy*ZhV?xGG06(M(o%V&r_+~5-HZ%af?z^`VAI_l|fRo1Jj3uh4ct#xhU z72`q$_|*ddsFSg}dIOV7hgNaRwsOEkw=*bc_#MKp?mC7EiCad|1S9K8OZc&@ci>ld z9V6$e)HfFKF zU5;(#rkaUigcl(O1K$P?)r{KOKL2H zesF`WH0pld6W9&r>s{eHQTFJ&>dHM_?!F0CJc}k=2q?*1qAy;nQIO$j;n;3~wl|cp z#ztsy8aP$v9=93VDdN}C&M}%h?+zV4!Q*A`s?sqscr)mWdm%>16IKDkUBc}6t^2tI zoBF%ssxJn?@B~&-=J0mhfk&z1m%*$w2HF<)L5R5EmB1$TA_V)z%2xuL7coEnD}nZ! zmtF~6V?6}s=bJf(ez7ARpYdpNfLy&RQ)&6&`r(Y~|b4s9xk&8{SZMDw|;B2wE_~L{X;Mc_4NKRp!xJz4aRO$AWqwv8lby zMj#BESQ=jItxawAF{UMIG^<^qve{cB=(ji-50QD;pK4MPQW5gUkq5x(#6H-}d6U#nL6-^To* zS_qJ}=8SmzMILyoR;P1Rln#l)7#wTfUTa%bS|-eC9$bXRPEc^9h8Cfyzt%{WuQRvX zFY*+>X@{L}-l3T0EtrM$$8$a))>crjS_a*5sC z`Z1SyZCD%pD6!XDyTF_s1AabzvN9fepHjPEbBy`hQ*s9TX| z#F%LZkAjm{srM1Qz|AwZqx!A#jO)SUwC4GH7uvGFT7QJ;TH^NB%UohEYkdPstk;{^ zx(oHIY`tHIj;&c;C;z?${UB+Gl8vlELn52QAk2d(HwIuYonm9cmuw2FnPUHXJ! z*#)z7bbov||LxNI=8Ba$%Q#vx<|n9&gM#$!mQ!-o;E5lOZ6H}^z%Q~`TteDd($U+72?@;p5^Cx^7ifCw+DGL zuT(eySQEfReV_n#oXZ%bFKLTSckj;jdLqYa>qr)fi{bJnr#_;{)xb=NVD;Ipl_ zXihORE=-?tYSR@Z#9jW=_I(@>xOf6TI0dI)bTfV&YnTq-keC5q;50FhG1cgGxI zcLW+et~{)S>GR4HN`$_pduZeqWJ&m2AiP{Bwp8gb^>u`R??HU!v+6eI-SSKC~8)zGK3umvwQnpi^mX!7M zPUUHE?w|uw_cTp`a|a)kq3%AkYeuWXw1?W%Hrh|u1Nv!DjTd62#Z%0c>}z)%C1 zHwxS)@J4|r1sVeH75JY7eq7+w0>23uh57CPyjgqq3T^M!So048D)eQ*DE+neUN#Y~ zXB%FF6~$nJ{VRO0hBc@yz(#fEym#{>Y7Cg($=GGOf;yG@UF@nF2lhvTy_fz6yw*pX zx|s7>g?sQ(OtAOT-$>oNTsmtGDGx~ zi?PfweN8Y&W|(5vc`_5I8x`y-ecyKiXD#;$cA0*HDAhz2BnnRN31A-+>@wy2VPqFe z?An;!v;HH%KI~%m_|p`jZ@btd{sg@L9|gOYKJIUUMb~5JhD`dDV4SKk_C>*tx!7}p z-R@#MyHP5;7|(8$?i0)zQIx(d8~J--cjOWDon>`Dkh*)^x_=bxq2Ng^3(jLZx%Y>H zliD<}Q!aK+I|uBHV9w09P*JdFi9Mv1o)YXbeL{->dr7dX#CB+A24Ui!LrH?XTc-0oibmWCKgFFBZup^g4Zunz_QUb_!< z(YSEBb^k1NP7j>*Du@p?7{=j(O6`EW>KS%Q+2N_D>=63CI?kg~9spEnLds_Z&InvB z;i%sSuguaTYJv&^?-aNo@Up=B1wJV7BLW`>JVBq3@}~s;p1>~(d=Bte5oaG!KTNLx zhT-W9zf1Rp9tC_fbcJ50PlukMkn&>aH>gu;JL#p+rzxsDqCN$RFZ?vME4POK5K;CK z^+if4?+(8LXoQa-_OQ0MDR+f`i1HW1e=Blcr#qDYhS0Nz{xW<5^nVB^02>-lK$_kd z0X>dAu3cdrxZhT#lWuN|pf-Vht&_$DW&yLxCBVaU5BNjMFEu_2%EOHblt0$k2F*X! z=xE-FOy$K;j}jIA3(A+lbEoostjVaX)09hp3DOpnpEe#*3QDjksa(bw2T|VJbcga0 zl+U1?XqpBbZb~3aaVV#oWUYWC=WJWR6d2;%gXO5pKkh(fd94W{pkHw z;cRUFpz@rux%s1@bTprU4!Z;%5qP@!3g}DCpMcC?1?4v7*P4GwuPA@s{5j>j%J-X} z0sM#NFDoH3!Y%Y8^g_z(fS6EKET}FtT%_*+-Yk@p0{2lTC^;$u zo}&dooBrIF63IU0>uQJUQ~pfgSJXdK?oqy?KBV3wl*hDIUx)e<{S9eKyRt=jyYi&+ zg7Qt}ka|ot)t^^?pa!uno3OhOGQ>Lp&ujC5YT%c#@^*r*(k|>F3iSZ0@TLIymv}AL zUrz(U0mhz+o!zR=n3M=Uq?3n6z*Jp5oKIQhRpn2(Rc?<6z&?# z&Xsa!4J&S3Feo)@nRtG(J>oKkoH-k}vI~{7hFOZw7w(D|y{34(%B?6dW#bttS6L~g zFFS9nq}6x*mXhOz*>aHvOlx*ey-Hk8mgWnVS(-IUmHMjqo69unTGX|Mf@Q<16bzfZ zM>%_$#5#sV5uBKUm4gD#ubG!Mds9USPl^?JM)Dp{$$7Sxr&R$PZdge^SmAB z;oC9^UQM4_nl8-DS=kC6X(>@I`!EplLI4TLy3&w>G6Sq)a_n({e|pI$+RnloK2p%vTJ(xsW>%4c= z#jvPo&I}ZahKpgw>L#4P2Sto!TEue|)1thA#8XDf!+UAmIBDyh=6Njb9w zUz@A?TCHY2TP)vSUWhD9juAxsh3P_WG+Q~ls`KIOtWhJPA0a?MpE)}Vaf28MI+|lAwPj*Q$C5m;eIr9d ziQ)dq!PIbaGBI|1d?-1bNmE~9B01Tg8cX(NM#k=N(B$pOzVS?=cQEOh1H#K@2_mtY zjUuJs4V5f@E@SMJDitaP%*W*m3VfYW_0K`CE6gN2LbW&G(hJ{feU7J-W0SXz3?(O%!xNLEVg&HQ^V;@ zVsOx*p{LZ?$S|7?tYay*&*W$#b1SV~HDZP5 z!j9|Wq)?VS;?A5QC8%m69t**n(lKMYh_xbd+P00^sp3MWP$?RT3KqiD9Kuz?CHEV4 z&MHV;UR}8?;;&UbTh5jiR##wzc?8SV6@6xT!79w0U85>v;qY`eYn@x8m2+rXtMCp* zouklrs)YD$meYncUqEI+h&dAlyD(Kh-s5wHd`*BidiQ*Gbp>xDt14G?>(;ZGGFc0L zIDpOAIB(Vuq2HLAo0-WjQ^ld78AnpPYBF~)95B(jRX-XKWO0lc#q0$s*)^5nrFAPpCaHz743BZ2K1BPcH zFcUAh+FrP7yYn`;Y(78fYc#{s8UV<3(pZVuGPsfZJdkc&{t9-b=}N37&*8QY@p zh&Tt2=Oi6sAE;WMEnTtjx`js|!71fz^3GJw*|17}FuP#RRWrzbD|_DYks^|-0n41l zJWPpz-fZq1=AFq9D3YqLw zs+2b_h{~L76$>*?rtax36q$`vXOS=xHysdm$znwYDY>0GvmwShc}U*h0_!=s6l zve4C(zG4Agi%zb%nx9F}E)~-9dC`9;d!aB3MS9H(4vuW59#5Y&&!CWkMiois3y5>Q79M?;N9z?8 zm|HlGgaoWT){eVyw{*kqb#`auY?-s1L)7%E%kHJQ7-_C70XJFVKCx%bWs721>~^d@aYt{pCW2x8T062l4xfSB%0tYi$nubE3QtgA5L)4#-S>qK8$FB zl6ZscNrXgRv+Z0!DE4A8ZX|9piTiV(jL548~|28*%_}h zH)*uaf}b@>&?%h5jY5KsdkWB*lTM<}qRgo$VGb<}>c@{;vrK9nfG!qBho0KKxg138 zoQ#d<-6AsAvJcC`6BXnbGFNOj$4)2EejY!aPN27wxQ_zkTDB_Bz${80H_MrU6kDV% z;JlNT?)hKqa1;h+acpv)1fEhJA|54y4}xCr6hEU9RTK7$@>w{F<0f#KP3#ifiz$ZT z9%g{i&h2ol5x7|r10RDX>`2f#<_q@a-^l=SE+#oO#Y0#-<>60uC7t4u6 z0s&u3d!(h^kE(VYceDNhj3%IP_mM3f4QLODnvRa(lebLX9epu;Q;>YorOyY0LGBNw zCcQz4G)0&GFuL?ygQLS2S-!{cg2VU6&h16f?DNdf)Z~!<)VaMP8h)FRmZjfuXy0{i zKL`f`toD`;wZpHqEd3qGfIN(jNJlV$dHB1Ii0Th0TRM&@w9k9c^tRi0#x#p~Nk90E(S$TK+oh`9pyhHWR|MAw0xg?cf-RS~3sBWN z6gpW;7`IUqB~O8}3MM%Gd^__4=L>`W`TN4}Vf;}bzvcDD>@ zN6Y0M>+!WAj%cdy45)#}OA&=a)$WOOg|4k0Ht1jagkG)F_wL@a4_mfE*WEaMc<-+0(Kuz&jCfgAVY8z6-Odz|mLhzx~x#D|la>ZATH z?-MWnOlcRgrfH1gsPhz{P$sgW%E^yS#jNCqTUmr&tzde*9j};D=8|#?t-iXY;2Xf7gpI^nGUWwRrJ+ z^eb>;>bvPQC)oDsUTYy+(odS_v&GZ>X3jY`KJ8dgPgmH4JZZa6Lpy#`V56=&|I5ne z)O$`}ICSu|2_?W7-*(*GWy;+q6fi@yZs|7NzdTrS%I-`%k6X2WPxCwrb8*%gc0I zd*dhc%kNM<9VcXKx6zu@D!%Z>9z5QU`&$owo|TI5^3zPQPRq6Xscqh;@h(|Gs=}Et zx8%{5F;3Qa28nG2eXgeI_|8FJWBfYpg?4)gAq>~8qT7foi_;+P!5bT6oIJAkaN@E$ z338ub;O9K2PD+$V^22Fcy&cwW&-UZFT;6WwjINx|L((PztJ%b?LSouNCpG>S))3VRzl~j^^-@tb5$8 zLqN$s+BIjDZnE(rdNynK%zDQhJvnpsrmQ_1pWoA^<4sy&+OR8Le3#xJO4qBxQh6Np z;Iws_M!ZvW=_Q;5AMF}isC(*ON1Zj;kieIl;uy(I8%#74;&+qg`1$Rhq{)%2t;?S8xtz zk9JLGi?-noN`&07hBlt+H!Rcr$PLv=0K<_RJPQF4*Z%hd2%f